[libvirt] [PATCH v2 06/10] qemu: Build qemu command line for scsi-generic
Osier Yang
jyang at redhat.com
Wed Apr 3 09:19:25 UTC 2013
On 01/04/13 20:00, Han Cheng wrote:
> For scsi-generic, the command line will be like:
>
> -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
>
> The relationship between the libvirt address attrs and the qdev
> properties are(channel should always be 0):
> bus=scsi<controller>.0
> scsi-id=<target>
> lun=<unit>
>
> Signed-off-by: Han Cheng <hanc.fnst at cn.fujitsu.com>
> ---
> src/qemu/qemu_command.c | 133 +++++++++++++++++++++++++++++++++++++++++++++--
> src/qemu/qemu_command.h | 6 ++
> 2 files changed, 134 insertions(+), 5 deletions(-)
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index eac72c2..e1af64f 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -557,7 +557,7 @@ qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
> if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
> if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
> controllerModel =
> - virDomainInfoFindControllerModel(def, &disk->info,
> + virDomainDeviceFindControllerModel(def, &disk->info,
> VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
Indention.
>
> if ((qemuSetScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
> @@ -659,7 +659,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;
> }
> @@ -3179,7 +3188,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
> }
>
> controllerModel =
> - virDomainInfoFindControllerModel(def, &disk->info,
> + virDomainDeviceFindControllerModel(def, &disk->info,
> VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
And this.
> if ((qemuSetScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
> goto error;
> @@ -4370,6 +4379,86 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev)
> return ret;
> }
>
> +char *
> +qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev, virQEMUCapsPtr qemuCaps)
> +{
> + 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))) {
Indentions?
> + goto error;
> + }
> +
> + virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg);
> + virBufferAsprintf(&buf, ",id=%s-%s",
> + virDomainDeviceAddressTypeToString(dev->info->type),
> + dev->info->alias);
> + if (dev->readonly &&
> + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY))
> + virBufferAsprintf(&buf, ",readonly=on");
> + if (virBufferError(&buf)) {
> + virReportOOMError();
> + goto error;
> + }
> + VIR_FREE(sg);
Like what I commented in 5/10 for the frees. This can be simplified.
> +
> + 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 controllerModel = -1;
> +
> + controllerModel = virDomainDeviceFindControllerModel(def, dev->info,
> + VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
> + if (qemuSetScsiControllerModel(def, qemuCaps, &controllerModel) < 0)
> + goto error;
> + /* TODO: deal with lsi or ibm controller */
> + if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) {
> + virBufferAsprintf(&buf, "scsi-generic");
> + if (dev->info->addr.drive.bus != 0) {
> + virReportError(VIR_ERR_XML_ERROR,
> + "%s", _("SCSI controller only supports 1 bus"));
> + goto error;
> + }
> + /* TODO: deal with early version qemu which does not support bus... */
> + virBufferAsprintf(&buf,
> + ",bus=scsi%d.0,channel=0,scsi-id=%d,lun=%d",
> + dev->info->addr.drive.controller,
> + 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 (dev->info->bootIndex)
> + virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
> + } else {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("unknown controller"));
Improper error:
_("Unsupport controller model '%s'"),
virDomainControllerModelSCSITypeToString(controllerModel))
> + goto error;
> + }
> + 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
> @@ -7433,10 +7522,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 &&
> @@ -7453,6 +7543,39 @@ qemuBuildCommandLine(virConnectPtr conn,
> " supported with this version of qemu"));
> goto error;
> }
> + if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
> + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_GENERIC_BOOTINDEX)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("booting from assigned SCSI devices is not"
> + " supported with this version of qemu"));
> + 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_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;
> }
> }
>
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 17687f4..188f899 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -139,6 +139,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,
More information about the libvir-list
mailing list