[RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Hannes Reinecke

Hi all,

I got bored and implemented SCSI passthrough for the virtio-blk driver.
Principle is quite simple, just put the missing fields (cdb, sense and
status header) on the virtio queue and then call the SG_IO ioctl on the
host.

So when using '-drive file=/dev/sgXX,if=virtio,format=host_device' you
can happily call any sg_XX command on the resulting vdX device. Quite
neat, methinks. And it's even backwards compatible, so each of these
patches should work without the other one applied.

As one would have guessed there are two patches, one for the linux
kernel to modify the virtio-blk driver in the guest and one for the
qemu/kvm userland program to modify the virtio-blk driver on the host.
This patch is relative to avi's kvm-userland tree from kernel.org.

As usual, comments etc to me.

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries  Storage
[EMAIL PROTECTED] +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
virtio: Implement SCSI passthrough for virtio-blk

This patch implements SCSI passthrough for any virtio-blk device.
The data on the virtio queue will only be modified for a SCSI command,
so the normal I/O flow is unchanged.

Signed-off-by: Hannes Reinecke [EMAIL PROTECTED]

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 4225109..46f03d2 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -35,6 +35,7 @@ struct virtblk_req
struct list_head list;
struct request *req;
struct virtio_blk_outhdr out_hdr;
+   struct virtio_blk_inhdr in_hdr;
u8 status;
 };
 
@@ -47,20 +48,29 @@ static void blk_done(struct virtqueue *vq)
 
