[libvirt] [PATCHv7.6 9/9] blockjob: relabel entire existing chain

Eric Blake eblake at redhat.com
Mon Sep 24 15:59:43 UTC 2012


When using block copy to pivot over to a new chain, the backing files
for the new chain might still need labeling (particularly if the user
passes --reuse-ext with a relative backing file name).  Relabeling a
file that is already labeled won't hurt, so this just labels the entire
chain at the point of the pivot.

https://bugzilla.redhat.com/show_bug.cgi?id=856247

* src/qemu/qemu_driver.c (qemuDomainBlockPivot): Relabel chain before
asking qemu to pivot.
---

Diff from v7.5: relabel the new disk chain, not the old chain

 src/qemu/qemu_driver.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8201c9d..828ad6e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12596,6 +12596,9 @@ qemuDomainBlockPivot(virConnectPtr conn,
     virDomainBlockJobInfo info;
     bool reopen = qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_REOPEN);
     bool resume = false;
+    virCgroupPtr cgroup = NULL;
+    char *oldsrc = NULL;
+    char *olddriver = NULL;

     /* Probe the status, if needed.  */
     if (!disk->mirroring) {
@@ -12643,6 +12646,30 @@ qemuDomainBlockPivot(virConnectPtr conn,
         }
     }

+    /* We previously labeled only the top-level image; but if the
+     * image includes a relative backing file, the pivot may result in
+     * qemu needing to open the entire backing chain, so we need to
+     * label the entire chain.  This action is safe even if the
+     * backing chain has already been labeled.  */
+    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
+        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unable to find cgroup for %s"),
+                       vm->def->name);
+        goto cleanup;
+    }
+    oldsrc = disk->src;
+    olddriver = disk->driverType;
+    disk->src = disk->mirror;
+    disk->driverType = disk->mirrorFormat;
+    if ((cgroup && qemuSetupDiskCgroup(driver, vm, cgroup, disk) < 0) ||
+        virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
+                                        disk) < 0) {
+        disk->src = oldsrc;
+        disk->driverType = olddriver;
+        goto cleanup;
+    }
+
     /* Attempt the pivot.  */
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorDrivePivot(priv->mon, device, disk->mirror,
@@ -12662,10 +12689,8 @@ qemuDomainBlockPivot(virConnectPtr conn,
          * portion of the chain, and is made more difficult by the
          * fact that we aren't tracking the full chain ourselves; so
          * for now, we leak the access to the original.  */
-        VIR_FREE(disk->src);
-        VIR_FREE(disk->driverType);
-        disk->src = disk->mirror;
-        disk->driverType = disk->mirrorFormat;
+        VIR_FREE(oldsrc);
+        VIR_FREE(olddriver);
         disk->mirror = NULL;
         disk->mirrorFormat = NULL;
         disk->mirroring = false;
@@ -12677,12 +12702,16 @@ qemuDomainBlockPivot(virConnectPtr conn,
          * 'query-block', to see what state we really got left in
          * before killing the mirroring job?  And just as on the
          * success case, there's security labeling to worry about.  */
+        disk->src = oldsrc;
+        disk->driverType = olddriver;
         VIR_FREE(disk->mirror);
         VIR_FREE(disk->mirrorFormat);
         disk->mirroring = false;
     }

 cleanup:
+    if (cgroup)
+        virCgroupFree(&cgroup);
     if (resume && virDomainObjIsActive(vm) &&
         qemuProcessStartCPUs(driver, vm, conn,
                              VIR_DOMAIN_RUNNING_UNPAUSED,
-- 
1.7.11.4




More information about the libvir-list mailing list