On 05/03/2013 02:07 PM, Osier Yang wrote: > From: Han Cheng <hanc.fnst@xxxxxxxxxxxxxx> > > Except the scsi host device's controller is "lsilogic", mapping > between the libvirt attributes and scsi-generic properties is: > > libvirt qemu > ----------------------------------------- > controller bus ($libvirt_controller.0) > bus channel > target scsi-id > unit lun > > For scsi host device with "lsilogic" controller, the mapping is: > ('target (libvirt)' must be 0, as it's not used; 'unit (libvirt) > must <= 7). > > libvirt qemu > ---------------------------------------------------------- > controller && bus bus ($libvirt_controller.$libvirt_bus) > unit scsi-id > Might be nice to include this mapping in the code comments especially for those looking for this type of information some day that may not think to look in a git commit log... > It's not good to hardcode/hard-check limits of these attributes, > and even worse, these limits are not documented, one has to find > out by either testing or reading the qemu code, I'm looking forward > to qemu expose limits like these one day). For example, exposing > "max_target", "max_lun" for megasas: > > static const struct SCSIBusInfo megasas_scsi_info = { > .tcq = true, > .max_target = MFI_MAX_LD, > .max_lun = 255, > > .transfer_data = megasas_xfer_complete, > .get_sg_list = megasas_get_sg_list, > .complete = megasas_command_complete, > .cancel = megasas_command_cancel, > }; > > Example of the qemu command line (lsilogic controller): > > -drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \ > -device scsi-generic,bus=scsi0.0,scsi-id=8,\ > drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0 > > Example of the qemu command line (virtio-scsi controller): > > -drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \ > -device scsi-generic,bus=scsi0.0,channel=0,scsi-id=128,lun=128,\ > drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0 > > Signed-off-by: Han Cheng <hanc.fnst@xxxxxxxxxxxxxx> > Signed-off-by: Osier Yang <jyang@xxxxxxxxxx> > > --- > v3 - v4: > * Remove checking for "bug == 0" > * Split "bootindex" and "readonly" support into another patch > > v2.5 - v3: > * Add support for all other controllers, but not only virtio-scsi > * Add checking for "bus == 0" > * Add checking for "target == 0" && "unit <= 7" for scsi host device > which is on "lsilogic" controller. > * Integrate xml2argv test from 10/10 of v2.5 into this patch > --- > src/qemu/qemu_command.c | 132 ++++++++++++++++++++- > src/qemu/qemu_command.h | 6 + > .../qemuxml2argv-hostdev-scsi-lsi.args | 9 ++ > .../qemuxml2argv-hostdev-scsi-lsi.xml | 35 ++++++ > .../qemuxml2argv-hostdev-scsi-virtio-scsi.args | 9 ++ > ...l => qemuxml2argv-hostdev-scsi-virtio-scsi.xml} | 0 > tests/qemuxml2argvtest.c | 9 ++ > tests/qemuxml2xmltest.c | 3 +- > 8 files changed, 199 insertions(+), 4 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.xml > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.args > rename tests/qemuxml2argvdata/{qemuxml2argv-hostdev-scsi.xml => qemuxml2argv-hostdev-scsi-virtio-scsi.xml} (100%) > > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index 575dce1..df896aa 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -48,6 +48,7 @@ > #include "device_conf.h" > #include "virstoragefile.h" > #include "virtpm.h" > +#include "virscsi.h" > #if defined(__linux__) > # include <linux/capability.h> > #endif > @@ -745,7 +746,16 @@ qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev > } > } > > - if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0) { > + if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { > + if (virAsprintf(&hostdev->info->alias, "hostdev-%s-%d-%d-%d", > + hostdev->source.subsys.u.scsi.adapter, > + hostdev->source.subsys.u.scsi.bus, > + hostdev->source.subsys.u.scsi.target, > + hostdev->source.subsys.u.scsi.unit) < 0) { > + virReportOOMError(); > + return -1; > + } > + } else if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0) { > virReportOOMError(); > return -1; > } > @@ -4673,7 +4683,96 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev) > return ret; > } > > +char * > +qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev, > + virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED) > +{ > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + char *sg = NULL; > + > + if (!(sg = virSCSIDeviceGetDevStr(dev->source.subsys.u.scsi.adapter, > + dev->source.subsys.u.scsi.bus, > + dev->source.subsys.u.scsi.target, > + dev->source.subsys.u.scsi.unit))) { > + goto error; > + } > + > + virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg); > + virBufferAsprintf(&buf, ",id=%s-%s", > + virDomainDeviceAddressTypeToString(dev->info->type), > + dev->info->alias); > + > + if (virBufferError(&buf)) { > + virReportOOMError(); > + goto error; > + } > + VIR_FREE(sg); No comments on remainder. I assume the test config is good - at least it's there! ACK John > + return virBufferContentAndReset(&buf); > +error: > + VIR_FREE(sg); > + virBufferFreeAndReset(&buf); > + return NULL; > +} > + > +char * > +qemuBuildSCSIHostdevDevStr(virDomainDefPtr def, > + virDomainHostdevDefPtr dev, > + virQEMUCapsPtr qemuCaps) > +{ > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + int model = -1; > + > + model = virDomainDeviceFindControllerModel(def, dev->info, > + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); > + > + if (qemuSetScsiControllerModel(def, qemuCaps, &model) < 0) > + goto error; > + > + if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { > + if (dev->info->addr.drive.target != 0) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("target must be 0 for scsi host device " > + "if its controller model is 'lsilogic'")); > + goto error; > + } > + > + if (dev->info->addr.drive.unit > 7) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("unit must be not more than 7 for scsi host " > + "device if its controller model is 'lsilogic'")); > + goto error; > + } > + } > + > + virBufferAsprintf(&buf, "scsi-generic"); > + > + if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { > + virBufferAsprintf(&buf, ",bus=scsi%d.%d,scsi-id=%d", > + dev->info->addr.drive.controller, > + dev->info->addr.drive.bus, > + dev->info->addr.drive.unit); > + } else { > + virBufferAsprintf(&buf, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", > + dev->info->addr.drive.controller, > + dev->info->addr.drive.bus, > + dev->info->addr.drive.target, > + dev->info->addr.drive.unit); > + } > > + virBufferAsprintf(&buf, ",drive=%s-%s,id=%s", > + virDomainDeviceAddressTypeToString(dev->info->type), > + dev->info->alias, dev->info->alias); > + > + if (virBufferError(&buf)) { > + virReportOOMError(); > + goto error; > + } > + > + return virBufferContentAndReset(&buf); > +error: > + virBufferFreeAndReset(&buf); > + return NULL; > +} > > /* This function outputs a -chardev command line option which describes only the > * host side of the character device */ > @@ -7927,10 +8026,11 @@ qemuBuildCommandLine(virConnectPtr conn, > if (hostdev->info->bootIndex) { > if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || > (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && > - hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) { > + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && > + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)) { > virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > _("booting from assigned devices is only " > - "supported for PCI and USB devices")); > + "supported for PCI, USB and SCSI devices")); > goto error; > } else { > if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { > @@ -8039,6 +8139,32 @@ qemuBuildCommandLine(virConnectPtr conn, > goto error; > } > } > + > + /* SCSI */ > + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && > + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { > + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) && > + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && > + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) { > + char *drvstr; > + > + virCommandAddArg(cmd, "-drive"); > + if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps))) > + goto error; > + virCommandAddArg(cmd, drvstr); > + VIR_FREE(drvstr); > + > + virCommandAddArg(cmd, "-device"); > + if (!(devstr = qemuBuildSCSIHostdevDevStr(def, hostdev, qemuCaps))) > + goto error; > + virCommandAddArg(cmd, devstr); > + VIR_FREE(devstr); > + } else { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("SCSI passthrough is not supported by this version of qemu")); > + goto error; > + } > + } > } > > /* Migration is very annoying due to wildly varying syntax & > diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h > index a706942..9e4975d 100644 > --- a/src/qemu/qemu_command.h > +++ b/src/qemu/qemu_command.h > @@ -138,6 +138,12 @@ char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev); > char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, > virQEMUCapsPtr qemuCaps); > > +char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev, > + virQEMUCapsPtr qemuCaps); > +char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def, > + virDomainHostdevDefPtr dev, > + virQEMUCapsPtr qemuCaps); > + > char * qemuBuildHubDevStr(virDomainHubDefPtr dev, virQEMUCapsPtr qemuCaps); > char * qemuBuildRedirdevDevStr(virDomainDefPtr def, > virDomainRedirdevDefPtr dev, > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.args > new file mode 100644 > index 0000000..06f7938 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.args > @@ -0,0 +1,9 @@ > +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \ > +-m 214 -smp 1 -nographic -nodefaults -monitor \ > +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ > +-device lsi,id=scsi0,bus=pci.0,addr=0x3 -usb \ > +-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \ > +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ > +-drive file=/dev/sg0,if=none,id=drive-hostdev-scsi_host0-0-0-0 \ > +-device scsi-generic,bus=scsi0.0,scsi-id=7,drive=drive-hostdev-scsi_host0-0-0-0,id=hostdev-scsi_host0-0-0-0 \ > +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.xml > new file mode 100644 > index 0000000..98c469c > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi.xml > @@ -0,0 +1,35 @@ > +<domain type='qemu'> > + <name>QEMUGuest2</name> > + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> > + <memory unit='KiB'>219100</memory> > + <currentMemory unit='KiB'>219100</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/QEMUGuest2'/> > + <target dev='hda' bus='ide'/> > + <address type='drive' controller='0' bus='0' target='0' unit='0'/> > + </disk> > + <controller type='scsi' index='0'/> > + <controller type='usb' index='0'/> > + <controller type='ide' index='0'/>72ae3d932c0119a3e0f8a9175b8e46977cae046a > + <controller type='pci' index='0' model='pci-root'/> > + <hostdev mode='subsystem' type='scsi' managed='yes'> > + <source> > + <adapter name='scsi_host0'/> > + <address bus='0' target='0' unit='0'/> > + </source> > + <address type='drive' controller='0' bus='0' target='0' unit='7'/> > + </hostdev> > + <memballoon model='virtio'/> > + </devices> > +</domain> > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.args > new file mode 100644 > index 0000000..b92afc7 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.args > @@ -0,0 +1,9 @@ > +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ > +pc -m 214 -smp 1 -nographic -nodefaults -monitor \ > +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ > +-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 -usb \ > +-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \ > +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ > +-drive file=/dev/sg0,if=none,id=drive-hostdev-scsi_host0-0-0-0 \ > +-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=4,lun=8,drive=drive-hostdev-scsi_host0-0-0-0,id=hostdev-scsi_host0-0-0-0 \ > +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.xml > similarity index 100% > rename from tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi.xml > rename to tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-scsi.xml > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > index 1286273..abe04b3 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -974,6 +974,15 @@ mymain(void) > DO_TEST("pci-autoadd-addr", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); > DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); > > + DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_DRIVE, > + QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, > + QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI, > + QEMU_CAPS_DEVICE_SCSI_GENERIC); > + DO_TEST("hostdev-scsi-virtio-scsi", QEMU_CAPS_DRIVE, > + QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, > + QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_VIRTIO_SCSI, > + QEMU_CAPS_DEVICE_SCSI_GENERIC); > + > virObjectUnref(driver.config); > virObjectUnref(driver.caps); > virObjectUnref(driver.xmlopt); > diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c > index 1ca1f7e..08c3eeb 100644 > --- a/tests/qemuxml2xmltest.c > +++ b/tests/qemuxml2xmltest.c > @@ -285,7 +285,8 @@ mymain(void) > DO_TEST_DIFFERENT("pci-autoadd-addr"); > DO_TEST_DIFFERENT("pci-autoadd-idx"); > > - DO_TEST("hostdev-scsi"); > + DO_TEST("hostdev-scsi-lsi"); > + DO_TEST("hostdev-scsi-virtio-scsi"); > > virObjectUnref(driver.caps); > virObjectUnref(driver.xmlopt); > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list