aff97e
From 7da89c42f92a7ce7430908ab08ea3b380306b603 Mon Sep 17 00:00:00 2001
3ec523
From: Michal Privoznik <mprivozn@redhat.com>
3ec523
Date: Thu, 11 Sep 2014 13:17:11 +0200
3ec523
Subject: [PATCH] virDomainUndefineFlags: Allow NVRAM unlinking
3ec523
3ec523
When a domain is undefined, there are options to remove it's
3ec523
managed save state or snapshots. However, there's another file
3ec523
that libvirt creates per domain: the NVRAM variable store file.
3ec523
Make sure that the file is not left behind if the domain is
3ec523
undefined.
3ec523
3ec523
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
3ec523
(cherry picked from commit 273b6581ca8dae11e6ff40e3d13813fdbb37d41b)
3ec523
---
3ec523
 include/libvirt/libvirt.h.in |  2 ++
3ec523
 src/qemu/qemu_driver.c       | 20 +++++++++++++++++++-
3ec523
 tools/virsh-domain.c         | 20 ++++++++++++++++----
3ec523
 tools/virsh.pod              |  6 +++++-
3ec523
 4 files changed, 42 insertions(+), 6 deletions(-)
3ec523
3ec523
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
3ec523
index a64f597..8996231 100644
3ec523
--- a/include/libvirt/libvirt.h.in
3ec523
+++ b/include/libvirt/libvirt.h.in
3ec523
@@ -2257,6 +2257,8 @@ typedef enum {
3ec523
     VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA = (1 << 1), /* If last use of domain,
3ec523
                                                           then also remove any
3ec523
                                                           snapshot metadata */
3ec523
+    VIR_DOMAIN_UNDEFINE_NVRAM              = (1 << 2), /* Also remove any
3ec523
+                                                          nvram file */
3ec523
 
3ec523
     /* Future undefine control flags should come here. */
3ec523
 } virDomainUndefineFlagsValues;
3ec523
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
3ec523
index 239a300..588eba4 100644
3ec523
--- a/src/qemu/qemu_driver.c
3ec523
+++ b/src/qemu/qemu_driver.c
3ec523
@@ -6402,7 +6402,8 @@ qemuDomainUndefineFlags(virDomainPtr dom,
3ec523
     virQEMUDriverConfigPtr cfg = NULL;
3ec523
 
3ec523
     virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
3ec523
-                  VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
3ec523
+                  VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
3ec523
+                  VIR_DOMAIN_UNDEFINE_NVRAM, -1);
3ec523
 
3ec523
     if (!(vm = qemuDomObjFromDomain(dom)))
3ec523
         return -1;
3ec523
@@ -6451,6 +6452,23 @@ qemuDomainUndefineFlags(virDomainPtr dom,
3ec523
         }
3ec523
     }
3ec523
 
3ec523
+    if (!virDomainObjIsActive(vm) &&
3ec523
+        vm->def->os.loader && vm->def->os.loader->nvram &&
3ec523
+        virFileExists(vm->def->os.loader->nvram)) {
3ec523
+        if (!(flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {
3ec523
+            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3ec523
+                           _("cannot delete inactive domain with nvram"));
3ec523
+            goto cleanup;
3ec523
+        }
3ec523
+
3ec523
+        if (unlink(vm->def->os.loader->nvram) < 0) {
3ec523
+            virReportSystemError(errno,
3ec523
+                                 _("failed to remove nvram: %s"),
3ec523
+                                 vm->def->os.loader->nvram);
3ec523
+            goto cleanup;
3ec523
+        }
3ec523
+    }
3ec523
+
3ec523
     if (virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm) < 0)
3ec523
         goto cleanup;
3ec523
 
3ec523
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
3ec523
index c75cd73..d84db51 100644
3ec523
--- a/tools/virsh-domain.c
3ec523
+++ b/tools/virsh-domain.c
3ec523
@@ -3038,6 +3038,10 @@ static const vshCmdOptDef opts_undefine[] = {
3ec523
      .type = VSH_OT_BOOL,
3ec523
      .help = N_("remove all domain snapshot metadata, if inactive")
3ec523
     },
