---
src/hyperv/hyperv_driver.c | 232 ++++++++++++++++++++++++++++++++++++++++++++
src/hyperv/hyperv_private.h | 2 +
2 files changed, 234 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 348b39c..daae371 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -56,6 +56,9 @@ hypervFreePrivate(hypervPrivate **priv)
if ((*priv)->caps != NULL)
virObjectUnref((*priv)->caps);
+ if ((*priv)->xmlopt != NULL)
+ virObjectUnref((*priv)->xmlopt);
+
hypervFreeParsedUri(&(*priv)->parsedUri);
VIR_FREE(*priv);
}
@@ -195,6 +198,9 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
goto cleanup;
}
+ /* Init xmlopt to parse Domain XML */
+ priv->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL);
+
conn->privateData = priv;
priv = NULL;
result = VIR_DRV_OPEN_SUCCESS;
@@ -1860,6 +1866,229 @@ hypervDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
int *nparams)
return type;
}
+/* Format a number as a string value */
+static char *num2str(unsigned long value)
+{
+ int sz;
+ char *result;
+
+ sz = snprintf (NULL, 0, "%lu", value);
+ if (VIR_ALLOC_N(result, sz + 1) < 0) {
+ return NULL;
+ }
+
+ sprintf(result, "%lu", value);
+ return result;
+}
+
+
+
+static int
+hypervDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
+{
+ 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;
+ virBuffer query2 = VIR_BUFFER_INITIALIZER;
+ Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+ Msvm_MemorySettingData *memorySettingData = NULL;
+ eprParam eprparam;
+ embeddedParam embeddedparam;
+ int nb_params;
+ const char *selector =
"CreationClassName=Msvm_VirtualSystemManagementService";
+ unsigned long memory_mb = memory/1024;
+ char *memory_str = NULL;
+
+ /* Memory value must be a multiple of 2 MB; round up it accordingly if necessary */
+ if (memory_mb % 2) memory_mb++;
+
+ /* Convert the memory value as a string */
+ memory_str = num2str(memory_mb);
+ if (memory_str == NULL)
+ goto cleanup;
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ VIR_DEBUG("memory=%sMb, uuid=%s", memory_str, uuid_string);
+
+ /* Prepare EPR param */
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAsprintf(&query, "where Name =
\"%s\"",uuid_string);
+ eprparam.query = &query;
+ eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+ /* Prepare EMBEDDED param 1 */
+ /* Get Msvm_VirtualSystemSettingData */
+ virBufferAsprintf(&query2,
+ "associators of "
+
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+ "Name=\"%s\"} "
+ "where AssocClass = Msvm_SettingsDefineState "
+ "ResultClass = Msvm_VirtualSystemSettingData",
+ uuid_string);
+
+ if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query2,
&virtualSystemSettingData) < 0)
+ goto cleanup;
+
+ /* Get Msvm_MemorySettingData */
+ virBufferFreeAndReset(&query2);
+ virBufferAsprintf(&query2,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent
"
+ "ResultClass = Msvm_MemorySettingData",
+ virtualSystemSettingData->data->InstanceID);
+
+ if (hypervGetMsvmMemorySettingDataList(priv, &query2, &memorySettingData)
< 0)
+ goto cleanup;
+
+ embeddedparam.nbProps = 2;
+ if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+ goto cleanup;
+ (*tab_props).name = "Limit";
+ (*tab_props).val = memory_str;
+ (*(tab_props+1)).name = "InstanceID";
+ (*(tab_props+1)).val = memorySettingData->data->InstanceID;
+ embeddedparam.instanceName = "Msvm_MemorySettingData";
+ embeddedparam.prop_t = tab_props;
+ embeddedparam.nbProps = 2;
+
+ /* 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;
+
+ result = hypervInvokeMethod(priv, params, nb_params,
"ModifyVirtualSystemResources",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI,
selector);
+
+ cleanup:
+ VIR_FREE(tab_props);
+ VIR_FREE(params);
+ VIR_FREE(memory_str);
+ hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+ hypervFreeObject(priv, (hypervObject *)memorySettingData);
+ virBufferFreeAndReset(&query);
+ virBufferFreeAndReset(&query2);
+
+ return result;
+}
+
+static int
+hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = -1, nb_params;
+ const char *selector =
"CreationClassName=Msvm_VirtualSystemManagementService";
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ hypervPrivate *priv = domain->conn->privateData;
+ invokeXmlParam *params = NULL;
+ properties_t *tab_props = NULL;
+ eprParam eprparam;
+ embeddedParam embeddedparam;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+ Msvm_MemorySettingData *memorySettingData = NULL;
+ unsigned long memory_mb = memory / 1024; /* Memory converted in MB */
+ char *memory_str = NULL;
+
+ /* Memory value must be a multiple of 2 MB; round up it accordingly if necessary */
+ if (memory_mb % 2) memory_mb++;
+
+ /* Convert the memory value as a string */
+ memory_str = num2str(memory_mb);
+ if (memory_str == NULL)
+ goto cleanup;
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ VIR_DEBUG("memory=%sMb, uuid=%s", memory_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);
+ if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
&virtualSystemSettingData) < 0)
+ goto cleanup;
+
+ /* Get Msvm_MemorySettingData */
+ virBufferFreeAndReset(&query);
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent
"
+ "ResultClass = Msvm_MemorySettingData",
+ virtualSystemSettingData->data->InstanceID);
+ if (hypervGetMsvmMemorySettingDataList(priv, &query, &memorySettingData) <
0)
+ goto cleanup;
+
+ /* 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 = memory_str;
+ (*(tab_props+1)).name = "InstanceID";
+ (*(tab_props+1)).val = memorySettingData->data->InstanceID;
+ embeddedparam.instanceName = "Msvm_MemorySettingData";
+ 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;
+
+ if (hypervInvokeMethod(priv, params, nb_params,
"ModifyVirtualSystemResources",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain
memory"));
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ VIR_FREE(tab_props);
+ VIR_FREE(params);
+ VIR_FREE(memory_str);
+ hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+ hypervFreeObject(priv, (hypervObject *)memorySettingData);
+ virBufferFreeAndReset(&query);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+ return hypervDomainSetMemoryFlags(domain, memory, 0);
+}
static virHypervisorDriver hypervHypervisorDriver = {
.name = "Hyper-V",
@@ -1909,6 +2138,9 @@ static virHypervisorDriver hypervHypervisorDriver = {
.domainGetSchedulerParametersFlags = hypervDomainGetSchedulerParametersFlags, /*
1.2.10 */
.domainGetSchedulerParameters = hypervDomainGetSchedulerParameters, /* 1.2.10 */
.domainGetSchedulerType = hypervDomainGetSchedulerType, /* 1.2.10 */
+ .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.10 */
+ .domainSetMemory = hypervDomainSetMemory, /* 1.2.10 */
+ .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.10 */
};
/* Retrieves host system UUID */
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index d9aa0bd..2dfce6e 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -27,6 +27,7 @@
# include "virerror.h"
# include "hyperv_util.h"
# include "capabilities.h"
+# include "domain_conf.h"
# include "openwsman.h"
typedef struct _hypervPrivate hypervPrivate;
@@ -35,6 +36,7 @@ struct _hypervPrivate {
hypervParsedUri *parsedUri;
WsManClient *client;
virCapsPtr caps;
+ virDomainXMLOptionPtr xmlopt;
};
#endif /* __HYPERV_PRIVATE_H__ */
--
2.7.4