[libvirt] [PATCH 4/4] Implement QMP support for extracting CPU thread ID

Daniel P. Berrange berrange at redhat.com
Fri Jan 22 17:01:14 UTC 2010


The KVM build of QEMU includs the thread ID of each vCPU in the
'query-cpus' output. This is required for pinning guests to
particular host CPUs

* src/qemu/qemu_monitor_json.c: Extract 'thread_id' from CPU info
---
 src/qemu/qemu_monitor_json.c |   82 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7dd2bdb..8e88c7e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -536,6 +536,85 @@ int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon)
 }
 
 
+/*
+ * [ { "CPU": 0, "current": true, "halted": false, "pc": 3227107138 },
+ *   { "CPU": 1, "current": false, "halted": true, "pc": 7108165 } ]
+ */
+static int
+qemuMonitorJSONExtractCPUInfo(virJSONValuePtr reply,
+                              int **pids)
+{
+    virJSONValuePtr data;
+    int ret = -1;
+    int i;
+    int *threads = NULL;
+    int ncpus;
+
+    if (!(data = virJSONValueObjectGet(reply, "return"))) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                         _("cpu reply was missing return data"));
+        goto cleanup;
+    }
+
+    if (data->type != VIR_JSON_TYPE_ARRAY) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                         _("cpu information was not an array"));
+        goto cleanup;
+    }
+
+    if ((ncpus = virJSONValueArraySize(data)) <= 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                         _("cpu information was empty"));
+        goto cleanup;
+    }
+
+    if (VIR_REALLOC_N(threads, ncpus) < 0) {
+        virReportOOMError(NULL);
+        goto cleanup;
+    }
+
+    for (i = 0 ; i < ncpus ; i++) {
+        virJSONValuePtr entry = virJSONValueArrayGet(data, i);
+        int cpu;
+        int thread;
+        if (!entry) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("character device information was missing aray element"));
+            goto cleanup;
+        }
+
+        if (virJSONValueObjectGetNumberInt(entry, "CPU", &cpu) < 0) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("cpu information was missing cpu number"));
+            goto cleanup;
+        }
+
+        if (virJSONValueObjectGetNumberInt(entry, "thread_id", &thread) < 0) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("cpu information was missing thread ID"));
+            goto cleanup;
+        }
+
+        if (cpu != i) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                             _("unexpected cpu index %d expecting %d"),
+                             i, cpu);
+            goto cleanup;
+        }
+
+        threads[i] = thread;
+    }
+
+    *pids = threads;
+    threads = NULL;
+    ret = 0;
+
+cleanup:
+    VIR_FREE(threads);
+    return ret;
+}
+
+
 int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon,
                               int **pids)
 {
@@ -554,7 +633,8 @@ int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon,
     if (ret == 0)
         ret = qemuMonitorJSONCheckError(cmd, reply);
 
-    /* XXX extract PIDs if present - QEMU hasn't implement this yet :-( */
+    if (ret == 0)
+        ret = qemuMonitorJSONExtractCPUInfo(reply, pids);
 
     virJSONValueFree(cmd);
     virJSONValueFree(reply);
-- 
1.6.6




More information about the libvir-list mailing list