Now that security, cgroup and locking APIs support working on individual images and we track the backing chain security info on a per-image basis we can finally kill swapping the disk source in virDomainDiskDef and use the virStorageSource directly. --- src/qemu/qemu_driver.c | 85 ++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 47 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fbab2f1..5203431 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12062,61 +12062,52 @@ typedef enum { VIR_DISK_CHAIN_READ_WRITE, } qemuDomainDiskChainMode; -/* Several operations end up adding or removing a single element of a - * disk backing file chain; this helper function ensures that the lock - * manager, cgroup device controller, and security manager labelling - * are all aware of each new file before it is added to a chain, and - * can revoke access to a file no longer needed in a chain. */ +/* Several operations end up adding or removing a single element of a disk + * backing file chain; this helper function ensures that the lock manager, + * cgroup device controller, and security manager labelling are all aware of + * each new file before it is added to a chain, and can revoke access to a file + * no longer needed in a chain. */ static int qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, virStorageSourcePtr elem, qemuDomainDiskChainMode mode) { - /* The easiest way to label a single file with the same - * permissions it would have as if part of the disk chain is to - * temporarily modify the disk in place. */ - virStorageSource origdisk; - bool origreadonly = disk->src->readonly; + bool readonly = elem->readonly; virQEMUDriverConfigPtr cfg = NULL; int ret = -1; - /* XXX Labelling of non-local files isn't currently supported */ - if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_NETWORK) - return 0; - cfg = virQEMUDriverGetConfig(driver); - /* XXX Need to refactor the security manager and lock daemon to - * operate directly on a virStorageSourcePtr plus tidbits rather - * than a full virDomainDiskDef. */ - memcpy(&origdisk, disk->src, sizeof(origdisk)); - memcpy(disk->src, elem, sizeof(*elem)); - disk->src->readonly = mode == VIR_DISK_CHAIN_READ_ONLY; + elem->readonly = mode == VIR_DISK_CHAIN_READ_ONLY; if (mode == VIR_DISK_CHAIN_NO_ACCESS) { - if (virSecurityManagerRestoreDiskLabel(driver->securityManager, - vm->def, disk) < 0) - VIR_WARN("Unable to restore security label on %s", disk->src->path); - if (qemuTeardownDiskCgroup(vm, disk) < 0) - VIR_WARN("Failed to teardown cgroup for disk path %s", - disk->src->path); - if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0) - VIR_WARN("Unable to release lock on %s", disk->src->path); - } else if (virDomainLockDiskAttach(driver->lockManager, cfg->uri, - vm, disk) < 0 || - qemuSetupDiskCgroup(vm, disk) < 0 || - virSecurityManagerSetDiskLabel(driver->securityManager, - vm->def, disk) < 0) { - goto cleanup; + if (virSecurityManagerRestoreImageLabel(driver->securityManager, + vm->def, elem) < 0) + VIR_WARN("Unable to restore security label on %s", elem->path); + + if (qemuSetImageCgroup(vm, elem, true) < 0) + VIR_WARN("Failed to teardown cgroup for disk path %s", elem->path); + + if (virDomainLockImageDetach(driver->lockManager, vm, elem) < 0) + VIR_WARN("Unable to release lock on %s", elem->path); + } else { + if (virDomainLockImageAttach(driver->lockManager, cfg->uri, + vm, elem) < 0) + goto cleanup; + + if (qemuSetImageCgroup(vm, elem, false) < 0) + goto cleanup; + + if (virSecurityManagerSetImageLabel(driver->securityManager, + vm->def, elem) < 0) + goto cleanup; } ret = 0; cleanup: - memcpy(disk->src, &origdisk, sizeof(origdisk)); - disk->src->readonly = origreadonly; + elem->readonly = readonly; virObjectUnref(cfg); return ret; } @@ -12885,9 +12876,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, VIR_FORCE_CLOSE(fd); } - if (qemuDomainPrepareDiskChainElement(driver, vm, disk, snap->src, + if (qemuDomainPrepareDiskChainElement(driver, vm, snap->src, VIR_DISK_CHAIN_READ_WRITE) < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, disk, snap->src, + qemuDomainPrepareDiskChainElement(driver, vm, snap->src, VIR_DISK_CHAIN_NO_ACCESS); goto cleanup; } @@ -12982,7 +12973,7 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver, ignore_value(virStorageFileInit(disk->src)); - qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src, + qemuDomainPrepareDiskChainElement(driver, vm, disk->src, VIR_DISK_CHAIN_NO_ACCESS); if (need_unlink && virStorageFileStat(disk->src, &st) == 0 && S_ISREG(st.st_mode) && @@ -15300,9 +15291,9 @@ qemuDomainBlockCopy(virDomainObjPtr vm, if (VIR_STRDUP(mirror->path, dest) < 0) goto endjob; - if (qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, + if (qemuDomainPrepareDiskChainElement(driver, vm, mirror, VIR_DISK_CHAIN_READ_WRITE) < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, + qemuDomainPrepareDiskChainElement(driver, vm, mirror, VIR_DISK_CHAIN_NO_ACCESS); goto endjob; } @@ -15314,7 +15305,7 @@ qemuDomainBlockCopy(virDomainObjPtr vm, virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0); qemuDomainObjExitMonitor(driver, vm); if (ret < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, + qemuDomainPrepareDiskChainElement(driver, vm, mirror, VIR_DISK_CHAIN_NO_ACCESS); goto endjob; } @@ -15516,10 +15507,10 @@ qemuDomainBlockCommit(virDomainPtr dom, * operation succeeds, but doing that requires tracking the * operation in XML across libvirtd restarts. */ clean_access = true; - if (qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource, + if (qemuDomainPrepareDiskChainElement(driver, vm, baseSource, VIR_DISK_CHAIN_READ_WRITE) < 0 || (top_parent != disk->src && - qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, + qemuDomainPrepareDiskChainElement(driver, vm, top_parent, VIR_DISK_CHAIN_READ_WRITE) < 0)) goto endjob; @@ -15538,10 +15529,10 @@ qemuDomainBlockCommit(virDomainPtr dom, endjob: if (ret < 0 && clean_access) { /* Revert access to read-only, if possible. */ - qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource, + qemuDomainPrepareDiskChainElement(driver, vm, baseSource, VIR_DISK_CHAIN_READ_ONLY); if (top_parent != disk->src) - qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, + qemuDomainPrepareDiskChainElement(driver, vm, top_parent, VIR_DISK_CHAIN_READ_ONLY); } if (!qemuDomainObjEndJob(driver, vm)) -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list