?? On 08/09/2016 08:39 AM, Jason Miesionczek wrote: > --- > src/hyperv/hyperv_driver.c | 176 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 176 insertions(+) > > diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c > index b2d1abf..7d956d3 100644 > --- a/src/hyperv/hyperv_driver.c > +++ b/src/hyperv/hyperv_driver.c > @@ -1401,6 +1401,178 @@ hypervConnectGetVersion(virConnectPtr conn, unsigned long *version) > return result; > } > > +static int > +hypervConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) > +{ > + int result = -1; > + hypervPrivate *priv = conn->privateData; > + virBuffer query = VIR_BUFFER_INITIALIZER; > + Msvm_ProcessorSettingData *processorSettingData = NULL; > + > + /* Get Msvm_ProcessorSettingData maximum definition */ > + virBufferAddLit(&query, "SELECT * FROM Msvm_ProcessorSettingData " > + "WHERE InstanceID LIKE 'Microsoft:Definition%Maximum'"); I see this is going to be a theme - I guess that's how it works. Maybe all these strings should be part of some #define GET_MAX_VCPU_STR "..." > + > + if (hypervGetMsvmProcessorSettingDataList(priv, &query, &processorSettingData) < 0) { Long line - > 80 chars > + goto cleanup; > + } > + > + if (processorSettingData == NULL) { > + virReportError(VIR_ERR_INTERNAL_ERROR, You'll need a "%s", here too > + _("Could not get maximum definition of Msvm_ProcessorSettingData")); really long line consider "text.... text " "more text" > + goto cleanup; > + } > + > + result = processorSettingData->data->SocketCount * processorSettingData->data->ProcessorsPerSocket; Long line > + > + cleanup: > + hypervFreeObject(priv, (hypervObject *) processorSettingData); > + virBufferFreeAndReset(&query); > + > + return result; > +} > + > +static int > +hypervDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) > +{ > + int result = -1; > + char uuid_string[VIR_UUID_STRING_BUFLEN]; > + hypervPrivate *priv = domain->conn->privateData; > + Msvm_ComputerSystem *computerSystem = NULL; > + Msvm_ProcessorSettingData *processorSettingData = NULL; > + Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL; > + virBuffer query = VIR_BUFFER_INITIALIZER; > + > + virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM, -1); Long line - typically one flag per line - makes it easier to insert more flags. > + > + virUUIDFormat(domain->uuid, uuid_string); > + > + /* Get Msvm_ComputerSystem */ > + if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) { > + goto cleanup; > + } > + > + /* If @flags includes VIR_DOMAIN_VCPU_LIVE, > + this will query a running domain (which will fail if domain is not active) */ > + if (flags & VIR_DOMAIN_VCPU_LIVE) { > + if (computerSystem->data->EnabledState != MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED) { > + virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not active")); > + goto cleanup; > + } > + } > + > + /* If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum virtual CPU limit is queried */ > + if (flags & VIR_DOMAIN_VCPU_MAXIMUM) { > + result = hypervConnectGetMaxVcpus(domain->conn, NULL); > + goto cleanup; > + } > + > + /* Get Msvm_VirtualSystemSettingData */ > + virBufferAsprintf(&query, > + "associators of " > + "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," > + "Name=\"%s\"} " > + "where AssocClass = Msvm_SettingsDefineState " > + "ResultClass = Msvm_VirtualSystemSettingData", > + uuid_string); > + if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, &virtualSystemSettingData) < 0) { > + goto cleanup; > + } > + if (virtualSystemSettingData == NULL) { > + virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for domain %s"), > + "Msvm_VirtualSystemSettingData", computerSystem->data->ElementName); syntax-check complained here - just make 4 lines out of this... > + goto cleanup; > + } > + > + /* Get Msvm_ProcessorSettingData */ > + virBufferFreeAndReset(&query); > + virBufferAsprintf(&query, > + "associators of " > + "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " > + "where AssocClass = Msvm_VirtualSystemSettingDataComponent " > + "ResultClass = Msvm_ProcessorSettingData", > + virtualSystemSettingData->data->InstanceID); > + if (hypervGetMsvmProcessorSettingDataList(priv, &query, &processorSettingData) < 0) { > + goto cleanup; > + } > + if (processorSettingData == NULL) { > + virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for domain %s"), > + "Msvm_ProcessorSettingData", computerSystem->data->ElementName); syntax-check complained here - just make 4 lines out of this... > + goto cleanup; > + } > + > + result = processorSettingData->data->VirtualQuantity; > + > + cleanup: > + hypervFreeObject(priv, (hypervObject *)computerSystem); > + hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData); > + hypervFreeObject(priv, (hypervObject *)processorSettingData); > + virBufferFreeAndReset(&query); > + > + return result; > +} > + > +static int > +hypervDomainGetMaxVcpus(virDomainPtr dom) > +{ > + /* If the guest is inactive, this is basically the same as virConnectGetMaxVcpus() */ > + return (hypervDomainIsActive(dom)) ? > + hypervDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) > + : hypervConnectGetMaxVcpus(dom->conn, NULL); > +} > + > +static int > +hypervDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, > + unsigned char *cpumaps, int maplen) > +{ > + int count = 0, i; > + hypervPrivate *priv = domain->conn->privateData; > + virBuffer query = VIR_BUFFER_INITIALIZER; > + Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor *hypervVirtualProcessor = NULL; > + > + /* FIXME: no information stored in cpumaps */ > + if ((cpumaps != NULL) && (maplen > 0)) > + memset(cpumaps, 0, maxinfo * maplen); There's a few examples out there that you should be able to use... > + > + /* Loop for each vCPU */ > + for (i = 0; i < maxinfo; i++) { > + > + /* Get vCPU stats */ > + hypervFreeObject(priv, (hypervObject *)hypervVirtualProcessor); > + hypervVirtualProcessor = NULL; > + virBufferFreeAndReset(&query); > + virBufferAddLit(&query, WIN32_PERFRAWDATA_HVSTATS_HYPERVHYPERVISORVIRTUALPROCESSOR_WQL_SELECT); > + /* Attribute Name format : <domain_name>:Hv VP <vCPU_number> */ > + virBufferAsprintf(&query, "where Name = \"%s:Hv VP %d\"", domain->name, i); > + > + if (hypervGetWin32PerfRawDataHvStatsHyperVHypervisorVirtualProcessorList( > + priv, &query, &hypervVirtualProcessor) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Could not get stats on vCPU #%d"), i); Since you're continuing, perhaps a VIR_WARN or VIR_INFO is more appropriate? However, when the caller/client returns you could then get more than one "info[0].number = 0, .state = 0, cpuTime = 0, .cpu = 0" So the question becomes - should this fail instead. > + continue; > + } > + > + /* Fill structure info */ > + info[i].number = i; > + if (hypervVirtualProcessor == NULL) { > + info[i].state = VIR_VCPU_OFFLINE; > + info[i].cpuTime = 0LLU; > + info[i].cpu = -1; > + } else { > + info[i].state = VIR_VCPU_RUNNING; > + info[i].cpuTime = hypervVirtualProcessor->data->PercentTotalRunTime; > + info[i].cpu = i; > + } > + > + count++; > + } > + > + hypervFreeObject(priv, (hypervObject *)hypervVirtualProcessor); > + virBufferFreeAndReset(&query); > + > + return count; > +} > + > static virHypervisorDriver hypervHypervisorDriver = { > .name = "Hyper-V", > .connectOpen = hypervConnectOpen, /* 0.9.5 */ > @@ -1437,6 +1609,10 @@ static virHypervisorDriver hypervHypervisorDriver = { > .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */ > .connectGetCapabilities = hypervConnectGetCapabilities, /* 1.2.10 */ > .connectGetVersion = hypervConnectGetVersion, /* 1.2.10 */ > + .connectGetMaxVcpus = hypervConnectGetMaxVcpus, /* 1.2.10 */ > + .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 1.2.10 */ > + .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 1.2.10 */ > + .domainGetVcpus = hypervDomainGetVcpus, /* 1.2.10 */ 2.3.0 at the earliest John [I need to run for the evening - it's after 630P where I'm at - will pick up again tomorrow] > }; > > /* Retrieves host system UUID */ > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list