984721
From d415286e93faf2f9c4fa5c5c589aa8d3f433d01d Mon Sep 17 00:00:00 2001
984721
Message-Id: <d415286e93faf2f9c4fa5c5c589aa8d3f433d01d@dist-git>
984721
From: Michal Privoznik <mprivozn@redhat.com>
984721
Date: Fri, 19 Jun 2020 11:43:13 +0200
984721
Subject: [PATCH] qemu: Create multipath targets for PRs
984721
MIME-Version: 1.0
984721
Content-Type: text/plain; charset=UTF-8
984721
Content-Transfer-Encoding: 8bit
984721
984721
If a disk has persistent reservations enabled, qemu-pr-helper
984721
might open not only /dev/mapper/control but also individual
984721
targets of the multipath device. We are already querying for them
984721
in CGroups, but now we have to create them in the namespace too.
984721
This was brought up in [1].
984721
984721
1: https://bugzilla.redhat.com/show_bug.cgi?id=1711045#c61
984721
984721
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
984721
Tested-by: Lin Ma <LMa@suse.com>
984721
Reviewed-by: Jim Fehlig <jfehlig@suse.com>
984721
(cherry picked from commit a30078cb832646177defd256e77c632905f1e6d0)
984721
984721
https://bugzilla.redhat.com/show_bug.cgi?id=1839992
984721
984721
Conflicts:
984721
- src/qemu/qemu_domain.c: Well, the upstream has NVMe and
984721
  downstream doesn't. So the functions I'm modifying look
984721
  different in the upstream. Tough luck.
984721
- src/util/virdevmapper.h: The upstream moved to gnulib macros
984721
  (G_GNUC_NO_INLINE in this case). But since I'm removing changes
984721
  to qemuhotplugtest below, this particular change wasn't needed.
984721
  The include of "internal.h" is though (because of next commit).
984721
- tests/qemuhotplugmock.c:
984721
- tests/qemuhotplugtest.c: I'm completely dropping these two
984721
  changes because the upstream went a long way since and these
984721
  are only tests.
984721
984721
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
984721
Message-Id: <f33e5c3f08bb8ea4e5fb65d6ee3e7542cdddf3b0.1592559697.git.mprivozn@redhat.com>
984721
Reviewed-by: Ján Tomko <jtomko@redhat.com>
984721
---
984721
 src/qemu/qemu_domain.c  | 59 ++++++++++++++++++++++++++++-------------
984721
 src/util/virdevmapper.h |  2 ++
984721
 2 files changed, 42 insertions(+), 19 deletions(-)
984721
984721
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
984721
index b4792c9476..489e20a28a 100644
984721
--- a/src/qemu/qemu_domain.c
984721
+++ b/src/qemu/qemu_domain.c
984721
@@ -57,6 +57,7 @@
984721
 #include "secret_util.h"
984721
 #include "logging/log_manager.h"
984721
 #include "locking/domain_lock.h"
984721
+#include "virdevmapper.h"
984721
 
984721
 #ifdef MAJOR_IN_MKDEV
984721
 # include <sys/mkdev.h>
984721
@@ -11325,13 +11326,29 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
984721
     int ret = -1;
984721
 
984721
     for (next = disk->src; virStorageSourceIsBacking(next); next = next->backingStore) {
984721
+        VIR_AUTOSTRINGLIST targetPaths = NULL;
984721
+        size_t i;
984721
+
984721
         if (!next->path || !virStorageSourceIsLocalStorage(next)) {
984721
             /* Not creating device. Just continue. */
984721
             continue;
984721
         }
984721
 
984721
         if (qemuDomainCreateDevice(next->path, data, false) < 0)
984721
-            goto cleanup;
984721
+            return -1;
984721
+
984721
+        if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
984721
+            errno != ENOSYS && errno != EBADF) {
984721
+            virReportSystemError(errno,
984721
+                                 _("Unable to get devmapper targets for %s"),
984721
+                                 next->path);
984721
+            return -1;
984721
+        }
984721
+
984721
+        for (i = 0; targetPaths && targetPaths[i]; i++) {
984721
+            if (qemuDomainCreateDevice(targetPaths[i], data, false) < 0)
984721
+                return -1;
984721
+        }
984721
     }
984721
 
984721
     /* qemu-pr-helper might require access to /dev/mapper/control. */
984721
@@ -12342,39 +12359,43 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
984721
                              virStorageSourcePtr src)
984721
 {
984721
     virStorageSourcePtr next;
984721
-    const char **paths = NULL;
984721
+    VIR_AUTOSTRINGLIST paths = NULL;
984721
     size_t npaths = 0;
984721
-    char *dmPath = NULL;
984721
-    int ret = -1;
984721
-
984721
-    if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
984721
-        return 0;
984721
 
984721
     for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) {
984721
+        VIR_AUTOSTRINGLIST targetPaths = NULL;
984721
+
984721
         if (virStorageSourceIsEmpty(next) ||
984721
             !virStorageSourceIsLocalStorage(next)) {
984721
             /* Not creating device. Just continue. */
984721
             continue;
984721
         }
984721
 
984721
-        if (VIR_APPEND_ELEMENT_COPY(paths, npaths, next->path) < 0)
984721
-            goto cleanup;
984721
+        if (virStringListAdd(&paths, next->path) < 0)
984721
+            return -1;
984721
+
984721
+        if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
984721
+            errno != ENOSYS && errno != EBADF) {
984721
+            virReportSystemError(errno,
984721
+                                 _("Unable to get devmapper targets for %s"),
984721
+                                 next->path);
984721
+            return -1;
984721
+        }
984721
+
984721
+        if (virStringListMerge(&paths, &targetPaths) < 0)
984721
+            return -1;
984721
     }
984721
 
984721
     /* qemu-pr-helper might require access to /dev/mapper/control. */
984721
     if (src->pr &&
984721
-        (VIR_STRDUP(dmPath, DEVICE_MAPPER_CONTROL_PATH) < 0 ||
984721
-         VIR_APPEND_ELEMENT_COPY(paths, npaths, dmPath) < 0))
984721
-        goto cleanup;
984721
+        virStringListAdd(&paths, DEVICE_MAPPER_CONTROL_PATH) < 0)
984721
+        return -1;
984721
 
984721
-    if (qemuDomainNamespaceMknodPaths(vm, paths, npaths) < 0)
984721
-        goto cleanup;
984721
+    npaths = virStringListLength((const char **) paths);
984721
+    if (qemuDomainNamespaceMknodPaths(vm, (const char **) paths, npaths) < 0)
984721
+        return -1;
984721
 
984721
-    ret = 0;
984721
- cleanup:
984721
-    VIR_FREE(dmPath);
984721
-    VIR_FREE(paths);
984721
-    return ret;
984721
+    return 0;
984721
 }
984721
 
984721
 
984721
diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h
984721
index 34d6655e77..42a7828fde 100644
984721
--- a/src/util/virdevmapper.h
984721
+++ b/src/util/virdevmapper.h
984721
@@ -24,6 +24,8 @@
984721
 #ifndef __VIR_DEVMAPPER_H__
984721
 # define __VIR_DEVMAPPER_H__
984721
 
984721
+#include "internal.h"
984721
+
984721
 int
984721
 virDevMapperGetTargets(const char *path,
984721
                        char ***devPaths);
984721
-- 
984721
2.27.0
984721