render / rpms / libvirt

Forked from rpms/libvirt 11 months ago
Clone
43f536
From c7c9c9aba8445df4dcdf46e67860d4ab1ee6cf6b Mon Sep 17 00:00:00 2001
43f536
Message-Id: <c7c9c9aba8445df4dcdf46e67860d4ab1ee6cf6b@dist-git>
43f536
From: Michal Privoznik <mprivozn@redhat.com>
43f536
Date: Fri, 22 Nov 2019 16:43:59 +0100
43f536
Subject: [PATCH] qemu: Forcibly mknod() even if it exists
43f536
MIME-Version: 1.0
43f536
Content-Type: text/plain; charset=UTF-8
43f536
Content-Transfer-Encoding: 8bit
43f536
43f536
Another weird bug appeared concerning qemu namespaces. Basically
43f536
the problem is as follows:
43f536
43f536
1) Issue an API that causes libvirt to create a node in domain's
43f536
   namespace, say /dev/nvme0n1 with 8:0 as major:minor (the API can
43f536
   be attach-disk for instance). Or simply create the node from a
43f536
   console by hand.
43f536
43f536
2) Detach the disk from qemu.
43f536
43f536
3) Do something that makes /dev/nvme0n1 change it's minor number.
43f536
43f536
4) Try to attach the disk again.
43f536
43f536
The problem is, in a few cases - like disk-detach - we don't
43f536
remove the corresponding /dev node from the mount namespace
43f536
(because it may be used by some other disk's backing chain). But
43f536
this creates a problem, because if the node changes its MAJ:MIN
43f536
numbers we don't propagate the change into the domain's
43f536
namespace. We do plain mknod() and ignore EEXIST which obviously
43f536
is not enough because it doesn't guarantee that the node has
43f536
updated MAJ:MIN pair.
43f536
43f536
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
43f536
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
43f536
(cherry picked from commit cdd8a6690ee3fa4b4b8ca1d4531924bd33be136a)
43f536
43f536
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1775680
43f536
43f536
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
43f536
Message-Id: <ae34b78e6bac1be642301ba44c41c49f32db6cb0.1574437416.git.mprivozn@redhat.com>
43f536
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
43f536
---
43f536
 src/qemu/qemu_domain.c | 25 +++++++++----------------
43f536
 1 file changed, 9 insertions(+), 16 deletions(-)
43f536
43f536
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
43f536
index 249ec4d259..f2ff610750 100644
43f536
--- a/src/qemu/qemu_domain.c
43f536
+++ b/src/qemu/qemu_domain.c
43f536
@@ -11111,16 +11111,14 @@ qemuDomainCreateDeviceRecursive(const char *device,
43f536
                                             allow_noent, ttl - 1) < 0)
43f536
             goto cleanup;
43f536
     } else if (isDev) {
43f536
-        if (create &&
43f536
-            mknod(devicePath, sb.st_mode, sb.st_rdev) < 0) {
43f536
-            if (errno == EEXIST) {
43f536
-                ret = 0;
43f536
-            } else {
43f536
+        if (create) {
43f536
+            unlink(devicePath);
43f536
+            if (mknod(devicePath, sb.st_mode, sb.st_rdev) < 0) {
43f536
                 virReportSystemError(errno,
43f536
                                      _("Failed to make device %s"),
43f536
                                      devicePath);
43f536
+                goto cleanup;
43f536
             }
43f536
-            goto cleanup;
43f536
         }
43f536
     } else if (isReg) {
43f536
         if (create &&
43f536
@@ -11889,17 +11887,12 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
43f536
     } else if (isDev) {
43f536
         VIR_DEBUG("Creating dev %s (%d,%d)",
43f536
                   data->file, major(data->sb.st_rdev), minor(data->sb.st_rdev));
43f536
+        unlink(data->file);
43f536
         if (mknod(data->file, data->sb.st_mode, data->sb.st_rdev) < 0) {
43f536
-            /* Because we are not removing devices on hotunplug, or
43f536
-             * we might be creating part of backing chain that
43f536
-             * already exist due to a different disk plugged to
43f536
-             * domain, accept EEXIST. */
43f536
-            if (errno != EEXIST) {
43f536
-                virReportSystemError(errno,
43f536
-                                     _("Unable to create device %s"),
43f536
-                                     data->file);
43f536
-                goto cleanup;
43f536
-            }
43f536
+            virReportSystemError(errno,
43f536
+                                 _("Unable to create device %s"),
43f536
+                                 data->file);
43f536
+            goto cleanup;
43f536
         } else {
43f536
             delDevice = true;
43f536
         }
43f536
-- 
43f536
2.24.0
43f536