[libvirt] [PATCH 01/27] qemu: monitor: Return structures from qemuMonitorGetCPUInfo

Peter Krempa pkrempa at redhat.com
Fri Aug 5 13:55:57 UTC 2016


The function will gradually add more returned data. Return a struct for
every vCPU containing the data.
---
 src/qemu/qemu_domain.c  | 25 +++++++++-------------
 src/qemu/qemu_monitor.c | 57 +++++++++++++++++++++++++++++++++++++++++++------
 src/qemu/qemu_monitor.h | 13 ++++++++++-
 3 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index efc46f9..6c6ee13 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5709,10 +5709,11 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
                           int asyncJob)
 {
     virDomainVcpuDefPtr vcpu;
+    qemuDomainVcpuPrivatePtr vcpupriv;
+    qemuMonitorCPUInfoPtr info = NULL;
     size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
-    pid_t *cpupids = NULL;
-    int ncpupids;
     size_t i;
+    int rc;
     int ret = -1;

     /*
@@ -5748,32 +5749,26 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,

     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
         return -1;
-    ncpupids = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &cpupids);
+
+    rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus);
+
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;

-    /* failure to get the VCPU <-> PID mapping or to execute the query
-     * command will not be treated fatal as some versions of qemu don't
-     * support this command */
-    if (ncpupids <= 0) {
-        virResetLastError();
-        ret = 0;
+    if (rc < 0)
         goto cleanup;
-    }

     for (i = 0; i < maxvcpus; i++) {
         vcpu = virDomainDefGetVcpu(vm->def, i);
+        vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);

-        if (i < ncpupids)
-            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = cpupids[i];
-        else
-            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = 0;
+        vcpupriv->tid = info[i].tid;
     }

     ret = 0;

  cleanup:
-    VIR_FREE(cpupids);
+    qemuMonitorCPUInfoFree(info, maxvcpus);
     return ret;
 }

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 83e1272..285beae 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1656,25 +1656,68 @@ qemuMonitorSystemReset(qemuMonitorPtr mon)
 }


+void
+qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
+                       size_t ncpus ATTRIBUTE_UNUSED)
+{
+    if (!cpus)
+        return;
+
+    VIR_FREE(cpus);
+}
+
+
 /**
  * qemuMonitorGetCPUInfo:
  * @mon: monitor
- * @pids: returned array of thread ids corresponding to the vCPUs
+ * @cpus: pointer filled by array of qemuMonitorCPUInfo structures
+ * @maxvcpus: total possible number of vcpus
+ *
+ * Detects VCPU information. If qemu doesn't support or fails reporting
+ * information this function will return success as other parts of libvirt
+ * are able to cope with that.
  *
- * Detects the vCPU thread ids. Returns count of detected vCPUs on success,
- * 0 if qemu didn't report thread ids (does not report libvirt error),
- * -1 on error (reports libvirt error).
+ * Returns 0 on success (including if qemu didn't report any data) and
+ *  -1 on error (reports libvirt error).
  */
 int
 qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
-                      int **pids)
+                      qemuMonitorCPUInfoPtr *vcpus,
+                      size_t maxvcpus)
 {
+    qemuMonitorCPUInfoPtr info = NULL;
+    int *pids = NULL;
+    size_t i;
+    int ret = -1;
+    int rc;
+
     QEMU_CHECK_MONITOR(mon);

+    if (VIR_ALLOC_N(info, maxvcpus) < 0)
+        return -1;
+
     if (mon->json)
-        return qemuMonitorJSONQueryCPUs(mon, pids);
+        rc = qemuMonitorJSONQueryCPUs(mon, &pids);
     else
-        return qemuMonitorTextQueryCPUs(mon, pids);
+        rc = qemuMonitorTextQueryCPUs(mon, &pids);
+
+    if (rc < 0) {
+        virResetLastError();
+        VIR_STEAL_PTR(*vcpus, info);
+        ret = 0;
+        goto cleanup;
+    }
+
+    for (i = 0; i < rc; i++)
+        info[i].tid = pids[i];
+
+    VIR_STEAL_PTR(*vcpus, info);
+    ret = 0;
+
+ cleanup:
+    qemuMonitorCPUInfoFree(info, maxvcpus);
+    VIR_FREE(pids);
+    return ret;
 }


diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 591d3ed..3fa993f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -390,8 +390,19 @@ int qemuMonitorGetStatus(qemuMonitorPtr mon,
 int qemuMonitorSystemReset(qemuMonitorPtr mon);
 int qemuMonitorSystemPowerdown(qemuMonitorPtr mon);

+
+struct _qemuMonitorCPUInfo {
+    pid_t tid;
+};
+typedef struct _qemuMonitorCPUInfo qemuMonitorCPUInfo;
+typedef qemuMonitorCPUInfo *qemuMonitorCPUInfoPtr;
+
+void qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr list,
+                            size_t nitems);
 int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
-                          int **pids);
+                          qemuMonitorCPUInfoPtr *vcpus,
+                          size_t maxvcpus);
+
 int qemuMonitorGetVirtType(qemuMonitorPtr mon,
                            virDomainVirtType *virtType);
 int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
-- 
2.9.2




More information about the libvir-list mailing list