[PATCH 2/6] hyperv: implement domainGetVcpus

Matt Coleman mcoleman at datto.com
Thu Nov 12 11:51:54 UTC 2020


Co-authored-by: Sri Ramanujam <sramanujam at datto.com>
Signed-off-by: Matt Coleman <matt at datto.com>
---
 src/hyperv/hyperv_driver.c | 56 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 9fda0d6047..56d6da80e0 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1078,6 +1078,61 @@ hypervDomainGetState(virDomainPtr domain, int *state, int *reason,
 }
 
 
+static int
+hypervDomainGetVcpus(virDomainPtr domain,
+                     virVcpuInfoPtr info,
+                     int maxinfo,
+                     unsigned char *cpumaps,
+                     int maplen)
+{
+    int count = 0;
+    int vcpu_number;
+    hypervPrivate *priv = domain->conn->privateData;
+    Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor *vproc = NULL;
+
+    /* Hyper-V does not allow setting CPU affinity: all cores will be used */
+    if (cpumaps && maplen > 0)
+        memset(cpumaps, 0xFF, maxinfo * maplen);
+
+    for (vcpu_number = 0; vcpu_number < maxinfo; vcpu_number++) {
+        g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER;
+
+        /* Name format: <domain_name>:Hv VP <vCPU_number> */
+        g_autofree char *vcpu_name = g_strdup_printf("%s:Hv VP %d", domain->name, vcpu_number);
+
+        /* try to free objects from previous iteration */
+        hypervFreeObject(priv, (hypervObject *)vproc);
+        vproc = NULL;
+
+        /* get the info */
+        virBufferEscapeSQL(&query,
+                           WIN32_PERFRAWDATA_HVSTATS_HYPERVHYPERVISORVIRTUALPROCESSOR_WQL_SELECT
+                           "WHERE Name = '%s'",
+                           vcpu_name);
+
+        if (hypervGetWmiClass(Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor, &vproc) < 0)
+            continue;
+
+        /* fill structure info */
+        info[vcpu_number].number = vcpu_number;
+        if (vproc) {
+            info[vcpu_number].state = VIR_VCPU_RUNNING;
+            info[vcpu_number].cpuTime = vproc->data->PercentTotalRunTime * 100;
+            info[vcpu_number].cpu = VIR_VCPU_INFO_CPU_UNAVAILABLE;
+        } else {
+            info[vcpu_number].state = VIR_VCPU_OFFLINE;
+            info[vcpu_number].cpuTime = 0LLU;
+            info[vcpu_number].cpu = VIR_VCPU_INFO_CPU_OFFLINE;
+        }
+        count++;
+    }
+
+    hypervFreeObject(priv, (hypervObject *)vproc);
+
+    return count;
+}
+
+
 static char *
 hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
 {
@@ -1875,6 +1930,7 @@ static virHypervisorDriver hypervHypervisorDriver = {
     .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 3.6.0 */
     .domainGetInfo = hypervDomainGetInfo, /* 0.9.5 */
     .domainGetState = hypervDomainGetState, /* 0.9.5 */
+    .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */
     .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.5 */
     .connectListDefinedDomains = hypervConnectListDefinedDomains, /* 0.9.5 */
     .connectNumOfDefinedDomains = hypervConnectNumOfDefinedDomains, /* 0.9.5 */
-- 
2.27.0





More information about the libvir-list mailing list