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