From: yvinter <yves.vinter@xxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list