Blame SOURCES/libvirt-qemuDomainAttachDeviceMknodHelper-Remove-symlink-before-creating-it.patch

23265d
From f30ba86ea92bb2a77b9620cea318bc3ebe0bf2a5 Mon Sep 17 00:00:00 2001
23265d
Message-Id: <f30ba86ea92bb2a77b9620cea318bc3ebe0bf2a5@dist-git>
23265d
From: Michal Privoznik <mprivozn@redhat.com>
23265d
Date: Tue, 9 Jan 2018 09:34:24 +0100
23265d
Subject: [PATCH] qemuDomainAttachDeviceMknodHelper: Remove symlink before
23265d
 creating it
23265d
23265d
RHEL-7.5: https://bugzilla.redhat.com/show_bug.cgi?id=1528502
23265d
RHEL-7.4.z: https://bugzilla.redhat.com/show_bug.cgi?id=1532183
23265d
23265d
So imagine you have /dev/blah symlink which points to /dev/sda.
23265d
You attach /dev/blah as disk to your domain. Libvirt correctly
23265d
creates the /dev/blah -> /dev/sda symlink in the qemu namespace.
23265d
However, then you detach the disk, change the symlink so that it
23265d
points to /dev/sdb and tries to attach the disk again. This time,
23265d
however, the attach fails (well, qemu attaches wrong disk)
23265d
because the code assumes that symlinks don't change. Well they
23265d
do.
23265d
23265d
This is inspired by test fix written by Eduardo Habkost.
23265d
23265d
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
23265d
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
23265d
(cherry picked from commit db98e7f67ea0d7699410f514f01947cef5128a6c)
23265d
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
23265d
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
23265d
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
23265d
---
23265d
 src/qemu/qemu_domain.c | 22 ++++++++++++++++------
23265d
 1 file changed, 16 insertions(+), 6 deletions(-)
23265d
23265d
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
23265d
index dd70bd6367..ade06f07db 100644
23265d
--- a/src/qemu/qemu_domain.c
23265d
+++ b/src/qemu/qemu_domain.c
23265d
@@ -8470,13 +8470,23 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
23265d
 
23265d
     if (isLink) {
23265d
         VIR_DEBUG("Creating symlink %s -> %s", data->file, data->target);
23265d
+
23265d
+        /* First, unlink the symlink target. Symlinks change and
23265d
+         * therefore we have no guarantees that pre-existing
23265d
+         * symlink is still valid. */
23265d
+        if (unlink(data->file) < 0 &&
23265d
+            errno != ENOENT) {
23265d
+            virReportSystemError(errno,
23265d
+                                 _("Unable to remove symlink %s"),
23265d
+                                 data->file);
23265d
+            goto cleanup;
23265d
+        }
23265d
+
23265d
         if (symlink(data->target, data->file) < 0) {
23265d
-            if (errno != EEXIST) {
23265d
-                virReportSystemError(errno,
23265d
-                                     _("Unable to create symlink %s"),
23265d
-                                     data->target);
23265d
-                goto cleanup;
23265d
-            }
23265d
+            virReportSystemError(errno,
23265d
+                                 _("Unable to create symlink %s (pointing to %s)"),
23265d
+                                 data->file, data->target);
23265d
+            goto cleanup;
23265d
         } else {
23265d
             delDevice = true;
23265d
         }
23265d
-- 
23265d
2.15.1
23265d