]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemuDomainAttachDeviceMknodHelper: Remove symlink before creating it
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 4 Jan 2018 10:11:53 +0000 (11:11 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 8 Jan 2018 08:53:48 +0000 (09:53 +0100)
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>
src/qemu/qemu_domain.c

index de46ab996265175e01a5b12bd51434c4cf2d0ac8..a88fe11996e653700bdeb0531d2fbd7c492f404b 100644 (file)
@@ -9745,13 +9745,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;
         }