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

Mark Harvey markh794 at gmail.com
Fri Jul 30 08:55:51 CEST 2010


On Fri, Jul 30, 2010 at 12:58 PM, FUJITA Tomonori
<fujita.tomonori at lab.ntt.co.jp> wrote:
> 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;
>  }
>

Applied this patch (a story in itself with 'corporate firewall rules'
in place)..

So far, with this patch in place, it has passed all the current
NetBackup 'Drive Qualification tests'.
I'm just waiting on the last one to complete which writes random data
to complete tape to test EOT behaviour.

As I've only got one spare tape in this library, I'm not sure if this
test will succeed as it is suppose to load a 2nd blank tape.. Oh well.
I'll check back in on progress once I'm at home to see if it
completed, otherwise it will be tomorrow.

However, all tests so far have passed.
 - basic opening, closing & writing to tape
 - fast block locate tests
 - Force errors and check correct response
 - various reads/writes & positioning to check drive performance.

i.e.
Add a tested-by: Mark Harvey on this patch :)

p.s.
As you have gone to the trouble to send a SCSI Inquiry to the device,
any chance of using that info to update "Type" message as well ?

Many thanks
Mark
--
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