Adding a field to the domain's private vcpu object to hold the halted state information. Adding two functions in support of the halted state: - qemuDomainGetVcpuHalted: retrieve the halted state from a private vcpu object - qemuDomainRefreshVcpuHalted: obtain the per-vcpu halted states via qemu monitor and store the results in the private vcpu objects Signed-off-by: Viktor Mihajlovski <mihajlov@xxxxxxxxxxxxxxxxxx> Reviewed-by: Bjoern Walk <bwalk@xxxxxxxxxxxxxxxxxx> Signed-off-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxxxxxxx> --- src/qemu/qemu_domain.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 4 +++ 2 files changed, 86 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 286f096..945a75d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5650,6 +5650,88 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, return ret; } +/** + * qemuDomainGetVcpuHalted: + * @vm: domain object + * @vcpu: cpu id + * + * Returns the vCPU halted state. + */ +bool +qemuDomainGetVcpuHalted(virDomainObjPtr vm, + unsigned int vcpuid) +{ + virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid); + return QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->halted; +} + +/** + * qemuDomainRefreshVcpuHalted: + * @driver: qemu driver data + * @vm: domain object + * @asyncJob: current asynchronous job type + * + * Updates vCPU halted state in the private data of @vm. + * + * Returns number of detected vCPUs on success, -1 on error and reports + * an appropriate error, -2 if the domain doesn't exist any more. + */ +int +qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + virDomainVcpuDefPtr vcpu; + size_t maxvcpus = virDomainDefGetVcpusMax(vm->def); + bool *cpuhalted = NULL; + int ncpuhalted; + size_t i; + int ret = -1; + + /* Not supported currently for TCG, see above + */ + if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU) + return 0; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + ncpuhalted = qemuMonitorGetCPUState(qemuDomainGetMonitor(vm), &cpuhalted); + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + ret = -2; + goto cleanup; + } + + /* Don't fail for older QEMUs + */ + if (ncpuhalted <= 0) { + virResetLastError(); + ret = 0; + goto cleanup; + } + + for (i = 0; i < maxvcpus; i++) { + vcpu = virDomainDefGetVcpu(vm->def, i); + + if (i < ncpuhalted) + QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->halted = cpuhalted[i]; + else + QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->halted = false; + } + + if (ncpuhalted != virDomainDefGetVcpus(vm->def)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("got wrong number of vCPUs from QEMU monitor. " + "got %d, wanted %d"), + ncpuhalted, virDomainDefGetVcpus(vm->def)); + goto cleanup; + } + + ret = ncpuhalted; + + cleanup: + VIR_FREE(cpuhalted); + return ret; +} bool qemuDomainSupportsNicdev(virDomainDefPtr def, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 114db98..44add02 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -316,6 +316,7 @@ struct _qemuDomainVcpuPrivate { virObject parent; pid_t tid; /* vcpu thread id */ + bool halted; /* vcpu halted state */ }; # define QEMU_DOMAIN_VCPU_PRIVATE(vcpu) \ @@ -649,6 +650,9 @@ bool qemuDomainHasVcpuPids(virDomainObjPtr vm); pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpuid); int qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob); +bool qemuDomainGetVcpuHalted(virDomainObjPtr vm, unsigned int vcpu); +int qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver, virDomainObjPtr vm, + int asyncJob); bool qemuDomainSupportsNicdev(virDomainDefPtr def, virDomainNetDefPtr net); -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list