[libvirt] [PATCH v2 0/6]qemu: add usb-bot scsi controller support

BZ:https://bugzilla.redhat.com/show_bug.cgi?id=917702 v2: After discussion in BZ, qemu guys hope the usb-bot(+usb-uas) can be supported although the absence of its hot-plug feature. In this patch, libvirt gives an unsupported error in this case. v1: https://www.redhat.com/archives/libvir-list/2013-September/msg00020.html And as the missing of hot-plug feature, the replacement of usb-storage is not a urgent thing. disk attached to usb-storage supports hot-plug/unplug already. Guannan Ren(6) qemu: add usb-bot qemu cap flag qemu: add usb-bot model scsi controller support qemu: add usb-bot support from disks points of view qemu: refactor out function to build scsi device qemu commandline qemu: no hot-plug/unplug support currently for usb-bot tests: add xml2argv test for usb-bot scsi controller docs/formatdomain.html.in | 4 ++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 5 +++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------- src/qemu/qemu_hotplug.c | 14 ++++++++++++++ src/vmx/vmx.c | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args | 11 +++++++++++ tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml | 33 +++++++++++++++++++++++++++++++++ tests/qemuxml2argvtest.c | 3 +++ 13 files changed, 259 insertions(+), 58 deletions(-)

QEMU_CAPS_DEVICE_USB_BOT /* -device usb-bot */ --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d94188a..5cd7d45 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -241,6 +241,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "usb-storage", /* 155 */ "usb-storage.removable", "virtio-mmio", + "usb-bot", ); struct _virQEMUCaps { @@ -1379,6 +1380,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA }, { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL }, { "usb-net", QEMU_CAPS_DEVICE_USB_NET }, + { "usb-bot", QEMU_CAPS_DEVICE_USB_BOT }, { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG }, { "virtio-rng-s390", QEMU_CAPS_DEVICE_VIRTIO_RNG }, { "virtio-rng-ccw", QEMU_CAPS_DEVICE_VIRTIO_RNG }, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f3c8fa8..1e17f4f 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -196,6 +196,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_DEVICE_USB_STORAGE = 155, /* -device usb-storage */ QEMU_CAPS_USB_STORAGE_REMOVABLE = 156, /* usb-storage.removable */ QEMU_CAPS_DEVICE_VIRTIO_MMIO = 157, /* -device virtio-mmio */ + QEMU_CAPS_DEVICE_USB_BOT = 158, /* -device usb-bot */ QEMU_CAPS_LAST, /* this must always be the last item */ }; -- 1.8.3.1

