
On 08/09/2016 08:39 AM, Jason Miesionczek wrote:
--- src/hyperv/hyperv_driver.c | 117 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index daae371..db59ce1 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -2090,6 +2090,121 @@ hypervDomainSetMemory(virDomainPtr domain, unsigned long memory) return hypervDomainSetMemoryFlags(domain, memory, 0); }
+ +static int +hypervDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus, + unsigned int flags ATTRIBUTE_UNUSED) +{ + int result = -1; + invokeXmlParam *params = NULL; + char uuid_string[VIR_UUID_STRING_BUFLEN]; + hypervPrivate *priv = domain->conn->privateData; + properties_t *tab_props = NULL; + virBuffer query = VIR_BUFFER_INITIALIZER; + Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL; + Msvm_ProcessorSettingData *processorSettingData = NULL; + eprParam eprparam; + embeddedParam embeddedparam; + int nb_params; + const char *selector = "CreationClassName=Msvm_VirtualSystemManagementService"; + char *nvcpus_str = NULL; + + /* Convert nvcpus as a string value */ + nvcpus_str = num2str(nvcpus); + if (nvcpus_str == NULL) + goto cleanup;
Again virAsprintf()... and your indents are off
+ + virUUIDFormat(domain->uuid, uuid_string); + + VIR_DEBUG("nvcpus=%s, uuid=%s", nvcpus_str, uuid_string); + + /* Get Msvm_VirtualSystemSettingData */ + virBufferAsprintf(&query, + "associators of " + "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," + "Name=\"%s\"} " + "where AssocClass = Msvm_SettingsDefineState " + "ResultClass = Msvm_VirtualSystemSettingData", + uuid_string);
The more I see these the more I wonder if there couldn't be a way to "merge" the syntax in a common function which could take uncommon parameters for specific fields... Then those would be called properly and errors handled... IOW: Don't cut-n-paste - create a generic function to formulate the queries...
+ + if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, &virtualSystemSettingData) < 0) + goto cleanup;
The common code could even include this an be called such as: if (!(vssd = hypervGetMsvmVSSDList(priv, uuid_string, xxx))) where xxx would be required only if the CreationClassName, AssocClass, or ResultClass would changed - and be name appropriately using constants.
+ + /* 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 Msvm_ProcessorSettingData for domain %s"), + virtualSystemSettingData->data->ElementName); + goto cleanup; + }
Same goes here - some sort of helper function would be *most* advantageous for review and the code bloat reduction act.
+ + /* Prepare EPR param */ + virBufferFreeAndReset(&query); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); + virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string); + eprparam.query = &query; + eprparam.wmiProviderURI = ROOT_VIRTUALIZATION; + + /* Prepare EMBEDDED param */ + embeddedparam.nbProps = 2; + if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0) + goto cleanup; + (*tab_props).name = "VirtualQuantity"; + (*tab_props).val = nvcpus_str; + (*(tab_props+1)).name = "InstanceID"; + (*(tab_props+1)).val = processorSettingData->data->InstanceID; + embeddedparam.instanceName = "Msvm_ProcessorSettingData"; + embeddedparam.prop_t = tab_props; + + /* Create invokeXmlParam */ + nb_params = 2; + if (VIR_ALLOC_N(params, nb_params) < 0) + goto cleanup; + (*params).name = "ComputerSystem"; + (*params).type = EPR_PARAM; + (*params).param = &eprparam; + (*(params+1)).name = "ResourceSettingData"; + (*(params+1)).type = EMBEDDED_PARAM; + (*(params+1)).param = &embeddedparam; +
Ewww *tab_probs, *params* Something tells me this sequence could also use a good helper routine. I just seems there's too much cut-n-paste or repetitive code...
+ if (hypervInvokeMethod(priv, params, nb_params, "ModifyVirtualSystemResources", + MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain vcpus")); + goto cleanup; + } + + result = 0; + + cleanup: + VIR_FREE(tab_props); + VIR_FREE(params); + VIR_FREE(nvcpus_str); + hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData); + hypervFreeObject(priv, (hypervObject *)processorSettingData); + virBufferFreeAndReset(&query); + + return result; +} + + + +static int +hypervDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) +{ + return hypervDomainSetVcpusFlags(domain, nvcpus, 0); +} + static virHypervisorDriver hypervHypervisorDriver = { .name = "Hyper-V", .connectOpen = hypervConnectOpen, /* 0.9.5 */ @@ -2141,6 +2256,8 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.10 */ .domainSetMemory = hypervDomainSetMemory, /* 1.2.10 */ .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.10 */ + .domainSetVcpus = hypervDomainSetVcpus, /* 1.2.10 */ + .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 1.2.10 */
2.3.0 at the earliest John
};
/* Retrieves host system UUID */