Signed-off-by: Vineeth Pillai <viremana(a)linux.microsoft.com>
Signed-off-by: Praveen K Paladugu <prapal(a)linux.microsoft.com>
---
src/ch/ch_domain.c | 25 +++++++++
src/ch/ch_domain.h | 4 ++
src/ch/ch_driver.c | 134 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 163 insertions(+)
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 36333a8a3f..3f34e87e04 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -336,3 +336,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 f01c0e5ad0..1ec7643216 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 108644e503..31e9de7f6a 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -942,6 +942,137 @@ 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",
@@ -978,6 +1109,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 = {
--
2.27.0