[libvirt] [PATCH 09/10] qemu: monitor: Return structures from qemuMonitorGetCPUInfo
John Ferlan
jferlan at redhat.com
Wed Aug 3 13:21:28 UTC 2016
On 08/03/2016 04:11 AM, Peter Krempa wrote:
> The function will gradually add more returned data. Return a struct for
> every vCPU containing the data.
> ---
> src/qemu/qemu_domain.c | 26 ++++++++++-------------
> src/qemu/qemu_monitor.c | 56 ++++++++++++++++++++++++++++++++++++++++++-------
> 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 4cdd012..9d389f7 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -5682,10 +5682,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;
>
> /*
> @@ -5721,31 +5722,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;
> }
FWIW:
Once we reach this point the VIR_DOMAIN_VIRT_QEMU check is the only way
qemuDomainHasVcpuPids can return 0 in qemuDomainValidateVcpuInfo... So I
wonder - would it be useful to alter that function too so that we're
sure things match up properly vis-a-vis the 'tid' and online checks?
And my alter, I was thinking along the lines of a similar check for
VIR_DOMAIN_VIRT_QEMU...
>
> 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 4403bdd..0011ceb 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -1656,25 +1656,67 @@ 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) {
If qemuMonitorJSONExtractCPUInfo() finds ncpus == 0, then it returns an
error which won't be "cleaned up" unless rc <= 0
> + virResetLastError();
> + ret = 0;
> + goto cleanup;
So, ret == 0, we go to cleanup, it cleans up 'info', then our caller
finds rc == 0, so it can fall into that for maxvcpus loop looking 'info'
and then of course freeing 'info' again.
> + }
> +
> + for (i = 0; i < rc; i++)
> + info[i].tid = pids[i];
Still no "gaps" in our "internal" pids list which is fine, but I assume
could change in the future... Just keeping it fresh in my mind ;-)
ACK with the necessary adjustments for the above rc check condition
which I think would be along the lines of:
if (rc <= 0)
virResetLastError();
if (rc < 0)
goto cleanup;
But I could be wrong...
John
> +
> + VIR_STEAL(*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 805656b..1ef002a 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,
>
More information about the libvir-list
mailing list