Question about SCSI serial number retrieval algorithm

Petr Uzel petr.uzel at suse.cz
Fri Nov 2 10:25:15 UTC 2012


Hi,

I have a question about algorithm used in dmraid to retrieve the
serial number from the scsi device:

lib/device/scsi.c:

 77 /*
 78  * Retrieve SCSI serial number.
 79  */
 80 #define MAX_RESPONSE_LEN        255
 81 int
 82 get_scsi_serial(struct lib_context *lc, int fd, struct dev_info *di,
 83                 enum ioctl_type type)
 84 {
 85         int ret = 0;
 86         size_t actual_len;
 87         unsigned char *response;
 88         /*
 89          * Define ioctl function and offset into response buffer of serial
 90          * string length field (serial string follows length field immediately)
 91          */
 92         struct {
 93                 int (*ioctl_func) (int, unsigned char *, size_t);
 94                 unsigned int start;
 95         } param[] = {
 96                 { sg_inquiry, 3},
 97                 { old_inquiry, 11},
 98         }, *p = (SG == type) ? param : param + 1;
 99
100         if (!(response = dbg_malloc(MAX_RESPONSE_LEN)))
101                 return 0;
102
103         actual_len = p->start + 1;
104         if ((ret = (p->ioctl_func(fd, response, actual_len)))) {
105                 size_t serial_len = (size_t) response[p->start];
106
107                 if (serial_len > actual_len) {
108                         actual_len += serial_len;
109                         ret = p->ioctl_func(fd, response, actual_len);
110                 }
111
112                 ret = ret &&
113                      (di->serial = dbg_strdup(remove_white_space (lc, (char *) &response[p->start + 1], serial_len)));
114         }


If type == SG, this function uses two SG_IO ioctls() to retrieve the serial number.
First with response buffer length set to 4 (line 104), which is just enough to get the serial
number length, which is later used to set the length of buffer for the second ioctl() (line 109).

Why is this? Why not use sufficiently long buffer (MAX_RESPONSE_LEN) right with the first ioctl()?

I'm asking this because I've encountered a device which requires the buffer to be long
enough to store the serial number, otherwise the SCSI inquiry command timeouts [*]. If this
happens, not only that it gets stuck for some time, but also the response buffer from the first
ioctl contains all zeros, so serial_len on line 105 is set to 0 and condition on line
107 is false -> second ioctl() is not executed...

[*] I know this is likely a bug outside dmraid.


I'd really appreciate if someone could shed some light into why it is done this way.

Thanks in advance,

Petr

--
Petr Uzel
IRC: ptr_uzl @ freenode
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/ataraid-list/attachments/20121102/013731c0/attachment.sig>


More information about the Ataraid-list mailing list