readsector0: block count calculation wrong
authorHannes Reinecke <hare@suse.de>
Tue, 3 May 2011 08:06:59 +0000 (10:06 +0200)
committerHannes Reinecke <hare@suse.de>
Tue, 3 May 2011 08:06:59 +0000 (10:06 +0200)
readsector0/libsg is getting the number of blocks wrong, as it
doesn't check the length of the buffer.

Signed-off-by: Hannes Reinecke <hare@suse.de>
libmultipath/checkers/emc_clariion.c
libmultipath/checkers/libsg.c
libmultipath/checkers/libsg.h
libmultipath/checkers/readsector0.c

index fa04468..b42d267 100644 (file)
@@ -182,7 +182,8 @@ int libcheck_check (struct checker * c)
                unsigned char buf[4096];
 
                memset(buf, 0, 4096);
-               ret = sg_read(c->fd, &buf[0], sbb = &sb[0], c->timeout);
+               ret = sg_read(c->fd, &buf[0], 4096,
+                             sbb = &sb[0], SENSE_BUFF_LEN, c->timeout);
                if (ret == PATH_DOWN) {
                        hexadecimal_to_ascii(ct->wwn, wwnstr);
 
index 2f6af75..5a989d3 100644 (file)
 #include "../libmultipath/sg_include.h"
 
 int
-sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
-        unsigned int timeout)
+sg_read (int sg_fd, unsigned char * buff, int buff_len,
+        unsigned char * sense, int sense_len, unsigned int timeout)
 {
        /* defaults */
-       int blocks = 1;
+       int blocks;
        long long start_block = 0;
        int bs = 512;
        int cdbsz = 10;
        int * diop = NULL;
 
        unsigned char rdCmd[cdbsz];
-       unsigned char *sbb = senseBuff;
+       unsigned char *sbb = sense;
        struct sg_io_hdr io_hdr;
        int res;
        int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
@@ -33,6 +33,7 @@ sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
        if (fstat(sg_fd, &filestatus) != 0)
                return PATH_DOWN;
        bs = (filestatus.st_blksize > 4096)? 4096: filestatus.st_blksize;
+       blocks = buff_len / bs;
        memset(rdCmd, 0, cdbsz);
        sz_ind = 1;
        rdCmd[0] = rd_opcode[sz_ind];
@@ -50,15 +51,15 @@ sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
        io_hdr.dxfer_len = bs * blocks;
        io_hdr.dxferp = buff;
-       io_hdr.mx_sb_len = SENSE_BUFF_LEN;
-       io_hdr.sbp = senseBuff;
+       io_hdr.mx_sb_len = sense_len;
+       io_hdr.sbp = sense;
        io_hdr.timeout = timeout;
        io_hdr.pack_id = (int)start_block;
        if (diop && *diop)
        io_hdr.flags |= SG_FLAG_DIRECT_IO;
 
-retry: 
-       memset(senseBuff, 0, SENSE_BUFF_LEN);
+retry:
+       memset(sense, 0, sense_len);
        while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) && (EINTR == errno));
 
        if (res < 0) {
index 071bc61..3994f45 100644 (file)
@@ -3,7 +3,7 @@
 
 #define SENSE_BUFF_LEN 32
 
-int sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
-            unsigned int timeout);
+int sg_read (int sg_fd, unsigned char * buff, int buff_len,
+            unsigned char * sense, int sense_len, unsigned int timeout);
 
 #endif /* _LIBSG_H */
index 3647dd9..0550fb6 100644 (file)
@@ -29,7 +29,8 @@ int libcheck_check (struct checker * c)
        unsigned char sbuf[SENSE_BUFF_LEN];
        int ret;
 
-       ret = sg_read(c->fd, &buf[0], &sbuf[0], c->timeout);
+       ret = sg_read(c->fd, &buf[0], 4069, &sbuf[0],
+                     SENSE_BUFF_LEN, c->timeout);
 
        switch (ret)
        {