]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ch_driver, ch_domain: vcpu info getter callbacks
authorPraveen K Paladugu <prapal@linux.microsoft.com>
Fri, 10 Dec 2021 20:34:39 +0000 (20:34 +0000)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 6 Jan 2022 15:03:55 +0000 (16:03 +0100)
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_domain.c
src/ch/ch_domain.h
src/ch/ch_driver.c

index 761cd15c566817689b49797916ce89778802e5c3..abd176eda6ef12bb759f43e3b0bdd31322a2deb7 100644 (file)
@@ -330,3 +330,29 @@ 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;
+}
index f01c0e5ad06f355fe336e621b5bbd662ab1e6668..3352318820c1e70b30ee5047dab5edd99dc7aee8 100644 (file)
@@ -82,3 +82,11 @@ 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);
index 06cfb1c5ef9811b72593eef183d558a66be71e7e..d78954fc95ab45eb8305dd7c5b0ad0eb4b66d2df 100644 (file)
@@ -941,6 +941,142 @@ 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);
+            g_autoptr(virBitmap) map = NULL;
+
+            if (!(map = virProcessGetAffinity(vcpupid)))
+                return -1;
+
+            virBitmapToDataBuf(map, cpumap, maplen);
+        }
+
+        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",
@@ -977,6 +1113,9 @@ static virHypervisorDriver chHypervisorDriver = {
     .domainIsActive = chDomainIsActive,                     /* 7.5.0 */
     .domainOpenConsole = chDomainOpenConsole,               /* 7.8.0 */
     .nodeGetInfo = chNodeGetInfo,                           /* 7.5.0 */
+    .domainGetVcpus = chDomainGetVcpus,                     /* 8.0.0 */
+    .domainGetVcpusFlags = chDomainGetVcpusFlags,           /* 8.0.0 */
+    .domainGetMaxVcpus = chDomainGetMaxVcpus,               /* 8.0.0 */
 };
 
 static virConnectDriver chConnectDriver = {