[stgt] Using tgtd to pass through a SCSI tape drive

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Fri Jul 30 04:58:24 CEST 2010


On Thu, 29 Jul 2010 22:11:45 +0000
markh794 at gmail.com wrote:

> Timeout values.
> 
> Looking around for real-world timeout values, I found this example:
> http://www-01.ibm.com/support/docview.wss?uid=ssg1S7003248
> 
> The table starting at page 48 (Drive Commands) lists each command timeout  
> value.
> 
> The 'long erase' is the longest at 235minutes.
> "locate" and "erase" are around 15minutes.
> "rewind" around 8 minutes.
> 
> Looks like there really needs to be some way to set a timeout value per  
> SCSI OP code.

Probably, two timeout values are enough like st driver.

Before that, we need to set up timeout values per device type.

The following patch blindly makes the timeout value longer for type
devices.


diff --git a/usr/bs_sg.c b/usr/bs_sg.c
index dfd49c3..babbb8b 100644
--- a/usr/bs_sg.c
+++ b/usr/bs_sg.c
@@ -46,7 +46,8 @@
 #include "tgtadm_error.h"
 
 #define BS_SG_RESVD_SZ  (512 * 1024)
-#define BS_SG_TIMEOUT	2000
+
+static unsigned int sg_timeout = 30 * 1000; /* 30 seconds */
 
 static int graceful_read(int fd, void *p_read, int to_read)
 {
@@ -149,7 +150,7 @@ static int bs_bsg_cmd_submit(struct scsi_cmd *cmd)
 	/* SCSI: (auto)sense data */
 	io_hdr.response = (unsigned long)cmd->sense_buffer;
 	/* Using the same 2000 millisecond timeout.. */
-	io_hdr.timeout = BS_SG_TIMEOUT;
+	io_hdr.timeout = sg_timeout;
 	/* [i->o] unused internally */
 	io_hdr.usr_ptr = (unsigned long)cmd;
 	dprintf("[%d] Set io_hdr->usr_ptr from cmd: %p\n", getpid(), cmd);
@@ -168,6 +169,29 @@ static int bs_bsg_cmd_submit(struct scsi_cmd *cmd)
 	return 0;
 }
 
+static void bs_sg_cmd_setup(struct sg_io_hdr *hdr,
+			   unsigned char *cmd, int cmd_len,
+			   void *data, int data_len, int direction,
+			   void *sense, int sense_len,
+			   int timeout)
+{
+	memset(hdr, 0, sizeof(*hdr));
+	hdr->interface_id = 'S';
+	hdr->cmdp = cmd;
+	hdr->cmd_len = cmd_len;
+
+	hdr->dxfer_direction = direction;
+	hdr->dxfer_len = data_len;
+	hdr->dxferp = data;
+
+	hdr->mx_sb_len = sense_len;
+	hdr->sbp = sense;
+	hdr->timeout = timeout;
+	hdr->pack_id = -1;
+	hdr->usr_ptr = NULL;
+	hdr->flags = 0;
+}
+
 static int bs_sg_cmd_submit(struct scsi_cmd *cmd)
 {
 	struct scsi_lu *dev = cmd->dev;
@@ -191,7 +215,7 @@ static int bs_sg_cmd_submit(struct scsi_cmd *cmd)
 	}
 	io_hdr.mx_sb_len = sizeof(cmd->sense_buffer);
 	io_hdr.sbp = cmd->sense_buffer;
-	io_hdr.timeout = BS_SG_TIMEOUT;
+	io_hdr.timeout = sg_timeout;
 	io_hdr.pack_id = -1;
 	io_hdr.usr_ptr = cmd;
 	io_hdr.flags |= SG_FLAG_DIRECT_IO;
@@ -318,6 +342,9 @@ static int init_bsg_device(int fd)
 static int init_sg_device(int fd)
 {
 	int t, err;
+	struct sg_io_hdr hdr;
+	unsigned char cmd[6];
+	unsigned char resp[36];
 
 	err = ioctl(fd, SG_GET_VERSION_NUM, &t);
 	if ((err < 0) || (t < 30000)) {
@@ -332,6 +359,20 @@ static int init_sg_device(int fd)
 		return -1;
 	}
 
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&resp, 0, sizeof(resp));
+
+	cmd[0] = INQUIRY;
+	cmd[4] = sizeof(resp);
+
+	bs_sg_cmd_setup(&hdr, cmd, sizeof(cmd), resp, sizeof(resp),
+			SG_DXFER_FROM_DEV, NULL, 0, 30000);
+
+	err = ioctl(fd, SG_IO, &hdr);
+
+	if (!err && (resp[0] & 0x1f) == TYPE_TAPE)
+		sg_timeout = 14000 * 1000;
+
 	return 0;
 }
 


--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list