d759b5
From 29a17260cc1875640e62f63bfe7fa9661dc9fe70 Mon Sep 17 00:00:00 2001
d759b5
Message-Id: <29a17260cc1875640e62f63bfe7fa9661dc9fe70@dist-git>
43f536
From: Michal Privoznik <mprivozn@redhat.com>
d759b5
Date: Wed, 20 Nov 2019 14:34:11 +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
d759b5
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1752978
d759b5
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
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d759b5
Message-Id: <058a9025fdcb817d3334e6c5a7c6a4fe1e95e761.1574256841.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
d759b5
index e7d7a3baeb..3c67769771 100644
43f536
--- a/src/qemu/qemu_domain.c
43f536
+++ b/src/qemu/qemu_domain.c
d759b5
@@ -11191,16 +11191,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 &&
d759b5
@@ -11969,17 +11967,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