summaryrefslogtreecommitdiffstats
path: root/hw/scsi-generic.c
diff options
context:
space:
mode:
authorRonnie Sahlberg2012-05-25 13:59:01 +0200
committerPaolo Bonzini2012-07-02 10:18:41 +0200
commit983924532f61091fd90d1f2fafa4aa938c414dbb (patch)
tree6e5b0d42da73b28d6c6ad261768d0fb4cc29e621 /hw/scsi-generic.c
parentscsi-disk: implement READ DISC INFORMATION (diff)
downloadqemu-983924532f61091fd90d1f2fafa4aa938c414dbb.tar.gz
qemu-983924532f61091fd90d1f2fafa4aa938c414dbb.tar.xz
qemu-983924532f61091fd90d1f2fafa4aa938c414dbb.zip
ISCSI: Add SCSI passthrough via scsi-generic to libiscsi
Update iscsi to allow passthrough of SG_IO scsi commands when the iscsi device is forced to be scsi-generic. Implement both bdrv_ioctl() and bdrv_aio_ioctl() in the iscsi backend, emulate the SG_IO ioctl and pass the SCSI commands across to the iscsi target. This allows end-to-end passthrough of SCSI all the way from the guest, to qemu, via scsi-generic, then libiscsi all the way to the iscsi target. To activate this you need to specify that the iscsi lun should be treated as a scsi-generic device. Example: -device lsi -device scsi-generic,drive=MyISCSI \ -drive file=iscsi://10.1.1.125/iqn.ronnie.test/1,if=none,id=MyISCSI Note, you can currently not boot a qemu guest from a scsi device. Note, This only works when the host is linux, since the emulation relies on definitions of SG_IO from the scsi-generic implementation in the linux kernel. It should be fairly easy to re-implement some structures similar enough for non-linux hosts to do the same style of passthrough via a fake scsi generic layer and libiscsi if need be. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/scsi-generic.c')
-rw-r--r--hw/scsi-generic.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index d856d23b3b..8d5106061e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -400,12 +400,6 @@ static int scsi_generic_initfn(SCSIDevice *s)
return -1;
}
- /* check we are really using a /dev/sg* file */
- if (!bdrv_is_sg(s->conf.bs)) {
- error_report("not /dev/sg*");
- return -1;
- }
-
if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
error_report("Device doesn't support drive option werror");
return -1;
@@ -416,8 +410,11 @@ static int scsi_generic_initfn(SCSIDevice *s)
}
/* check we are using a driver managing SG_IO (version 3 and after */
- if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
- sg_version < 30000) {
+ if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0) {
+ error_report("scsi generic interface not supported");
+ return -1;
+ }
+ if (sg_version < 30000) {
error_report("scsi generic interface too old");
return -1;
}