Message ID | 2cd59ce454e0da02eeb75ab7461ef420b30864f5.1599470071.git.tgolembi@redhat.com |
---|---|
State | Superseded |
Headers | show |
Series | qga: add command guest-get-disk | expand |
Hi On Mon, Sep 7, 2020 at 1:15 PM Tomáš Golembiovský <tgolembi@redhat.com> wrote: > 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", > ... > }, > "slaves": [] > } > ] > } > > Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com> > --- > qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 91 insertions(+), 6 deletions(-) > > diff --git a/qga/commands-win32.c b/qga/commands-win32.c > index e9976a0c46..9ac847a187 100644 > --- a/qga/commands-win32.c > +++ b/qga/commands-win32.c > @@ -945,6 +945,91 @@ out: > return list; > } > > +GuestDiskInfoList *qmp_guest_get_disks(Error **errp) > +{ > + 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; > + > + g_debug(" getting device path"); > + while (!SetupDiGetDeviceInterfaceDetail(dev_info, &dev_iface_data, > + pdev_iface_detail_data, > + size, &size, > + NULL)) { > + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { > + pdev_iface_detail_data = g_malloc(size); > Since this is called in a loop, you should use g_realloc() to avoid potential leaks. + pdev_iface_detail_data->cbSize = > + sizeof(*pdev_iface_detail_data); > + } else { > + g_debug("failed to get device interface details"); > + 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) > @@ -952,6 +1037,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) > @@ -2229,9 +2320,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.25.0 > > > The rest looks ok to me. -- Marc-André Lureau <div dir="ltr"><div dir="ltr">Hi<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 7, 2020 at 1:15 PM Tomáš Golembiovský <<a href="mailto:tgolembi@redhat.com">tgolembi@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The command lists all the physical disk drives. Unlike for Linux<br> partitions and virtual volumes are not listed.<br> <br> Example output:<br> <br> {<br> "return": [<br> {<br> "name": "\\\\.\\PhysicalDrive0",<br> "partition": false,<br> "address": {<br> "serial": "QM00001",<br> "bus-type": "sata",<br> ...<br> },<br> "slaves": []<br> }<br> ]<br> }<br> <br> Signed-off-by: Tomáš Golembiovský <<a href="mailto:tgolembi@redhat.com" target="_blank">tgolembi@redhat.com</a>><br> ---<br> qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++---<br> 1 file changed, 91 insertions(+), 6 deletions(-)<br> <br> diff --git a/qga/commands-win32.c b/qga/commands-win32.c<br> index e9976a0c46..9ac847a187 100644<br> --- a/qga/commands-win32.c<br> +++ b/qga/commands-win32.c<br> @@ -945,6 +945,91 @@ out:<br> return list;<br> }<br> <br> +GuestDiskInfoList *qmp_guest_get_disks(Error **errp)<br> +{<br> + GuestDiskInfoList *new = NULL, *ret = NULL;<br> + HDEVINFO dev_info;<br> + SP_DEVICE_INTERFACE_DATA dev_iface_data;<br> + int i;<br> +<br> + dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, 0, 0,<br> + DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);<br> + if (dev_info == INVALID_HANDLE_VALUE) {<br> + error_setg_win32(errp, GetLastError(), "failed to get device tree");<br> + return NULL;<br> + }<br> +<br> + g_debug("enumerating devices");<br> + dev_iface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);<br> + for (i = 0;<br> + SetupDiEnumDeviceInterfaces(dev_info, NULL, &GUID_DEVINTERFACE_DISK,<br> + i, &dev_iface_data);<br> + i++) {<br> + GuestDiskAddress *address = NULL;<br> + GuestDiskInfo *disk = NULL;<br> + Error *local_err = NULL;<br> + g_autofree PSP_DEVICE_INTERFACE_DETAIL_DATA<br> + pdev_iface_detail_data = NULL;<br> + STORAGE_DEVICE_NUMBER sdn;<br> + HANDLE dev_file;<br> + DWORD size = 0;<br> +<br> + g_debug(" getting device path");<br> + while (!SetupDiGetDeviceInterfaceDetail(dev_info, &dev_iface_data,<br> + pdev_iface_detail_data,<br> + size, &size,<br> + NULL)) {<br> + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {<br> + pdev_iface_detail_data = g_malloc(size);<br></blockquote><div><br></div><div>Since this is called in a loop, you should use g_realloc() to avoid potential leaks.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> + pdev_iface_detail_data->cbSize =<br> + sizeof(*pdev_iface_detail_data);<br> + } else {<br> + g_debug("failed to get device interface details");<br> + continue;<br> + }<br> + }<br> +<br> + g_debug(" device: %s", pdev_iface_detail_data->DevicePath);<br> + dev_file = CreateFile(pdev_iface_detail_data->DevicePath, 0,<br> + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);<br> + if (!DeviceIoControl(dev_file, IOCTL_STORAGE_GET_DEVICE_NUMBER,<br> + NULL, 0, &sdn, sizeof(sdn), &size, NULL)) {<br> + CloseHandle(dev_file);<br> + debug_error("failed to get storage device number");<br> + continue;<br> + }<br> + CloseHandle(dev_file);<br> +<br> + disk = g_new0(GuestDiskInfo, 1);<br> + disk->name = g_strdup_printf("\\\\.\\PhysicalDrive%lu",<br> + sdn.DeviceNumber);<br> +<br> + g_debug(" number: %lu", sdn.DeviceNumber);<br> + address = g_malloc0(sizeof(GuestDiskAddress));<br> + address->has_dev = true;<br> + address->dev = g_strdup(disk->name);<br> + get_single_disk_info(sdn.DeviceNumber, address, &local_err);<br> + if (local_err) {<br> + g_debug("failed to get disk info: %s",<br> + error_get_pretty(local_err));<br> + error_free(local_err);<br> + qapi_free_GuestDiskAddress(address);<br> + address = NULL;<br> + } else {<br> + disk->address = address;<br> + disk->has_address = true;<br> + }<br> +<br> + new = g_malloc0(sizeof(GuestDiskInfoList));<br> + new->value = disk;<br> + new->next = ret;<br> + ret = new;<br> + }<br> +<br> + SetupDiDestroyDeviceInfoList(dev_info);<br> + return ret;<br> +}<br> +<br> #else<br> <br> static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)<br> @@ -952,6 +1037,12 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)<br> return NULL;<br> }<br> <br> +GuestDiskInfoList *qmp_guest_get_disks(Error **errp)<br> +{<br> + error_setg(errp, QERR_UNSUPPORTED);<br> + return NULL;<br> +}<br> +<br> #endif /* CONFIG_QGA_NTDDSCSI */<br> <br> static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)<br> @@ -2229,9 +2320,3 @@ GuestOSInfo *qmp_guest_get_osinfo(Error **errp)<br> <br> return info;<br> }<br> -<br> -GuestDiskInfoList *qmp_guest_get_disks(Error **errp)<br> -{<br> - error_setg(errp, QERR_UNSUPPORTED);<br> - return NULL;<br> -}<br> -- <br> 2.25.0<br> <br> <br> </blockquote></div><div><br></div><div>The rest looks ok to me.<br></div><br>-- <br><div dir="ltr" class="gmail_signature">Marc-André Lureau<br></div></div>
diff --git a/qga/commands-win32.c b/qga/commands-win32.c index e9976a0c46..9ac847a187 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -945,6 +945,91 @@ out: return list; } +GuestDiskInfoList *qmp_guest_get_disks(Error **errp) +{ + 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; + + g_debug(" getting device path"); + while (!SetupDiGetDeviceInterfaceDetail(dev_info, &dev_iface_data, + pdev_iface_detail_data, + size, &size, + NULL)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + pdev_iface_detail_data = g_malloc(size); + pdev_iface_detail_data->cbSize = + sizeof(*pdev_iface_detail_data); + } else { + g_debug("failed to get device interface details"); + 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) @@ -952,6 +1037,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) @@ -2229,9 +2320,3 @@ GuestOSInfo *qmp_guest_get_osinfo(Error **errp) return info; } - -GuestDiskInfoList *qmp_guest_get_disks(Error **errp) -{ - error_setg(errp, QERR_UNSUPPORTED); - return NULL; -}
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", ... }, "slaves": [] } ] } Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com> --- qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 6 deletions(-)