diff options
Diffstat (limited to 'extras/multipath')
-rw-r--r-- | extras/multipath/Makefile | 11 | ||||
-rw-r--r-- | extras/multipath/main.c | 43 | ||||
-rw-r--r-- | extras/multipath/main.h | 17 | ||||
-rw-r--r-- | extras/multipath/sg_include.h | 1 |
4 files changed, 43 insertions, 29 deletions
diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 0835d7a2c6..9e0ce124c6 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -9,10 +9,10 @@ exec_prefix = ${prefix} bindir = ${exec_prefix}/bin CC = gcc -CFLAGS = -g -O2 -Wall -Wunused -Wstrict-prototypes -LDFLAGS = -lsysfs -ldevmapper +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../klibc/klibc/include -I../../klibc/klibc/include/bits32 -I/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/include -I../../klibc/linux/include -I../../libsysfs -I. +LDFLAGS = -lsysfs -ldevmapper -ldlist -OBJS = main.o sg_err.o +OBJS = main.o all: $(EXEC) strip $(EXEC) @@ -20,7 +20,7 @@ all: $(EXEC) @echo "Make complete" $(EXEC): $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) + $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) clean: rm -f core *.o $(EXEC) @@ -30,5 +30,4 @@ install: install -m 755 $(EXEC) $(bindir)/ # Code dependencies -main.o: main.c main.h sg_err.h sg_include.h -sg_err.o: sg_err.c sg_err.h sg_include.h +main.o: main.c main.h sg_include.h diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 0ed74c52a9..b5ab664433 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -23,7 +23,6 @@ #include <sys/types.h> #include <sys/stat.h> #include <linux/kdev_t.h> -#include <errno.h> #include <string.h> #include <sys/ioctl.h> #include <libsysfs.h> @@ -34,7 +33,6 @@ static int do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, void *resp, int mx_resp_len, int noisy) { - int res; unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 0, 0, 0, 0, 0 }; unsigned char sense_b[SENSE_BUFF_LEN]; @@ -61,14 +59,27 @@ do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, perror("SG_IO (inquiry) error"); return -1; } - res = sg_err_category3(&io_hdr); - switch (res) { - case SG_ERR_CAT_CLEAN: - case SG_ERR_CAT_RECOVERED: + + /* treat SG_ERR here to get rid of sg_err.[ch] */ + io_hdr.status &= 0x7e; + if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && + (0 == io_hdr.driver_status)) return 0; - default: - return -1; + if ((SCSI_CHECK_CONDITION == io_hdr.status) || + (SCSI_COMMAND_TERMINATED == io_hdr.status) || + (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { + if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { + int sense_key; + unsigned char * sense_buffer = io_hdr.sbp; + if (sense_buffer[0] & 0x2) + sense_key = sense_buffer[1] & 0xf; + else + sense_key = sense_buffer[2] & 0xf; + if(RECOVERED_ERROR == sense_key) + return 0; + } } + return -1; } static int @@ -191,7 +202,7 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) int sg_fd; struct sysfs_directory * sdir; struct sysfs_directory * devp; - struct sysfs_dlink * linkp; + struct sysfs_link * linkp; char buff[FILE_NAME_SIZE]; char block_path[FILE_NAME_SIZE]; @@ -199,17 +210,15 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(block_path, "%s/block", conf->sysfs_path); sdir = sysfs_open_directory(block_path); sysfs_read_directory(sdir); - devp = sdir->subdirs; - while (devp != NULL) { + dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { sysfs_read_directory(devp); - linkp = devp->links; - while (linkp != NULL) { + if(devp->links == NULL) + continue; + dlist_for_each_data(devp->links, linkp, struct sysfs_link) { if (!strncmp(linkp->name, "device", 6)) break; - linkp = linkp->next; } if (linkp == NULL) { - devp = devp->next; continue; } @@ -217,21 +226,19 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(all_paths[k].sg_dev, "/dev/%s", buff); strcpy(all_paths[k].dev, all_paths[k].sg_dev); if ((sg_fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) { - devp = devp->next; continue; } get_lun_strings(sg_fd, &all_paths[k]); get_unique_id(sg_fd, &all_paths[k]); all_paths[k].state = do_tur(sg_fd); close(sg_fd); - basename(linkp->target->path, buff); + basename(linkp->target, buff); sscanf(buff, "%i:%i:%i:%i", &all_paths[k].sg_id.host_no, &all_paths[k].sg_id.channel, &all_paths[k].sg_id.scsi_id, &all_paths[k].sg_id.lun); k++; - devp = devp->next; } sysfs_close_directory(sdir); diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 43a24ac7bc..019cb843a8 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -21,7 +21,16 @@ /* local includes */ #include "sg_include.h" -#include "sg_err.h" + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +/* exerpt from "scsi.h" */ +#define RECOVERED_ERROR 0x01 +#define SCSI_IOCTL_GET_IDLUN 0x5382 +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 /* global defs */ #define WWID_SIZE 33 @@ -37,7 +46,7 @@ #define TUR_CMD_LEN 6 #define MX_ALLOC_LEN 255 #define BLKGETSIZE _IO(0x12,96) -#define DM_TARGET "striped" +#define DM_TARGET "multipath" #define PINDEX(x,y) mp[(x)].pindex[(y)] @@ -96,8 +105,8 @@ struct env { /* Build version */ #define PROG "multipath" -#define VERSION_CODE 0x000005 -#define DATE_CODE 0x120903 +#define VERSION_CODE 0x000006 +#define DATE_CODE 0x271103 #define MULTIPATH_VERSION(version) \ (version >> 16) & 0xFF, \ diff --git a/extras/multipath/sg_include.h b/extras/multipath/sg_include.h index 6b6dd6f372..460506826e 100644 --- a/extras/multipath/sg_include.h +++ b/extras/multipath/sg_include.h @@ -9,7 +9,6 @@ #include <linux/../scsi/scsi.h> #else #include <scsi/sg.h> - #include <scsi/scsi.h> #endif #endif |