In the case of other SCSI host devices, the device that is created within the guest will be within the usual SCSI namespace (e.g., host:bus:target:lun). But for vhost-scsi, the actual naming structure will come from the host configuration, and will be invisible to both QEMU and Libvirt. So specifying one with an <address type='drive' ...> tag (as is often done for virtio-scsi) doesn't make sense in this case, as it will be ignored. Nevertheless, we need something to identify our vhost-scsi device, so for that we'll drop back to the devno mapping that we use for other disks. (This option exists only for vhost-scsi-ccw, but not vhost-scsi-pci. Hrm...) This becomes <address type='ccw' ...> in the case of s390 systems, and puts the device number on the resulting QEMU command line. Thus, existing device number conflict detection can be used across other devices that may or may not be specified in the guest XML. If one is not specified, we need to be sure to allocate one so that we can avoid polluting the device numbers with silently-created entries. Signed-off-by: Eric Farman <farman@xxxxxxxxxxxxxxxxxx> Reviewed-by: Bjoern Walk <bwalk@xxxxxxxxxxxxxxxxxx> Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxxxxxxx> --- src/conf/domain_conf.c | 19 +++++++++++++++++-- src/qemu/qemu_command.c | 7 +++++++ src/qemu/qemu_domain_address.c | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1768292..ae070ec 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4067,6 +4067,12 @@ virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt, size_t i; int ret; + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && + hostdev->source.subsys.u.scsi.protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_VHOST) { + return 0; + } + if (xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_WIDE_SCSI) max_unit = SCSI_WIDE_BUS_MAX_CONT_UNIT; else @@ -12829,8 +12835,17 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt, } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - if (def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + if (def->source.subsys.u.scsi.protocol == + VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_VHOST && + def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("vhost-scsi device must use 'ccw' address type")); + goto error; + } else if (def->source.subsys.u.scsi.protocol != + VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_VHOST && + def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { virReportError(VIR_ERR_XML_ERROR, "%s", _("SCSI host device must use 'drive' " "address type")); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6677c28..ca800c0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4597,6 +4597,13 @@ qemuBuildSCSIVhostHostdevDevStr(const virDomainDef *def, virBufferAsprintf(&buf, ",id=%s", dev->info->alias); + /* vhost-scsi-ccw has a devno parameter */ + if (dev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) + virBufferAsprintf(&buf, ",devno=%x.%x.%04x", + dev->info->addr.ccw.cssid, + dev->info->addr.ccw.ssid, + dev->info->addr.ccw.devno); + for (i = 0; vhostfd && i < vhostfdSize; i++) { if (mon) VIR_FORCE_CLOSE(vhostfd[i]); diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 787b357..238efd5 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -317,6 +317,16 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, def->controllers[i]->info.type = type; } + for (i = 0; i < def->nhostdevs; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->hostdevs[i]->source.subsys.type == + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && + def->hostdevs[i]->source.subsys.u.scsi.protocol == + VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_VHOST && + def->hostdevs[i]->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->hostdevs[i]->info->type = type; + } + if (def->memballoon && def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO && def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list