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(a)linux.vnet.ibm.com>
Reviewed-by: Bjoern Walk <bwalk(a)linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy(a)linux.vnet.ibm.com>
---
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