usb-bot is SCSI HBA which support only one SCSI target with ID 0. we can create one or more SCSI devices connected to it with -device as its luns. For usb-bot the limit is 15 luns. The difference from other SCSI controllers is that usb-bot needs usb-bus support. That means usb-bot is required to be attached to a existing USB controller. libvirt xml example: <devices> ... <controller type='usb' index='0'> </controller> <controller type='scsi' index='0' model='usb-bot'> <address type='usb' bus='0' port='1'/> </controller> ... </devices> QEMU commandline should be: -device piix3-usb-uhci,id=usb \ -device usb-bot,id=scsi0,bus=usb.0,port=1 --- docs/formatdomain.html.in | 4 ++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 52 +++++++++++++++++++++++++++++++++++++++++-- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 16 +++++++++++++ src/vmx/vmx.c | 3 ++- 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f8bfe0b..07887f2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2417,8 +2417,8 @@ control how many devices can be connected through the controller. A "scsi" controller has an optional attribute <code>model</code>, which is one of "auto", "buslogic", - "ibmvscsi", "lsilogic", "lsisas1068", "lsisas1078", "virtio-scsi" or - "vmpvscsi". A "usb" controller has an optional attribute + "ibmvscsi", "lsilogic", "lsisas1068", "lsisas1078", "virtio-scsi", + "vmpvscsi" or "usb-bot". A "usb" controller has an optional attribute <code>model</code>, which is one of "piix3-uhci", "piix4-uhci", "ehci", "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3", "vt82c686b-uhci", "pci-ohci" or "nec-xhci". Additionally, diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ecd3a42..7ce9888 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1537,6 +1537,7 @@ <value>ibmvscsi</value> <value>virtio-scsi</value> <value>lsisas1078</value> + <value>usb-bot</value> </choice> </attribute> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index aed2a9d..7fd9422 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -326,7 +326,8 @@ VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAS "vmpvscsi", "ibmvscsi", "virtio-scsi", - "lsisas1078"); + "lsisas1078", + "usb-bot"); VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "piix3-uhci", @@ -5772,6 +5773,17 @@ virDomainControllerDefParseXML(xmlNodePtr node, goto error; switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: + if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("usb-bot mode of scsi controller requires " + "address of type 'usb'")); + goto error; + } + } + break; case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: { char *ports = virXMLPropString(node, "ports"); if (ports) { @@ -5863,7 +5875,8 @@ virDomainControllerDefParseXML(xmlNodePtr node, def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO && - def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Controllers must use the 'pci' address type")); goto error; @@ -13803,6 +13816,38 @@ virDomainDefMaybeAddSmartcardController(virDomainDefPtr def) return 0; } +static int +virDomainDefMaybeAddUSBcontroller(virDomainDefPtr def) +{ + size_t i; + int maxController = -1; + + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDefPtr cont = def->controllers[i]; + + if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + if (cont->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) + continue; + + if ((int)cont->info.addr.usb.bus > maxController) + maxController = cont->info.addr.usb.bus; + } + + if (maxController == -1) + return 0; + + for (i = 0; i <= maxController; i++) { + if (virDomainDefMaybeAddController(def, + VIR_DOMAIN_CONTROLLER_TYPE_USB, + i, -1) < 0) + return -1; + } + + return 0; +} + /* * Based on the declared <address/> info for any devices, * add necessary drive controllers which are not already present @@ -13841,6 +13886,9 @@ virDomainDefAddImplicitControllers(virDomainDefPtr def) if (virDomainDefMaybeAddHostdevSCSIcontroller(def) < 0) return -1; + if (virDomainDefMaybeAddUSBcontroller(def) < 0) + return -1; + return 0; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 539bc1c..11ed18a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -790,6 +790,7 @@ enum virDomainControllerModelSCSI { VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078, + VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1521431..f40c050 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -713,6 +713,14 @@ qemuSetScsiControllerModel(virDomainDefPtr def, return -1; } break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU doesn't support " + "usb-bot scsi controller")); + return -1; + } + break; case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: /*TODO: need checking work here if necessary */ break; @@ -2749,6 +2757,11 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, def->controllers[i]->idx == 0) continue; + /* SCSI controller model 'usb-bot' needs address of USB type */ + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) + continue; + if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) continue; if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) @@ -4702,6 +4715,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: virBufferAddLit(&buf, "lsi"); break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT: + virBufferAddLit(&buf, "usb-bot"); + break; case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: virBufferAddLit(&buf, "spapr-vscsi"); break; diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 40416a0..052a7f5 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -514,7 +514,8 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, "pvscsi", "UNUSED ibmvscsi", "UNUSED virtio-scsi", - "UNUSED lsisas1078"); + "UNUSED lsisas1078", + "UNUSED usb-scsi"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -- 1.8.3.1

