|
|
c1c534 |
From 2570986655a119553082702dad8f256fb72ead75 Mon Sep 17 00:00:00 2001
|
|
|
c1c534 |
Message-Id: <2570986655a119553082702dad8f256fb72ead75@dist-git>
|
|
|
c1c534 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c1c534 |
Date: Wed, 22 Nov 2017 18:21:35 +0100
|
|
|
c1c534 |
Subject: [PATCH] qemu: domain: Don't call namespace setup for storage already
|
|
|
c1c534 |
accessed by vm
|
|
|
c1c534 |
|
|
|
c1c534 |
When doing block commit we need to allow write for members of the
|
|
|
c1c534 |
backing chain so that we can commit the data into them.
|
|
|
c1c534 |
|
|
|
c1c534 |
qemuDomainDiskChainElementPrepare was used for this which since commit
|
|
|
c1c534 |
786d8d91b4 calls qemuDomainNamespaceSetupDisk which has very adverse
|
|
|
c1c534 |
side-effects, namely it relabels the nodes to the same label it has in
|
|
|
c1c534 |
the main namespace. This was messing up permissions for the commit
|
|
|
c1c534 |
operation since its touching various parts of a single backing chain.
|
|
|
c1c534 |
|
|
|
c1c534 |
Since we are are actually not introducing new images at that point add a
|
|
|
c1c534 |
flag for qemuDomainDiskChainElementPrepare which will refrain from
|
|
|
c1c534 |
calling to the namespace setup function.
|
|
|
c1c534 |
|
|
|
c1c534 |
Calls from qemuDomainSnapshotCreateSingleDiskActive and
|
|
|
c1c534 |
qemuDomainBlockCopyCommon do introduce new members all calls from
|
|
|
c1c534 |
qemuDomainBlockCommit do not, so the calls are anotated accordingly.
|
|
|
c1c534 |
|
|
|
c1c534 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1506072
|
|
|
c1c534 |
(cherry picked from commit 3746a38e7b9ae5342675547624122d55e73d6c81)
|
|
|
c1c534 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c1c534 |
---
|
|
|
c1c534 |
src/qemu/qemu_domain.c | 17 ++++++++++++++---
|
|
|
c1c534 |
src/qemu/qemu_domain.h | 3 ++-
|
|
|
c1c534 |
src/qemu/qemu_driver.c | 12 ++++++------
|
|
|
c1c534 |
3 files changed, 22 insertions(+), 10 deletions(-)
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
|
c1c534 |
index 485e085cea..72d67adfe3 100644
|
|
|
c1c534 |
--- a/src/qemu/qemu_domain.c
|
|
|
c1c534 |
+++ b/src/qemu/qemu_domain.c
|
|
|
c1c534 |
@@ -6074,15 +6074,25 @@ qemuDomainDiskChainElementRevoke(virQEMUDriverPtr driver,
|
|
|
c1c534 |
|
|
|
c1c534 |
/**
|
|
|
c1c534 |
* qemuDomainDiskChainElementPrepare:
|
|
|
c1c534 |
+ * @driver: qemu driver data
|
|
|
c1c534 |
+ * @vm: domain object
|
|
|
c1c534 |
+ * @elem: source structure to set access for
|
|
|
c1c534 |
+ * @readonly: setup read-only access if true
|
|
|
c1c534 |
+ * @newSource: @elem describes a storage source which @vm can't access yet
|
|
|
c1c534 |
*
|
|
|
c1c534 |
* Allow a VM access to a single element of a disk backing chain; this helper
|
|
|
c1c534 |
* ensures that the lock manager, cgroup device controller, and security manager
|
|
|
c1c534 |
- * labelling are all aware of each new file before it is added to a chain */
|
|
|
c1c534 |
+ * labelling are all aware of each new file before it is added to a chain.
|
|
|
c1c534 |
+ *
|
|
|
c1c534 |
+ * When modifying permissions of @elem which @vm can already access (is in the
|
|
|
c1c534 |
+ * backing chain) @newSource needs to be set to false.
|
|
|
c1c534 |
+ */
|
|
|
c1c534 |
int
|
|
|
c1c534 |
qemuDomainDiskChainElementPrepare(virQEMUDriverPtr driver,
|
|
|
c1c534 |
virDomainObjPtr vm,
|
|
|
c1c534 |
virStorageSourcePtr elem,
|
|
|
c1c534 |
- bool readonly)
|
|
|
c1c534 |
+ bool readonly,
|
|
|
c1c534 |
+ bool newSource)
|
|
|
c1c534 |
{
|
|
|
c1c534 |
bool was_readonly = elem->readonly;
|
|
|
c1c534 |
virQEMUDriverConfigPtr cfg = NULL;
|
|
|
c1c534 |
@@ -6095,7 +6105,8 @@ qemuDomainDiskChainElementPrepare(virQEMUDriverPtr driver,
|
|
|
c1c534 |
if (virDomainLockImageAttach(driver->lockManager, cfg->uri, vm, elem) < 0)
|
|
|
c1c534 |
goto cleanup;
|
|
|
c1c534 |
|
|
|
c1c534 |
- if (qemuDomainNamespaceSetupDisk(driver, vm, elem) < 0)
|
|
|
c1c534 |
+ if (newSource &&
|
|
|
c1c534 |
+ qemuDomainNamespaceSetupDisk(driver, vm, elem) < 0)
|
|
|
c1c534 |
goto cleanup;
|
|
|
c1c534 |
|
|
|
c1c534 |
if (qemuSetupImageCgroup(vm, elem) < 0)
|
|
|
c1c534 |
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|
|
c1c534 |
index ff5328277c..caf583373f 100644
|
|
|
c1c534 |
--- a/src/qemu/qemu_domain.h
|
|
|
c1c534 |
+++ b/src/qemu/qemu_domain.h
|
|
|
c1c534 |
@@ -688,7 +688,8 @@ void qemuDomainDiskChainElementRevoke(virQEMUDriverPtr driver,
|
|
|
c1c534 |
int qemuDomainDiskChainElementPrepare(virQEMUDriverPtr driver,
|
|
|
c1c534 |
virDomainObjPtr vm,
|
|
|
c1c534 |
virStorageSourcePtr elem,
|
|
|
c1c534 |
- bool readonly);
|
|
|
c1c534 |
+ bool readonly,
|
|
|
c1c534 |
+ bool newSource);
|
|
|
c1c534 |
|
|
|
c1c534 |
int qemuDomainCleanupAdd(virDomainObjPtr vm,
|
|
|
c1c534 |
qemuDomainCleanupCallback cb);
|
|
|
c1c534 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
c1c534 |
index 6096e00b2a..b35ab6d30e 100644
|
|
|
c1c534 |
--- a/src/qemu/qemu_driver.c
|
|
|
c1c534 |
+++ b/src/qemu/qemu_driver.c
|
|
|
c1c534 |
@@ -14578,7 +14578,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
/* set correct security, cgroup and locking options on the new image */
|
|
|
c1c534 |
- if (qemuDomainDiskChainElementPrepare(driver, vm, dd->src, false) < 0) {
|
|
|
c1c534 |
+ if (qemuDomainDiskChainElementPrepare(driver, vm, dd->src, false, true) < 0) {
|
|
|
c1c534 |
qemuDomainDiskChainElementRevoke(driver, vm, dd->src);
|
|
|
c1c534 |
goto cleanup;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
@@ -17173,7 +17173,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
|
|
|
c1c534 |
keepParentLabel) < 0)
|
|
|
c1c534 |
goto endjob;
|
|
|
c1c534 |
|
|
|
c1c534 |
- if (qemuDomainDiskChainElementPrepare(driver, vm, mirror, false) < 0) {
|
|
|
c1c534 |
+ if (qemuDomainDiskChainElementPrepare(driver, vm, mirror, false, true) < 0) {
|
|
|
c1c534 |
qemuDomainDiskChainElementRevoke(driver, vm, mirror);
|
|
|
c1c534 |
goto endjob;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
@@ -17566,9 +17566,9 @@ qemuDomainBlockCommit(virDomainPtr dom,
|
|
|
c1c534 |
* operation succeeds, but doing that requires tracking the
|
|
|
c1c534 |
* operation in XML across libvirtd restarts. */
|
|
|
c1c534 |
clean_access = true;
|
|
|
c1c534 |
- if (qemuDomainDiskChainElementPrepare(driver, vm, baseSource, false) < 0 ||
|
|
|
c1c534 |
+ if (qemuDomainDiskChainElementPrepare(driver, vm, baseSource, false, false) < 0 ||
|
|
|
c1c534 |
(top_parent && top_parent != disk->src &&
|
|
|
c1c534 |
- qemuDomainDiskChainElementPrepare(driver, vm, top_parent, false) < 0))
|
|
|
c1c534 |
+ qemuDomainDiskChainElementPrepare(driver, vm, top_parent, false, false) < 0))
|
|
|
c1c534 |
goto endjob;
|
|
|
c1c534 |
|
|
|
c1c534 |
/* Start the commit operation. Pass the user's original spelling,
|
|
|
c1c534 |
@@ -17612,9 +17612,9 @@ qemuDomainBlockCommit(virDomainPtr dom,
|
|
|
c1c534 |
if (ret < 0 && clean_access) {
|
|
|
c1c534 |
virErrorPtr orig_err = virSaveLastError();
|
|
|
c1c534 |
/* Revert access to read-only, if possible. */
|
|
|
c1c534 |
- qemuDomainDiskChainElementPrepare(driver, vm, baseSource, true);
|
|
|
c1c534 |
+ qemuDomainDiskChainElementPrepare(driver, vm, baseSource, true, false);
|
|
|
c1c534 |
if (top_parent && top_parent != disk->src)
|
|
|
c1c534 |
- qemuDomainDiskChainElementPrepare(driver, vm, top_parent, true);
|
|
|
c1c534 |
+ qemuDomainDiskChainElementPrepare(driver, vm, top_parent, true, false);
|
|
|
c1c534 |
|
|
|
c1c534 |
if (orig_err) {
|
|
|
c1c534 |
virSetError(orig_err);
|
|
|
c1c534 |
--
|
|
|
c1c534 |
2.15.0
|
|
|
c1c534 |
|