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;
+ }
+
+ 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;
+
+ result = 0;
+ cleanup:
+ VIR_FREE(memory_str);
+ hypervFreeEmbeddedParam(memResource);
+ hypervFreeObject(priv, (hypervObject *) vssd);
+ hypervFreeObject(priv, (hypervObject *) memsd);
+ return result;
+}
+
+
+static int
+hypervDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+ return hypervDomainSetMemoryFlags(domain, memory, 0);
+}
+
+
static virHypervisorDriver hypervHypervisorDriver = {
.name = "Hyper-V",
.connectOpen = hypervConnectOpen, /* 0.9.5 */
@@ -1531,6 +1634,8 @@ static virHypervisorDriver hypervHypervisorDriver = {
.domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
.domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
.domainSendKey = hypervDomainSendKey, /* TODO: version */
+ .domainSetMemory = hypervDomainSetMemory, /* TODO: version */
+ .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* TODO: version */
.connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
};
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index ad5b93e..1e5e73a 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -1636,3 +1636,54 @@ hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
return 0;
}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_VirtualSystemSettingData
+ */
+
+int
+hypervGetMsvmVirtualSystemSettingDataFromUUID(hypervPrivate *priv,
+ const char *uuid_string, Msvm_VirtualSystemSettingData **list)
+{
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+ "Name=\"%s\"} "
+ "where AssocClass = Msvm_SettingsDefineState "
+ "ResultClass = Msvm_VirtualSystemSettingData",
+ uuid_string);
+
+ if (hypervGetWmiClassList(priv, Msvm_VirtualSystemSettingData_WmiInfo, &query,
+ (hypervObject **) list) < 0 || *list == NULL)
+ return -1;
+
+ return 0;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_MemorySettingData
+ */
+
+int
+hypervGetMsvmMemorySettingDataFromVSSD(hypervPrivate *priv,
+ const char *vssd_instanceid, Msvm_MemorySettingData **list)
+{
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
+ "ResultClass = Msvm_MemorySettingData",
+ vssd_instanceid);
+
+ if (hypervGetWmiClassList(priv, Msvm_MemorySettingData_WmiInfo, &query,
+ (hypervObject **) list) < 0 || *list == NULL)
+ return -1;
+
+ return 0;
+}
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index 5c9da04..cc53078 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -35,6 +35,9 @@
# define HYPERV_DEFAULT_PARAM_COUNT 5
+# define MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_SELECTOR \
+ "CreationClassName=Msvm_VirtualSystemManagementService"
+
int hypervVerifyResponse(WsManClient *client, WsXmlDocH response,
const char *detail);
@@ -212,6 +215,10 @@ int hypervGetMsvmVirtualSystemSettingDataList(hypervPrivate *priv,
virBufferPtr query,
Msvm_VirtualSystemSettingData **list);
+int hypervGetMsvmVirtualSystemSettingDataFromUUID(hypervPrivate *priv,
+ const char *uuid_string,
+ Msvm_VirtualSystemSettingData **list);
+
int hypervGetMsvmProcessorSettingDataList(hypervPrivate *priv,
virBufferPtr query,
Msvm_ProcessorSettingData **list);
@@ -219,6 +226,10 @@ int hypervGetMsvmProcessorSettingDataList(hypervPrivate *priv,
int hypervGetMsvmMemorySettingDataList(hypervPrivate *priv, virBufferPtr query,
Msvm_MemorySettingData **list);
+int hypervGetMsvmMemorySettingDataFromVSSD(hypervPrivate *priv,
+ const char *vssd_instanceid,
+ Msvm_MemorySettingData **list);
+
int hypervGetMsvmKeyboardList(hypervPrivate *priv, virBufferPtr query,
Msvm_Keyboard **list);
diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
index 4ccda04..da19765 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -787,6 +787,36 @@ class Msvm_VirtualSystemManagementService
boolean Started
end
+class v2/Msvm_VirtualSystemManagementService
+ string InstanceID
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ string Name
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ uint16 CommunicationStatus
+ uint16 DetailedStatus
+ uint16 OperatingStatus
+ uint16 PrimaryStatus
+ uint16 EnabledState
+ string OtherEnabledState
+ uint16 RequestedState
+ uint16 EnabledDefault
+ datetime TimeOfLastStateChange
+ uint16 AvailableRequestedStates[]
+ uint16 TransitioningToState
+ string SystemCreationClassName
+ string SystemName
+ string CreationClassName
+ string PrimaryOwnerName
+ string PrimaryOwnerContact
+ string StartMode
+ boolean Started
+end
class Msvm_VirtualSystemGlobalSettingData
string Caption
--
2.9.4
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
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 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.