Blame SOURCES/libvirt-qemu-domain-Don-t-call-namespace-setup-for-storage-already-accessed-by-vm.patch

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