2017-06-12 22:13 GMT+02:00 Sri Ramanujam <sramanujam(a)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