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