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:
parent
363e9a68d4
commit
66df8bf4e7
@ -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;
|
||||||
|
|
||||||
|
if (qemuSetImageCgroup(vm, elem, false) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
||||||
|
vm->def, elem) < 0)
|
||||||
goto cleanup;
|
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))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user