/**
* qemuDomainDiskChainElementPrepare:
+ * @driver: qemu driver data
+ * @vm: domain object
+ * @elem: source structure to set access for
+ * @readonly: setup read-only access if true
+ * @newSource: @elem describes a storage source which @vm can't access yet
*
* Allow a VM access to a single element of a disk backing chain; this helper
* 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 */
+ * labelling are all aware of each new file before it is added to a chain.
+ *
+ * When modifying permissions of @elem which @vm can already access (is in the
+ * backing chain) @newSource needs to be set to false.
+ */
int
qemuDomainDiskChainElementPrepare(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virStorageSourcePtr elem,
- bool readonly)
+ bool readonly,
+ bool newSource)
{
bool was_readonly = elem->readonly;
virQEMUDriverConfigPtr cfg = NULL;
if (virDomainLockImageAttach(driver->lockManager, cfg->uri, vm, elem) < 0)
goto cleanup;
- if (qemuDomainNamespaceSetupDisk(driver, vm, elem) < 0)
+ if (newSource &&
+ qemuDomainNamespaceSetupDisk(driver, vm, elem) < 0)
goto cleanup;
if (qemuSetupImageCgroup(vm, elem) < 0)
}
/* set correct security, cgroup and locking options on the new image */
- if (qemuDomainDiskChainElementPrepare(driver, vm, dd->src, false) < 0) {
+ if (qemuDomainDiskChainElementPrepare(driver, vm, dd->src, false, true) < 0) {
qemuDomainDiskChainElementRevoke(driver, vm, dd->src);
goto cleanup;
}
keepParentLabel) < 0)
goto endjob;
- if (qemuDomainDiskChainElementPrepare(driver, vm, mirror, false) < 0) {
+ if (qemuDomainDiskChainElementPrepare(driver, vm, mirror, false, true) < 0) {
qemuDomainDiskChainElementRevoke(driver, vm, mirror);
goto endjob;
}
* operation succeeds, but doing that requires tracking the
* operation in XML across libvirtd restarts. */
clean_access = true;
- if (qemuDomainDiskChainElementPrepare(driver, vm, baseSource, false) < 0 ||
+ if (qemuDomainDiskChainElementPrepare(driver, vm, baseSource, false, false) < 0 ||
(top_parent && top_parent != disk->src &&
- qemuDomainDiskChainElementPrepare(driver, vm, top_parent, false) < 0))
+ qemuDomainDiskChainElementPrepare(driver, vm, top_parent, false, false) < 0))
goto endjob;
/* Start the commit operation. Pass the user's original spelling,
if (ret < 0 && clean_access) {
virErrorPtr orig_err = virSaveLastError();
/* Revert access to read-only, if possible. */
- qemuDomainDiskChainElementPrepare(driver, vm, baseSource, true);
+ qemuDomainDiskChainElementPrepare(driver, vm, baseSource, true, false);
if (top_parent && top_parent != disk->src)
- qemuDomainDiskChainElementPrepare(driver, vm, top_parent, true);
+ qemuDomainDiskChainElementPrepare(driver, vm, top_parent, true, false);
if (orig_err) {
virSetError(orig_err);