spin_lock_irqsave(vblk-lock, flags);
while ((vbr = vblk-vq-vq_ops-get_buf(vblk-vq, len)) != NULL) {
-   int uptodate;
+   int error;
+   unsigned int bytes;
switch (vbr-status) {
case VIRTIO_BLK_S_OK:
-   uptodate = 1;
+   error = 0;
break;
case VIRTIO_BLK_S_UNSUPP:
-   uptodate = -ENOTTY;
+   error = -ENOTTY;
break;
default:
-   uptodate = 0;
+   error = -EIO;
break;
}
 
-   end_dequeued_request(vbr-req, uptodate);
+   if (blk_pc_request(vbr-req)) {
+   vbr-req-data_len = vbr-in_hdr.residual;
+   bytes = vbr-in_hdr.data_len;
+   vbr-req-sense_len = vbr-in_hdr.sense_len;
+   vbr-req-errors = vbr-in_hdr.status;
+   } else
+   bytes = blk_rq_bytes(vbr-req);
+
+   __blk_end_request(vbr-req, error, bytes);
list_del(vbr-list);
mempool_free(vbr, vblk-pool);
}
@@ -72,7 +82,7 @@ static void blk_done(struct virtqueue *vq)
 static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
   struct request *req)
 {
-   unsigned long num, out, in;
+   unsigned long num, out = 0, in = 0;
struct virtblk_req *vbr;
 
vbr = mempool_alloc(vblk-pool, GFP_ATOMIC);
@@ -99,20 +109,31 @@ static bool do_req(struct request_queue *q, struct 
virtio_blk *vblk,
 
/* This init could be done at vblk creation time */
sg_init_table(vblk-sg, VIRTIO_MAX_SG);
-   sg_set_buf(vblk-sg[0], vbr-out_hdr, sizeof(vbr-out_hdr));
-   num = blk_rq_map_sg(q, vbr-req, vblk-sg+1);
-   sg_set_buf(vblk-sg[num+1], vbr-status, sizeof(vbr-status));
-
-   if (rq_data_dir(vbr-req) == WRITE) {
-   vbr-out_hdr.type |= VIRTIO_BLK_T_OUT;
-   out = 1 + num;
-   in = 1;
-   } else {
-   vbr-out_hdr.type |= VIRTIO_BLK_T_IN;
-   out = 1;
-   in = 1 + num;
+   sg_set_buf(vblk-sg[out], vbr-out_hdr, sizeof(vbr-out_hdr));
+   out++;
+   if (blk_pc_request(vbr-req)) {
+   sg_set_buf(vblk-sg[out], vbr-req-cmd, vbr-req-cmd_len);
+   out++;
+   }
+   num = blk_rq_map_sg(q, vbr-req, vblk-sg+out);
+   if (blk_pc_request(vbr-req)) {
+   sg_set_buf(vblk-sg[num+out+in], vbr-req-sense, 96);
+   in++;
+   sg_set_buf(vblk-sg[num+out+in], vbr-in_hdr,
+  sizeof(vbr-in_hdr));
+   in++;
+   }
+   sg_set_buf(vblk-sg[num+out+in], vbr-status, sizeof(vbr-status));
+   in++;
+   if (num) {
+   if (rq_data_dir(vbr-req) == WRITE) {
+   vbr-out_hdr.type |= VIRTIO_BLK_T_OUT;
+   out += num;
+   } else {
+   vbr-out_hdr.type |= VIRTIO_BLK_T_IN;
+   in += num;
+   }
}
-
if 

Re: [RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Christian Borntraeger
Am Freitag, 29. August 2008 schrieb Hannes Reinecke:
 So when using '-drive file=/dev/sgXX,if=virtio,format=host_device' you
 can happily call any sg_XX command on the resulting vdX device. Quite
 neat, methinks. And it's even backwards compatible, so each of these
 patches should work without the other one applied.

Does not work here. If the host does not support the pass-through, the device 
drivers waits for an response. I tried  sdparm /dev/vda with a patched kernel 
and an unpatched userspace.

I think you should use a feature bit to avoid problems.

Christian

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Hannes Reinecke

Hi Christian,

Christian Borntraeger wrote:

Am Freitag, 29. August 2008 schrieb Hannes Reinecke:

So when using '-drive file=/dev/sgXX,if=virtio,format=host_device' you
can happily call any sg_XX command on the resulting vdX device. Quite
neat, methinks. And it's even backwards compatible, so each of these
patches should work without the other one applied.


Does not work here. If the host does not support the pass-through, the device 
drivers waits for an response. I tried  sdparm /dev/vda with a patched kernel 
and an unpatched userspace.



Hmm. Works here, using an unpatched kvm-73.
Which version did you use?

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries  Storage
[EMAIL PROTECTED] +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Christian Borntraeger
Am Freitag, 29. August 2008 schrieb Hannes Reinecke:
 Hmm. Works here, using an unpatched kvm-73.
 Which version did you use?

I use the s390 userspace prototype kuli which uses an virtio transport similar 
to lguest.

I retried and it seems to race. Most of the time it works fine, but sometimes 
sdparm hangs. I will have a 2nd look. 

sysrq-t gives me the following trace:

Call Trace:
([04000755bc78] 0x4000755bc78)
sdparmD 0043659e 0  2493  1
0012004a 0744f740 0744f778 001896469fd23785
   0744f778 009e5500 0043f230 00120130
   0744f778 06d39400 06d39f80 0001
   009e6f00 076bf8e8 0744f7c8 07530670
   0043f610 00435e66 0744f7c8 0744f868
Call Trace:
([00435e66] schedule+0x32e/0x7ec)
 [0043659e] schedule_timeout+0xba/0x10c
 [004358da] wait_for_common+0xbe/0x1a8
 [0027ec3e] blk_execute_rq+0x86/0xc4
 [00282768] sg_io+0x1a4/0x360
 [00282f8c] scsi_cmd_ioctl+0x2bc/0x3f0
 [002c3108] virtblk_ioctl+0x44/0x58
 [0027ff18] blkdev_driver_ioctl+0x98/0xa4
 [0027ffd8] blkdev_ioctl+0xb4/0x7f8
 [001e1572] block_ioctl+0x3a/0x48
 [001bca0a] vfs_ioctl+0x52/0xdc
 [001bcb0a] do_vfs_ioctl+0x76/0x350
 [001bce6e] sys_ioctl+0x8a/0xa0
 [0011282c] sysc_tracego+0xe/0x14
 [02114286] 0x2114286
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Hannes Reinecke

Hi Christian,

Christian Borntraeger wrote:

Am Freitag, 29. August 2008 schrieb Hannes Reinecke:

Hmm. Works here, using an unpatched kvm-73.
Which version did you use?


I use the s390 userspace prototype kuli which uses an virtio transport similar 
to lguest.


I retried and it seems to race. Most of the time it works fine, but sometimes 
sdparm hangs. I will have a 2nd look. 


sysrq-t gives me the following trace:

Call Trace:
([04000755bc78] 0x4000755bc78)
sdparmD 0043659e 0  2493  1
0012004a 0744f740 0744f778 001896469fd23785
   0744f778 009e5500 0043f230 00120130
   0744f778 06d39400 06d39f80 0001
   009e6f00 076bf8e8 0744f7c8 07530670
   0043f610 00435e66 0744f7c8 0744f868
Call Trace:
([00435e66] schedule+0x32e/0x7ec)
 [0043659e] schedule_timeout+0xba/0x10c
 [004358da] wait_for_common+0xbe/0x1a8
 [0027ec3e] blk_execute_rq+0x86/0xc4
 [00282768] sg_io+0x1a4/0x360
 [00282f8c] scsi_cmd_ioctl+0x2bc/0x3f0
 [002c3108] virtblk_ioctl+0x44/0x58
 [0027ff18] blkdev_driver_ioctl+0x98/0xa4
 [0027ffd8] blkdev_ioctl+0xb4/0x7f8
 [001e1572] block_ioctl+0x3a/0x48
 [001bca0a] vfs_ioctl+0x52/0xdc
 [001bcb0a] do_vfs_ioctl+0x76/0x350
 [001bce6e] sys_ioctl+0x8a/0xa0
 [0011282c] sysc_tracego+0xe/0x14
 [02114286] 0x2114286


I'm tempted to say 'not my fault'; the submitted SCSI request on
the _host_ hangs and doesn't come back.
Looks more like a SCSI problem on the host ...

Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries  Storage
[EMAIL PROTECTED] +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH] SCSI passthrough for virtio-blk

2008-08-29 Thread Christian Borntraeger
Thanks for your feedback.

Here is a second try to allows to propagate scsi error code from host-guest.
Makes sense?

Signed-off-by: Christian Borntraeger [EMAIL PROTECTED]

---
 drivers/block/virtio_blk.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: kvm/drivers/block/virtio_blk.c
===
--- kvm.orig/drivers/block/virtio_blk.c
+++ kvm/drivers/block/virtio_blk.c
@@ -62,7 +62,7 @@ static void blk_done(struct virtqueue *v
break;
}
 
-   if (blk_pc_request(vbr-req)) {
+   if (blk_pc_request(vbr-req)  len = sizeof(vbr-in_hdr)) {
vbr-req-data_len = vbr-in_hdr.residual;
bytes = vbr-in_hdr.data_len;
vbr-req-sense_len = vbr-in_hdr.sense_len;

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html