render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
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