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