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(a)linux.vnet.ibm.com>
Reviewed-by: Bjoern Walk <bwalk(a)linux.vnet.ibm.com>
Signed-off-by: Boris Fiuczynski <fiuczy(a)linux.vnet.ibm.com>
---
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