3ec523
+    {.name = "nvram",
3ec523
+     .type = VSH_OT_BOOL,
3ec523
+     .help = N_("remove nvram file, if inactive")
3ec523
+    },
3ec523
     {.name = NULL}
3ec523
 };
3ec523
 
3ec523
@@ -3060,6 +3064,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
3ec523
     bool snapshots_metadata = vshCommandOptBool(cmd, "snapshots-metadata");
3ec523
     bool wipe_storage = vshCommandOptBool(cmd, "wipe-storage");
3ec523
     bool remove_all_storage = vshCommandOptBool(cmd, "remove-all-storage");
3ec523
+    bool nvram = vshCommandOptBool(cmd, "nvram");
3ec523
     /* Positive if these items exist.  */
3ec523
     int has_managed_save = 0;
3ec523
     int has_snapshots_metadata = 0;
3ec523
@@ -3103,6 +3108,9 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
3ec523
         flags |= VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA;
3ec523
         snapshots_safe = true;
3ec523
     }
3ec523
+    if (nvram) {
3ec523
+        flags |= VIR_DOMAIN_UNDEFINE_NVRAM;
3ec523
+    }
3ec523
 
3ec523
     if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
3ec523
         return false;
3ec523
@@ -3293,11 +3301,15 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
3ec523
      * VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in 0.9.4, the
3ec523
      * VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA flag was not present
3ec523
      * until 0.9.5; skip to piecewise emulation if we couldn't prove
3ec523
-     * above that the new API is safe.  */
3ec523
-    if (managed_save_safe && snapshots_safe) {
3ec523
+     * above that the new API is safe.
3ec523
+     * Moreover, only the newer UndefineFlags() API understands
3ec523
+     * the VIR_DOMAIN_UNDEFINE_NVRAM flag. So if user has
3ec523
+     * specified --nvram we must use the Flags() API. */
3ec523
+    if ((managed_save_safe && snapshots_safe) || nvram) {
3ec523
         rc = virDomainUndefineFlags(dom, flags);
3ec523
-        if (rc == 0 || (last_error->code != VIR_ERR_NO_SUPPORT &&
3ec523
-                        last_error->code != VIR_ERR_INVALID_ARG))
3ec523
+        if (rc == 0 || nvram ||
3ec523
+            (last_error->code != VIR_ERR_NO_SUPPORT &&
3ec523
+             last_error->code != VIR_ERR_INVALID_ARG))
3ec523
             goto out;
3ec523
         vshResetLibvirtError();
3ec523
     }
3ec523
diff --git a/tools/virsh.pod b/tools/virsh.pod
3ec523
index ea9267e..a9fad73 100644
3ec523
--- a/tools/virsh.pod
3ec523
+++ b/tools/virsh.pod
3ec523
@@ -2058,7 +2058,7 @@ Output the device used for the TTY console of the domain. If the information
3ec523
 is not available the processes will provide an exit code of 1.
3ec523
 
3ec523
 =item B<undefine> I<domain> [I<--managed-save>] [I<--snapshots-metadata>]
3ec523
-[ {I<--storage> B<volumes> | I<--remove-all-storage>} I<--wipe-storage>]
3ec523
+[I<--nvram>] [ {I<--storage> B<volumes> | I<--remove-all-storage>} I<--wipe-storage>]
3ec523
 
3ec523
 Undefine a domain. If the domain is running, this converts it to a
3ec523
 transient domain, without stopping it. If the domain is inactive,
3ec523
@@ -2074,6 +2074,10 @@ domain.  Without the flag, attempts to undefine an inactive domain with
3ec523
 snapshot metadata will fail.  If the domain is active, this flag is
3ec523
 ignored.
3ec523
 
3ec523
+The I<--nvram> flag ensures no nvram (/domain/os/nvram/) file is
3ec523
+left behind. If the domain has an nvram file and the flag is
3ec523
+omitted, the undefine will fail.
3ec523
+
3ec523
 The I<--storage> flag takes a parameter B<volumes>, which is a comma separated
3ec523
 list of volume target names or source paths of storage volumes to be removed
3ec523
 along with the undefined domain. Volumes can be undefined and thus removed only