]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add a method for extracting QEMU argv from /proc
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 17 Jun 2011 14:34:00 +0000 (15:34 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 12 Jul 2011 14:39:04 +0000 (15:39 +0100)
To enable attaching to externally launched QEMU, we need
to be able to reverse engineer a guest XML config based
on the argv for a PID in /proc

* src/qemu/qemu_command.c, src/qemu/qemu_command.h: Add
  qemuParseCommandLinePid which extracts QEMU config from
  argv in /proc, given a PID number

src/qemu/qemu_command.c
src/qemu/qemu_command.h

index db72c306733e8cea3eb0c4a0941915854f3ad5f3..67b35e6868bddc6a68d86900c77077c160a34e2d 100644 (file)
@@ -6624,3 +6624,109 @@ cleanup:
 
     return def;
 }
+
+
+static int qemuParseProcFileStrings(unsigned int pid,
+                                    const char *name,
+                                    const char ***list)
+{
+    char *path = NULL;
+    int ret = -1;
+    char *data = NULL;
+    ssize_t len;
+    char *tmp;
+    size_t nstr = 0;
+    const char **str = NULL;
+    int i;
+
+    if (virAsprintf(&path, "/proc/%u/%s", pid, name) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if ((len = virFileReadAll(path, 1024*128, &data)) < 0)
+        goto cleanup;
+
+    tmp = data;
+    while (tmp < (data + len)) {
+        if (VIR_EXPAND_N(str, nstr, 1) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if (!(str[nstr-1] = strdup(tmp))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        /* Skip arg */
+        tmp += strlen(tmp);
+        /* Skip \0 separator */
+        tmp++;
+    }
+
+    if (VIR_EXPAND_N(str, nstr, 1) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    str[nstr-1] = NULL;
+
+    ret = nstr-1;
+    *list = str;
+
+cleanup:
+    if (ret < 0) {
+        for (i = 0 ; str && str[i] ; i++)
+            VIR_FREE(str[i]);
+        VIR_FREE(str);
+    }
+    VIR_FREE(data);
+    VIR_FREE(path);
+    return ret;
+}
+
+virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps,
+                                        unsigned int pid,
+                                        char **pidfile,
+                                        virDomainChrSourceDefPtr *monConfig,
+                                        bool *monJSON)
+{
+    virDomainDefPtr def = NULL;
+    const char **progargv = NULL;
+    const char **progenv = NULL;
+    char *exepath = NULL;
+    char *emulator;
+    int i;
+
+    if (qemuParseProcFileStrings(pid, "cmdline", &progargv) < 0 ||
+        qemuParseProcFileStrings(pid, "environ", &progenv) < 0)
+        goto cleanup;
+
+    if (!(def = qemuParseCommandLine(caps, progenv, progargv,
+                                     pidfile, monConfig, monJSON)))
+        goto cleanup;
+
+    if (virAsprintf(&exepath, "/proc/%u/exe", pid) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (virFileResolveLink(exepath, &emulator) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to resolve %s for pid %u"),
+                             exepath, pid);
+        goto cleanup;
+    }
+    VIR_FREE(def->emulator);
+    def->emulator = emulator;
+
+cleanup:
+    VIR_FREE(exepath);
+    for (i = 0 ; progargv && progargv[i] ; i++)
+        VIR_FREE(progargv[i]);
+    VIR_FREE(progargv);
+    for (i = 0 ; progenv && progenv[i] ; i++)
+        VIR_FREE(progenv[i]);
+    VIR_FREE(progenv);
+    return def;
+}
index ae08c2a8cd0f6d082b20684053211e99a4744b8e..87660f2f8ff63c1c632ea6bb5a87db359b39d312 100644 (file)
@@ -155,6 +155,11 @@ virDomainDefPtr qemuParseCommandLineString(virCapsPtr caps,
                                            char **pidfile,
                                            virDomainChrSourceDefPtr *monConfig,
                                            bool *monJSON);
+virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps,
+                                        unsigned int pid,
+                                        char **pidfile,
+                                        virDomainChrSourceDefPtr *monConfig,
+                                        bool *monJSON);
 
 int qemuDomainAssignPCIAddresses(virDomainDefPtr def);
 qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def);