From f30ba86ea92bb2a77b9620cea318bc3ebe0bf2a5 Mon Sep 17 00:00:00 2001 Message-Id: From: Michal Privoznik Date: Tue, 9 Jan 2018 09:34:24 +0100 Subject: [PATCH] qemuDomainAttachDeviceMknodHelper: Remove symlink before creating it RHEL-7.5: https://bugzilla.redhat.com/show_bug.cgi?id=1528502 RHEL-7.4.z: https://bugzilla.redhat.com/show_bug.cgi?id=1532183 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 Reviewed-by: Andrea Bolognani (cherry picked from commit db98e7f67ea0d7699410f514f01947cef5128a6c) Signed-off-by: Michal Privoznik Signed-off-by: Jiri Denemark Reviewed-by: Andrea Bolognani --- 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 dd70bd6367..ade06f07db 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8470,13 +8470,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; } -- 2.15.1