render / rpms / libvirt

Forked from rpms/libvirt 5 months ago
Clone
404507
From 6c4c780eda082ef395b70af89b8b8942b9ad4a9d Mon Sep 17 00:00:00 2001
404507
Message-Id: <6c4c780eda082ef395b70af89b8b8942b9ad4a9d@dist-git>
23265d
From: Michal Privoznik <mprivozn@redhat.com>
404507
Date: Mon, 8 Jan 2018 10:16:19 +0100
23265d
Subject: [PATCH] qemuDomainAttachDeviceMknodHelper: Remove symlink before
23265d
 creating it
23265d
404507
https://bugzilla.redhat.com/show_bug.cgi?id=1528502
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
404507
index 8967f2774d..b0c78cc7c4 100644
23265d
--- a/src/qemu/qemu_domain.c
23265d
+++ b/src/qemu/qemu_domain.c
404507
@@ -9559,13 +9559,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