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