Question about SCSI serial number retrieval algorithm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Attachment: pgp6GJxcaXdZw.pgp
Description: PGP signature

_______________________________________________
Ataraid-list mailing list
Ataraid-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/ataraid-list

[Index of Archives]     [Linux RAID]     [Linux Device Mapper]     [Linux IDE]     [Linux SCSI]     [Kernel]     [Linux Books]     [Linux Admin]     [GFS]     [RPM]     [Yosemite Campgrounds]     [AMD 64]

  Powered by Linux