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