1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: Refactor qemuDomainPrepareDiskChainElement

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.
This commit is contained in:
Peter Krempa 2014-06-25 17:23:44 +02:00
parent 363e9a68d4
commit 66df8bf4e7

View File

@ -12066,61 +12066,52 @@ typedef enum {
VIR_DISK_CHAIN_READ_WRITE, VIR_DISK_CHAIN_READ_WRITE,
} qemuDomainDiskChainMode; } qemuDomainDiskChainMode;
/* Several operations end up adding or removing a single element of a /* Several operations end up adding or removing a single element of a disk
* disk backing file chain; this helper function ensures that the lock * backing file chain; this helper function ensures that the lock manager,
* manager, cgroup device controller, and security manager labelling * cgroup device controller, and security manager labelling are all aware of
* are all aware of each new file before it is added to a chain, and * each new file before it is added to a chain, and can revoke access to a file
* can revoke access to a file no longer needed in a chain. */ * no longer needed in a chain. */
static int static int
qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver, qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr disk,
virStorageSourcePtr elem, virStorageSourcePtr elem,
qemuDomainDiskChainMode mode) qemuDomainDiskChainMode mode)
{ {
/* The easiest way to label a single file with the same bool readonly = elem->readonly;
* 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;
virQEMUDriverConfigPtr cfg = NULL; virQEMUDriverConfigPtr cfg = NULL;
int ret = -1; 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); cfg = virQEMUDriverGetConfig(driver);
/* XXX Need to refactor the security manager and lock daemon to elem->readonly = mode == VIR_DISK_CHAIN_READ_ONLY;
* 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;
if (mode == VIR_DISK_CHAIN_NO_ACCESS) { if (mode == VIR_DISK_CHAIN_NO_ACCESS) {
if (virSecurityManagerRestoreDiskLabel(driver->securityManager, if (virSecurityManagerRestoreImageLabel(driver->securityManager,
vm->def, disk) < 0) vm->def, elem) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src->path); VIR_WARN("Unable to restore security label on %s", elem->path);
if (qemuTeardownDiskCgroup(vm, disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s", if (qemuSetImageCgroup(vm, elem, true) < 0)
disk->src->path); VIR_WARN("Failed to teardown cgroup for disk path %s", elem->path);
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
VIR_WARN("Unable to release lock on %s", disk->src->path); if (virDomainLockImageDetach(driver->lockManager, vm, elem) < 0)
} else if (virDomainLockDiskAttach(driver->lockManager, cfg->uri, VIR_WARN("Unable to release lock on %s", elem->path);
vm, disk) < 0 || } else {
qemuSetupDiskCgroup(vm, disk) < 0 || if (virDomainLockImageAttach(driver->lockManager, cfg->uri,
virSecurityManagerSetDiskLabel(driver->securityManager, vm, elem) < 0)
vm->def, disk) < 0) { goto cleanup;
goto cleanup;
if (qemuSetImageCgroup(vm, elem, false) < 0)
goto cleanup;
if (virSecurityManagerSetImageLabel(driver->securityManager,
vm->def, elem) < 0)
goto cleanup;
} }
ret = 0; ret = 0;
cleanup: cleanup:
memcpy(disk->src, &origdisk, sizeof(origdisk)); elem->readonly = readonly;
disk->src->readonly = origreadonly;
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;
} }
@ -12889,9 +12880,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(fd);
} }
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, snap->src, if (qemuDomainPrepareDiskChainElement(driver, vm, snap->src,
VIR_DISK_CHAIN_READ_WRITE) < 0) { VIR_DISK_CHAIN_READ_WRITE) < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, snap->src, qemuDomainPrepareDiskChainElement(driver, vm, snap->src,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto cleanup; goto cleanup;
} }
@ -12986,7 +12977,7 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
ignore_value(virStorageFileInit(disk->src)); ignore_value(virStorageFileInit(disk->src));
qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src, qemuDomainPrepareDiskChainElement(driver, vm, disk->src,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
if (need_unlink && if (need_unlink &&
virStorageFileStat(disk->src, &st) == 0 && S_ISREG(st.st_mode) && virStorageFileStat(disk->src, &st) == 0 && S_ISREG(st.st_mode) &&
@ -15345,9 +15336,9 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
if (virStorageSourceInitChainElement(disk->mirror, disk->src, false) < 0) if (virStorageSourceInitChainElement(disk->mirror, disk->src, false) < 0)
goto endjob; goto endjob;
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, if (qemuDomainPrepareDiskChainElement(driver, vm, mirror,
VIR_DISK_CHAIN_READ_WRITE) < 0) { VIR_DISK_CHAIN_READ_WRITE) < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, qemuDomainPrepareDiskChainElement(driver, vm, mirror,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto endjob; goto endjob;
} }
@ -15359,7 +15350,7 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0); virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
qemuDomainObjExitMonitor(driver, vm); qemuDomainObjExitMonitor(driver, vm);
if (ret < 0) { if (ret < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, mirror, qemuDomainPrepareDiskChainElement(driver, vm, mirror,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto endjob; goto endjob;
} }
@ -15566,10 +15557,10 @@ qemuDomainBlockCommit(virDomainPtr dom,
* operation succeeds, but doing that requires tracking the * operation succeeds, but doing that requires tracking the
* operation in XML across libvirtd restarts. */ * operation in XML across libvirtd restarts. */
clean_access = true; clean_access = true;
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource, if (qemuDomainPrepareDiskChainElement(driver, vm, baseSource,
VIR_DISK_CHAIN_READ_WRITE) < 0 || VIR_DISK_CHAIN_READ_WRITE) < 0 ||
(top_parent && top_parent != disk->src && (top_parent && top_parent != disk->src &&
qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, qemuDomainPrepareDiskChainElement(driver, vm, top_parent,
VIR_DISK_CHAIN_READ_WRITE) < 0)) VIR_DISK_CHAIN_READ_WRITE) < 0))
goto endjob; goto endjob;
@ -15612,10 +15603,10 @@ qemuDomainBlockCommit(virDomainPtr dom,
endjob: endjob:
if (ret < 0 && clean_access) { if (ret < 0 && clean_access) {
/* Revert access to read-only, if possible. */ /* Revert access to read-only, if possible. */
qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource, qemuDomainPrepareDiskChainElement(driver, vm, baseSource,
VIR_DISK_CHAIN_READ_ONLY); VIR_DISK_CHAIN_READ_ONLY);
if (top_parent && top_parent != disk->src) if (top_parent && top_parent != disk->src)
qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, qemuDomainPrepareDiskChainElement(driver, vm, top_parent,
VIR_DISK_CHAIN_READ_ONLY); VIR_DISK_CHAIN_READ_ONLY);
} }
if (!qemuDomainObjEndJob(driver, vm)) if (!qemuDomainObjEndJob(driver, vm))