|
|
709dde |
From 5c5fbed35d6c8b44533ff8a29afb9a85131ea7e9 Mon Sep 17 00:00:00 2001
|
|
|
709dde |
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
|
|
709dde |
Date: Fri, 8 Jan 2021 07:40:59 -0500
|
|
|
709dde |
Subject: [PATCH 08/10] qga: add implementation of guest-get-disks for Windows
|
|
|
709dde |
MIME-Version: 1.0
|
|
|
709dde |
Content-Type: text/plain; charset=UTF-8
|
|
|
709dde |
Content-Transfer-Encoding: 8bit
|
|
|
709dde |
|
|
|
709dde |
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
709dde |
Message-id: <20210108074101.290008-9-marcandre.lureau@redhat.com>
|
|
|
709dde |
Patchwork-id: 100527
|
|
|
709dde |
O-Subject: [RHEL-8.3.0.z qemu-kvm PATCH 08/10] qga: add implementation of guest-get-disks for Windows
|
|
|
709dde |
Bugzilla: 1913818
|
|
|
709dde |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
709dde |
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
709dde |
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
709dde |
|
|
|
709dde |
From: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
709dde |
|
|
|
709dde |
From: Tomáš Golembiovský <tgolembi@redhat.com>
|
|
|
709dde |
|
|
|
709dde |
The command lists all the physical disk drives. Unlike for Linux
|
|
|
709dde |
partitions and virtual volumes are not listed.
|
|
|
709dde |
|
|
|
709dde |
Example output:
|
|
|
709dde |
|
|
|
709dde |
{
|
|
|
709dde |
"return": [
|
|
|
709dde |
{
|
|
|
709dde |
"name": "\\\\.\\PhysicalDrive0",
|
|
|
709dde |
"partition": false,
|
|
|
709dde |
"address": {
|
|
|
709dde |
"serial": "QM00001",
|
|
|
709dde |
"bus-type": "sata",
|
|
|
709dde |
...
|
|
|
709dde |
},
|
|
|
709dde |
"dependents": []
|
|
|
709dde |
}
|
|
|
709dde |
]
|
|
|
709dde |
}
|
|
|
709dde |
|
|
|
709dde |
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
|
|
709dde |
Signed-off-by: Michael Roth <michael.roth@amd.com>
|
|
|
709dde |
|
|
|
709dde |
(cherry picked from commit c67d2efd9d1771fd886e3b58771adaa62897f3d9)
|
|
|
709dde |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
709dde |
---
|
|
|
709dde |
qga/commands-win32.c | 107 ++++++++++++++++++++++++++++++++++++++++---
|
|
|
709dde |
1 file changed, 101 insertions(+), 6 deletions(-)
|
|
|
709dde |
|
|
|
709dde |
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
|
|
|
709dde |
index be63fa2b208..a07725e874b 100644
|
|
|
709dde |
--- a/qga/commands-win32.c
|
|
|
709dde |
+++ b/qga/commands-win32.c
|
|
|
709dde |
@@ -960,6 +960,101 @@ out:
|
|
|
709dde |
return list;
|
|
|
709dde |
}
|
|
|
709dde |
|
|
|
709dde |
+GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
|
|
|
709dde |
+{
|
|
|
709dde |
+ ERRP_GUARD();
|
|
|
709dde |
+ GuestDiskInfoList *new = NULL, *ret = NULL;
|
|
|
709dde |
+ HDEVINFO dev_info;
|
|
|
709dde |
+ SP_DEVICE_INTERFACE_DATA dev_iface_data;
|
|
|
709dde |
+ int i;
|
|
|
709dde |
+
|
|
|
709dde |
+ dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, 0, 0,
|
|
|
709dde |
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
|
|
709dde |
+ if (dev_info == INVALID_HANDLE_VALUE) {
|
|
|
709dde |
+ error_setg_win32(errp, GetLastError(), "failed to get device tree");
|
|
|
709dde |
+ return NULL;
|
|
|
709dde |
+ }
|
|
|
709dde |
+
|
|
|
709dde |
+ g_debug("enumerating devices");
|
|
|
709dde |
+ dev_iface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
|
|
709dde |
+ for (i = 0;
|
|
|
709dde |
+ SetupDiEnumDeviceInterfaces(dev_info, NULL, &GUID_DEVINTERFACE_DISK,
|
|
|
709dde |
+ i, &dev_iface_data);
|
|
|
709dde |
+ i++) {
|
|
|
709dde |
+ GuestDiskAddress *address = NULL;
|
|
|
709dde |
+ GuestDiskInfo *disk = NULL;
|
|
|
709dde |
+ Error *local_err = NULL;
|
|
|
709dde |
+ g_autofree PSP_DEVICE_INTERFACE_DETAIL_DATA
|
|
|
709dde |
+ pdev_iface_detail_data = NULL;
|
|
|
709dde |
+ STORAGE_DEVICE_NUMBER sdn;
|
|
|
709dde |
+ HANDLE dev_file;
|
|
|
709dde |
+ DWORD size = 0;
|
|
|
709dde |
+ BOOL result;
|
|
|
709dde |
+ int attempt;
|
|
|
709dde |
+
|
|
|
709dde |
+ g_debug(" getting device path");
|
|
|
709dde |
+ for (attempt = 0, result = FALSE; attempt < 2 && !result; attempt++) {
|
|
|
709dde |
+ result = SetupDiGetDeviceInterfaceDetail(dev_info,
|
|
|
709dde |
+ &dev_iface_data, pdev_iface_detail_data, size, &size, NULL);
|
|
|
709dde |
+ if (result) {
|
|
|
709dde |
+ break;
|
|
|
709dde |
+ }
|
|
|
709dde |
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
|
709dde |
+ pdev_iface_detail_data = g_realloc(pdev_iface_detail_data,
|
|
|
709dde |
+ size);
|
|
|
709dde |
+ pdev_iface_detail_data->cbSize =
|
|
|
709dde |
+ sizeof(*pdev_iface_detail_data);
|
|
|
709dde |
+ } else {
|
|
|
709dde |
+ g_debug("failed to get device interface details");
|
|
|
709dde |
+ break;
|
|
|
709dde |
+ }
|
|
|
709dde |
+ }
|
|
|
709dde |
+ if (!result) {
|
|
|
709dde |
+ g_debug("skipping device");
|
|
|
709dde |
+ continue;
|
|
|
709dde |
+ }
|
|
|
709dde |
+
|
|
|
709dde |
+ g_debug(" device: %s", pdev_iface_detail_data->DevicePath);
|
|
|
709dde |
+ dev_file = CreateFile(pdev_iface_detail_data->DevicePath, 0,
|
|
|
709dde |
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
709dde |
+ if (!DeviceIoControl(dev_file, IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
|
|
709dde |
+ NULL, 0, &sdn, sizeof(sdn), &size, NULL)) {
|
|
|
709dde |
+ CloseHandle(dev_file);
|
|
|
709dde |
+ debug_error("failed to get storage device number");
|
|
|
709dde |
+ continue;
|
|
|
709dde |
+ }
|
|
|
709dde |
+ CloseHandle(dev_file);
|
|
|
709dde |
+
|
|
|
709dde |
+ disk = g_new0(GuestDiskInfo, 1);
|
|
|
709dde |
+ disk->name = g_strdup_printf("\\\\.\\PhysicalDrive%lu",
|
|
|
709dde |
+ sdn.DeviceNumber);
|
|
|
709dde |
+
|
|
|
709dde |
+ g_debug(" number: %lu", sdn.DeviceNumber);
|
|
|
709dde |
+ address = g_malloc0(sizeof(GuestDiskAddress));
|
|
|
709dde |
+ address->has_dev = true;
|
|
|
709dde |
+ address->dev = g_strdup(disk->name);
|
|
|
709dde |
+ get_single_disk_info(sdn.DeviceNumber, address, &local_err);
|
|
|
709dde |
+ if (local_err) {
|
|
|
709dde |
+ g_debug("failed to get disk info: %s",
|
|
|
709dde |
+ error_get_pretty(local_err));
|
|
|
709dde |
+ error_free(local_err);
|
|
|
709dde |
+ qapi_free_GuestDiskAddress(address);
|
|
|
709dde |
+ address = NULL;
|
|
|
709dde |
+ } else {
|
|
|
709dde |
+ disk->address = address;
|
|
|
709dde |
+ disk->has_address = true;
|
|
|
709dde |
+ }
|
|
|
709dde |
+
|
|
|
709dde |
+ new = g_malloc0(sizeof(GuestDiskInfoList));
|
|
|
709dde |
+ new->value = disk;
|
|
|
709dde |
+ new->next = ret;
|
|
|
709dde |
+ ret = new;
|
|
|
709dde |
+ }
|
|
|
709dde |
+
|
|
|
709dde |
+ SetupDiDestroyDeviceInfoList(dev_info);
|
|
|
709dde |
+ return ret;
|
|
|
709dde |
+}
|
|
|
709dde |
+
|
|
|
709dde |
#else
|
|
|
709dde |
|
|
|
709dde |
static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
|
|
|
709dde |
@@ -967,6 +1062,12 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
|
|
|
709dde |
return NULL;
|
|
|
709dde |
}
|
|
|
709dde |
|
|
|
709dde |
+GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
|
|
|
709dde |
+{
|
|
|
709dde |
+ error_setg(errp, QERR_UNSUPPORTED);
|
|
|
709dde |
+ return NULL;
|
|
|
709dde |
+}
|
|
|
709dde |
+
|
|
|
709dde |
#endif /* CONFIG_QGA_NTDDSCSI */
|
|
|
709dde |
|
|
|
709dde |
static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
|
|
|
709dde |
@@ -2234,9 +2335,3 @@ GuestOSInfo *qmp_guest_get_osinfo(Error **errp)
|
|
|
709dde |
|
|
|
709dde |
return info;
|
|
|
709dde |
}
|
|
|
709dde |
-
|
|
|
709dde |
-GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
|
|
|
709dde |
-{
|
|
|
709dde |
- error_setg(errp, QERR_UNSUPPORTED);
|
|
|
709dde |
- return NULL;
|
|
|
709dde |
-}
|
|
|
709dde |
--
|
|
|
709dde |
2.27.0
|
|
|
709dde |
|