[PATCH 0/3] Add virDomainBlockInfo() support to hyperv driver
Feature requested by MTV project. See patches for more details Jonathon Jongsma (3): conf: support windows paths in virDomainDiskByName() hyperv: Add resource subtype definitions hyperv: Add basic domainGetBlockInfo() API implementation src/conf/domain_conf.c | 6 +- src/hyperv/hyperv_driver.c | 234 ++++++++++++++++++++++++-- src/hyperv/hyperv_driver.h | 11 ++ src/hyperv/hyperv_wmi.c | 41 +++++ src/hyperv/hyperv_wmi.h | 7 + src/hyperv/hyperv_wmi_generator.input | 109 ++++++++++++ 6 files changed, 392 insertions(+), 16 deletions(-) -- 2.53.0
With the hyperv driver, disks might have windows paths like "c:\path\to\disk.vhdx". Currently, this function supports paths, but only if they're in unix format. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/conf/domain_conf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 453e301041..a77670ea8d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15459,10 +15459,12 @@ virDomainDiskIndexByName(virDomainDef *def, const char *name, /* We prefer the <target dev='name'/> name (it's shorter, required * for all disks, and should be unambiguous), but also support * <source file='name'/> (if unambiguous). Assume dst if there is - * no leading slash, source name otherwise. */ + * no leading slash (Unix path) or drive letter (Windows path like C:\), + * source name otherwise. */ for (i = 0; i < def->ndisks; i++) { vdisk = def->disks[i]; - if (*name != '/') { + if (*name != '/' && + !(g_ascii_isalpha(name[0]) && name[1] == ':')) { if (STREQ(vdisk->dst, name)) return i; } else if (STREQ_NULLABLE(virDomainDiskGetSource(vdisk), name)) { -- 2.53.0
Rather than using raw strings, create definitions for each subtype string so that they can be re-used without needing to know the exact string format. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- Note: I originally intended to use these constants in the next patch, but later changed my approach and didn't actually use these in the blockinfo implementation. Nevertheless it seems like a useful change. src/hyperv/hyperv_driver.c | 29 +++++++++++++++-------------- src/hyperv/hyperv_driver.h | 11 +++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index eb28093028..3cebab305b 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -447,7 +447,7 @@ hypervDomainCreateSCSIController(virDomainPtr domain, virDomainControllerDef *de return -1; if (hypervSetEmbeddedProperty(scsiResource, "ResourceSubType", - "Microsoft:Hyper-V:Synthetic SCSI Controller") < 0) + HYPERV_RESOURCE_SUBTYPE_SCSI_CONTROLLER) < 0) return -1; /* perform the settings change */ @@ -493,7 +493,7 @@ hypervDomainAddVirtualDiskParent(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(controllerResource, "ResourceSubType", - "Microsoft:Hyper-V:Synthetic Disk Drive") < 0) + HYPERV_RESOURCE_SUBTYPE_DISK_DRIVE) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &controllerResource, @@ -537,7 +537,7 @@ hypervDomainAddVirtualHardDisk(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(volumeResource, "ResourceSubType", - "Microsoft:Hyper-V:Virtual Hard Disk") < 0) + HYPERV_RESOURCE_SUBTYPE_VIRTUAL_HARD_DISK) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &volumeResource, @@ -615,10 +615,11 @@ hypervDomainAttachPhysicalDisk(virDomainPtr domain, /* prepare HostResource */ /* get Msvm_DiskDrive root device ID */ - virBufferAddLit(&query, - MSVM_RESOURCEALLOCATIONSETTINGDATA_WQL_SELECT - "WHERE ResourceSubType = 'Microsoft:Hyper-V:Physical Disk Drive' " - "AND InstanceID LIKE '%%Default%%'"); + virBufferEscapeSQL(&query, + MSVM_RESOURCEALLOCATIONSETTINGDATA_WQL_SELECT + "WHERE ResourceSubType = '%s' " + "AND InstanceID LIKE '%%Default%%'", + HYPERV_RESOURCE_SUBTYPE_PHYSICAL_DISK_DRIVE); if (hypervGetWmiClass(Msvm_ResourceAllocationSettingData, &diskdefault) < 0) return -1; @@ -666,7 +667,7 @@ hypervDomainAttachPhysicalDisk(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(diskResource, "ResourceSubType", - "Microsoft:Hyper-V:Physical Disk Drive") < 0) + HYPERV_RESOURCE_SUBTYPE_PHYSICAL_DISK_DRIVE) < 0) return -1; if (hypervSetEmbeddedProperty(diskResource, "HostResource", hostResource) < 0) @@ -715,7 +716,7 @@ hypervDomainAddOpticalDrive(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(driveResource, "ResourceSubType", - "Microsoft:Hyper-V:Synthetic DVD Drive") < 0) + HYPERV_RESOURCE_SUBTYPE_DVD_DRIVE) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &driveResource, @@ -758,7 +759,7 @@ hypervDomainAddOpticalDisk(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(volumeResource, "ResourceSubType", - "Microsoft:Hyper-V:Virtual CD/DVD Disk") < 0) + HYPERV_RESOURCE_SUBTYPE_VIRTUAL_DVD_DISK) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &volumeResource, @@ -828,7 +829,7 @@ hypervDomainAttachFloppy(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(volumeResource, "ResourceSubType", - "Microsoft:Hyper-V:Virtual Floppy Disk") < 0) + HYPERV_RESOURCE_SUBTYPE_VIRTUAL_FLOPPY_DISK) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &volumeResource, @@ -1087,7 +1088,7 @@ hypervDomainAttachSyntheticEthernetAdapter(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(portResource, "ResourceSubType", - "Microsoft:Hyper-V:Synthetic Ethernet Port") < 0) + HYPERV_RESOURCE_SUBTYPE_ETHERNET_PORT) < 0) return -1; if (hypervSetEmbeddedProperty(portResource, @@ -1156,7 +1157,7 @@ hypervDomainAttachSyntheticEthernetAdapter(virDomainPtr domain, return -1; if (hypervSetEmbeddedProperty(connectionResource, - "ResourceSubType", "Microsoft:Hyper-V:Ethernet Connection") < 0) + "ResourceSubType", HYPERV_RESOURCE_SUBTYPE_ETHERNET_CONNECTION) < 0) return -1; if (hypervMsvmVSMSAddResourceSettings(domain, &connectionResource, @@ -1294,7 +1295,7 @@ hypervDomainDefParseVirtualExtent(hypervPrivate *priv, disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; /* note if it's a CDROM disk */ - if (STREQ(disk_entry->data->ResourceSubType, "Microsoft:Hyper-V:Virtual CD/DVD Disk")) + if (STREQ(disk_entry->data->ResourceSubType, HYPERV_RESOURCE_SUBTYPE_VIRTUAL_DVD_DISK)) disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; else disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; diff --git a/src/hyperv/hyperv_driver.h b/src/hyperv/hyperv_driver.h index 3764844494..27be81ea1c 100644 --- a/src/hyperv/hyperv_driver.h +++ b/src/hyperv/hyperv_driver.h @@ -27,4 +27,15 @@ #define HYPERV_MAX_IDE_CHANNELS 2 #define HYPERV_MAX_DRIVES_PER_IDE_CHANNEL 2 +/* ResourceSubType values for Msvm_*AllocationSettingData */ +#define HYPERV_RESOURCE_SUBTYPE_SCSI_CONTROLLER "Microsoft:Hyper-V:Synthetic SCSI Controller" +#define HYPERV_RESOURCE_SUBTYPE_DISK_DRIVE "Microsoft:Hyper-V:Synthetic Disk Drive" +#define HYPERV_RESOURCE_SUBTYPE_VIRTUAL_HARD_DISK "Microsoft:Hyper-V:Virtual Hard Disk" +#define HYPERV_RESOURCE_SUBTYPE_PHYSICAL_DISK_DRIVE "Microsoft:Hyper-V:Physical Disk Drive" +#define HYPERV_RESOURCE_SUBTYPE_DVD_DRIVE "Microsoft:Hyper-V:Synthetic DVD Drive" +#define HYPERV_RESOURCE_SUBTYPE_VIRTUAL_DVD_DISK "Microsoft:Hyper-V:Virtual CD/DVD Disk" +#define HYPERV_RESOURCE_SUBTYPE_VIRTUAL_FLOPPY_DISK "Microsoft:Hyper-V:Virtual Floppy Disk" +#define HYPERV_RESOURCE_SUBTYPE_ETHERNET_PORT "Microsoft:Hyper-V:Synthetic Ethernet Port" +#define HYPERV_RESOURCE_SUBTYPE_ETHERNET_CONNECTION "Microsoft:Hyper-V:Ethernet Connection" + int hypervRegister(void); -- 2.53.0
This adds initial support for virDomainGetBlockInfo() for the hyperv driver. It currently supports: - physical disk drives that are assigned to a vm - virtual disk drives backed by a .VHD file that are local to the host - other drives backed by local files (e.g. cdrom with a .iso) It will fail to get allocation and physical values for any drives backed by files that are not local to the host (e.g. on network shares) Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/hyperv/hyperv_driver.c | 205 ++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.c | 41 ++++++ src/hyperv/hyperv_wmi.h | 7 + src/hyperv/hyperv_wmi_generator.input | 109 ++++++++++++++ 4 files changed, 362 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3cebab305b..e332b8a860 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -26,6 +26,9 @@ #include "internal.h" #include "datatypes.h" +#include "libvirt/libvirt.h" +#include "libvirt/virterror.h" +#include "virbuffer.h" #include "virdomainobjlist.h" #include "virauth.h" #include "viralloc.h" @@ -3822,6 +3825,207 @@ hypervDomainInterfaceAddresses(virDomainPtr dom, } +static int +hypervGetFileSize(hypervPrivate *priv, + const char *filePath, + unsigned long long *fileSize) +{ + g_autoptr(CIM_DataFile) dataFile = NULL; + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + g_autofree char *escapedPath = NULL; + + virBufferAddLit(&query, CIM_DATAFILE_WQL_SELECT); + virBufferEscapeSQL(&query, "WHERE Name='%s'", filePath); + + if (hypervGetWmiClass(CIM_DataFile, &dataFile) < 0 || !dataFile) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not query file size for '%1$s'"), filePath); + return -1; + } + + *fileSize = dataFile->data->FileSize; + return 0; +} + + +static int +hypervGetPhysicalDiskBlockInfo(hypervPrivate *priv, + unsigned int driveNumber, + virDomainBlockInfoPtr info) +{ + g_autoptr(Win32_DiskDrive) diskDrive = NULL; + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&query, WIN32_DISKDRIVE_WQL_SELECT "WHERE Index=%u", driveNumber); + + if (hypervGetWmiClass(Win32_DiskDrive, &diskDrive) < 0 || !diskDrive) { + virReportError(VIR_ERR_INVALID_ARG, + _("Could not find physical disk with drive number %1$u"), driveNumber); + return -1; + } + + info->capacity = info->allocation = info->physical = diskDrive->data->Size; + return 0; +} + + +static int +hypervGetVHDCapacity(hypervPrivate *priv, + const char *path, + unsigned long long *capacity) +{ + g_auto(WsXmlDocH) settingDataDoc = NULL; + g_autofree char *maxInternalSizeStr = NULL; + + if (hypervImageManagementServiceGetVHDSD(priv, path, &settingDataDoc) < 0) + return -1; + + maxInternalSizeStr = ws_xml_get_xpath_value(settingDataDoc, + (char *)"//PROPERTY[@NAME='MaxInternalSize']/VALUE"); + + if (!maxInternalSizeStr) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find MaxInternalSize in VHD SettingData for '%1$s'"), path); + return -1; + } + + if (virStrToLong_ull(maxInternalSizeStr, NULL, 10, capacity) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse MaxInternalSize '%1$s' for '%2$s'"), + maxInternalSizeStr, path); + return -1; + } + + return 0; +} + + +static int +hypervGetVirtualDiskBlockInfo(hypervPrivate *priv, + const char *diskpath, + virDomainBlockInfoPtr info) +{ + unsigned long long capacity = 0; + unsigned long long allocation = 0; + /* This might fail if diskpath is not a vhd file, but continue anyway as it + * might be e.g. an ISO that is not supported by the ImageManagementService */ + int rcapacity = hypervGetVHDCapacity(priv, diskpath, &capacity); + + /* querying actual file allocation only works for local files, so may fail + * for files on network shares */ + int rallocation = hypervGetFileSize(priv, diskpath, &allocation); + + /* if both queries were unsuccessful, just return an error */ + if (rcapacity < 0 && rallocation < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to get info for disk '%s'"), diskpath); + return -1; + } + + /* if we failed to get the capacity from the ImageManagementService (i.e. + * the disk path wasn't a vhd file), just use the file size */ + if (capacity == 0) + capacity = allocation; + + info->capacity = capacity; + info->physical = info->allocation = allocation; + return 0; +} + +static int +hypervDomainGetBlockInfo(virDomainPtr domain, + const char *path, + virDomainBlockInfoPtr info, + unsigned int flags) +{ + hypervPrivate *priv = domain->conn->privateData; + char uuid_string[VIR_UUID_STRING_BUFLEN]; + g_autoptr(Msvm_ResourceAllocationSettingData) resource_settings = NULL; + g_autoptr(Msvm_StorageAllocationSettingData) storage_settings = NULL; + g_autoptr(Msvm_VirtualSystemSettingData) system_settings = NULL; + g_autoptr(virDomainDef) def = NULL; + virDomainDiskDef *disk = NULL; + const char *diskpath = NULL; + + virCheckFlags(0, -1); + + virUUIDFormat(domain->uuid, uuid_string); + + if (hypervGetMsvmVirtualSystemSettingDataFromUUID(priv, uuid_string, &system_settings) < 0) { + virReportError(VIR_ERR_NO_DOMAIN, _("No domain with UUID %1$s"), uuid_string); + return -1; + } + + if (hypervGetResourceAllocationSD(priv, + system_settings->data->InstanceID, + &resource_settings) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get resource allocation settings data")); + return -1; + } + + if (hypervGetStorageAllocationSD(priv, + system_settings->data->InstanceID, + &storage_settings) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get storage allocation settings data")); + return -1; + } + + if (!(def = virDomainDefNew(priv->xmlopt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to create a new virDomainDef")); + return -1; + } + + /* Process storage and resources to get disk names */ + if (hypervDomainDefParseStorage(priv, def, resource_settings, storage_settings) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to parse storage")); + return -1; + } + + disk = virDomainDiskByName(def, path, false); + if (!disk) { + virReportError(VIR_ERR_INVALID_ARG, + _("invalid path %1$s not assigned to domain"), path); + return -1; + } + + diskpath = virDomainDiskGetSource(disk); + if (!diskpath) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk '%1$s' has no source path"), path); + return -1; + } + + if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_BLOCK) { + unsigned int driveNumber = 0; + g_autoptr(Msvm_DiskDrive) diskdrive = NULL; + + /* BLOCK type disks have their source path set to the windows drive number */ + if (virStrToLong_ui(diskpath, NULL, 10, &driveNumber) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid drive number '%1$s' for physical disk"), diskpath); + return -1; + } + + if (hypervGetPhysicalDiskBlockInfo(priv, driveNumber, info) < 0) + return -1; + } else if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { + /* first try querying the disk via the image management service which supports .vhd(x) files */ + if (hypervGetVirtualDiskBlockInfo(priv, diskpath, info) < 0) + return -1; + } else { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("Unsupported disk type %1$d for disk '%2$s'"), + virDomainDiskGetType(disk), path); + return -1; + } + + return 0; +} + + static virHypervisorDriver hypervHypervisorDriver = { .name = "Hyper-V", .connectOpen = hypervConnectOpen, /* 0.9.5 */ @@ -3886,6 +4090,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainSendKey = hypervDomainSendKey, /* 3.6.0 */ .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */ .domainInterfaceAddresses = hypervDomainInterfaceAddresses, /* 12.1.0 */ + .domainGetBlockInfo = hypervDomainGetBlockInfo, /* 12.1.0 */ }; diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index eee42b5c70..90bbc42b6d 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -31,6 +31,7 @@ #include <u/syslog.h> #include "internal.h" +#include "libvirt/virterror.h" #include "virerror.h" #include "datatypes.h" #include "viralloc.h" @@ -1507,6 +1508,46 @@ hypervGetEthernetPortAllocationSD(hypervPrivate *priv, } +int +hypervImageManagementServiceGetVHDSD(hypervPrivate *priv, + const char *vhdPath, + WsXmlDocH *settingDataDoc) +{ + hypervInvokeParamsList *params = NULL; + g_auto(WsXmlDocH) response = NULL; + g_autofree char *settingDataXmlStr = NULL; + + params = hypervCreateInvokeParamsList("GetVirtualHardDiskSettingData", + MSVM_IMAGEMANAGEMENTSERVICE_SELECTOR, + Msvm_ImageManagementService_WmiInfo); + if (hypervAddSimpleParam(params, "Path", vhdPath) < 0) + return -1; + + if (hypervInvokeMethod(priv, ¶ms, &response) < 0) + return -1; + + settingDataXmlStr = ws_xml_get_xpath_value(response, + (char *)"/s:Envelope/s:Body/p:GetVirtualHardDiskSettingData_OUTPUT/p:SettingData"); + + if (!settingDataXmlStr) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not extract SettingData from response for '%1$s'"), vhdPath); + return -1; + } + + /* the method returns an embedded CIM-XML document as a string, so we need + * to parse it as xml */ + *settingDataDoc = ws_xml_read_memory(settingDataXmlStr, strlen(settingDataXmlStr), "UTF-8", 0); + if (!*settingDataDoc) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not parse VHD SettingData XML for '%1$s'"), vhdPath); + return -1; + } + + return 0; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Msvm_VirtualSystemManagementService */ diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h index 9093aec455..11d61edfc5 100644 --- a/src/hyperv/hyperv_wmi.h +++ b/src/hyperv/hyperv_wmi.h @@ -36,6 +36,9 @@ #define MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_SELECTOR \ "CreationClassName=Msvm_VirtualSystemManagementService" +#define MSVM_IMAGEMANAGEMENTSERVICE_SELECTOR \ + "CreationClassName=Msvm_ImageManagementService" + int hypervVerifyResponse(WsManClient *client, WsXmlDocH response, const char *detail); @@ -263,6 +266,10 @@ int hypervGetEthernetPortAllocationSD(hypervPrivate *priv, const char *id, Msvm_EthernetPortAllocationSettingData **data); +int hypervImageManagementServiceGetVHDSD(hypervPrivate *priv, + const char *vhdPath, + WsXmlDocH *settingDataDoc); + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Msvm_VirtualSystemManagementService */ diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input index e6053267f8..017b7a0fa5 100644 --- a/src/hyperv/hyperv_wmi_generator.input +++ b/src/hyperv/hyperv_wmi_generator.input @@ -1143,3 +1143,112 @@ class Msvm_VideoHead uint32 CurrentNumberOfColumns uint64 CurrentNumberOfColors end + + +class Msvm_ImageManagementService + 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_VirtualHardDiskSettingData + string InstanceID + string Caption + string Description + string ElementName + uint16 Type + uint16 Format + string Path + string ParentPath + datetime ParentTimestamp + string ParentIdentifier + uint64 MaxInternalSize + uint32 BlockSize + uint32 LogicalSectorSize + uint32 PhysicalSectorSize + string VirtualDiskId + uint64 DataAlignment + uint16 PmemAddressAbstractionType + boolean IsPmemCompatible +end + + +class Win32_DiskDrive + uint16 Availability + uint32 BytesPerSector + uint16 Capabilities[] + string CapabilityDescriptions[] + string Caption + string CompressionMethod + uint32 ConfigManagerErrorCode + boolean ConfigManagerUserConfig + string CreationClassName + uint64 DefaultBlockSize + string Description + string DeviceID + boolean ErrorCleared + string ErrorDescription + string ErrorMethodology + string FirmwareRevision + uint32 Index + datetime InstallDate + string InterfaceType + uint32 LastErrorCode + string Manufacturer + uint64 MaxBlockSize + uint64 MaxMediaSize + boolean MediaLoaded + string MediaType + uint64 MinBlockSize + string Model + string Name + boolean NeedsCleaning + uint32 NumberOfMediaSupported + uint32 Partitions + string PNPDeviceID + uint16 PowerManagementCapabilities[] + boolean PowerManagementSupported + uint32 SCSIBus + uint16 SCSILogicalUnit + uint16 SCSIPort + uint16 SCSITargetId + uint32 SectorsPerTrack + string SerialNumber + uint32 Signature + uint64 Size + string Status + uint16 StatusInfo + string SystemCreationClassName + string SystemName + uint64 TotalCylinders + uint32 TotalHeads + uint64 TotalSectors + uint64 TotalTracks + uint32 TracksPerCylinder +end -- 2.53.0
On 2/19/26 10:31 PM, Jonathon Jongsma via Devel wrote:
This adds initial support for virDomainGetBlockInfo() for the hyperv driver. It currently supports: - physical disk drives that are assigned to a vm - virtual disk drives backed by a .VHD file that are local to the host - other drives backed by local files (e.g. cdrom with a .iso)
It will fail to get allocation and physical values for any drives backed by files that are not local to the host (e.g. on network shares)
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/hyperv/hyperv_driver.c | 205 ++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.c | 41 ++++++ src/hyperv/hyperv_wmi.h | 7 + src/hyperv/hyperv_wmi_generator.input | 109 ++++++++++++++ 4 files changed, 362 insertions(+)
Squash this in: diff --git i/src/hyperv/hyperv_driver.c w/src/hyperv/hyperv_driver.c index e332b8a860..a363c58a3c 100644 --- i/src/hyperv/hyperv_driver.c +++ w/src/hyperv/hyperv_driver.c @@ -26,8 +26,6 @@ #include "internal.h" #include "datatypes.h" -#include "libvirt/libvirt.h" -#include "libvirt/virterror.h" #include "virbuffer.h" #include "virdomainobjlist.h" #include "virauth.h" @@ -3917,7 +3915,9 @@ hypervGetVirtualDiskBlockInfo(hypervPrivate *priv, /* if both queries were unsuccessful, just return an error */ if (rcapacity < 0 && rallocation < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to get info for disk '%s'"), diskpath); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to get info for disk '%1$s'"), + diskpath); return -1; } diff --git i/src/hyperv/hyperv_wmi.c w/src/hyperv/hyperv_wmi.c index 90bbc42b6d..4611833142 100644 --- i/src/hyperv/hyperv_wmi.c +++ w/src/hyperv/hyperv_wmi.c @@ -31,7 +31,6 @@ #include <u/syslog.h> #include "internal.h" -#include "libvirt/virterror.h" #include "virerror.h" #include "datatypes.h" #include "viralloc.h" Michal
On 2/19/26 10:31 PM, Jonathon Jongsma via Devel wrote:
Feature requested by MTV project. See patches for more details
Jonathon Jongsma (3): conf: support windows paths in virDomainDiskByName() hyperv: Add resource subtype definitions hyperv: Add basic domainGetBlockInfo() API implementation
src/conf/domain_conf.c | 6 +- src/hyperv/hyperv_driver.c | 234 ++++++++++++++++++++++++-- src/hyperv/hyperv_driver.h | 11 ++ src/hyperv/hyperv_wmi.c | 41 +++++ src/hyperv/hyperv_wmi.h | 7 + src/hyperv/hyperv_wmi_generator.input | 109 ++++++++++++ 6 files changed, 392 insertions(+), 16 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Jonathon Jongsma -
Michal Prívozník