|
|
6ae9ed |
From 45a8d716bb066cb05d59e5aeb9c46814f0de3b01 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <45a8d716bb066cb05d59e5aeb9c46814f0de3b01@dist-git>
|
|
|
6ae9ed |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
6ae9ed |
Date: Wed, 24 Aug 2016 16:11:24 -0400
|
|
|
6ae9ed |
Subject: [PATCH] qemu: monitor: Add algorithm for combining
|
|
|
6ae9ed |
query-(hotpluggable-)-cpus data
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
|
|
|
6ae9ed |
|
|
|
6ae9ed |
For hotplug purposes it's necessary to retrieve data using
|
|
|
6ae9ed |
query-hotpluggable-cpus while the old query-cpus API report thread IDs
|
|
|
6ae9ed |
and order of hotplug.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
This patch adds code that merges the data using a rather non-trivial
|
|
|
6ae9ed |
algorithm and fills the data to the qemuMonitorCPUInfo structure for
|
|
|
6ae9ed |
adding to appropriate place in the domain definition.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit 9bbbc88a8f343be6217c49fc4eef033376c0c648)
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
src/qemu/qemu_domain.c | 2 +-
|
|
|
6ae9ed |
src/qemu/qemu_monitor.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
6ae9ed |
src/qemu/qemu_monitor.h | 23 +++++-
|
|
|
6ae9ed |
3 files changed, 220 insertions(+), 10 deletions(-)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
index be602ef..ebd0d9e 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
@@ -5754,7 +5754,7 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus);
|
|
|
6ae9ed |
+ rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus, false);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
|
|
|
6ae9ed |
index 573c94a..1f633fc 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_monitor.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_monitor.c
|
|
|
6ae9ed |
@@ -1651,13 +1651,36 @@ qemuMonitorSystemReset(qemuMonitorPtr mon)
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+static void
|
|
|
6ae9ed |
+qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus,
|
|
|
6ae9ed |
+ size_t ncpus)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < ncpus; i++) {
|
|
|
6ae9ed |
+ cpus[i].id = 0;
|
|
|
6ae9ed |
+ cpus[i].socket_id = -1;
|
|
|
6ae9ed |
+ cpus[i].core_id = -1;
|
|
|
6ae9ed |
+ cpus[i].thread_id = -1;
|
|
|
6ae9ed |
+ cpus[i].vcpus = 0;
|
|
|
6ae9ed |
+ cpus[i].tid = 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_FREE(cpus[i].qom_path);
|
|
|
6ae9ed |
+ VIR_FREE(cpus[i].alias);
|
|
|
6ae9ed |
+ VIR_FREE(cpus[i].type);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
void
|
|
|
6ae9ed |
qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
|
|
|
6ae9ed |
- size_t ncpus ATTRIBUTE_UNUSED)
|
|
|
6ae9ed |
+ size_t ncpus)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
if (!cpus)
|
|
|
6ae9ed |
return;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoClear(cpus, ncpus);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
VIR_FREE(cpus);
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -1678,10 +1701,156 @@ qemuMonitorQueryCpusFree(struct qemuMonitorQueryCpusEntry *entries,
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
/**
|
|
|
6ae9ed |
+ * Legacy approach doesn't allow out of order cpus, thus no complex matching
|
|
|
6ae9ed |
+ * algorithm is necessary */
|
|
|
6ae9ed |
+static void
|
|
|
6ae9ed |
+qemuMonitorGetCPUInfoLegacy(struct qemuMonitorQueryCpusEntry *cpuentries,
|
|
|
6ae9ed |
+ size_t ncpuentries,
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoPtr vcpus,
|
|
|
6ae9ed |
+ size_t maxvcpus)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < maxvcpus; i++) {
|
|
|
6ae9ed |
+ if (i < ncpuentries)
|
|
|
6ae9ed |
+ vcpus[i].tid = cpuentries[i].tid;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* for legacy hotplug to work we need to fake the vcpu count added by
|
|
|
6ae9ed |
+ * enabling a given vcpu */
|
|
|
6ae9ed |
+ vcpus[i].vcpus = 1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/**
|
|
|
6ae9ed |
+ * qemuMonitorGetCPUInfoHotplug:
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * This function stitches together data retrieved via query-hotpluggable-cpus
|
|
|
6ae9ed |
+ * which returns entities on the hotpluggable level (which may describe more
|
|
|
6ae9ed |
+ * than one guest logical vcpu) with the output of query-cpus, having an entry
|
|
|
6ae9ed |
+ * per enabled guest logical vcpu.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * query-hotpluggable-cpus conveys following information:
|
|
|
6ae9ed |
+ * - topology information and number of logical vcpus this entry creates
|
|
|
6ae9ed |
+ * - device type name of the entry that needs to be used when hotplugging
|
|
|
6ae9ed |
+ * - qom path in qemu which can be used to map the entry against query-cpus
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * query-cpus conveys following information:
|
|
|
6ae9ed |
+ * - thread id of a given guest logical vcpu
|
|
|
6ae9ed |
+ * - order in which the vcpus were inserted
|
|
|
6ae9ed |
+ * - qom path to allow mapping the two together
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * The libvirt's internal structure has an entry for each possible (even
|
|
|
6ae9ed |
+ * disabled) guest vcpu. The purpose is to map the data together so that we are
|
|
|
6ae9ed |
+ * certain of the thread id mapping and the information required for vcpu
|
|
|
6ae9ed |
+ * hotplug.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * This function returns 0 on success and -1 on error, but does not report
|
|
|
6ae9ed |
+ * libvirt errors so that fallback approach can be used.
|
|
|
6ae9ed |
+ */
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
+qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotplugvcpus,
|
|
|
6ae9ed |
+ size_t nhotplugvcpus,
|
|
|
6ae9ed |
+ struct qemuMonitorQueryCpusEntry *cpuentries,
|
|
|
6ae9ed |
+ size_t ncpuentries,
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoPtr vcpus,
|
|
|
6ae9ed |
+ size_t maxvcpus)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ char *tmp;
|
|
|
6ae9ed |
+ int order = 1;
|
|
|
6ae9ed |
+ size_t totalvcpus = 0;
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
+ size_t j;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* ensure that the total vcpu count reported by query-hotpluggable-cpus equals
|
|
|
6ae9ed |
+ * to the libvirt maximum cpu count */
|
|
|
6ae9ed |
+ for (i = 0; i < nhotplugvcpus; i++)
|
|
|
6ae9ed |
+ totalvcpus += hotplugvcpus[i].vcpus;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* trim '/thread...' suffix from the data returned by query-cpus */
|
|
|
6ae9ed |
+ for (i = 0; i < ncpuentries; i++) {
|
|
|
6ae9ed |
+ if (cpuentries[i].qom_path &&
|
|
|
6ae9ed |
+ (tmp = strstr(cpuentries[i].qom_path, "/thread")))
|
|
|
6ae9ed |
+ *tmp = '\0';
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (totalvcpus != maxvcpus) {
|
|
|
6ae9ed |
+ VIR_DEBUG("expected '%zu' total vcpus got '%zu'", maxvcpus, totalvcpus);
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* Note the order in which the hotpluggable entities are inserted by
|
|
|
6ae9ed |
+ * matching them to the query-cpus entries */
|
|
|
6ae9ed |
+ for (i = 0; i < ncpuentries; i++) {
|
|
|
6ae9ed |
+ for (j = 0; j < nhotplugvcpus; j++) {
|
|
|
6ae9ed |
+ if (!cpuentries[i].qom_path ||
|
|
|
6ae9ed |
+ !hotplugvcpus[j].qom_path ||
|
|
|
6ae9ed |
+ STRNEQ(cpuentries[i].qom_path, hotplugvcpus[j].qom_path))
|
|
|
6ae9ed |
+ continue;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* add ordering info for hotpluggable entries */
|
|
|
6ae9ed |
+ if (hotplugvcpus[j].enable_id == 0)
|
|
|
6ae9ed |
+ hotplugvcpus[j].enable_id = order++;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* transfer appropriate data from the hotpluggable list to corresponding
|
|
|
6ae9ed |
+ * entries. the entries returned by qemu may in fact describe multiple
|
|
|
6ae9ed |
+ * logical vcpus in the guest */
|
|
|
6ae9ed |
+ j = 0;
|
|
|
6ae9ed |
+ for (i = 0; i < nhotplugvcpus; i++) {
|
|
|
6ae9ed |
+ vcpus[j].socket_id = hotplugvcpus[i].socket_id;
|
|
|
6ae9ed |
+ vcpus[j].core_id = hotplugvcpus[i].core_id;
|
|
|
6ae9ed |
+ vcpus[j].thread_id = hotplugvcpus[i].thread_id;
|
|
|
6ae9ed |
+ vcpus[j].vcpus = hotplugvcpus[i].vcpus;
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(vcpus[j].qom_path, hotplugvcpus[i].qom_path);
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(vcpus[j].alias, hotplugvcpus[i].alias);
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(vcpus[j].type, hotplugvcpus[i].type);
|
|
|
6ae9ed |
+ vcpus[j].id = hotplugvcpus[i].enable_id;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* skip over vcpu entries covered by this hotpluggable entry */
|
|
|
6ae9ed |
+ j += hotplugvcpus[i].vcpus;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* match entries from query cpus to the output array taking into account
|
|
|
6ae9ed |
+ * multi-vcpu objects */
|
|
|
6ae9ed |
+ for (j = 0; j < ncpuentries; j++) {
|
|
|
6ae9ed |
+ /* find the correct entry or beginning of group of entries */
|
|
|
6ae9ed |
+ for (i = 0; i < maxvcpus; i++) {
|
|
|
6ae9ed |
+ if (cpuentries[j].qom_path && vcpus[i].qom_path &&
|
|
|
6ae9ed |
+ STREQ(cpuentries[j].qom_path, vcpus[i].qom_path))
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (i == maxvcpus) {
|
|
|
6ae9ed |
+ VIR_DEBUG("too many query-cpus entries for a given "
|
|
|
6ae9ed |
+ "query-hotpluggable-cpus entry");
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (vcpus[i].vcpus != 1) {
|
|
|
6ae9ed |
+ /* find a possibly empty vcpu thread for core granularity systems */
|
|
|
6ae9ed |
+ for (; i < maxvcpus; i++) {
|
|
|
6ae9ed |
+ if (vcpus[i].tid == 0)
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ vcpus[i].tid = cpuentries[j].tid;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ return 0;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/**
|
|
|
6ae9ed |
* qemuMonitorGetCPUInfo:
|
|
|
6ae9ed |
* @mon: monitor
|
|
|
6ae9ed |
* @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
|
|
|
6ae9ed |
* @maxvcpus: total possible number of vcpus
|
|
|
6ae9ed |
+ * @hotplug: query data relevant for hotplug support
|
|
|
6ae9ed |
*
|
|
|
6ae9ed |
* Detects VCPU information. If qemu doesn't support or fails reporting
|
|
|
6ae9ed |
* information this function will return success as other parts of libvirt
|
|
|
6ae9ed |
@@ -1693,20 +1862,32 @@ qemuMonitorQueryCpusFree(struct qemuMonitorQueryCpusEntry *entries,
|
|
|
6ae9ed |
int
|
|
|
6ae9ed |
qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
|
|
6ae9ed |
qemuMonitorCPUInfoPtr *vcpus,
|
|
|
6ae9ed |
- size_t maxvcpus)
|
|
|
6ae9ed |
+ size_t maxvcpus,
|
|
|
6ae9ed |
+ bool hotplug)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
- qemuMonitorCPUInfoPtr info = NULL;
|
|
|
6ae9ed |
+ struct qemuMonitorQueryHotpluggableCpusEntry *hotplugcpus = NULL;
|
|
|
6ae9ed |
+ size_t nhotplugcpus = 0;
|
|
|
6ae9ed |
struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
|
|
|
6ae9ed |
size_t ncpuentries = 0;
|
|
|
6ae9ed |
- size_t i;
|
|
|
6ae9ed |
int ret = -1;
|
|
|
6ae9ed |
int rc;
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoPtr info = NULL;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- QEMU_CHECK_MONITOR(mon);
|
|
|
6ae9ed |
+ if (hotplug)
|
|
|
6ae9ed |
+ QEMU_CHECK_MONITOR_JSON(mon);
|
|
|
6ae9ed |
+ else
|
|
|
6ae9ed |
+ QEMU_CHECK_MONITOR(mon);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (VIR_ALLOC_N(info, maxvcpus) < 0)
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ /* initialize a few non-zero defaults */
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoClear(info, maxvcpus);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (hotplug &&
|
|
|
6ae9ed |
+ (qemuMonitorJSONGetHotpluggableCPUs(mon, &hotplugcpus, &nhotplugcpus)) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
if (mon->json)
|
|
|
6ae9ed |
rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries);
|
|
|
6ae9ed |
else
|
|
|
6ae9ed |
@@ -1721,15 +1902,23 @@ qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- for (i = 0; i < ncpuentries; i++)
|
|
|
6ae9ed |
- info[i].tid = cpuentries[i].tid;
|
|
|
6ae9ed |
+ if (!hotplugcpus ||
|
|
|
6ae9ed |
+ qemuMonitorGetCPUInfoHotplug(hotplugcpus, nhotplugcpus,
|
|
|
6ae9ed |
+ cpuentries, ncpuentries,
|
|
|
6ae9ed |
+ info, maxvcpus) < 0) {
|
|
|
6ae9ed |
+ /* Fallback to the legacy algorithm. Hotplug paths will make sure that
|
|
|
6ae9ed |
+ * the apropriate data is present */
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoClear(info, maxvcpus);
|
|
|
6ae9ed |
+ qemuMonitorGetCPUInfoLegacy(cpuentries, ncpuentries, info, maxvcpus);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
|
|
|
6ae9ed |
VIR_STEAL_PTR(*vcpus, info);
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
cleanup:
|
|
|
6ae9ed |
- qemuMonitorCPUInfoFree(info, maxvcpus);
|
|
|
6ae9ed |
+ qemuMonitorQueryHotpluggableCpusFree(hotplugcpus, nhotplugcpus);
|
|
|
6ae9ed |
qemuMonitorQueryCpusFree(cpuentries, ncpuentries);
|
|
|
6ae9ed |
+ qemuMonitorCPUInfoFree(info, maxvcpus);
|
|
|
6ae9ed |
return ret;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
|
|
|
6ae9ed |
index 027a7a9..d07e60c 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_monitor.h
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_monitor.h
|
|
|
6ae9ed |
@@ -409,6 +409,9 @@ struct qemuMonitorQueryHotpluggableCpusEntry {
|
|
|
6ae9ed |
int socket_id;
|
|
|
6ae9ed |
int core_id;
|
|
|
6ae9ed |
int thread_id;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* internal data */
|
|
|
6ae9ed |
+ int enable_id;
|
|
|
6ae9ed |
};
|
|
|
6ae9ed |
void qemuMonitorQueryHotpluggableCpusFree(struct qemuMonitorQueryHotpluggableCpusEntry *entries,
|
|
|
6ae9ed |
size_t nentries);
|
|
|
6ae9ed |
@@ -416,6 +419,23 @@ void qemuMonitorQueryHotpluggableCpusFree(struct qemuMonitorQueryHotpluggableCpu
|
|
|
6ae9ed |
|
|
|
6ae9ed |
struct _qemuMonitorCPUInfo {
|
|
|
6ae9ed |
pid_t tid;
|
|
|
6ae9ed |
+ int id; /* order of enabling of the given cpu */
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* topology info for hotplug purposes. Hotplug of given vcpu impossible if
|
|
|
6ae9ed |
+ * all entries are -1 */
|
|
|
6ae9ed |
+ int socket_id;
|
|
|
6ae9ed |
+ int core_id;
|
|
|
6ae9ed |
+ int thread_id;
|
|
|
6ae9ed |
+ unsigned int vcpus; /* number of vcpus added if given entry is hotplugged */
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* name of the qemu type to add in case of hotplug */
|
|
|
6ae9ed |
+ char *type;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* alias of an hotpluggable entry. Entries with alias can be hot-unplugged */
|
|
|
6ae9ed |
+ char *alias;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* internal for use in the matching code */
|
|
|
6ae9ed |
+ char *qom_path;
|
|
|
6ae9ed |
};
|
|
|
6ae9ed |
typedef struct _qemuMonitorCPUInfo qemuMonitorCPUInfo;
|
|
|
6ae9ed |
typedef qemuMonitorCPUInfo *qemuMonitorCPUInfoPtr;
|
|
|
6ae9ed |
@@ -424,7 +444,8 @@ void qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr list,
|
|
|
6ae9ed |
size_t nitems);
|
|
|
6ae9ed |
int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
|
|
6ae9ed |
qemuMonitorCPUInfoPtr *vcpus,
|
|
|
6ae9ed |
- size_t maxvcpus);
|
|
|
6ae9ed |
+ size_t maxvcpus,
|
|
|
6ae9ed |
+ bool hotplug);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
int qemuMonitorGetVirtType(qemuMonitorPtr mon,
|
|
|
6ae9ed |
virDomainVirtType *virtType);
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.10.0
|
|
|
6ae9ed |
|