
2017-06-12 22:13 GMT+02:00 Sri Ramanujam <sramanujam@datto.com>:
Introduces support for virDomainSetMemory. This also serves an an example for how to use the new method invocation API with a more complicated method, this time including an EPR and embedded param. --- src/hyperv/hyperv_driver.c | 105 ++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.c | 51 +++++++++++++++++ src/hyperv/hyperv_wmi.h | 11 ++++ src/hyperv/hyperv_wmi_generator.input | 30 ++++++++++ 4 files changed, 197 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3f5b94e..f557408 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1497,6 +1497,109 @@ hypervDomainSendKey(virDomainPtr domain, unsigned int codeset, }
+static int +hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory, + unsigned int flags) +{ + int result = -1; + char uuid_string[VIR_UUID_STRING_BUFLEN]; + hypervPrivate *priv = domain->conn->privateData; + char *memory_str = NULL; + hypervInvokeParamsListPtr params = NULL; + unsigned long memory_mb = VIR_ROUND_UP(VIR_DIV_UP(memory, 1024), 2); + Msvm_VirtualSystemSettingData *vssd = NULL; + Msvm_MemorySettingData *memsd = NULL; + virBuffer eprQuery = VIR_BUFFER_INITIALIZER; + virHashTablePtr memResource = NULL; + + virCheckFlags(0, -1); + + if (virAsprintf(&memory_str, "%lu", memory_mb) < 0) + goto cleanup; + + virUUIDFormat(domain->uuid, uuid_string); + + if (hypervGetMsvmVirtualSystemSettingDataFromUUID(priv, uuid_string, &vssd) < 0) + goto cleanup; + + if (hypervGetMsvmMemorySettingDataFromVSSD(priv, vssd->data.common->InstanceID, + &memsd) < 0) + goto cleanup; + + if (priv->wmiVersion == HYPERV_WMI_VERSION_V1) { + params = hypervCreateInvokeParamsList(priv, "ModifyVirtualSystemResources", + MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_SELECTOR, + Msvm_VirtualSystemManagementService_WmiInfo); + + if (!params) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create params")); + goto cleanup; + } + + virBufferAddLit(&eprQuery, MSVM_COMPUTERSYSTEM_WQL_SELECT); + virBufferAsprintf(&eprQuery, "where Name = \"%s\"", uuid_string); + + if (hypervAddEprParam(params, "ComputerSystem", priv, &eprQuery, + Msvm_ComputerSystem_WmiInfo) < 0) + goto cleanup; + } else if (priv->wmiVersion == HYPERV_WMI_VERSION_V2) { + params = hypervCreateInvokeParamsList(priv, "ModifyResourceSettings", + MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_SELECTOR, + Msvm_VirtualSystemManagementService_WmiInfo); + + if (!params) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create params")); + goto cleanup; + } + } + + memResource = hypervCreateEmbeddedParam(priv, Msvm_MemorySettingData_WmiInfo); + if (!memResource) + goto cleanup; + + if (hypervSetEmbeddedProperty(memResource, "VirtualQuantity", memory_str) < 0) + goto cleanup; + + if (hypervSetEmbeddedProperty(memResource, "InstanceID", + memsd->data.common->InstanceID) < 0) + goto cleanup; + + if (priv->wmiVersion == HYPERV_WMI_VERSION_V1) { + if (hypervAddEmbeddedParam(params, priv, "ResourceSettingData", + memResource, Msvm_MemorySettingData_WmiInfo) < 0) + goto cleanup; + + } else if (priv->wmiVersion == HYPERV_WMI_VERSION_V2) { + if (hypervAddEmbeddedParam(params, priv, "ResourceSettings", + memResource, Msvm_MemorySettingData_WmiInfo) < 0) + goto cleanup; + } +
memResource has to be set to NULL here, as I explained in my previous mail. hypervInvokeMethod will always free memResource. Therefore, hypervInvokeMethod will free memResource even if it fails and the code below go to cleanup, with memResource != NULL. Then memResource will be freed again, resulting in a double-free. That's why memResource needs to be set to NULL before calling hypervInvokeMethod, not afterwards.
+ if (hypervInvokeMethod(priv, params, NULL) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not set memory")); + goto cleanup; + } + + /* set embedded param to NULL on success to avoid double-free in cleanup */ + memResource = NULL;
Setting memResource to NULL here is too late.
+ + result = 0; + cleanup: + VIR_FREE(memory_str); + hypervFreeEmbeddedParam(memResource); + hypervFreeObject(priv, (hypervObject *) vssd); + hypervFreeObject(priv, (hypervObject *) memsd); + return result; +}
-- Matthias Bolte http://photron.blogspot.com