diff --git a/qga/commands-posix.c b/qga/commands-posix.c index e8467ac567..744c2b5a5d 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -996,6 +996,39 @@ cleanup: return ret; } +/* + * Store disk device info for non-PCI virtio devices (for example s390x + * channel I/O devices). Returns true if information has been stored, or + * false for failure. + */ +static bool build_guest_fsinfo_for_nonpci_virtio(char const *syspath, + GuestDiskAddress *disk, + Error **errp) +{ + unsigned int tgt[3]; + char *p; + + if (!strstr(syspath, "/virtio") || !strstr(syspath, "/block")) { + g_debug("Unsupported virtio device '%s'", syspath); + return false; + } + + p = strstr(syspath, "/target"); + if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u", + &tgt[0], &tgt[1], &tgt[2]) == 3) { + /* virtio-scsi: target*:0:: */ + disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; + disk->bus = tgt[0]; + disk->target = tgt[1]; + disk->unit = tgt[2]; + } else { + /* virtio-blk: 1 disk per 1 device */ + disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO; + } + + return true; +} + /* Store disk device info specified by @sysfs into @fs */ static void build_guest_fsinfo_for_real_device(char const *syspath, GuestFilesystemInfo *fs, @@ -1046,7 +1079,14 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, udev_device_unref(udevice); #endif - has_hwinf = build_guest_fsinfo_for_pci_dev(syspath, disk, errp); + if (strstr(syspath, "/devices/pci")) { + has_hwinf = build_guest_fsinfo_for_pci_dev(syspath, disk, errp); + } else if (strstr(syspath, "/virtio")) { + has_hwinf = build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp); + } else { + g_debug("Unsupported device type for '%s'", syspath); + has_hwinf = false; + } if (has_hwinf || disk->has_dev || disk->has_serial) { list->next = fs->disk;