From: yvinter <yves.vinter(a)bull.net>
---
src/hyperv/hyperv_driver.c | 377 ++++++++++++++++++++++++++++++++++
src/hyperv/hyperv_wmi_generator.input | 41 ++++
2 files changed, 418 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index f68eaad..cbe4397 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2424,6 +2424,383 @@ hypervDomainUndefine(virDomainPtr domain)
+/*
+ * Creates the attribute __PATH for the RASD object
+ * The attribute is build like this:
+ *
\\<host_name>\root\virtualization:Msvm_ResourceAllocationSettingData.InstanceID="<rasdInstanceID>"
+ * where backslashes in rasdInstanceID are doubled
+ */
+static int
+hypervGetResourceAllocationSettingDataPATH(virDomainPtr domain, char *rasdInstanceID,
char **__path)
+{
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ hypervPrivate *priv = domain->conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ char *strTemp = NULL;
+ int result = -1, i = 0, j = 0, n = 0;
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ /* Get host name */
+ virBufferAsprintf(&query,
+ "associators of "
+
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+ "Name=\"%s\"} "
+ "where AssocClass = Msvm_HostedDependency "
+ "ResultClass = Msvm_ComputerSystem",
+ uuid_string);
+ if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+ if (computerSystem == NULL) {
+ virReportError(VIR_ERR_NO_DOMAIN, _("No domain with UUID %s"),
uuid_string);
+ goto cleanup;
+ }
+
+ /* Count the number of backslash character */
+ strTemp = strchr(rasdInstanceID, '\\');
+ while (strTemp != NULL) {
+ n++;
+ strTemp = strchr(++strTemp, '\\');
+ }
+ /* Double the blackslashes */
+ if (VIR_ALLOC_N(strTemp, strlen(rasdInstanceID) + 1 + n) < 0)
+ goto cleanup;
+ while (rasdInstanceID[i] != '\0') {
+ strTemp[j] = rasdInstanceID[i];
+ if (rasdInstanceID[i] == '\\') {
+ j++;
+ strTemp[j] = '\\';
+ }
+ i++;
+ j++;
+ }
+ strTemp[j] = '\0';
+
+ /* Create the attribute __PATH */
+ /* FIXME: *__path allocated with 255 characters (static value) */
+ if (VIR_ALLOC_N(*__path, 255) < 0)
+ goto cleanup;
+ sprintf(*__path, "\\\\");
+ strcat(*__path, computerSystem->data->ElementName);
+ strcat(*__path,
"\\root\\virtualization:Msvm_ResourceAllocationSettingData.InstanceID=\"");
+ strcat(*__path, strTemp);
+ strcat(*__path, "\"");
+
+ result = 0;
+
+ cleanup:
+ VIR_FREE(strTemp);
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+ virBufferFreeAndReset(&query);
+
+ return result;
+}
+
+
+
+/* hypervDomainAttachDisk
+ * FIXME:
+ * - added ressources must me removed in case of error
+ * - allow attaching disks on iSCSI (implemented only on IDE)
+ * - allow attaching ISO images (on DVD devices)
+ * - implement associated detach method
+ */
+ATTRIBUTE_UNUSED static int
+hypervDomainAttachDisk(virDomainPtr domain, virDomainDiskDefPtr disk)
+{
+ int result = -1, nb_params;
+ const char *selector =
"CreationClassName=Msvm_VirtualSystemManagementService";
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ char *ideRasdPath = NULL, *newDiskDrivePath = NULL;
+ char ideControler[2], ideControlerAddr[2];
+ hypervPrivate *priv = domain->conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+ Msvm_ResourceAllocationSettingData *resourceAllocationSettingData = NULL;
+ Msvm_ResourceAllocationSettingData *resourceAllocationSettingData2 = NULL;
+ Msvm_ResourceAllocationSettingData *resourceAllocationSettingData3 = NULL;
+ Msvm_ResourceAllocationSettingData *resourceAllocationSettingData4 = NULL;
+ Msvm_ResourceAllocationSettingData *ideRasd = NULL; /* resourceAllocationSettingData
subtree -> do not disallocate */
+ Msvm_ResourceAllocationSettingData *diskRasd = NULL; /*
resourceAllocationSettingData2 subtree -> do not disallocate */
+ Msvm_ResourceAllocationSettingData *newDiskDrive = NULL; /*
resourceAllocationSettingData3 subtree -> do not disallocate */
+ Msvm_AllocationCapabilities *allocationCapabilities = NULL;
+ Msvm_AllocationCapabilities *allocationCapabilities2 = NULL;
+ invokeXmlParam *params = NULL;
+ properties_t *tab_props = NULL;
+ eprParam eprparam1, eprparam2;
+ embeddedParam embeddedparam1, embeddedparam2;
+
+ /* Initialization */
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ /* Set IDE Controler 0 or 1 and address 0 or 1 */
+ if (STREQ(disk->dst, "hda")) {
+ sprintf(ideControler, "%d", 0);
+ sprintf(ideControlerAddr, "%d", 0);
+ } else if (STREQ(disk->dst, "hdb")) {
+ sprintf(ideControler, "%d", 0);
+ sprintf(ideControlerAddr, "%d", 1);
+ } else if (STREQ(disk->dst, "hdc")) {
+ sprintf(ideControler, "%d", 1);
+ sprintf(ideControlerAddr, "%d", 0);
+ } else if (STREQ(disk->dst, "hdd")) {
+ sprintf(ideControler, "%d", 1);
+ sprintf(ideControlerAddr, "%d", 1);
+ } else {
+ /* IDE Controler 0 and address 0 choosen by default */
+ sprintf(ideControler, "%d", 0);
+ sprintf(ideControlerAddr, "%d", 0);
+ }
+
+ VIR_DEBUG("src=%s, dst=IDE Controller %s:%s, uuid=%s",
+ disk->src->path, ideControler, ideControlerAddr, uuid_string);
+
+ /* Get the current VM settings object */
+ 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 the settings for IDE Controller on the VM */
+ virBufferFreeAndReset(&query);
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent
"
+ "ResultClass = Msvm_ResourceAllocationSettingData",
+ virtualSystemSettingData->data->InstanceID);
+ if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
&resourceAllocationSettingData) < 0) {
+ goto cleanup;
+ }
+ ideRasd = resourceAllocationSettingData;
+ while (ideRasd != NULL) {
+ if (ideRasd->data->ResourceType == 5 &&
STREQ(ideRasd->data->Address, ideControler)) {
+ /* IDE Controller 0 or 1 */
+ break;
+ }
+ ideRasd = ideRasd->next;
+ }
+ if (ideRasd == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find IDE Controller %s"), ideControler);
+ goto cleanup;
+ }
+
+ /* Get the settings for 'Microsoft Synthetic Disk Drive' */
+ virBufferFreeAndReset(&query);
+ virBufferAddLit(&query, MSVM_ALLOCATIONCAPABILITIES_WQL_SELECT);
+ virBufferAddLit(&query, "WHERE ResourceSubType = 'Microsoft Synthetic
Disk Drive'");
+ if (hypervGetMsvmAllocationCapabilitiesList(priv, &query,
&allocationCapabilities) < 0) {
+ goto cleanup;
+ }
+
+ /* Get default values for 'Microsoft Synthetic Disk Drive' */
+ virBufferFreeAndReset(&query);
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_AllocationCapabilities.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_SettingsDefineCapabilities "
+ "ResultClass = Msvm_ResourceAllocationSettingData",
+ allocationCapabilities->data->InstanceID);
+ if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
&resourceAllocationSettingData2) < 0) {
+ goto cleanup;
+ }
+ diskRasd = resourceAllocationSettingData2;
+ while (diskRasd != NULL) {
+ if (strstr(diskRasd->data->InstanceID, "Default") != NULL) {
+ /* Default values */
+ break;
+ }
+ diskRasd = diskRasd->next;
+ }
+ if (diskRasd == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not get default values for 'Microsoft Synthetic
Disk Drive'"));
+ goto cleanup;
+ }
+
+ /* Create the attribute _PATH for the RASD object */
+ if (hypervGetResourceAllocationSettingDataPATH(domain,
ideRasd->data->InstanceID, &ideRasdPath) < 0) {
+ goto cleanup;
+ }
+
+ /* Add default disk drive */
+ /* Prepare EPR param */
+ virBufferFreeAndReset(&query);
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAsprintf(&query, "where Name = \"%s\"",
uuid_string);
+ eprparam1.query = &query;
+ eprparam1.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+ /* Prepare EMBEDDED param 1 */
+ embeddedparam1.nbProps = 4;
+ if (VIR_ALLOC_N(tab_props, embeddedparam1.nbProps) < 0)
+ goto cleanup;
+ (*tab_props).name = "Parent";
+ (*tab_props).val = ideRasdPath;
+ (*(tab_props+1)).name = "Address";
+ (*(tab_props+1)).val = ideControlerAddr;
+ (*(tab_props+2)).name = "ResourceType";
+ (*(tab_props+2)).val = "22";
+ (*(tab_props+3)).name = "ResourceSubType";
+ (*(tab_props+3)).val = diskRasd->data->ResourceSubType;
+ embeddedparam1.instanceName = MSVM_RESOURCEALLOCATIONSETTINGDATA_CLASSNAME;
+ embeddedparam1.prop_t = tab_props;
+
+ /* Create invokeXmlParam tab */
+ nb_params = 2;
+ if (VIR_ALLOC_N(params, nb_params) < 0)
+ goto cleanup;
+ (*params).name = "TargetSystem";
+ (*params).type = EPR_PARAM;
+ (*params).param = &eprparam1;
+ (*(params+1)).name = "ResourceSettingData";
+ (*(params+1)).type = EMBEDDED_PARAM;
+ (*(params+1)).param = &embeddedparam1;
+
+ if (hypervInvokeMethod(priv, params, nb_params,
"AddVirtualSystemResources",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not add
default disk drive"));
+ goto cleanup;
+ }
+
+ /* Get the instance of the new default drive disk */
+ virBufferFreeAndReset(&query);
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent
"
+ "ResultClass = Msvm_ResourceAllocationSettingData",
+ virtualSystemSettingData->data->InstanceID);
+ if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
&resourceAllocationSettingData3) < 0) {
+ goto cleanup;
+ }
+ newDiskDrive = resourceAllocationSettingData3;
+ while (newDiskDrive != NULL) {
+ if (newDiskDrive->data->ResourceType == 22 &&
+ STREQ(newDiskDrive->data->ResourceSubType, "Microsoft Synthetic
Disk Drive") &&
+ STREQ(newDiskDrive->data->Parent, ideRasdPath) &&
+ STREQ(newDiskDrive->data->Address, ideControlerAddr)) {
+ break;
+ }
+ newDiskDrive = newDiskDrive->next;
+ }
+ if (newDiskDrive == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find 'Microsoft Synthetic Disk
Drive'"));
+ goto cleanup;
+ }
+
+ /* Get the settings for 'Microsoft Virtual Hard Disk' */
+ virBufferFreeAndReset(&query);
+ virBufferAddLit(&query, MSVM_ALLOCATIONCAPABILITIES_WQL_SELECT);
+ virBufferAddLit(&query, "WHERE ResourceSubType = 'Microsoft Virtual Hard
Disk'");
+ if (hypervGetMsvmAllocationCapabilitiesList(priv, &query,
&allocationCapabilities2) < 0) {
+ goto cleanup;
+ }
+
+ /* Get default values for 'Microsoft Virtual Hard Drive' */
+ virBufferFreeAndReset(&query);
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_AllocationCapabilities.InstanceID=\"%s\"}
"
+ "where AssocClass = Msvm_SettingsDefineCapabilities "
+ "ResultClass = Msvm_ResourceAllocationSettingData",
+ allocationCapabilities2->data->InstanceID);
+ if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
&resourceAllocationSettingData4) < 0) {
+ goto cleanup;
+ }
+ diskRasd = resourceAllocationSettingData4;
+ while (diskRasd != NULL) {
+ if (strstr(diskRasd->data->InstanceID, "Default") != NULL) {
+ /* Default values */
+ break;
+ }
+ diskRasd = diskRasd->next;
+ }
+ if (diskRasd == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not get default values for 'Microsoft Virtual
Hard Drive'"));
+ goto cleanup;
+ }
+
+ /* Create the attribute _PATH for the RASD object */
+ if (hypervGetResourceAllocationSettingDataPATH(domain,
newDiskDrive->data->InstanceID, &newDiskDrivePath) < 0) {
+ goto cleanup;
+ }
+
+ /* Add the new VHD */
+ /* Prepare EPR param 2 */
+ virBufferFreeAndReset(&query);
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAsprintf(&query, "where Name = \"%s\"",
uuid_string);
+ eprparam2.query = &query;
+ eprparam2.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+ /* Prepare EMBEDDED param 2 */
+ VIR_FREE(tab_props);
+ embeddedparam2.nbProps = 4;
+ if (VIR_ALLOC_N(tab_props, embeddedparam2.nbProps) < 0)
+ goto cleanup;
+ (*tab_props).name = "Parent";
+ (*tab_props).val = newDiskDrivePath;
+ (*(tab_props+1)).name = "Connection";
+ (*(tab_props+1)).val = disk->src->path;
+ (*(tab_props+2)).name = "ResourceType";
+ (*(tab_props+2)).val = "21";
+ (*(tab_props+3)).name = "ResourceSubType";
+ (*(tab_props+3)).val = diskRasd->data->ResourceSubType;
+ embeddedparam2.instanceName = MSVM_RESOURCEALLOCATIONSETTINGDATA_CLASSNAME;
+ embeddedparam2.prop_t = tab_props;
+
+ /* Create invokeXmlParam tab */
+ VIR_FREE(params);
+ nb_params = 2;
+ if (VIR_ALLOC_N(params, nb_params) < 0)
+ goto cleanup;
+ (*params).name = "TargetSystem";
+ (*params).type = EPR_PARAM;
+ (*params).param = &eprparam2;
+ (*(params+1)).name = "ResourceSettingData";
+ (*(params+1)).type = EMBEDDED_PARAM;
+ (*(params+1)).param = &embeddedparam2;
+
+ if (hypervInvokeMethod(priv, params, nb_params,
"AddVirtualSystemResources",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not attach hard disk drive"));
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ VIR_FREE(ideRasdPath);
+ VIR_FREE(newDiskDrivePath);
+ VIR_FREE(tab_props);
+ VIR_FREE(params);
+ hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+ hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData);
+ hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData2);
+ hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData3);
+ hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData4);
+ hypervFreeObject(priv, (hypervObject *)allocationCapabilities);
+ hypervFreeObject(priv, (hypervObject *)allocationCapabilities2);
+ virBufferFreeAndReset(&query);
+
+ return result;
+}
+
+
+
static virDriver hypervDriver = {
.no = VIR_DRV_HYPERV,
.name = "Hyper-V",
diff --git a/src/hyperv/hyperv_wmi_generator.input
b/src/hyperv/hyperv_wmi_generator.input
index 79b5ee2..24d399f 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -605,3 +605,44 @@ class Msvm_VirtualSystemGlobalSettingData
boolean AllowFullSCSICommandSet
string Version
end
+
+
+class Msvm_ResourceAllocationSettingData
+ string Caption
+ string Description
+ string InstanceID
+ string ElementName
+ uint16 ResourceType
+ string OtherResourceType
+ string ResourceSubType
+ string PoolID
+ uint16 ConsumerVisibility
+ string HostResource[]
+ string AllocationUnits
+ uint64 VirtualQuantity
+ uint64 Reservation
+ uint64 Limit
+ uint32 Weight
+ boolean AutomaticAllocation
+ boolean AutomaticDeallocation
+ string Parent
+ string Connection[]
+ string Address
+ uint16 MappingBehavior
+ string VirtualSystemIdentifiers[]
+end
+
+
+class Msvm_AllocationCapabilities
+ string Caption
+ string Description
+ string ElementName
+ string InstanceID
+ string OtherResourceType
+ uint16 RequestTypesSupported
+ string ResourceSubType
+ uint16 ResourceType
+ uint16 SharingMode
+ uint16 SupportedAddStates[]
+ uint16 SupportedRemoveStates[]
+end
--
1.9.1