[libvirt] [PATCH 5/7] qemu: Make QMP probing process reusable

Jiri Denemark jdenemar at redhat.com
Tue Jul 23 16:11:34 UTC 2013


---
 src/qemu/qemu_capabilities.c | 192 +++++++++++++++++++++++++++----------------
 1 file changed, 120 insertions(+), 72 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5dc3c9e..9440396 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2464,6 +2464,116 @@ cleanup:
     return ret;
 }
 
+static virCommandPtr
+virQEMUCapsInitQMPCommandNew(const char *binary,
+                             const char *monitor,
+                             const char *pidfile,
+                             uid_t runUid,
+                             gid_t runGid)
+{
+    virCommandPtr cmd;
+
+    /*
+     * We explicitly need to use -daemonize here, rather than
+     * virCommandDaemonize, because we need to synchronize
+     * with QEMU creating its monitor socket API. Using
+     * daemonize guarantees control won't return to libvirt
+     * until the socket is present.
+     */
+    cmd = virCommandNewArgList(binary,
+                               "-S",
+                               "-no-user-config",
+                               "-nodefaults",
+                               "-nographic",
+                               "-M", "none",
+                               "-qmp", monitor,
+                               "-pidfile", pidfile,
+                               "-daemonize",
+                               NULL);
+    virCommandAddEnvPassCommon(cmd);
+    virCommandClearCaps(cmd);
+    virCommandSetGID(cmd, runGid);
+    virCommandSetUID(cmd, runUid);
+    return cmd;
+}
+
+static int
+virQEMUCapsInitQMPCommandRun(virCommandPtr cmd,
+                             const char *binary,
+                             const char *pidfile,
+                             virDomainChrSourceDefPtr config,
+                             qemuMonitorPtr *mon,
+                             pid_t *pid)
+{
+    int status = 0;
+    virDomainObj vm;
+    int ret = -1;
+
+    if (virCommandRun(cmd, &status) < 0) {
+        ret = -2;
+        goto cleanup;
+    }
+
+    if (status != 0) {
+        VIR_DEBUG("QEMU %s exited with status %d", binary, status);
+        goto cleanup;
+    }
+
+    if (virPidFileReadPath(pidfile, pid) < 0) {
+        VIR_DEBUG("Failed to read pidfile %s", pidfile);
+        goto cleanup;
+    }
+
+    memset(&vm, 0, sizeof(vm));
+    vm.pid = *pid;
+
+    if (!(*mon = qemuMonitorOpen(&vm, config, true, &callbacks)))
+        goto cleanup;
+
+    virObjectLock(*mon);
+
+    if (qemuMonitorSetCapabilities(*mon) < 0) {
+        virErrorPtr err = virGetLastError();
+        VIR_DEBUG("Failed to set monitor capabilities %s",
+                  err ? err->message : "<unknown problem>");
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    return ret;
+}
+
+static void
+virQEMUCapsInitQMPCommandAbort(virCommandPtr *cmd,
+                               qemuMonitorPtr *mon,
+                               pid_t *pid,
+                               const char *pidfile)
+{
+    if (*mon)
+        virObjectUnlock(*mon);
+    qemuMonitorClose(*mon);
+    *mon = NULL;
+
+    virCommandAbort(*cmd);
+    virCommandFree(*cmd);
+    *cmd = NULL;
+
+    if (*pid != 0) {
+        char ebuf[1024];
+
+        VIR_DEBUG("Killing QMP caps process %lld", (long long) *pid);
+        if (virProcessKill(*pid, SIGKILL) < 0 && errno != ESRCH)
+            VIR_ERROR(_("Failed to kill process %lld: %s"),
+                      (long long) *pid,
+                      virStrerror(errno, ebuf, sizeof(ebuf)));
+        *pid = 0;
+    }
+
+    if (pidfile)
+        unlink(pidfile);
+}
+
 static int
 virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
                    const char *libDir,
@@ -2475,13 +2585,11 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
     qemuMonitorPtr mon = NULL;
     int major, minor, micro;
     char *package = NULL;
-    int status = 0;
     virDomainChrSourceDef config;
     char *monarg = NULL;
     char *monpath = NULL;
     char *pidfile = NULL;
     pid_t pid = 0;
-    virDomainObj vm;
 
     /* the ".sock" sufix is important to avoid a possible clash with a qemu
      * domain called "capabilities"
@@ -2507,58 +2615,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 
     VIR_DEBUG("Try to get caps via QMP qemuCaps=%p", qemuCaps);
 
-    /*
-     * We explicitly need to use -daemonize here, rather than
-     * virCommandDaemonize, because we need to synchronize
-     * with QEMU creating its monitor socket API. Using
-     * daemonize guarantees control won't return to libvirt
-     * until the socket is present.
-     */
-    cmd = virCommandNewArgList(qemuCaps->binary,
-                               "-S",
-                               "-no-user-config",
-                               "-nodefaults",
-                               "-nographic",
-                               "-M", "none",
-                               "-qmp", monarg,
-                               "-pidfile", pidfile,
-                               "-daemonize",
-                               NULL);
-    virCommandAddEnvPassCommon(cmd);
-    virCommandClearCaps(cmd);
-    virCommandSetGID(cmd, runGid);
-    virCommandSetUID(cmd, runUid);
-
-    if (virCommandRun(cmd, &status) < 0)
-        goto cleanup;
+    cmd = virQEMUCapsInitQMPCommandNew(qemuCaps->binary, monarg, pidfile,
+                                       runUid, runGid);
 
-    if (status != 0) {
-        ret = 0;
-        VIR_DEBUG("QEMU %s exited with status %d", qemuCaps->binary, status);
-        goto cleanup;
-    }
-
-    if (virPidFileReadPath(pidfile, &pid) < 0) {
-        VIR_DEBUG("Failed to read pidfile %s", pidfile);
-        ret = 0;
-        goto cleanup;
-    }
-
-    memset(&vm, 0, sizeof(vm));
-    vm.pid = pid;
-
-    if (!(mon = qemuMonitorOpen(&vm, &config, true, &callbacks))) {
-        ret = 0;
-        goto cleanup;
-    }
-
-    virObjectLock(mon);
-
-    if (qemuMonitorSetCapabilities(mon) < 0) {
-        virErrorPtr err = virGetLastError();
-        VIR_DEBUG("Failed to set monitor capabilities %s",
-                  err ? err->message : "<unknown problem>");
-        ret = 0;
+    if ((ret = virQEMUCapsInitQMPCommandRun(cmd, qemuCaps->binary, pidfile,
+                                            &config, &mon, &pid)) < 0) {
+        if (ret == -2)
+            ret = -1;
+        else
+            ret = 0;
         goto cleanup;
     }
 
@@ -2617,28 +2682,11 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
     ret = 0;
 
 cleanup:
-    if (mon)
-        virObjectUnlock(mon);
-    qemuMonitorClose(mon);
-    virCommandAbort(cmd);
-    virCommandFree(cmd);
+    virQEMUCapsInitQMPCommandAbort(&cmd, &mon, &pid, pidfile);
     VIR_FREE(monarg);
     VIR_FREE(monpath);
     VIR_FREE(package);
-
-    if (pid != 0) {
-        char ebuf[1024];
-
-        VIR_DEBUG("Killing QMP caps process %lld", (long long) pid);
-        if (virProcessKill(pid, SIGKILL) < 0 && errno != ESRCH)
-            VIR_ERROR(_("Failed to kill process %lld: %s"),
-                      (long long) pid,
-                      virStrerror(errno, ebuf, sizeof(ebuf)));
-    }
-    if (pidfile) {
-        unlink(pidfile);
-        VIR_FREE(pidfile);
-    }
+    VIR_FREE(pidfile);
     return ret;
 }
 
-- 
1.8.3.2




More information about the libvir-list mailing list