6ae9ed
From 69f7fb4615fb51ea9913650552b9d4937f2ad12b Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <69f7fb4615fb51ea9913650552b9d4937f2ad12b@dist-git>
6ae9ed
From: Peter Krempa <pkrempa@redhat.com>
6ae9ed
Date: Wed, 24 Aug 2016 16:11:17 -0400
6ae9ed
Subject: [PATCH] qemu: monitor: Return structures from qemuMonitorGetCPUInfo
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
6ae9ed
6ae9ed
The function will gradually add more returned data. Return a struct for
6ae9ed
every vCPU containing the data.
6ae9ed
6ae9ed
(cherry picked from commit 5b5f494a1bc5af7d162ca23cdb6527d15620e851)
6ae9ed
---
6ae9ed
 src/qemu/qemu_domain.c  | 25 +++++++++-------------
6ae9ed
 src/qemu/qemu_monitor.c | 57 +++++++++++++++++++++++++++++++++++++++++++------
6ae9ed
 src/qemu/qemu_monitor.h | 13 ++++++++++-
6ae9ed
 3 files changed, 72 insertions(+), 23 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
6ae9ed
index 9cbf938..52e9c1e 100644
6ae9ed
--- a/src/qemu/qemu_domain.c
6ae9ed
+++ b/src/qemu/qemu_domain.c
6ae9ed
@@ -5687,10 +5687,11 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
6ae9ed
                           int asyncJob)
6ae9ed
 {
6ae9ed
     virDomainVcpuDefPtr vcpu;
6ae9ed
+    qemuDomainVcpuPrivatePtr vcpupriv;
6ae9ed
+    qemuMonitorCPUInfoPtr info = NULL;
6ae9ed
     size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
6ae9ed
-    pid_t *cpupids = NULL;
6ae9ed
-    int ncpupids;
6ae9ed
     size_t i;
6ae9ed
+    int rc;
6ae9ed
     int ret = -1;
6ae9ed
 
6ae9ed
     /*
6ae9ed
@@ -5726,32 +5727,26 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
6ae9ed
 
6ae9ed
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
6ae9ed
         return -1;
6ae9ed
-    ncpupids = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &cpupids);
6ae9ed
+
6ae9ed
+    rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus);
6ae9ed
+
6ae9ed
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
6ae9ed
         goto cleanup;
6ae9ed
 
6ae9ed
-    /* failure to get the VCPU <-> PID mapping or to execute the query
6ae9ed
-     * command will not be treated fatal as some versions of qemu don't
6ae9ed
-     * support this command */
6ae9ed
-    if (ncpupids <= 0) {
6ae9ed
-        virResetLastError();
6ae9ed
-        ret = 0;
6ae9ed
+    if (rc < 0)
6ae9ed
         goto cleanup;
6ae9ed
-    }
6ae9ed
 
6ae9ed
     for (i = 0; i < maxvcpus; i++) {
6ae9ed
         vcpu = virDomainDefGetVcpu(vm->def, i);
6ae9ed
+        vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
6ae9ed
 
6ae9ed
-        if (i < ncpupids)
6ae9ed
-            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = cpupids[i];
6ae9ed
-        else
6ae9ed
-            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = 0;
6ae9ed
+        vcpupriv->tid = info[i].tid;
6ae9ed
     }
6ae9ed
 
6ae9ed
     ret = 0;
6ae9ed
 
6ae9ed
  cleanup:
6ae9ed
-    VIR_FREE(cpupids);
6ae9ed
+    qemuMonitorCPUInfoFree(info, maxvcpus);
6ae9ed
     return ret;
6ae9ed
 }
6ae9ed
 
