[libvirt] [PATCH] qemu: report vcpu state in virDomainGetVcpus

From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Currently, the virVcpuInfo returned by virDomainGetVcpus() will always report a state of VIR_VCPU_RUNNING for each defined domain vcpu even if the vcpu is currently in the halted state. As the monitor interface is in fact reporting the accurate state, it is rather easy to transport this information with the existing API. This is done by - adding a new state of VIR_VCPU_HALTED - extending the monitor to pass back the halted state for the vcpus - adding a new array to the private domain object reflecting the halted state for the vcpus and update it along with the vcpu pids array - modifying the driver code to report the vcpu state based on the halted indicator - extending virsh vcpuinfo to also display the halted state - modifying the monitor_json testcase The vcpu state is however not recorded in the internal XML format, since the state can change asynchronously (without notification). Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Signed-off-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.vnet.ibm.com> --- include/libvirt/libvirt-domain.h | 1 + src/qemu/qemu_domain.c | 26 +++++++++++++++++++++++++- src/qemu/qemu_domain.h | 2 ++ src/qemu/qemu_driver.c | 14 +++++++++++++- src/qemu/qemu_monitor.c | 7 ++++--- src/qemu/qemu_monitor.h | 3 ++- src/qemu/qemu_monitor_json.c | 22 +++++++++++++++++++--- src/qemu/qemu_monitor_json.h | 3 ++- src/qemu/qemu_monitor_text.c | 17 +++++++++++++++-- src/qemu/qemu_monitor_text.h | 3 ++- src/qemu/qemu_process.c | 1 + tests/qemumonitorjsontest.c | 18 +++++++++++++++--- tools/virsh-domain.c | 3 ++- 13 files changed, 103 insertions(+), 17 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 7ea93aa..98b9420 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1656,6 +1656,7 @@ typedef enum { VIR_VCPU_OFFLINE = 0, /* the virtual CPU is offline */ VIR_VCPU_RUNNING = 1, /* the virtual CPU is running */ VIR_VCPU_BLOCKED = 2, /* the virtual CPU is blocked on resource */ + VIR_VCPU_HALTED = 3, /* the virtual CPU is halted */ # ifdef VIR_ENUM_SENTINELS VIR_VCPU_LAST diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 42b5511..3428605 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1256,6 +1256,7 @@ qemuDomainObjPrivateFree(void *data) virDomainChrSourceDefFree(priv->monConfig); qemuDomainObjFreeJob(priv); VIR_FREE(priv->vcpupids); + VIR_FREE(priv->vcpuhalted); VIR_FREE(priv->lockState); VIR_FREE(priv->origname); @@ -5470,6 +5471,7 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, int asyncJob) { pid_t *cpupids = NULL; + bool *cpuhalted = NULL; int ncpupids = 0; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -5506,7 +5508,7 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids); + ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids, &cpuhalted); if (qemuDomainObjExitMonitor(driver, vm) < 0) { VIR_FREE(cpupids); return -2; @@ -5526,16 +5528,38 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, "got %d, wanted %d"), ncpupids, virDomainDefGetVcpus(vm->def)); VIR_FREE(cpupids); + VIR_FREE(cpuhalted); return -1; } done: VIR_FREE(priv->vcpupids); + VIR_FREE(priv->vcpuhalted); priv->nvcpupids = ncpupids; priv->vcpupids = cpupids; + priv->vcpuhalted = cpuhalted; return ncpupids; } +/** + * qemuDomainGetVcpuHalted: + * @vm: domain object + * @vcpu: cpu id + * + * Returns the vCPU halted state. + */ +bool +qemuDomainGetVcpuHalted(virDomainObjPtr vm, + unsigned int vcpu) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (vcpu >= priv->nvcpupids) + return 0; + + return priv->vcpuhalted[vcpu]; +} + bool qemuDomainSupportsNicdev(virDomainDefPtr def, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index c49f31c..8f7d421 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -186,6 +186,7 @@ struct _qemuDomainObjPrivate { int nvcpupids; int *vcpupids; + bool *vcpuhalted; virDomainPCIAddressSetPtr pciaddrs; virDomainCCWAddressSetPtr ccwaddrs; @@ -639,6 +640,7 @@ bool qemuDomainHasVcpuPids(virDomainObjPtr vm); pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpu); int qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob); +bool qemuDomainGetVcpuHalted(virDomainObjPtr vm, unsigned int vcpu); bool qemuDomainSupportsNicdev(virDomainDefPtr def, virDomainNetDefPtr net); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f9a3b15..f7ea745 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1477,13 +1477,17 @@ qemuDomainHelperGetVcpus(virDomainObjPtr vm, for (i = 0; i < virDomainDefGetVcpusMax(vm->def) && ncpuinfo < maxinfo; i++) { virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(vm->def, i); pid_t vcpupid = qemuDomainGetVcpuPid(vm, i); + bool vcpuhalted = qemuDomainGetVcpuHalted(vm, i); if (!vcpu->online) continue; if (info) { info[i].number = i; - info[i].state = VIR_VCPU_RUNNING; + if (vcpuhalted) + info[i].state = VIR_VCPU_HALTED; + else + info[i].state = VIR_VCPU_RUNNING; if (qemuGetProcessInfo(&(info[i].cpuTime), &(info[i].cpu), NULL, vm->pid, vcpupid) < 0) { @@ -5272,6 +5276,7 @@ qemuDomainGetVcpus(virDomainPtr dom, unsigned char *cpumaps, int maplen) { + virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; int ret = -1; @@ -5288,6 +5293,13 @@ qemuDomainGetVcpus(virDomainPtr dom, goto cleanup; } + if (qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", + _("could not detect vcpu pids")); + return -1; + } + ret = qemuDomainHelperGetVcpus(vm, info, NULL, maxinfo, cpumaps, maplen); cleanup: diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 098e654..0272fb4 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1656,14 +1656,15 @@ qemuMonitorSystemReset(qemuMonitorPtr mon) */ int qemuMonitorGetCPUInfo(qemuMonitorPtr mon, - int **pids) + int **pids, + bool **haltpids) { QEMU_CHECK_MONITOR(mon); if (mon->json) - return qemuMonitorJSONGetCPUInfo(mon, pids); + return qemuMonitorJSONGetCPUInfo(mon, pids, haltpids); else - return qemuMonitorTextGetCPUInfo(mon, pids); + return qemuMonitorTextGetCPUInfo(mon, pids, haltpids); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index cb4cca8..9f6ef72 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -391,7 +391,8 @@ int qemuMonitorSystemReset(qemuMonitorPtr mon); int qemuMonitorSystemPowerdown(qemuMonitorPtr mon); int qemuMonitorGetCPUInfo(qemuMonitorPtr mon, - int **pids); + int **pids, + bool **haltpids); int qemuMonitorGetVirtType(qemuMonitorPtr mon, virDomainVirtType *virtType); int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index bb426dc..87343c0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1324,13 +1324,15 @@ int qemuMonitorJSONSystemReset(qemuMonitorPtr mon) */ static int qemuMonitorJSONExtractCPUInfo(virJSONValuePtr reply, - int **pids) + int **pids, + bool **haltpids) { virJSONValuePtr data; int ret = -1; size_t i; int *threads = NULL; ssize_t ncpus; + bool *haltedpids = NULL; if (!(data = virJSONValueObjectGetArray(reply, "return"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1347,9 +1349,13 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr reply, if (VIR_ALLOC_N(threads, ncpus) < 0) goto cleanup; + if (VIR_ALLOC_N(haltedpids, ncpus) < 0) + goto cleanup; + for (i = 0; i < ncpus; i++) { virJSONValuePtr entry = virJSONValueArrayGet(data, i); int thread; + bool halted; if (!entry) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cpu information was missing an array element")); @@ -1363,21 +1369,31 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr reply, goto cleanup; } + if (virJSONValueObjectGetBoolean(entry, "halted", &halted) < 0) { + /* Some older qemu versions may not report the halted state, + * for backword compatibility we assume it's not halted */ + halted = false; + } + threads[i] = thread; + haltedpids[i] = halted; } *pids = threads; + *haltpids = haltedpids; threads = NULL; + haltedpids = NULL; ret = ncpus; cleanup: VIR_FREE(threads); + VIR_FREE(haltedpids); return ret; } int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon, - int **pids) + int **pids, bool **haltpids) { int ret = -1; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-cpus", @@ -1395,7 +1411,7 @@ int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon, if (qemuMonitorJSONCheckError(cmd, reply) < 0) goto cleanup; - ret = qemuMonitorJSONExtractCPUInfo(reply, pids); + ret = qemuMonitorJSONExtractCPUInfo(reply, pids, haltpids); cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 37a739e..c7808aa 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -59,7 +59,8 @@ int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon); int qemuMonitorJSONSystemReset(qemuMonitorPtr mon); int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon, - int **pids); + int **pids, + bool **haltpids); int qemuMonitorJSONGetVirtType(qemuMonitorPtr mon, virDomainVirtType *virtType); int qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 9295219..fbacdbd 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -501,12 +501,15 @@ int qemuMonitorTextSystemReset(qemuMonitorPtr mon) int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, - int **pids) + int **pids, + bool **haltpids) { char *qemucpus = NULL; char *line; pid_t *cpupids = NULL; size_t ncpupids = 0; + bool *cpuhalted = NULL; + size_t ncpuhalted = 0; if (qemuMonitorHMPCommand(mon, "info cpus", &qemucpus) < 0) return -1; @@ -517,7 +520,7 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, * (qemu) info cpus * * CPU #0: pc=0x00000000000f0c4a thread_id=30019 * CPU #1: pc=0x00000000fffffff0 thread_id=30020 - * CPU #2: pc=0x00000000fffffff0 thread_id=30021 + * CPU #2: pc=0x00000000fffffff0 (halted) thread_id=30021 * */ line = qemucpus; @@ -525,6 +528,7 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, char *offset = NULL; char *end = NULL; int tid = 0; + bool halted = false; /* Extract host Thread ID */ if ((offset = strstr(line, "thread_id=")) == NULL) @@ -538,6 +542,13 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, if (VIR_APPEND_ELEMENT_COPY(cpupids, ncpupids, tid) < 0) goto error; + /* Extract halted indicator */ + if ((offset = strstr(line, "(halted)")) != NULL) + halted = true; + + if (VIR_APPEND_ELEMENT_COPY(cpuhalted, ncpuhalted, halted) < 0) + goto error; + VIR_DEBUG("tid=%d", tid); /* Skip to next data line */ @@ -549,11 +560,13 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, /* Validate we got data for all VCPUs we expected */ VIR_FREE(qemucpus); *pids = cpupids; + *haltpids = cpuhalted; return ncpupids; error: VIR_FREE(qemucpus); VIR_FREE(cpupids); + VIR_FREE(cpuhalted); /* Returning 0 to indicate non-fatal failure, since * older QEMU does not have VCPU<->PID mapping and diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index eeaca52..e7009b3 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -50,7 +50,8 @@ int qemuMonitorTextSystemPowerdown(qemuMonitorPtr mon); int qemuMonitorTextSystemReset(qemuMonitorPtr mon); int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon, - int **pids); + int **pids, + bool **haltpids); int qemuMonitorTextGetVirtType(qemuMonitorPtr mon, virDomainVirtType *virtType); int qemuMonitorTextGetBalloonInfo(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 129c070..403b332 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5900,6 +5900,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, vm->pid = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); VIR_FREE(priv->vcpupids); + VIR_FREE(priv->vcpuhalted); priv->nvcpupids = 0; for (i = 0; i < vm->def->niothreadids; i++) vm->def->iothreadids[i]->thread_id = 0; diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index f698c14..441720e 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1210,6 +1210,8 @@ testQemuMonitorJSONqemuMonitorJSONGetCPUInfo(const void *data) int ret = -1; pid_t *cpupids = NULL; pid_t expected_cpupids[] = {17622, 17624, 17626, 17628}; + bool *cpuhalted = NULL; + bool expected_cpuhalted[] = {true, true, false, false}; int ncpupids; size_t i; @@ -1237,14 +1239,14 @@ testQemuMonitorJSONqemuMonitorJSONGetCPUInfo(const void *data) " \"current\": false," " \"CPU\": 2," " \"pc\": -2130530478," - " \"halted\": true," + " \"halted\": false," " \"thread_id\": 17626" " }," " {" " \"current\": false," " \"CPU\": 3," " \"pc\": -2130530478," - " \"halted\": true," + " \"halted\": false," " \"thread_id\": 17628" " }" " ]," @@ -1252,7 +1254,7 @@ testQemuMonitorJSONqemuMonitorJSONGetCPUInfo(const void *data) "}") < 0) goto cleanup; - ncpupids = qemuMonitorJSONGetCPUInfo(qemuMonitorTestGetMonitor(test), &cpupids); + ncpupids = qemuMonitorJSONGetCPUInfo(qemuMonitorTestGetMonitor(test), &cpupids, &cpuhalted); if (ncpupids != 4) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1269,10 +1271,20 @@ testQemuMonitorJSONqemuMonitorJSONGetCPUInfo(const void *data) } } + for (i = 0; i < ncpupids; i++) { + if (cpuhalted[i] != expected_cpuhalted[i]) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Expecting cpuhalted[%zu] = %d but got %d", + i, expected_cpuhalted[i], cpuhalted[i]); + goto cleanup; + } + } + ret = 0; cleanup: VIR_FREE(cpupids); + VIR_FREE(cpuhalted); qemuMonitorTestFree(test); return ret; } diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index dbdee5b..4650eb3 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -181,7 +181,8 @@ VIR_ENUM_IMPL(virshDomainVcpuState, VIR_VCPU_LAST, N_("offline"), N_("running"), - N_("blocked")) + N_("blocked"), + N_("halted")) static const char * virshDomainVcpuStateToString(int state) -- 2.9.0

On Fri, Jul 08, 2016 at 15:39:00 +0200, Boris Fiuczynski wrote:
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Currently, the virVcpuInfo returned by virDomainGetVcpus() will always report a state of VIR_VCPU_RUNNING for each defined domain vcpu even if the vcpu is currently in the halted state.
As the monitor interface is in fact reporting the accurate state, it is rather easy to transport this information with the existing API.
Could you please elaborat how you expect to use this info?
This is done by - adding a new state of VIR_VCPU_HALTED - extending the monitor to pass back the halted state for the vcpus - adding a new array to the private domain object reflecting the halted state for the vcpus and update it along with the vcpu pids array - modifying the driver code to report the vcpu state based on the halted indicator - extending virsh vcpuinfo to also display the halted state - modifying the monitor_json testcase
The vcpu state is however not recorded in the internal XML format, since the state can change asynchronously (without notification).
virDomainGetVcpus does not call qemuDomainDetectVcpuPids nor does not update the info in any way. qemuDomainDetectVcpuPids is called just at startup of the qemu process. As of such this is reporting old data at any time and thus doesn't really make much sense in the current state. Please note that calling qemuDomainDetectVcpuPids is not desired in virDomainGetVcpus. You would need to update just the vcpu states. Still doing so doesn't seem to make much sense and thus I'd like an elaboration why this is necessary.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Signed-off-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.vnet.ibm.com> --- include/libvirt/libvirt-domain.h | 1 + src/qemu/qemu_domain.c | 26 +++++++++++++++++++++++++- src/qemu/qemu_domain.h | 2 ++ src/qemu/qemu_driver.c | 14 +++++++++++++- src/qemu/qemu_monitor.c | 7 ++++--- src/qemu/qemu_monitor.h | 3 ++- src/qemu/qemu_monitor_json.c | 22 +++++++++++++++++++--- src/qemu/qemu_monitor_json.h | 3 ++- src/qemu/qemu_monitor_text.c | 17 +++++++++++++++-- src/qemu/qemu_monitor_text.h | 3 ++- src/qemu/qemu_process.c | 1 + tests/qemumonitorjsontest.c | 18 +++++++++++++++--- tools/virsh-domain.c | 3 ++- 13 files changed, 103 insertions(+), 17 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 7ea93aa..98b9420 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1656,6 +1656,7 @@ typedef enum { VIR_VCPU_OFFLINE = 0, /* the virtual CPU is offline */ VIR_VCPU_RUNNING = 1, /* the virtual CPU is running */ VIR_VCPU_BLOCKED = 2, /* the virtual CPU is blocked on resource */ + VIR_VCPU_HALTED = 3, /* the virtual CPU is halted */
# ifdef VIR_ENUM_SENTINELS VIR_VCPU_LAST diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 42b5511..3428605 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1256,6 +1256,7 @@ qemuDomainObjPrivateFree(void *data) virDomainChrSourceDefFree(priv->monConfig); qemuDomainObjFreeJob(priv); VIR_FREE(priv->vcpupids);
I'm currently refactoring the code to get rid of this structure. (See https://www.redhat.com/archives/libvir-list/2016-July/msg00182.html ) So this is going against that direction.
+ VIR_FREE(priv->vcpuhalted); VIR_FREE(priv->lockState); VIR_FREE(priv->origname);
[...]
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 098e654..0272fb4 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1656,14 +1656,15 @@ qemuMonitorSystemReset(qemuMonitorPtr mon) */ int qemuMonitorGetCPUInfo(qemuMonitorPtr mon, - int **pids) + int **pids, + bool **haltpids)
The name of the variable doesn't make sense. The array refers to vcpus rather than pids.
{ QEMU_CHECK_MONITOR(mon);
if (mon->json) - return qemuMonitorJSONGetCPUInfo(mon, pids); + return qemuMonitorJSONGetCPUInfo(mon, pids, haltpids); else - return qemuMonitorTextGetCPUInfo(mon, pids); + return qemuMonitorTextGetCPUInfo(mon, pids, haltpids);
Peter

On Fri, Jul 08, 2016 at 15:39:00 +0200, Boris Fiuczynski wrote:
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Currently, the virVcpuInfo returned by virDomainGetVcpus() will always report a state of VIR_VCPU_RUNNING for each defined domain vcpu even if the vcpu is currently in the halted state.
As the monitor interface is in fact reporting the accurate state, it is rather easy to transport this information with the existing API.
Could you please elaborat how you expect to use this info? Dpending on the architecture, the halted state is an indication that the virtual CPU is not in use. On s390x for example the halted state is only reported if the CPU is stopped or in disabled wait, both indicating that
On 08.07.2016 15:54, Peter Krempa wrote: the virtual CPUs are not enabled for the operating system. This information can be used by a libvirt client application for hotplugging decisions, and this is in fact the intention.
This is done by - adding a new state of VIR_VCPU_HALTED - extending the monitor to pass back the halted state for the vcpus - adding a new array to the private domain object reflecting the halted state for the vcpus and update it along with the vcpu pids array - modifying the driver code to report the vcpu state based on the halted indicator - extending virsh vcpuinfo to also display the halted state - modifying the monitor_json testcase
The vcpu state is however not recorded in the internal XML format, since the state can change asynchronously (without notification).
virDomainGetVcpus does not call qemuDomainDetectVcpuPids nor does not update the info in any way. qemuDomainDetectVcpuPids is called just at startup of the qemu process. As of such this is reporting old data at any time and thus doesn't really make much sense in the current state.
Well, it's also called in the course of CPU hotplugging to update the CPU pids, but you are right in that the info is getting stale quickly.
Please note that calling qemuDomainDetectVcpuPids is not desired in virDomainGetVcpus. You would need to update just the vcpu states.
Right, I can add another API to retrieve only the states, still using the same monitor interface. I didn't want to break policy (in fact I wasn't aware of that particular one), apologies. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On Fri, Jul 08, 2016 at 16:33:59 +0200, Viktor Mihajlovski wrote:
On Fri, Jul 08, 2016 at 15:39:00 +0200, Boris Fiuczynski wrote:
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Currently, the virVcpuInfo returned by virDomainGetVcpus() will always report a state of VIR_VCPU_RUNNING for each defined domain vcpu even if the vcpu is currently in the halted state.
As the monitor interface is in fact reporting the accurate state, it is rather easy to transport this information with the existing API.
Could you please elaborat how you expect to use this info? Dpending on the architecture, the halted state is an indication that the virtual CPU is not in use. On s390x for example the halted state is only reported if the CPU is stopped or in disabled wait, both indicating that
On 08.07.2016 15:54, Peter Krempa wrote: the virtual CPUs are not enabled for the operating system. This information can be used by a libvirt client application for hotplugging decisions, and this is in fact the intention.
Okay that sounds reasonable.
This is done by - adding a new state of VIR_VCPU_HALTED - extending the monitor to pass back the halted state for the vcpus - adding a new array to the private domain object reflecting the halted state for the vcpus and update it along with the vcpu pids array - modifying the driver code to report the vcpu state based on the halted indicator - extending virsh vcpuinfo to also display the halted state - modifying the monitor_json testcase
The vcpu state is however not recorded in the internal XML format, since the state can change asynchronously (without notification).
virDomainGetVcpus does not call qemuDomainDetectVcpuPids nor does not update the info in any way. qemuDomainDetectVcpuPids is called just at startup of the qemu process. As of such this is reporting old data at any time and thus doesn't really make much sense in the current state. Well, it's also called in the course of CPU hotplugging to update the CPU pids, but you are right in that the info is getting stale quickly.
Please note that calling qemuDomainDetectVcpuPids is not desired in virDomainGetVcpus. You would need to update just the vcpu states.
Right, I can add another API to retrieve only the states, still using the same monitor interface. I didn't want to break policy (in fact I wasn't aware of that particular one), apologies.
Well, there isn't much of a policy at this point. Just that updating of the thread IDs when not necessary isn't a good approach. Also please try to base the patch on the series I've posted so I don't have to rework it completely.

On 08.07.2016 16:38, Peter Krempa wrote: [snip]
Right, I can add another API to retrieve only the states, still using the same monitor interface. I didn't want to break policy (in fact I wasn't aware of that particular one), apologies.
Well, there isn't much of a policy at this point. Just that updating of the thread IDs when not necessary isn't a good approach.
Also please try to base the patch on the series I've posted so I don't have to rework it completely.
Dang, mid-air collision. I'll post an update once I've sampled your series. Thanks for the feedback. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (3)
-
Boris Fiuczynski
-
Peter Krempa
-
Viktor Mihajlovski