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