[PATCH 1/2] qemu: make sure capability probing process can start

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When daemon is killed right in the middle of probing a qemu binary for
its capabilities, the VM is left running.  Next time the daemon is
starting, it cannot start qemu process because the one that's already
running does have the pidfile flock()'d.

Reported-by: Wang Yufei <james.wangyufei@xxxxxxxxxx>

Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx>
---
 src/qemu/qemu_capabilities.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6fcb5c7..919780e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3243,6 +3243,47 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
     config.data.nix.path = monpath;
     config.data.nix.listen = false;

+    /*
+     * Check if there wasn't some older qemu left running, e.g. if
+     * someone killed libvirtd during the probing phase.
+     */
+    if (virFileExists(pidfile) &&
+        virPidFileReadPath(pidfile, &pid) == 0) {
+        char *cmdpath = NULL;
+        char *cmdline = NULL;
+        int len, pos = 0;
+
+        VIR_DEBUG("Checking if there's an older qemu process left running that "
+                  "was used for capability probing");
+
+        if (virAsprintf(&cmdpath, "/proc/%u/cmdline", pid) < 0)
+            goto cleanup;
+
+        len = virFileReadAll(cmdpath, 1024, &cmdline);
+        VIR_FREE(cmdpath);
+
+        /*
+         * This cycle gets trivially skipped if there was an error in
+         * virFileReadAll().
+         */
+        while (len > pos) {
+            /*
+             * Find the '-pidfile /path/to/capabilities.pidfile' to be
+             * sure we won't kill anyone else.
+             */
+            if (STREQ_NULLABLE(cmdline + pos, "-pidfile") &&
+                (pos += strlen(cmdline + pos) + 1) < len &&
+                STREQ_NULLABLE(cmdline + pos, pidfile)) {
+                virProcessKillPainfully(pid, true);
+                break;
+            }
+
+            pos += strlen(cmdline + pos) + 1;
+        }
+
+        VIR_FREE(cmdline);
+    }
+
     VIR_DEBUG("Try to get caps via QMP qemuCaps=%p", qemuCaps);

     /*
-- 
2.1.2

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]