[libvirt] [PATCH 6/7] qemu: Implement virDomainGetGuestVcpus

Peter Krempa pkrempa at redhat.com
Mon Jun 20 14:34:20 UTC 2016


Allow gathering available vcpu ids, their state and offlinability via
the qemu guest agent. The maximum id was chosen arbitrarily and ought
to be enough for everybody.
---
 src/qemu/qemu_driver.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 098840f..5b96ad8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -122,6 +122,8 @@ VIR_LOG_INIT("qemu.qemu_driver");
 #define QEMU_SCHED_MIN_QUOTA               1000LL
 #define QEMU_SCHED_MAX_QUOTA  18446744073709551LL

+#define QEMU_GUEST_VCPU_MAX_ID 4096
+
 #if HAVE_LINUX_KVM_H
 # include <linux/kvm.h>
 #endif
@@ -19724,6 +19726,117 @@ static int qemuDomainRename(virDomainPtr dom,
     return ret;
 }

+
+static int
+qemuDomainGetGuestVcpusParams(virTypedParameterPtr *params,
+                              unsigned int *nparams,
+                              qemuAgentCPUInfoPtr info,
+                              int ninfo)
+{
+    virTypedParameterPtr par = NULL;
+    int npar = 0;
+    int maxpar = 0;
+    virBitmapPtr vcpus = NULL;
+    virBitmapPtr online = NULL;
+    virBitmapPtr offlinable = NULL;
+    char *tmp = NULL;
+    size_t i;
+    int ret = -1;
+
+    if (!(vcpus = virBitmapNew(QEMU_GUEST_VCPU_MAX_ID)) ||
+        !(online = virBitmapNew(QEMU_GUEST_VCPU_MAX_ID)) ||
+        !(offlinable = virBitmapNew(QEMU_GUEST_VCPU_MAX_ID)))
+        goto cleanup;
+
+    for (i = 0; i < ninfo; i++) {
+        if (virBitmapSetBit(vcpus, info[i].id) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("vcpu id '%u' reported by guest agent is out of "
+                             "range"), info[i].id);
+            goto cleanup;
+        }
+
+        if (info[i].online)
+            ignore_value(virBitmapSetBit(online, info[i].id));
+
+        if (info[i].offlinable)
+            ignore_value(virBitmapSetBit(offlinable, info[i].id));
+    }
+
+#define ADD_BITMAP(name)                                                       \
+    if (!(tmp = virBitmapFormat(name)))                                        \
+        goto cleanup;                                                          \
+    if (virTypedParamsAddString(&par, &npar, &maxpar, #name, tmp) < 0)         \
+        goto cleanup;                                                          \
+    VIR_FREE(tmp)
+
+    ADD_BITMAP(vcpus);
+    ADD_BITMAP(online);
+    ADD_BITMAP(offlinable);
+
+#undef ADD_BITMAP
+
+    *params = par;
+    *nparams = npar;
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(tmp);
+    virBitmapFree(vcpus);
+    virBitmapFree(online);
+    virBitmapFree(offlinable);
+    return ret;
+}
+
+
+static int
+qemuDomainGetGuestVcpus(virDomainPtr dom,
+                        virTypedParameterPtr *params,
+                        unsigned int *nparams,
+                        unsigned int flags)
+{
+    virQEMUDriverPtr driver = dom->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    qemuAgentCPUInfoPtr info = NULL;
+    int ninfo = 0;
+    int ret = -1;
+
+    virCheckFlags(0, ret);
+
+    if (!(vm = qemuDomObjFromDomain(dom)))
+        goto cleanup;
+
+    if (virDomainGetGuestVcpusEnsureACL(dom->conn, vm->def) < 0)
+        goto cleanup;
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+        goto cleanup;
+
+    if (!qemuDomainAgentAvailable(vm, true))
+        goto endjob;
+
+    qemuDomainObjEnterAgent(vm);
+    ninfo = qemuAgentGetVCPUs(qemuDomainGetAgent(vm), &info);
+    qemuDomainObjExitAgent(vm);
+
+    if (ninfo < 0)
+        goto endjob;
+
+    if (qemuDomainGetGuestVcpusParams(params, nparams, info, ninfo) < 0)
+        goto endjob;
+
+    ret = 0;
+
+ endjob:
+    qemuDomainObjEndJob(driver, vm);
+
+ cleanup:
+    VIR_FREE(info);
+    virDomainObjEndAPI(&vm);
+    return ret;
+}
+
+
 static virHypervisorDriver qemuHypervisorDriver = {
     .name = QEMU_DRIVER_NAME,
     .connectOpen = qemuConnectOpen, /* 0.2.0 */
@@ -19935,6 +20048,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainSetUserPassword = qemuDomainSetUserPassword, /* 1.2.16 */
     .domainRename = qemuDomainRename, /* 1.2.19 */
     .domainMigrateStartPostCopy = qemuDomainMigrateStartPostCopy, /* 1.3.3 */
+    .domainGetGuestVcpus = qemuDomainGetGuestVcpus, /* 2.0.0 */
 };


-- 
2.8.3




More information about the libvir-list mailing list