usb-bot only supports 16 luns(0~15) and they must be contiguous, (using lun 0 and 2 without 1 doesn't work). In this case qemu doesn't throw an error, we can not find the lun 2 in guests. So Adding a checking function in libvirt to prevent from this case. --- src/conf/domain_conf.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 ++++ src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 32 ++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7fd9422..7a4969e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4302,6 +4302,65 @@ virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, return 0; } +bool +virDomainDiskAttachedToUsbbotLunIsContiguous(virDomainDefPtr def) +{ + size_t i; + int controllerModel; + virBitmapPtr units = NULL; + bool is_set = false; + bool ret = false; + + if (!(units = virBitmapNew(SCSI_CONTROLLER_USB_BOT_MODEL_MAX_LUNS))) + goto cleanup; + + for (i = 0; i < def->ndisks; i++) { + virDomainDiskDefPtr disk = def->disks[i]; + int unitValue = disk->info.addr.drive.unit; + + if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) + continue; + + controllerModel = + virDomainDeviceFindControllerModel(def, &disk->info, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); + if (controllerModel != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) + continue; + + /* usb-bot only supports 16 luns */ + if (unitValue & ~0xf) { + virReportError(VIR_ERR_XML_ERROR, + _("The address unit value of disk '%s' is too big"), + disk->src); + goto cleanup; + } + + if (virBitmapGetBit(units, unitValue, &is_set) == 0 && is_set) { + virReportError(VIR_ERR_XML_ERROR, + _("The address unit value of disk '%s' is already used"), + disk->src); + goto cleanup; + } + + if (unitValue > 0) { + if (virBitmapGetBit(units, unitValue - 1, &is_set) == 0 && !is_set) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("The address unit value of disk " + "attached to usb-bot controller is not contiguous")); + goto cleanup; + } + } + + ignore_value(virBitmapSetBit(units, unitValue)); + } + + ret = true; + +cleanup: + virBitmapFree(units); + return ret; +} + static virSecurityLabelDefPtr virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt, unsigned int flags) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 11ed18a..cea979f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -781,6 +781,8 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST } virDomainControllerModelPCI; +# define SCSI_CONTROLLER_USB_BOT_MODEL_MAX_LUNS 16 + enum virDomainControllerModelSCSI { VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC, @@ -2365,6 +2367,8 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def, int virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, virDomainDiskDefPtr def); +bool virDomainDiskAttachedToUsbbotLunIsContiguous(virDomainDefPtr def); + virDomainDiskDefPtr virDomainDiskRemove(virDomainDefPtr def, size_t i); virDomainDiskDefPtr diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 35f0f1b..c1f7da5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -179,6 +179,7 @@ virDomainDeviceFindControllerModel; virDomainDeviceInfoCopy; virDomainDeviceInfoIterate; virDomainDeviceTypeToString; +virDomainDiskAttachedToUsbbotLunIsContiguous; virDomainDiskBusTypeToString; virDomainDiskCacheTypeFromString; virDomainDiskCacheTypeToString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f40c050..1a6accd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4316,6 +4316,32 @@ qemuBuildDriveDevStr(virDomainDefPtr def, disk->info.addr.drive.controller, disk->info.addr.drive.bus, disk->info.addr.drive.unit); + } else if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { + if (disk->info.addr.drive.target != 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target must be 0 for controller " + "model 'usb-bot'")); + goto error; + } + + if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + virBufferAddLit(&opt, "scsi-cd"); + else + virBufferAddLit(&opt, "scsi-hd"); + } else { + virBufferAddLit(&opt, "scsi-disk"); + } + } else { + virBufferAddLit(&opt, "scsi-block"); + } + + virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.target, + disk->info.addr.drive.unit); } else { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { if (disk->info.addr.drive.target > 7) { @@ -8149,6 +8175,12 @@ qemuBuildCommandLine(virConnectPtr conn, } } + /* For disks attached to SCSI usb-bot controller, their + * unit value must be contiguous. + */ + if (!virDomainDiskAttachedToUsbbotLunIsContiguous(def)) + goto error; + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { for (j = 0; j < ARRAY_CARDINALITY(contOrder); j++) { for (i = 0; i < def->ncontrollers; i++) { -- 1.8.3.1

--- src/qemu/qemu_command.c | 124 +++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1a6accd..aa91f57 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4153,6 +4153,40 @@ error: return NULL; } +static int +qemuBuildSCSIDriveDevStr(int controllerModel, + virDomainDiskDefPtr disk, + virQEMUCapsPtr qemuCaps, + virBufferPtr opt) +{ + if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + virBufferAddLit(opt, "scsi-cd"); + else + virBufferAddLit(opt, "scsi-hd"); + } else { + virBufferAddLit(opt, "scsi-disk"); + } + } else { + virBufferAddLit(opt, "scsi-block"); + } + + + if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) + virBufferAsprintf(opt, ",bus=scsi%d.%d,scsi-id=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + else + virBufferAsprintf(opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.target, + disk->info.addr.drive.unit); + return 0; +} + char * qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskDefPtr disk, @@ -4291,94 +4325,32 @@ qemuBuildDriveDevStr(virDomainDefPtr def, if ((qemuSetScsiControllerModel(def, qemuCaps, &controllerModel)) < 0) goto error; - if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { + if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC || + controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { if (disk->info.addr.drive.target != 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("target must be 0 for controller " "model 'lsilogic'")); goto error; } - - if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { - virBufferAddLit(&opt, "scsi-block"); - } else { - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "scsi-cd"); - else - virBufferAddLit(&opt, "scsi-hd"); - } else { - virBufferAddLit(&opt, "scsi-disk"); - } - } - - virBufferAsprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d", - disk->info.addr.drive.controller, - disk->info.addr.drive.bus, - disk->info.addr.drive.unit); - } else if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { - if (disk->info.addr.drive.target != 0) { + } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { + if (disk->info.addr.drive.target > 7) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("target must be 0 for controller " - "model 'usb-bot'")); + _("This QEMU doesn't support target " + "greater than 7")); goto error; } - if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "scsi-cd"); - else - virBufferAddLit(&opt, "scsi-hd"); - } else { - virBufferAddLit(&opt, "scsi-disk"); - } - } else { - virBufferAddLit(&opt, "scsi-block"); - } - - virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", - disk->info.addr.drive.controller, - disk->info.addr.drive.bus, - disk->info.addr.drive.target, - disk->info.addr.drive.unit); - } else { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { - if (disk->info.addr.drive.target > 7) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This QEMU doesn't support target " - "greater than 7")); - goto error; - } - - if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) && - (disk->info.addr.drive.bus != 0)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This QEMU only supports both bus and " - "unit equal to 0")); - goto error; - } - } - - if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "scsi-cd"); - else - virBufferAddLit(&opt, "scsi-hd"); - } else { - virBufferAddLit(&opt, "scsi-disk"); - } - } else { - virBufferAddLit(&opt, "scsi-block"); + if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) && + (disk->info.addr.drive.bus != 0)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU only supports both bus and " + "unit equal to 0")); + goto error; } - - virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", - disk->info.addr.drive.controller, - disk->info.addr.drive.bus, - disk->info.addr.drive.target, - disk->info.addr.drive.unit); } + + qemuBuildSCSIDriveDevStr(controllerModel, disk, qemuCaps, &opt); break; case VIR_DOMAIN_DISK_BUS_SATA: if (disk->info.addr.drive.bus != 0) { -- 1.8.3.1