6ae9ed
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
6ae9ed
index 8a558ca..c3b9f41 100644
6ae9ed
--- a/src/qemu/qemu_monitor.c
6ae9ed
+++ b/src/qemu/qemu_monitor.c
6ae9ed
@@ -1651,25 +1651,68 @@ qemuMonitorSystemReset(qemuMonitorPtr mon)
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
+void
6ae9ed
+qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
6ae9ed
+                       size_t ncpus ATTRIBUTE_UNUSED)
6ae9ed
+{
6ae9ed
+    if (!cpus)
6ae9ed
+        return;
6ae9ed
+
6ae9ed
+    VIR_FREE(cpus);
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
 /**
6ae9ed
  * qemuMonitorGetCPUInfo:
6ae9ed
  * @mon: monitor
6ae9ed
- * @pids: returned array of thread ids corresponding to the vCPUs
6ae9ed
+ * @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
6ae9ed
+ * @maxvcpus: total possible number of vcpus
6ae9ed
  *
6ae9ed
- * Detects the vCPU thread ids. Returns count of detected vCPUs on success,
6ae9ed
- * 0 if qemu didn't report thread ids (does not report libvirt error),
6ae9ed
- * -1 on error (reports libvirt error).
6ae9ed
+ * Detects VCPU information. If qemu doesn't support or fails reporting
6ae9ed
+ * information this function will return success as other parts of libvirt
6ae9ed
+ * are able to cope with that.
6ae9ed
+ *
6ae9ed
+ * Returns 0 on success (including if qemu didn't report any data) and
6ae9ed
+ *  -1 on error (reports libvirt error).
6ae9ed
  */
6ae9ed
 int
6ae9ed
 qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
6ae9ed
-                      int **pids)
6ae9ed
+                      qemuMonitorCPUInfoPtr *vcpus,
6ae9ed
+                      size_t maxvcpus)
6ae9ed
 {
6ae9ed
+    qemuMonitorCPUInfoPtr info = NULL;
6ae9ed
+    int *pids = NULL;
6ae9ed
+    size_t i;
6ae9ed
+    int ret = -1;
6ae9ed
+    int rc;
6ae9ed
+
6ae9ed
     QEMU_CHECK_MONITOR(mon);
6ae9ed
 
6ae9ed
+    if (VIR_ALLOC_N(info, maxvcpus) < 0)
6ae9ed
+        return -1;
6ae9ed
+
6ae9ed
     if (mon->json)
6ae9ed
-        return qemuMonitorJSONQueryCPUs(mon, pids);
6ae9ed
+        rc = qemuMonitorJSONQueryCPUs(mon, &pids);
6ae9ed
     else
6ae9ed
-        return qemuMonitorTextQueryCPUs(mon, pids);
6ae9ed
+        rc = qemuMonitorTextQueryCPUs(mon, &pids);
6ae9ed
+
6ae9ed
+    if (rc < 0) {
6ae9ed
+        virResetLastError();
6ae9ed
+        VIR_STEAL_PTR(*vcpus, info);
6ae9ed
+        ret = 0;
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    for (i = 0; i < rc; i++)
6ae9ed
+        info[i].tid = pids[i];
6ae9ed
+
6ae9ed
+    VIR_STEAL_PTR(*vcpus, info);
6ae9ed
+    ret = 0;
6ae9ed
+
6ae9ed
+ cleanup:
6ae9ed
+    qemuMonitorCPUInfoFree(info, maxvcpus);
6ae9ed
+    VIR_FREE(pids);
6ae9ed
+    return ret;
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
6ae9ed
index b2f20e9..3ab3f08 100644
6ae9ed
--- a/src/qemu/qemu_monitor.h
6ae9ed
+++ b/src/qemu/qemu_monitor.h
6ae9ed
@@ -390,8 +390,19 @@ int qemuMonitorGetStatus(qemuMonitorPtr mon,
6ae9ed
 int qemuMonitorSystemReset(qemuMonitorPtr mon);
6ae9ed
 int qemuMonitorSystemPowerdown(qemuMonitorPtr mon);
6ae9ed
 
6ae9ed
+
6ae9ed
+struct _qemuMonitorCPUInfo {
6ae9ed
+    pid_t tid;
6ae9ed
+};
6ae9ed
+typedef struct _qemuMonitorCPUInfo qemuMonitorCPUInfo;
6ae9ed
+typedef qemuMonitorCPUInfo *qemuMonitorCPUInfoPtr;
6ae9ed
+
6ae9ed
+void qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr list,
6ae9ed
+                            size_t nitems);
6ae9ed
 int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
6ae9ed
-                          int **pids);
6ae9ed
+                          qemuMonitorCPUInfoPtr *vcpus,
6ae9ed
+                          size_t maxvcpus);
6ae9ed
+
6ae9ed
 int qemuMonitorGetVirtType(qemuMonitorPtr mon,
6ae9ed
                            virDomainVirtType *virtType);
6ae9ed
 int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
6ae9ed
-- 
6ae9ed
2.10.0
6ae9ed