[libvirt PATCH 05/13] ch_driver, ch_domain: vcpu info getter callbacks

Vineeth Pillai viremana at linux.microsoft.com
Thu Oct 21 17:37:57 UTC 2021


Signed-off-by: Vineeth Pillai <viremana at linux.microsoft.com>
Signed-off-by: Praveen K Paladugu <prapal at linux.microsoft.com>
---
 src/ch/ch_domain.c |  25 ++++++++
 src/ch/ch_domain.h |   4 ++
 src/ch/ch_driver.c | 138 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index fedde4581b..c0b0b1005a 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -338,3 +338,28 @@ virCHDomainGetMonitor(virDomainObj *vm)
 {
     return CH_DOMAIN_PRIVATE(vm)->monitor;
 }
+
+pid_t
+virCHDomainGetVcpuPid(virDomainObj *vm,
+                     unsigned int vcpuid)
+{
+    virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+    return CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid;
+}
+
+bool
+virCHDomainHasVcpuPids(virDomainObj *vm)
+{
+    size_t i;
+    size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
+    virDomainVcpuDef *vcpu;
+
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = virDomainDefGetVcpu(vm->def, i);
+
+        if (CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid > 0)
+            return true;
+    }
+
+    return false;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 75b9933130..d9c9d34a19 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -82,3 +82,7 @@ virCHDomainObjBeginJob(virDomainObj *obj, enum virCHDomainJob job)
 
 void
 virCHDomainObjEndJob(virDomainObj *obj);
+
+int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
+pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
+bool virCHDomainHasVcpuPids(virDomainObj *vm);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 1824d2fd16..8ea5ce393d 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -952,6 +952,141 @@ static int chStateInitialize(bool privileged,
     return ret;
 }
 
+static int
+chDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
+    virDomainObj *vm;
+    virDomainDef *def;
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                  VIR_DOMAIN_AFFECT_CONFIG |
+                  VIR_DOMAIN_VCPU_MAXIMUM |
+                  VIR_DOMAIN_VCPU_GUEST, -1);
+
+    if (!(vm = chDomObjFromDomain(dom)))
+        return -1;
+
+    if (virDomainGetVcpusFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
+        goto cleanup;
+
+    if (!(def = virDomainObjGetOneDef(vm, flags)))
+        goto cleanup;
+
+    if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
+        ret = virDomainDefGetVcpusMax(def);
+    else
+        ret = virDomainDefGetVcpus(def);
+
+
+    cleanup:
+        virDomainObjEndAPI(&vm);
+        return ret;
+}
+
+static int
+chDomainGetMaxVcpus(virDomainPtr dom)
+{
+    return chDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+static int
+chDomainHelperGetVcpus(virDomainObj *vm,
+                       virVcpuInfoPtr info,
+                       unsigned long long *cpuwait,
+                       int maxinfo,
+                       unsigned char *cpumaps,
+                       int maplen)
+{
+    size_t ncpuinfo = 0;
+    size_t i;
+
+    if (maxinfo == 0)
+        return 0;
+
+    if (!virCHDomainHasVcpuPids(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       "%s", _("cpu affinity is not supported"));
+        return -1;
+    }
+
+    if (info)
+        memset(info, 0, sizeof(*info) * maxinfo);
+
+    if (cpumaps)
+        memset(cpumaps, 0, sizeof(*cpumaps) * maxinfo);
+
+    for (i = 0; i < virDomainDefGetVcpusMax(vm->def) && ncpuinfo < maxinfo; i++) {
+        virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, i);
+        pid_t vcpupid = virCHDomainGetVcpuPid(vm, i);
+        virVcpuInfoPtr vcpuinfo = info + ncpuinfo;
+
+        if (!vcpu->online)
+            continue;
+
+        if (info) {
+            vcpuinfo->number = i;
+            vcpuinfo->state = VIR_VCPU_RUNNING;
+            if (virProcessGetStatInfo(&vcpuinfo->cpuTime,
+                                  &vcpuinfo->cpu, NULL,
+                                  vm->pid, vcpupid) < 0) {
+                virReportSystemError(errno, "%s",
+                                     _("cannot get vCPU placement & pCPU time"));
+                return -1;
+            }
+        }
+
+        if (cpumaps) {
+            unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, ncpuinfo);
+            virBitmap *map = NULL;
+
+            if (!(map = virProcessGetAffinity(vcpupid)))
+                return -1;
+
+            virBitmapToDataBuf(map, cpumap, maplen);
+            virBitmapFree(map);
+        }
+
+        if (cpuwait) {
+            if (virProcessGetSchedInfo(&(cpuwait[ncpuinfo]), vm->pid, vcpupid) < 0)
+                return -1;
+        }
+
+        ncpuinfo++;
+    }
+
+    return ncpuinfo;
+}
+
+static int
+chDomainGetVcpus(virDomainPtr dom,
+                   virVcpuInfoPtr info,
+                   int maxinfo,
+                   unsigned char *cpumaps,
+                   int maplen)
+{
+    virDomainObj *vm;
+    int ret = -1;
+
+    if (!(vm = chDomObjFromDomain(dom)))
+        goto cleanup;
+
+    if (virDomainGetVcpusEnsureACL(dom->conn, vm->def) < 0)
+        goto cleanup;
+
+    if (virDomainObjCheckActive(vm) < 0) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("cannot retrieve vcpu information for inactive domain"));
+        goto cleanup;
+    }
+
+    ret = chDomainHelperGetVcpus(vm, info, NULL, maxinfo, cpumaps, maplen);
+
+    cleanup:
+        virDomainObjEndAPI(&vm);
+        return ret;
+}
+
 /* Function Tables */
 static virHypervisorDriver chHypervisorDriver = {
     .name = "CH",
@@ -988,6 +1123,9 @@ static virHypervisorDriver chHypervisorDriver = {
     .domainIsActive = chDomainIsActive,                     /* 7.5.0 */
     .domainOpenConsole = chDomainOpenConsole,               /* 7.8.0 */
     .nodeGetInfo = chNodeGetInfo,                           /* 7.5.0 */
+    .domainGetVcpus = chDomainGetVcpus,                     /* 7.9.0 */
+    .domainGetVcpusFlags = chDomainGetVcpusFlags,           /* 7.9.0 */
+    .domainGetMaxVcpus = chDomainGetMaxVcpus,               /* 7.9.0 */
 };
 
 static virConnectDriver chConnectDriver = {
-- 
2.27.0





More information about the libvir-list mailing list