--- src/conf/domain_conf.c | 4 +++- src/qemu/qemu_hotplug.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7a4969e..60ca298 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17118,7 +17118,9 @@ virDomainDeviceIsUSB(virDomainDeviceDefPtr dev) (t == VIR_DOMAIN_DEVICE_HUB && dev->data.hub->type == VIR_DOMAIN_HUB_TYPE_USB) || (t == VIR_DOMAIN_DEVICE_REDIRDEV && - dev->data.redirdev->bus == VIR_DOMAIN_REDIRDEV_BUS_USB)) + dev->data.redirdev->bus == VIR_DOMAIN_REDIRDEV_BUS_USB) || + (t == VIR_DOMAIN_DEVICE_CONTROLLER && + dev->data.controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT)) return true; return false; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6cdee44..b6e3c4c 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -365,6 +365,13 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver, return -1; } + if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("device usb-bot hotplug unsupported currently")); + goto cleanup; + } + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0) goto cleanup; @@ -3009,6 +3016,13 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver, detach = vm->def->controllers[idx]; + if (detach->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + detach->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("device usb-bot cannot be detached currently")); + goto cleanup; + } + if (!virDomainDeviceAddressIsValid(&detach->info, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", -- 1.8.3.1

--- .../qemuxml2argv-disk-scsi-usbbot.args | 11 ++++++++ .../qemuxml2argv-disk-scsi-usbbot.xml | 33 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 3 files changed, 47 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args new file mode 100644 index 0000000..572a8b0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args @@ -0,0 +1,11 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-device usb-bot,id=scsi0 -usb \ +-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-scsi0-0-0-0 \ +-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\ +drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \ +-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-0-1 \ +-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=1,\ +drive=drive-scsi0-0-0-1,id=scsi0-0-0-1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml new file mode 100644 index 0000000..4be405f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='sda' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='disk'> + <source file='/tmp/scsidisk.img'/> + <target dev='sdb' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='scsi' index='0' model='usb-bot'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 15d3095..a904c71 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -552,6 +552,9 @@ mymain(void) DO_TEST("disk-scsi-device", QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_SCSI_LSI); + DO_TEST("disk-scsi-usbbot", + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_DEVICE_USB_BOT); DO_TEST("disk-scsi-device-auto", QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_SCSI_LSI); -- 1.8.3.1

On 09/10/2013 05:26 PM, Guannan Ren wrote:
BZ:https://bugzilla.redhat.com/show_bug.cgi?id=917702
v2: After discussion in BZ, qemu guys hope the usb-bot(+usb-uas) can be supported although the absence of its hot-plug feature. In this patch, libvirt gives an unsupported error in this case.
v1: https://www.redhat.com/archives/libvir-list/2013-September/msg00020.html
And as the missing of hot-plug feature, the replacement of usb-storage is not a urgent thing. disk attached to usb-storage supports hot-plug/unplug already.
Guannan Ren(6) qemu: add usb-bot qemu cap flag qemu: add usb-bot model scsi controller support qemu: add usb-bot support from disks points of view qemu: refactor out function to build scsi device qemu commandline qemu: no hot-plug/unplug support currently for usb-bot tests: add xml2argv test for usb-bot scsi controller
docs/formatdomain.html.in | 4 ++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 5 +++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------- src/qemu/qemu_hotplug.c | 14 ++++++++++++++ src/vmx/vmx.c | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args | 11 +++++++++++ tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml | 33 +++++++++++++++++++++++++++++++++ tests/qemuxml2argvtest.c | 3 +++ 13 files changed, 259 insertions(+), 58 deletions(-)
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
An inquiring ping. Shall we support usb-bot right now if its qemu hot-plug feature is not available yet. Gunannan
participants (1)
-
Guannan Ren