Imported Upstream version 0.6.3 upstream/0.6.3
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 14 Jan 2022 04:50:16 +0000 (13:50 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 14 Jan 2022 04:50:16 +0000 (13:50 +0900)
77 files changed:
Makefile
Makefile.inc
README
kpartx/Makefile
kpartx/dasd.c
kpartx/devmapper.c
kpartx/gpt.c
kpartx/kpartx.c
kpartx/kpartx.rules
kpartx/lopart.c
kpartx/ps3.c
kpartx/solaris.c
libmpathcmd/Makefile
libmpathcmd/mpath_cmd.c
libmpathpersist/Makefile
libmpathpersist/mpath_persist.c
libmpathpersist/mpath_pr_ioctl.c
libmpathpersist/mpath_pr_ioctl.h
libmpathpersist/mpath_updatepr.c
libmultipath/Makefile
libmultipath/blacklist.c
libmultipath/checkers.c
libmultipath/checkers.h
libmultipath/checkers/Makefile
libmultipath/checkers/cciss.h
libmultipath/checkers/cciss_tur.c
libmultipath/checkers/directio.c
libmultipath/checkers/emc_clariion.c
libmultipath/checkers/hp_sw.c
libmultipath/checkers/rbd.c [new file with mode: 0644]
libmultipath/checkers/rdac.c
libmultipath/checkers/readsector0.c
libmultipath/checkers/tur.c
libmultipath/defaults.h
libmultipath/devmapper.c
libmultipath/devmapper.h
libmultipath/dict.c
libmultipath/discovery.c
libmultipath/hwtable.c
libmultipath/lock.c
libmultipath/lock.h
libmultipath/memory.c
libmultipath/memory.h
libmultipath/parser.c
libmultipath/pgpolicies.c
libmultipath/print.c
libmultipath/print.h
libmultipath/prio.h
libmultipath/prioritizers/Makefile
libmultipath/prioritizers/alua.c
libmultipath/prioritizers/hp_sw.c
libmultipath/prioritizers/ontap.c
libmultipath/prioritizers/weightedpath.c
libmultipath/prioritizers/weightedpath.h
libmultipath/propsel.c
libmultipath/structs.h
libmultipath/structs_vec.c
libmultipath/structs_vec.h
libmultipath/uevent.c
libmultipath/util.h
libmultipath/version.h
libmultipath/waiter.c
libmultipath/waiter.h
libmultipath/wwids.c
mpathpersist/Makefile
mpathpersist/main.c
multipath/Makefile
multipath/main.c
multipath/multipath.conf.5
multipathd/Makefile
multipathd/cli.c
multipathd/main.c
multipathd/main.h
multipathd/pidfile.c
multipathd/uxclnt.c
multipathd/uxlsnr.c
multipathd/uxlsnr.h

index cf1acd910e6ba2d58e2006e6234f81ed52c4a89b..95c7dfb9823afa384eb8f9cff29bcebfb2bc4c63 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,3 @@
-# Makefile
 #
 # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
@@ -6,16 +5,23 @@
 #
 # Try to supply the linux kernel headers.
 #
-ifeq    ($(KRNLSRC),)
-KRNLLIB = /lib/modules/$(shell uname -r)
-ifeq    ($(shell test -r $(KRNLLIB)/source && echo 1),1)
-KRNLSRC = $(KRNLLIB)/source
-KRNLOBJ = $(KRNLLIB)/build
-else
-KRNLSRC = $(KRNLLIB)/build
-KRNLOBJ = $(KRNLLIB)/build
+ifeq ($(KRNLSRC),)
+       KRNLLIB = /lib/modules/$(shell uname -r)
+       ifeq ($(shell test -r $(KRNLLIB)/source && echo 1),1)
+               KRNLSRC = $(KRNLLIB)/source
+               KRNLOBJ = $(KRNLLIB)/build
+       else
+               KRNLSRC = $(KRNLLIB)/build
+               KRNLOBJ = $(KRNLLIB)/build
+       endif
 endif
+
+ifeq ($(MULTIPATH_VERSION),)
+       VERSION = $(shell basename ${PWD} | cut -d'-' -f3)
+else
+       VERSION = $(MULTIPATH_VERSION)
 endif
+
 export KRNLSRC
 export KRNLOBJ
 
@@ -30,12 +36,6 @@ BUILDDIRS = \
        mpathpersist \
        kpartx
 
-ifeq   ($(MULTIPATH_VERSION),)
-VERSION = $(shell basename ${PWD} | cut -d'-' -f3)
-else
-VERSION = $(MULTIPATH_VERSION)
-endif
-
 all: recurse
 
 recurse:
@@ -59,11 +59,11 @@ recurse_uninstall:
        $(MAKE) -C $$dir uninstall || exit $?; \
        done
 
-clean: recurse_clean
+clean: recurse_clean
 
-install:       recurse_install
+install: recurse_install
 
-uninstall:     recurse_uninstall
+uninstall: recurse_uninstall
 
 .PHONY:        TAGS
 TAGS:
index 3e8635ffe146cff6c54c8fae6fdcb89c5c35cf5f..0808e6425e8f82430161512c2e392e9827b0d1f0 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.inc
 #
 # Copyright (C) 2004 Christophe Varoqui, <christophe.varoqui@opensvc.com>
+#
 
 #
 # Allow to force some libraries to be used statically. (Uncomment one of the
@@ -39,32 +39,32 @@ ifndef SYSTEMDPATH
        SYSTEMDPATH=usr/lib
 endif
 
-prefix      =
-exec_prefix = $(prefix)
-bindir      = $(exec_prefix)/sbin
-libudevdir  = $(prefix)/$(SYSTEMDPATH)/udev
-udevrulesdir = $(libudevdir)/rules.d
-multipathdir = $(TOPDIR)/libmultipath
-mandir      = $(prefix)/usr/share/man/man8
-man5dir     = $(prefix)/usr/share/man/man5
-man3dir      = $(prefix)/usr/share/man/man3
-syslibdir   = $(prefix)/$(LIB)
-incdir      = $(prefix)/usr/include
-libdir     = $(prefix)/$(LIB)/multipath
-unitdir     = $(prefix)/$(SYSTEMDPATH)/systemd/system
-mpathpersistdir = $(TOPDIR)/libmpathpersist
-mpathcmddir = $(TOPDIR)/libmpathcmd
+prefix         =
+exec_prefix    = $(prefix)
+bindir         = $(exec_prefix)/sbin
+libudevdir     = $(prefix)/$(SYSTEMDPATH)/udev
+udevrulesdir   = $(libudevdir)/rules.d
+multipathdir   = $(TOPDIR)/libmultipath
+mandir         = $(prefix)/usr/share/man/man8
+man5dir                = $(prefix)/usr/share/man/man5
+man3dir                = $(prefix)/usr/share/man/man3
+syslibdir      = $(prefix)/$(LIB)
+incdir         = $(prefix)/usr/include
+libdir         = $(prefix)/$(LIB)/multipath
+unitdir                = $(prefix)/$(SYSTEMDPATH)/systemd/system
+mpathpersistdir        = $(TOPDIR)/libmpathpersist
+mpathcmddir    = $(TOPDIR)/libmpathcmd
 
-GZIP        = gzip -9 -c
-RM          = rm -f
-LN          = ln -sf
-INSTALL_PROGRAM = install
+GZIP           = gzip -9 -c
+RM             = rm -f
+LN             = ln -sf
+INSTALL_PROGRAM        = install
 
-OPTFLAGS     = -Wunused -Wstrict-prototypes -O2 -g -pipe -Wformat-security -Wall \
-               -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
+OPTFLAGS       = -Wunused -Wstrict-prototypes -O2 -g -pipe -Wformat-security -Wall \
+                 -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
 
-CFLAGS      = $(OPTFLAGS) -fPIC -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\"
-SHARED_FLAGS = -shared
+CFLAGS         = $(OPTFLAGS) -fPIC -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\"
+SHARED_FLAGS   = -shared
 
 %.o:   %.c
        $(CC) $(CFLAGS) -c -o $@ $<
diff --git a/README b/README
index c1c53fcf5df56f896550abc30d8d81da94294f6c..77b79b855cbe2542ab1bf32edb2d9bbede6f12d4 100644 (file)
--- a/README
+++ b/README
@@ -25,6 +25,5 @@ To get latest devel code: git clone http://git.opensvc.com/multipath-tools/.git
 
 Mailing list: http://www.redhat.com/mailman/listinfo/dm-devel
 Gitweb: http://git.opensvc.com/?p=multipath-tools/.git
-Patchwork: http://patchwork.kernel.org/project/dm-devel/list/
 
 Current maintainer is Christophe Varoqui <christophe.varoqui@opensvc.com>
index 54765451f05d65e8fcb72e7ec7262f416f7dfa9c..75b7606b42b5a9df8ab601d11eaa3860fc6c8e81 100644 (file)
@@ -1,4 +1,3 @@
-# Makefile
 #
 # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
@@ -6,15 +5,17 @@ include ../Makefile.inc
 
 CFLAGS += -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 
+LDFLAGS = -ldevmapper
+
 LIBDM_API_COOKIE = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_set_cookie' /usr/include/libdevmapper.h)
 
 ifneq ($(strip $(LIBDM_API_COOKIE)),0)
        CFLAGS += -DLIBDM_API_COOKIE
 endif
 
-LDFLAGS = -ldevmapper
 OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \
-       gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o
+       gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o
+
 EXEC = kpartx
 
 all: $(EXEC)
index 046a08b38edce6c25ada0b61bbee4de0d347f739..faf5e2e6331f14771e1448ae364a6d031d66c8c1 100644 (file)
@@ -233,7 +233,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                            || EBCtoASC[f1.DS1FMTID] == '5'
                            || EBCtoASC[f1.DS1FMTID] == '7'
                            || EBCtoASC[f1.DS1FMTID] == '9') {
-                               blk++;
+                               blk++;
                                continue;
                        }
 
@@ -243,7 +243,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                                break;
 
                        /* OK, we got valid partition data */
-                       offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
+                       offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
                        size  = cchh2blk(&f1.DS1EXT1.ulimit, &geo) -
                                offset + geo.sectors;
                        sp[counter].start = sectors512(offset, blocksize);
@@ -280,7 +280,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                retval = 1;
        }
 
- out:
+out:
        if (data != NULL)
                free(data);
        if (fd_dasd != -1 && fd_dasd != fd)
index 382f511cca2faff5b4806f78dd543cac1b3be9c8..474d879f522ee34bae37775c4e8968a98b3256e3 100644 (file)
@@ -47,7 +47,7 @@ dm_prereq (char * str, int x, int y, int z)
                target = (void *) target + target->next;
        } while (last_target != target);
 
-       out:
+out:
        dm_task_destroy(dmt);
        return r;
 }
@@ -85,7 +85,7 @@ dm_simplecmd (int task, const char *name, int no_flush, uint16_t udev_flags) {
        if (udev_wait_flag)
                        dm_udev_wait(cookie);
 #endif
-       out:
+out:
        dm_task_destroy(dmt);
        return r;
 }
index 75a1c2b94969e89e67b8181abe30966441c3b0a6..3511886433a6bb9cd0abea937a97931c537adb10 100644 (file)
@@ -592,7 +592,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
                return 1;
        }
 
- fail:
+fail:
        if (pgpt)  { free(pgpt);   pgpt=NULL; }
        if (agpt)  { free(agpt);   agpt=NULL; }
        if (pptes) { free(pptes); pptes=NULL; }
index b7b4047bbbea31f067838995336663757a41419e..d31fea89bb8d0c502b86c7f64ff7fad2a7b95be2 100644 (file)
@@ -258,7 +258,8 @@ main(int argc, char **argv){
                exit(1);
        }
 
-       while ((arg = getopt(argc, argv, short_opts)) != EOF) switch(arg) {
+       while ((arg = getopt(argc, argv, short_opts)) != EOF)
+               switch(arg) {
                case 'r':
                        ro=1;
                        break;
@@ -295,7 +296,7 @@ main(int argc, char **argv){
                default:
                        usage();
                        exit(1);
-       }
+               }
 
 #ifdef LIBDM_API_COOKIE
        if (!udev_sync)
index 8858a601bd444a1bb7f98cf5b4064bd2156bdbcd..1713f3cc8ba535ed477fef549f3ca1da026ab5bd 100644 (file)
@@ -38,6 +38,6 @@ ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", \
 ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", GOTO="kpartx_end"
 ENV{DM_NR_VALID_PATHS}=="0", GOTO="kpartx_end"
 ENV{DM_STATE}!="SUSPENDED", ENV{DM_UUID}=="mpath-*", \
-        RUN+="/sbin/kpartx -u -p -part /dev/$name"
+       RUN+="/sbin/kpartx -u -p -part /dev/$name"
 
 LABEL="kpartx_end"
index e8e3f08d87f583aafba25ebc82b657477599bfe7..0ab1688e981f3ce162a3c0c7906079bef7254550 100644 (file)
@@ -147,7 +147,7 @@ find_loop_by_file (const char * filename)
 extern char *
 find_unused_loop_device (void)
 {
-       char dev[20], *next_loop_dev = NULL;;
+       char dev[20], *next_loop_dev = NULL;
        int fd, next_loop = 0, somedev = 0, someloop = 0, loop_known = 0;
        struct stat statbuf;
        struct loop_info loopinfo;
@@ -211,23 +211,21 @@ find_unused_loop_device (void)
                fprintf(stderr, "mount: could not find any device /dev/loop#");
 
        else if (!someloop) {
-           if (loop_known == 1)
-               fprintf(stderr,
-                   "mount: Could not find any loop device.\n"
-                   "       Maybe /dev/loop# has a wrong major number?");
-           else if (loop_known == -1)
-               fprintf(stderr,
-                   "mount: Could not find any loop device, and, according to %s,\n"
-                   "       this kernel does not know about the loop device.\n"
-                   "       (If so, then recompile or `modprobe loop'.)",
-                     PROC_DEVICES);
-
-           else
-               fprintf(stderr,
-                   "mount: Could not find any loop device. Maybe this kernel does not know\n"
-                   "       about the loop device (then recompile or `modprobe loop'), or\n"
-                   "       maybe /dev/loop# has the wrong major number?");
-
+               if (loop_known == 1)
+                       fprintf(stderr,
+                               "mount: Could not find any loop device.\n"
+                               "       Maybe /dev/loop# has a wrong major number?");
+               else if (loop_known == -1)
+                       fprintf(stderr,
+                               "mount: Could not find any loop device, and, according to %s,\n"
+                               "       this kernel does not know about the loop device.\n"
+                               "       (If so, then recompile or `modprobe loop'.)",
+                               PROC_DEVICES);
+               else
+                       fprintf(stderr,
+                               "mount: Could not find any loop device. Maybe this kernel does not know\n"
+                               "       about the loop device (then recompile or `modprobe loop'), or\n"
+                               "       maybe /dev/loop# has the wrong major number?");
        } else
                fprintf(stderr, "mount: could not find any free loop device");
        return 0;
index 2fe868deab7f59530d144a46dafd3269d0bf0fe8..84550978f37cf995bf95e38f55e8d1786f64e6c7 100644 (file)
@@ -28,7 +28,7 @@ struct disklabel {
        u_int64_t d_res2;
        u_int64_t d_res3;
        struct d_partition d_partitions[MAX_PARTITIONS];
-       u_int8_t d_pad[0x600 - MAX_PARTITIONS * sizeof(struct d_partition)- 0x30];
+       u_int8_t d_pad[0x600 - MAX_PARTITIONS * sizeof(struct d_partition) - 0x30];
 };
 
 static int
index 355a6cb933c1a09bf3bd1b2b6e6aad0440b6beaf..01da379c65b2a778d1730e55ab0713ca77d652dd 100644 (file)
@@ -11,7 +11,7 @@
 struct solaris_x86_slice {
        unsigned short  s_tag;          /* ID tag of partition */
        unsigned short  s_flag;         /* permision flags */
-       daddr_t         s_start;        /* start sector no of partition */
+       long            s_start;        /* start sector no of partition */
        long            s_size;         /* # of blocks in partition */
 };
 
index 44c221d5127b1d07aced6b5bce36c5a689300255..457c4cafcd280e9007b44b16206d31244187fc94 100644 (file)
@@ -1,8 +1,6 @@
-# Makefile
-#
 include ../Makefile.inc
 
-SONAME=0
+SONAME = 0
 DEVLIB = libmpathcmd.so
 LIBS = $(DEVLIB).$(SONAME)
 
@@ -27,4 +25,4 @@ uninstall:
        $(RM) $(DESTDIR)$(incdir)/mpath_cmd.h
 
 clean:
-       $(RM) core *.a *.o *.gz *.so *.so.*
+       $(RM) core *.a *.o *.so *.so.* *.gz
index 2290ecb69570dde399247abfc4b8e5bb241dbcbe..c058479dcebf542f9b7ae0d6818a3a1ed7c010bf 100644 (file)
@@ -112,7 +112,7 @@ ssize_t mpath_recv_reply_len(int fd, unsigned int timeout)
                return ret;
        if (ret != sizeof(len)) {
                errno = EIO;
-               return ret;
+               return -1;
        }
        return len;
 }
index 07fcf70f1c7d761d29c292be831f5b68156e2e3c..1c4b2e13b63e185a35a068e43f68d5d34505af4b 100644 (file)
@@ -1,23 +1,20 @@
-# Makefile
-#
 include ../Makefile.inc
 
-SONAME=0
+SONAME = 0
 DEVLIB = libmpathpersist.so
 LIBS = $(DEVLIB).$(SONAME)
 
-
 CFLAGS += -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir)
-LIBDEPS +=  -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \
-       -L$(mpathcmddir) -lmpathcmd
+
+LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \
+          -L$(mpathcmddir) -lmpathcmd
 
 OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o
 
 all: $(LIBS)
 
-
 $(LIBS):
-       $(CC) -Wall -fPIC -c $(CFLAGS) *.c
+       $(CC) -c $(CFLAGS) *.c
        $(CC) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS)
        $(LN) $(LIBS) $(DEVLIB)
        $(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz
@@ -42,7 +39,4 @@ uninstall:
        $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB)
 
 clean:
-       $(RM) core *.a *.o
-       $(RM) libmpathpersist.so.0
-       $(RM) libmpathpersist.so
-       $(RM) mpath_persistent_reserve_in.3.gz mpath_persistent_reserve_out.3.gz
+       $(RM) core *.a *.o *.so *.so.* *.gz
index 252d6fcb1fad91875907b4f69da374e7275a95a6..75016511d22d7fb0f53d8183a2f383552e94925e 100644 (file)
@@ -514,7 +514,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
                        if (rc){
                                condlog (0, "%s: failed to create thread %d", mpp->wwid, rc);
                        }
-                       count = count +1;
+                       count = count + 1;
                }
        }
        for( i=0; i < active_pathcount ; i++){
@@ -642,7 +642,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
        struct path *pp = NULL;
        int active_pathcount = 0;
        pthread_attr_t attr;
-       int rc, found = 0;;
+       int rc, found = 0;
        int count = 0;
        int status = MPATH_PR_SUCCESS;
        struct prin_resp resp;
index cf7141ab17e26cbdc862188ecd228e4952eaeb0a..8b9ac3da554c78413b190c44856347d5158c1b69 100644 (file)
@@ -272,22 +272,22 @@ decode_transport_id(struct prin_fulldescr *fdesc, unsigned char * p, int length)
                fdesc->trnptid.format_code = ((p[0] >> 6) & 0x3);
                fdesc->trnptid.protocol_id = (p[0] & 0xf);
                switch (fdesc->trnptid.protocol_id) {
-                       case MPATH_PROTOCOL_ID_FC:
-                               memcpy(&fdesc->trnptid.n_port_name, &p[8], 8);
-                               jump = 24;
-                               break;
-                       case MPATH_PROTOCOL_ID_ISCSI:
-                               num = ((p[2] << 8) | p[3]);
-                               memcpy(&fdesc->trnptid.iscsi_name, &p[4], num);
-                               jump = (((num + 4) < 24) ? 24 : num + 4);
-                               break;
-                       case MPATH_PROTOCOL_ID_SAS:
-                               memcpy(&fdesc->trnptid.sas_address, &p[4], 8);
-                               jump = 24;
-                               break;
-                       default:
-                               jump = 24;
-                               break;
+               case MPATH_PROTOCOL_ID_FC:
+                       memcpy(&fdesc->trnptid.n_port_name, &p[8], 8);
+                       jump = 24;
+                       break;
+               case MPATH_PROTOCOL_ID_ISCSI:
+                       num = ((p[2] << 8) | p[3]);
+                       memcpy(&fdesc->trnptid.iscsi_name, &p[4], num);
+                       jump = (((num + 4) < 24) ? 24 : num + 4);
+                       break;
+               case MPATH_PROTOCOL_ID_SAS:
+                       memcpy(&fdesc->trnptid.sas_address, &p[4], 8);
+                       jump = 24;
+                       break;
+               default:
+                       jump = 24;
+                       break;
                }
        }
 }
@@ -411,62 +411,62 @@ int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr,
                return MPATH_PR_SUCCESS;
 
        switch(io_hdr.status) {
-               case SAM_STAT_GOOD:
-                       break;
-               case SAM_STAT_CHECK_CONDITION:
-                       condlog(2, "%s: Sense_Key=%02x, ASC=%02x ASCQ=%02x",
-                               dev, Sensedata->Sense_Key,
-                               Sensedata->ASC, Sensedata->ASCQ);
-                       switch(Sensedata->Sense_Key) {
-                               case NO_SENSE:
-                                       return MPATH_PR_NO_SENSE;
-                               case RECOVERED_ERROR:
-                                       return MPATH_PR_SUCCESS;
-                               case NOT_READY:
-                                       return MPATH_PR_SENSE_NOT_READY;
-                               case MEDIUM_ERROR:
-                                       return MPATH_PR_SENSE_MEDIUM_ERROR;
-                               case BLANK_CHECK:
-                                       return MPATH_PR_OTHER;
-                               case HARDWARE_ERROR:
-                                       return MPATH_PR_SENSE_HARDWARE_ERROR;
-                               case ILLEGAL_REQUEST:
-                                       return MPATH_PR_ILLEGAL_REQ;
-                               case UNIT_ATTENTION:
-                                       return MPATH_PR_SENSE_UNIT_ATTENTION;
-                               case DATA_PROTECT:
-                               case COPY_ABORTED:
-                                       return MPATH_PR_OTHER;
-                               case ABORTED_COMMAND:
-                                       return MPATH_PR_SENSE_ABORTED_COMMAND;
-
-                               default :
-                                       return MPATH_PR_OTHER;
-                       }
-               case SAM_STAT_RESERVATION_CONFLICT:
-                       return MPATH_PR_RESERV_CONFLICT;
+       case SAM_STAT_GOOD:
+               break;
+       case SAM_STAT_CHECK_CONDITION:
+               condlog(2, "%s: Sense_Key=%02x, ASC=%02x ASCQ=%02x",
+                       dev, Sensedata->Sense_Key,
+                       Sensedata->ASC, Sensedata->ASCQ);
+               switch(Sensedata->Sense_Key) {
+               case NO_SENSE:
+                       return MPATH_PR_NO_SENSE;
+               case RECOVERED_ERROR:
+                       return MPATH_PR_SUCCESS;
+               case NOT_READY:
+                       return MPATH_PR_SENSE_NOT_READY;
+               case MEDIUM_ERROR:
+                       return MPATH_PR_SENSE_MEDIUM_ERROR;
+               case BLANK_CHECK:
+                       return MPATH_PR_OTHER;
+               case HARDWARE_ERROR:
+                       return MPATH_PR_SENSE_HARDWARE_ERROR;
+               case ILLEGAL_REQUEST:
+                       return MPATH_PR_ILLEGAL_REQ;
+               case UNIT_ATTENTION:
+                       return MPATH_PR_SENSE_UNIT_ATTENTION;
+               case DATA_PROTECT:
+               case COPY_ABORTED:
+                       return MPATH_PR_OTHER;
+               case ABORTED_COMMAND:
+                       return MPATH_PR_SENSE_ABORTED_COMMAND;
 
                default :
-                       return  MPATH_PR_OTHER;
+                       return MPATH_PR_OTHER;
+               }
+       case SAM_STAT_RESERVATION_CONFLICT:
+               return MPATH_PR_RESERV_CONFLICT;
+
+       default :
+               return  MPATH_PR_OTHER;
        }
 
        switch(io_hdr.host_status) {
-               case DID_OK :
-                       break;
-               default :
-                       return MPATH_PR_OTHER;
+       case DID_OK :
+               break;
+       default :
+               return MPATH_PR_OTHER;
        }
        switch(io_hdr.driver_status)
        {
-               case DRIVER_OK:
-                       break;
-               default :
-                       return MPATH_PR_OTHER;
+       case DRIVER_OK:
+               break;
+       default :
+               return MPATH_PR_OTHER;
        }
        return MPATH_PR_SUCCESS;
 }
 
-int mpath_isLittleEndian()
+int mpath_isLittleEndian(void)
 {
        int num = 1;
        if(*(char *)&num == 1)
index 7dfda5a2b2c046aaeadf6772d3f6ec08196bc97a..625490f78652b86c47abece8c366e2de63896f53 100644 (file)
@@ -5,17 +5,17 @@
 
 #if 0
 static const char * pr_type_strs[] = {
-    "obsolete [0]",
-    "Write Exclusive",
-    "obsolete [2]",
-    "Exclusive Access",
-    "obsolete [4]",
-    "Write Exclusive, registrants only",
-    "Exclusive Access, registrants only",
-    "Write Exclusive, all registrants",
-    "Exclusive Access, all registrants",
-    "obsolete [9]", "obsolete [0xa]", "obsolete [0xb]", "obsolete [0xc]",
-    "obsolete [0xd]", "obsolete [0xe]", "obsolete [0xf]",
+       "obsolete [0]",
+       "Write Exclusive",
+       "obsolete [2]",
+       "Exclusive Access",
+       "obsolete [4]",
+       "Write Exclusive, registrants only",
+       "Exclusive Access, registrants only",
+       "Write Exclusive, all registrants",
+       "Exclusive Access, all registrants",
+       "obsolete [9]", "obsolete [0xa]", "obsolete [0xb]", "obsolete [0xc]",
+       "obsolete [0xd]", "obsolete [0xe]", "obsolete [0xf]",
 };
 #endif
 
@@ -24,43 +24,43 @@ typedef unsigned char    BYTE;      /* unsigned numeric, bit patterns */
 
 typedef struct SenseData
 {
-    BYTE        Error_Code;
-    BYTE        Segment_Number; /* not applicable to DAC */
-    BYTE        Sense_Key;
-    BYTE        Information[ 4 ];
-    BYTE        Additional_Len;
-    LWORD       Command_Specific_Info;
-    BYTE        ASC;
-    BYTE        ASCQ;
-    BYTE        Field_Replaceable_Unit;
-    BYTE        Sense_Key_Specific_Info[ 3 ];
-    BYTE        Recovery_Action[ 2 ];
-    BYTE        Total_Errors;
-    BYTE        Total_Retries;
-    BYTE        ASC_Stack_1;
-    BYTE        ASCQ_Stack_1;
-    BYTE        ASC_Stack_2;
-    BYTE        ASCQ_Stack_2;
-    BYTE        Additional_FRU_Info[ 8 ];
-    BYTE        Error_Specific_Info[ 3 ];
-    BYTE        Error_Detection_Point[ 4 ];
-    BYTE        Original_CDB[10];
-    BYTE        Host_ID;
-    BYTE        Host_Descriptor[ 2 ];
-    BYTE        Serial_Number[ 16 ];
-    BYTE        Array_SW_Revision[ 4 ];
-    BYTE        Data_Xfer_Operation;
-    BYTE        LUN_Number;
-    BYTE        LUN_Status;
-    BYTE        Drive_ID;
-    BYTE        Xfer_Start_Drive_ID;
-    BYTE        Drive_SW_Revision[ 4 ];
-    BYTE        Drive_Product_ID[ 16 ];
-    BYTE        PowerUp_Status[ 2 ];
-    BYTE        RAID_Level;
-    BYTE        Drive_Sense_ID[ 2 ];
-    BYTE        Drive_Sense_Data[ 32 ];
-    BYTE        Reserved2[24];
+       BYTE        Error_Code;
+       BYTE        Segment_Number; /* not applicable to DAC */
+       BYTE        Sense_Key;
+       BYTE        Information[ 4 ];
+       BYTE        Additional_Len;
+       LWORD       Command_Specific_Info;
+       BYTE        ASC;
+       BYTE        ASCQ;
+       BYTE        Field_Replaceable_Unit;
+       BYTE        Sense_Key_Specific_Info[ 3 ];
+       BYTE        Recovery_Action[ 2 ];
+       BYTE        Total_Errors;
+       BYTE        Total_Retries;
+       BYTE        ASC_Stack_1;
+       BYTE        ASCQ_Stack_1;
+       BYTE        ASC_Stack_2;
+       BYTE        ASCQ_Stack_2;
+       BYTE        Additional_FRU_Info[ 8 ];
+       BYTE        Error_Specific_Info[ 3 ];
+       BYTE        Error_Detection_Point[ 4 ];
+       BYTE        Original_CDB[10];
+       BYTE        Host_ID;
+       BYTE        Host_Descriptor[ 2 ];
+       BYTE        Serial_Number[ 16 ];
+       BYTE        Array_SW_Revision[ 4 ];
+       BYTE        Data_Xfer_Operation;
+       BYTE        LUN_Number;
+       BYTE        LUN_Status;
+       BYTE        Drive_ID;
+       BYTE        Xfer_Start_Drive_ID;
+       BYTE        Drive_SW_Revision[ 4 ];
+       BYTE        Drive_Product_ID[ 16 ];
+       BYTE        PowerUp_Status[ 2 ];
+       BYTE        RAID_Level;
+       BYTE        Drive_Sense_ID[ 2 ];
+       BYTE        Drive_Sense_Data[ 32 ];
+       BYTE        Reserved2[24];
 } SenseData_t;
 
 #define MPATH_PRIN_CMD 0x5e
index 9ff4b3050ec5475be1977d1759e6a1c0228e23f7..5af2e03258e51a01da07103b93d9ba294d3d0a46 100644 (file)
@@ -16,7 +16,6 @@
 #include "uxsock.h"
 #include "memory.h"
 
-unsigned long mem_allocated;    /* Total memory used in Bytes */
 
 int update_prflag(char * arg1, char * arg2, int noisy)
 {
index a14d4b3f61b95fa93d2300846847f858f7149053..3a20f8e05acecd75bc891296be81470094cb54c3 100644 (file)
@@ -1,15 +1,18 @@
-# Makefile
 #
 # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
 include ../Makefile.inc
 
-SONAME=0
+SONAME = 0
 DEVLIB = libmultipath.so
 LIBS = $(DEVLIB).$(SONAME)
+
 CFLAGS += -I$(mpathcmddir)
+
 LIBDEPS = -lpthread -ldl -ldevmapper -ludev -L$(mpathcmddir) -lmpathcmd
+
 ifdef SYSTEMD
+       CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD)
        ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1)
                LIBDEPS += -lsystemd
        else
@@ -17,14 +20,6 @@ ifdef SYSTEMD
        endif
 endif
 
-OBJS = memory.o parser.o vector.o devmapper.o callout.o \
-       hwtable.o blacklist.o util.o dmparser.o config.o \
-       structs.o discovery.o propsel.o dict.o \
-       pgpolicies.o debug.o defaults.o uevent.o \
-       switchgroup.o uxsock.o print.o alias.o log_pthread.o \
-       log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
-       lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o
-
 LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h)
 
 ifneq ($(strip $(LIBDM_API_FLUSH)),0)
@@ -43,16 +38,20 @@ ifneq ($(strip $(LIBUDEV_API_RECVBUF)),0)
        CFLAGS += -DLIBUDEV_API_RECVBUF
 endif
 
-ifdef SYSTEMD
-       CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD)
-endif
-
 LIBDM_API_DEFERRED = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_deferred_remove' /usr/include/libdevmapper.h)
 
 ifneq ($(strip $(LIBDM_API_DEFERRED)),0)
        CFLAGS += -DLIBDM_API_DEFERRED
 endif
 
+OBJS = memory.o parser.o vector.o devmapper.o callout.o \
+       hwtable.o blacklist.o util.o dmparser.o config.o \
+       structs.o discovery.o propsel.o dict.o \
+       pgpolicies.o debug.o defaults.o uevent.o \
+       switchgroup.o uxsock.o print.o alias.o log_pthread.o \
+       log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
+       lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o
+
 all: $(LIBS)
 
 $(LIBS): $(OBJS)
@@ -70,4 +69,4 @@ uninstall:
        $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB)
 
 clean:
-       $(RM) core *.a *.o *.gz *.so *.so.*
+       $(RM) core *.a *.o *.so *.so.* *.gz
index 2400eda1044147d19cb7f0e95a1dd09b8c5e031c..9687399df07bb784d1debfb76428da967b93320c 100644 (file)
@@ -210,7 +210,7 @@ setup_default_blist (struct config * conf)
                        if (alloc_ble_device(conf->blist_device))
                                return 1;
                        ble = VECTOR_SLOT(conf->blist_device,
-                                         VECTOR_SIZE(conf->blist_device) -1);
+                                         VECTOR_SIZE(conf->blist_device) - 1);
                        if (set_ble_device(conf->blist_device,
                                           STRDUP(hwe->vendor),
                                           STRDUP(hwe->bl_product),
index ad7d96cbe094e749a7568bbbbc271a48b6eba3ff..fd999b08b8cf98a95f0d546fe72ea1f636045562 100644 (file)
@@ -9,16 +9,16 @@
 #include "vector.h"
 
 char *checker_state_names[] = {
-      "wild",
-      "unchecked",
-      "down",
-      "up",
-      "shaky",
-      "ghost",
-      "pending",
-      "timeout",
-      "removed",
-      "delayed",
+       "wild",
+       "unchecked",
+       "down",
+       "up",
+       "shaky",
+       "ghost",
+       "pending",
+       "timeout",
+       "removed",
+       "delayed",
 };
 
 static LIST_HEAD(checkers);
@@ -138,6 +138,14 @@ struct checker * add_checker (char *multipath_dir, char * name)
        if (!c->free)
                goto out;
 
+       c->repair = (void (*)(struct checker *)) dlsym(c->handle,
+                                                      "libcheck_repair");
+       errstr = dlerror();
+       if (errstr != NULL)
+               condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!c->repair)
+               goto out;
+
        c->fd = 0;
        c->sync = 1;
        list_add(&c->node, &checkers);
@@ -203,6 +211,20 @@ void checker_put (struct checker * dst)
        free_checker(src);
 }
 
+void checker_repair (struct checker * c)
+{
+       if (!c || !checker_selected(c))
+               return;
+
+       c->message[0] = '\0';
+       if (c->disable) {
+               MSG(c, "checker disabled");
+               return;
+       }
+
+       c->repair(c);
+}
+
 int checker_check (struct checker * c)
 {
        int r;
@@ -272,6 +294,7 @@ void checker_get (char *multipath_dir, struct checker * dst, char * name)
        dst->sync = src->sync;
        strncpy(dst->name, src->name, CHECKER_NAME_LEN);
        strncpy(dst->message, src->message, CHECKER_MSG_LEN);
+       dst->repair = src->repair;
        dst->check = src->check;
        dst->init = src->init;
        dst->free = src->free;
index ac382d79066aea760369630e14d5bf5dcdfd9187..4fb97c98a8b02fc2b36c8ba26556ea685c429725 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "list.h"
 #include "memory.h"
+#include "defaults.h"
 
 /*
  *
@@ -84,8 +85,7 @@ enum path_check_state {
 #define EMC_CLARIION "emc_clariion"
 #define READSECTOR0  "readsector0"
 #define CCISS_TUR    "cciss_tur"
-
-#define DEFAULT_CHECKER TUR
+#define RBD          "rbd"
 
 #define ASYNC_TIMEOUT_SEC      30
 
@@ -112,6 +112,9 @@ struct checker {
                                                multipath-wide. Use MALLOC if
                                                you want to stuff data in. */
        int (*check)(struct checker *);
+       void (*repair)(struct checker *);     /* called if check returns
+                                               PATH_DOWN to bring path into
+                                               usable state */
        int (*init)(struct checker *);       /* to allocate the context */
        void (*free)(struct checker *);      /* to free the context */
 };
@@ -131,6 +134,7 @@ void checker_set_async (struct checker *);
 void checker_set_fd (struct checker *, int);
 void checker_enable (struct checker *);
 void checker_disable (struct checker *);
+void checker_repair (struct checker *);
 int checker_check (struct checker *);
 int checker_selected (struct checker *);
 char * checker_name (struct checker *);
index fb8fff091105bd23a658c35d6d81d766828a4c1f..11ab76f69865b166012534408317f729d37f14b2 100644 (file)
@@ -1,9 +1,11 @@
-# Makefile
 #
 # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
 include ../../Makefile.inc
 
+CFLAGS += -I..
+
+# If you add or remove a checker also update multipath/multipath.conf.5
 LIBS= \
        libcheckcciss_tur.so \
        libcheckreadsector0.so \
@@ -11,12 +13,14 @@ LIBS= \
        libcheckdirectio.so \
        libcheckemc_clariion.so \
        libcheckhp_sw.so \
-       libcheckrdac.so
-
-CFLAGS += -I..
+       libcheckrdac.so \
+       libcheckrbd.so
 
 all: $(LIBS)
 
+libcheckrbd.so: rbd.o
+       $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lrados -ludev
+
 libcheckdirectio.so: libsg.o directio.o
        $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio
 
index c9fa84a1eb13b26f1b25ff02d8ec6eff1bc78956..cf2094656f91b419fc10962918265bf29a48f11f 100644 (file)
 
 //Command List Structure
 typedef union _SCSI3Addr_struct {
-   struct {
-    BYTE Dev;
-    BYTE Bus:6;
-    BYTE Mode:2;        // b00
-  } PeripDev;
-   struct {
-    BYTE DevLSB;
-    BYTE DevMSB:6;
-    BYTE Mode:2;        // b01
-  } LogDev;
-   struct {
-    BYTE Dev:5;
-    BYTE Bus:3;
-    BYTE Targ:6;
-    BYTE Mode:2;        // b10
-  } LogUnit;
+       struct {
+               BYTE Dev;
+               BYTE Bus:6;
+               BYTE Mode:2;        // b00
+       } PeripDev;
+       struct {
+               BYTE DevLSB;
+               BYTE DevMSB:6;
+               BYTE Mode:2;        // b01
+       } LogDev;
+       struct {
+               BYTE Dev:5;
+               BYTE Bus:3;
+               BYTE Targ:6;
+               BYTE Mode:2;        // b10
+       } LogUnit;
 } SCSI3Addr_struct;
 
 typedef struct _PhysDevAddr_struct {
-  DWORD             TargetId:24;
-  DWORD             Bus:6;
-  DWORD             Mode:2;
-  SCSI3Addr_struct  Target[2]; //2 level target device addr
+       DWORD             TargetId:24;
+       DWORD             Bus:6;
+       DWORD             Mode:2;
+       SCSI3Addr_struct  Target[2]; //2 level target device addr
 } PhysDevAddr_struct;
 
 typedef struct _LogDevAddr_struct {
-  DWORD            VolId:30;
-  DWORD            Mode:2;
-  BYTE             reserved[4];
+       DWORD            VolId:30;
+       DWORD            Mode:2;
+       BYTE             reserved[4];
 } LogDevAddr_struct;
 
 typedef union _LUNAddr_struct {
-  BYTE               LunAddrBytes[8];
-  SCSI3Addr_struct   SCSI3Lun[4];
-  PhysDevAddr_struct PhysDev;
-  LogDevAddr_struct  LogDev;
+       BYTE               LunAddrBytes[8];
+       SCSI3Addr_struct   SCSI3Lun[4];
+       PhysDevAddr_struct PhysDev;
+       LogDevAddr_struct  LogDev;
 } LUNAddr_struct;
 
 typedef struct _RequestBlock_struct {
-  BYTE   CDBLen;
-  struct {
-    BYTE Type:3;
-    BYTE Attribute:3;
-    BYTE Direction:2;
-  } Type;
-  HWORD  Timeout;
-  BYTE   CDB[16];
+       BYTE   CDBLen;
+       struct {
+               BYTE Type:3;
+               BYTE Attribute:3;
+               BYTE Direction:2;
+       } Type;
+       HWORD  Timeout;
+       BYTE   CDB[16];
 } RequestBlock_struct;
 
 typedef union _MoreErrInfo_struct{
-  struct {
-    BYTE  Reserved[3];
-    BYTE  Type;
-    DWORD ErrorInfo;
-  }Common_Info;
-  struct{
-    BYTE  Reserved[2];
-    BYTE  offense_size;//size of offending entry
-    BYTE  offense_num; //byte # of offense 0-base
-    DWORD offense_value;
-  }Invalid_Cmd;
-}MoreErrInfo_struct;
+       struct {
+               BYTE  Reserved[3];
+               BYTE  Type;
+               DWORD ErrorInfo;
+       } Common_Info;
+       struct{
+               BYTE  Reserved[2];
+               BYTE  offense_size;//size of offending entry
+               BYTE  offense_num; //byte # of offense 0-base
+               DWORD offense_value;
+       } Invalid_Cmd;
+} MoreErrInfo_struct;
 
 typedef struct _ErrorInfo_struct {
-  BYTE               ScsiStatus;
-  BYTE               SenseLen;
-  HWORD              CommandStatus;
-  DWORD              ResidualCnt;
-  MoreErrInfo_struct MoreErrInfo;
-  BYTE               SenseInfo[SENSEINFOBYTES];
+       BYTE               ScsiStatus;
+       BYTE               SenseLen;
+       HWORD              CommandStatus;
+       DWORD              ResidualCnt;
+       MoreErrInfo_struct MoreErrInfo;
+       BYTE               SenseInfo[SENSEINFOBYTES];
 } ErrorInfo_struct;
 
 #pragma pack()
index 81500dc70d47fe1a1adb2840a3dd6db6b0117b66..a0ffffeb07905a07361c3a6323e59740f075ebbe 100644 (file)
@@ -59,6 +59,11 @@ void libcheck_free (struct checker * c)
        return;
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 extern int
 libcheck_check (struct checker * c)
 {
index 94bf8f7fd5f02dd924bb56ea1ae97e389c9540c3..eec12d5cf493c41b47397d307d9dbb7b8a344ef6 100644 (file)
@@ -118,6 +118,11 @@ void libcheck_free (struct checker * c)
        free(ct);
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 static int
 check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
 {
index 5e416a0d420919634fb981287263e8a422efc9ba..a7b9f8601e9b967194562c85a7440cb9d4c504df 100644 (file)
@@ -91,6 +91,11 @@ void libcheck_free (struct checker * c)
        free(c->context);
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 int libcheck_check (struct checker * c)
 {
        unsigned char sense_buffer[128] = { 0, };
index fe5e0f9e8c97ce5c7520e1aa763eceb8fa6178c7..0cc11115b48609a462b5da6c9978ebc9c5d2d61a 100644 (file)
@@ -44,6 +44,11 @@ void libcheck_free (struct checker * c)
        return;
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 static int
 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
        void *resp, int mx_resp_len, int noisy, unsigned int timeout)
diff --git a/libmultipath/checkers/rbd.c b/libmultipath/checkers/rbd.c
new file mode 100644 (file)
index 0000000..6f1b53a
--- /dev/null
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2016 Red Hat
+ * Copyright (c) 2004 Christophe Varoqui
+ *
+ * Code based off of tur.c and ceph's krbd.cc
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread.h>
+#include <libudev.h>
+#include <ifaddrs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include "rados/librados.h"
+
+#include "structs.h"
+#include "checkers.h"
+
+#include "../libmultipath/debug.h"
+#include "../libmultipath/uevent.h"
+
+struct rbd_checker_context;
+typedef int (thread_fn)(struct rbd_checker_context *ct, char *msg);
+
+#define RBD_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
+
+struct rbd_checker_context {
+       int rbd_bus_id;
+       char *client_addr;
+       char *config_info;
+       char *snap;
+       char *pool;
+       char *image;
+       char *username;
+       int remapped;
+       int blacklisted;
+
+       rados_t cluster;
+
+       int state;
+       int running;
+       time_t time;
+       thread_fn *fn;
+       pthread_t thread;
+       pthread_mutex_t lock;
+       pthread_cond_t active;
+       pthread_spinlock_t hldr_lock;
+       int holders;
+       char message[CHECKER_MSG_LEN];
+};
+
+int libcheck_init(struct checker * c)
+{
+       struct rbd_checker_context *ct;
+       struct udev_device *block_dev;
+       struct udev_device *bus_dev;
+       struct udev *udev;
+       struct stat sb;
+       const char *block_name, *addr, *config_info;
+       const char *image, *pool, *snap, *username;
+       char sysfs_path[PATH_SIZE];
+       int ret;
+
+       ct = malloc(sizeof(struct rbd_checker_context));
+       if (!ct)
+               return 1;
+       memset(ct, 0, sizeof(struct rbd_checker_context));
+       ct->holders = 1;
+       pthread_cond_init(&ct->active, NULL);
+       pthread_mutex_init(&ct->lock, NULL);
+       pthread_spin_init(&ct->hldr_lock, PTHREAD_PROCESS_PRIVATE);
+       c->context = ct;
+
+       /*
+        * The rbd block layer sysfs device is not linked to the rbd bus
+        * device that we interact with, so figure that out now.
+        */
+       if (fstat(c->fd, &sb) != 0)
+               goto free_ct;
+
+       udev = udev_new();
+       if (!udev)
+               goto free_ct;
+
+       block_dev = udev_device_new_from_devnum(udev, 'b', sb.st_rdev);
+       if (!block_dev)
+               goto free_udev;
+
+       block_name  = udev_device_get_sysname(block_dev);
+       ret = sscanf(block_name, "rbd%d", &ct->rbd_bus_id);
+
+       udev_device_unref(block_dev);
+       if (ret != 1)
+               goto free_udev;
+
+       snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d",
+                ct->rbd_bus_id);
+       bus_dev = udev_device_new_from_syspath(udev, sysfs_path);
+       if (!bus_dev)
+               goto free_udev;
+
+       addr = udev_device_get_sysattr_value(bus_dev, "client_addr");
+       if (!addr) {
+               condlog(0, "Could not find client_addr in rbd sysfs. Try "
+                       "updating kernel");
+               goto free_dev;
+       }
+
+       ct->client_addr = strdup(addr);
+       if (!ct->client_addr)
+               goto free_dev;
+
+       config_info = udev_device_get_sysattr_value(bus_dev, "config_info");
+       if (!config_info)
+               goto free_addr;
+
+       ct->config_info = strdup(config_info);
+       if (!ct->config_info)
+               goto free_addr;
+
+       username = strstr(config_info, "name=");
+       if (username) {
+               char *end;
+               int len;
+
+               username += 5;
+               end = strchr(username, ',');
+               if (!end)
+                       goto free_info;
+               len = end - username;
+
+               ct->username = malloc(len + 1);
+               if (!ct->username)
+                       goto free_info;
+               strncpy(ct->username, username, len);
+               ct->username[len] = '\0';
+       }
+
+       image = udev_device_get_sysattr_value(bus_dev, "name");
+       if (!image)
+               goto free_username;
+
+       ct->image = strdup(image);
+       if (!ct->image)
+               goto free_info;
+
+       pool = udev_device_get_sysattr_value(bus_dev, "pool");
+       if (!pool)
+               goto free_image;
+
+       ct->pool = strdup(pool);
+       if (!ct->pool)
+               goto free_image;
+
+       snap = udev_device_get_sysattr_value(bus_dev, "current_snap");
+       if (!snap)
+               goto free_pool;
+
+       if (strcmp("-", snap)) {
+               ct->snap = strdup(snap);
+               if (!ct->snap)
+                       goto free_pool;
+       }
+
+       if (rados_create(&ct->cluster, NULL) < 0) {
+               condlog(0, "Could not create rados cluster");
+               goto free_snap;
+       }
+
+       if (rados_conf_read_file(ct->cluster, NULL) < 0) {
+               condlog(0, "Could not read rados conf");
+               goto shutdown_rados;
+       }
+
+       ret = rados_connect(ct->cluster);
+       if (ret < 0) {
+               condlog(0, "Could not connect to rados cluster");
+               goto shutdown_rados;
+       }
+
+       udev_device_unref(bus_dev);
+       udev_unref(udev);
+
+       condlog(3, "rbd%d checker init %s %s/%s@%s %s", ct->rbd_bus_id,
+               ct->client_addr, ct->pool, ct->image, ct->snap ? ct->snap : "-",
+               ct->username ? ct->username : "none");
+       return 0;
+
+shutdown_rados:
+       rados_shutdown(ct->cluster);
+free_snap:
+       if (ct->snap)
+               free(ct->snap);
+free_pool:
+       free(ct->pool);
+free_image:
+       free(ct->image);
+free_username:
+       if (ct->username)
+               free(ct->username);
+free_info:
+       free(ct->config_info);
+free_addr:
+       free(ct->client_addr);
+free_dev:
+       udev_device_unref(bus_dev);
+free_udev:
+       udev_unref(udev);
+free_ct:
+       free(ct);
+       return 1;
+}
+
+void cleanup_context(struct rbd_checker_context *ct)
+{
+       pthread_mutex_destroy(&ct->lock);
+       pthread_cond_destroy(&ct->active);
+       pthread_spin_destroy(&ct->hldr_lock);
+
+       rados_shutdown(ct->cluster);
+
+       if (ct->username)
+               free(ct->username);
+       if (ct->snap)
+               free(ct->snap);
+       free(ct->pool);
+       free(ct->image);
+       free(ct->config_info);
+       free(ct->client_addr);
+       free(ct);
+}
+
+void libcheck_free(struct checker * c)
+{
+       if (c->context) {
+               struct rbd_checker_context *ct = c->context;
+               int holders;
+               pthread_t thread;
+
+               pthread_spin_lock(&ct->hldr_lock);
+               ct->holders--;
+               holders = ct->holders;
+               thread = ct->thread;
+               pthread_spin_unlock(&ct->hldr_lock);
+               if (holders)
+                       pthread_cancel(thread);
+               else
+                       cleanup_context(ct);
+               c->context = NULL;
+       }
+}
+
+static int rbd_is_blacklisted(struct rbd_checker_context *ct, char *msg)
+{
+       char *addr_tok, *start, *save;
+       char *cmd[2];
+       char *blklist, *stat;
+       size_t blklist_len, stat_len;
+       int ret;
+       char *end;
+
+       cmd[0] = "{\"prefix\": \"osd blacklist ls\"}";
+       cmd[1] = NULL;
+
+       ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0,
+                               &blklist, &blklist_len, &stat, &stat_len);
+       if (ret < 0) {
+               RBD_MSG(msg, "rbd checker failed: mon command failed %d",
+                       ret);
+               return ret;
+       }
+
+       if (!blklist || !blklist_len)
+               goto free_bufs;
+
+       /*
+        * parse list of addrs with the format
+        * ipv4:port/nonce date time\n
+        * or
+        * [ipv6]:port/nonce date time\n
+        */
+       ret = 0;
+       for (start = blklist; ; start = NULL) {
+               addr_tok = strtok_r(start, "\n", &save);
+               if (!addr_tok || !strlen(addr_tok))
+                       break;
+
+               end = strchr(addr_tok, ' ');
+               if (!end) {
+                       RBD_MSG(msg, "rbd%d checker failed: invalid blacklist %s",
+                                ct->rbd_bus_id, addr_tok);
+                       break;
+               }
+               *end = '\0';
+
+               if (!strcmp(addr_tok, ct->client_addr)) {
+                       ct->blacklisted = 1;
+                       RBD_MSG(msg, "rbd%d checker: %s is blacklisted",
+                               ct->rbd_bus_id, ct->client_addr);
+                       ret = 1;
+                       break;
+               }
+       }
+
+free_bufs:
+       rados_buffer_free(blklist);
+       rados_buffer_free(stat);
+       return ret;
+}
+
+int rbd_check(struct rbd_checker_context *ct, char *msg)
+{
+       if (ct->blacklisted || rbd_is_blacklisted(ct, msg) == 1)
+               return PATH_DOWN;
+
+       RBD_MSG(msg, "rbd checker reports path is up");
+       /*
+        * Path may have issues, but the ceph cluster is at least
+        * accepting IO, so we can attempt to do IO.
+        *
+        * TODO: in future versions, we can run other tests to
+        * verify OSDs and networks.
+        */
+       return PATH_UP;
+}
+
+int safe_write(int fd, const void *buf, size_t count)
+{
+       while (count > 0) {
+               ssize_t r = write(fd, buf, count);
+               if (r < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       return -errno;
+               }
+               count -= r;
+               buf = (char *)buf + r;
+       }
+       return 0;
+}
+
+static int sysfs_write_rbd_bus(const char *which, const char *buf,
+                              size_t buf_len)
+{
+       char sysfs_path[PATH_SIZE];
+       int fd;
+       int r;
+
+       /* we require newer kernels so single_major should alwayws be there */
+       snprintf(sysfs_path, sizeof(sysfs_path),
+                "/sys/bus/rbd/%s_single_major", which);
+       fd = open(sysfs_path, O_WRONLY);
+       if (fd < 0)
+               return -errno;
+
+       r = safe_write(fd, buf, buf_len);
+       close(fd);
+       return r;
+}
+
+static int rbd_remap(struct rbd_checker_context *ct)
+{
+       char *argv[11];
+       pid_t pid;
+       int ret = 0, i = 0;
+       int status;
+
+       pid = fork();
+       switch (pid) {
+       case 0:
+               argv[i++] = "rbd";
+               argv[i++] = "map";
+               argv[i++] = "-o noshare";
+               if (ct->username) {
+                       argv[i++] = "--id";
+                       argv[i++] = ct->username;
+               }
+               argv[i++] = "--pool";
+               argv[i++] = ct->pool;
+               if (ct->snap) {
+                       argv[i++] = "--snap";
+                       argv[i++] = ct->snap;
+               }
+               argv[i++] = ct->image;
+               argv[i] = NULL;
+
+               ret = execvp(argv[0], argv);
+               condlog(0, "Error executing rbd: %s", strerror(errno));
+               exit(-1);
+       case -1:
+               condlog(0, "fork failed: %s", strerror(errno));
+               return -1;
+       default:
+               ret = -1;
+               wait(&status);
+               if (WIFEXITED(status)) {
+                       status = WEXITSTATUS(status);
+                       if (status == 0)
+                               ret = 0;
+                       else
+                               condlog(0, "rbd failed with %d", status);
+               }
+       }
+
+       return ret;
+}
+
+static int sysfs_write_rbd_remove(const char *buf, int buf_len)
+{
+       return sysfs_write_rbd_bus("remove", buf, buf_len);
+}
+
+static int rbd_rm_blacklist(struct rbd_checker_context *ct)
+{
+       char *cmd[2];
+       char *stat, *cmd_str;
+       size_t stat_len;
+       int ret;
+
+       ret = asprintf(&cmd_str, "{\"prefix\": \"osd blacklist\", \"blacklistop\": \"rm\", \"addr\": \"%s\"}",
+                      ct->client_addr);
+       if (ret == -1)
+               return -ENOMEM;
+
+       cmd[0] = cmd_str;
+       cmd[1] = NULL;
+
+       ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0,
+                               NULL, 0, &stat, &stat_len);
+       if (ret < 0) {
+               condlog(1, "rbd%d repair failed to remove blacklist for %s %d",
+                       ct->rbd_bus_id, ct->client_addr, ret);
+               goto free_cmd;
+       }
+
+       condlog(1, "rbd%d repair rm blacklist for %s",
+              ct->rbd_bus_id, ct->client_addr);
+       free(stat);
+free_cmd:
+       free(cmd_str);
+       return ret;
+}
+
+static int rbd_repair(struct rbd_checker_context *ct, char *msg)
+{
+       char del[17];
+       int ret;
+
+       if (!ct->blacklisted)
+               return PATH_UP;
+
+       if (!ct->remapped) {
+               ret = rbd_remap(ct);
+               if (ret) {
+                       RBD_MSG(msg, "rbd%d repair failed to remap. Err %d",
+                               ct->rbd_bus_id, ret);
+                       return PATH_DOWN;
+               }
+       }
+       ct->remapped = 1;
+
+       snprintf(del, sizeof(del), "%d force", ct->rbd_bus_id);
+       ret = sysfs_write_rbd_remove(del, strlen(del) + 1);
+       if (ret) {
+               RBD_MSG(msg, "rbd%d repair failed to clean up. Err %d",
+                       ct->rbd_bus_id, ret);
+               return PATH_DOWN;
+       }
+
+       ret = rbd_rm_blacklist(ct);
+       if (ret) {
+               RBD_MSG(msg, "rbd%d repair could not remove blacklist entry. Err %d",
+                       ct->rbd_bus_id, ret);
+               return PATH_DOWN;
+       }
+
+       ct->remapped = 0;
+       ct->blacklisted = 0;
+
+       RBD_MSG(msg, "rbd%d has been repaired", ct->rbd_bus_id);
+       return PATH_UP;
+}
+
+#define rbd_thread_cleanup_push(ct) pthread_cleanup_push(cleanup_func, ct)
+#define rbd_thread_cleanup_pop(ct) pthread_cleanup_pop(1)
+
+void cleanup_func(void *data)
+{
+       int holders;
+       struct rbd_checker_context *ct = data;
+       pthread_spin_lock(&ct->hldr_lock);
+       ct->holders--;
+       holders = ct->holders;
+       ct->thread = 0;
+       pthread_spin_unlock(&ct->hldr_lock);
+       if (!holders)
+               cleanup_context(ct);
+}
+
+void *rbd_thread(void *ctx)
+{
+       struct rbd_checker_context *ct = ctx;
+       int state;
+
+       condlog(3, "rbd%d thread starting up", ct->rbd_bus_id);
+
+       ct->message[0] = '\0';
+       /* This thread can be canceled, so setup clean up */
+       rbd_thread_cleanup_push(ct)
+
+       /* checker start up */
+       pthread_mutex_lock(&ct->lock);
+       ct->state = PATH_PENDING;
+       pthread_mutex_unlock(&ct->lock);
+
+       state = ct->fn(ct, ct->message);
+
+       /* checker done */
+       pthread_mutex_lock(&ct->lock);
+       ct->state = state;
+       pthread_mutex_unlock(&ct->lock);
+       pthread_cond_signal(&ct->active);
+
+       condlog(3, "rbd%d thead finished, state %s", ct->rbd_bus_id,
+               checker_state_name(state));
+       rbd_thread_cleanup_pop(ct);
+       return ((void *)0);
+}
+
+static void rbd_timeout(struct timespec *tsp)
+{
+       struct timeval now;
+
+       gettimeofday(&now, NULL);
+       tsp->tv_sec = now.tv_sec;
+       tsp->tv_nsec = now.tv_usec * 1000;
+       tsp->tv_nsec += 1000000; /* 1 millisecond */
+}
+
+static int rbd_exec_fn(struct checker *c, thread_fn *fn)
+{
+       struct rbd_checker_context *ct = c->context;
+       struct timespec tsp;
+       pthread_attr_t attr;
+       int rbd_status, r;
+
+       if (c->sync)
+               return rbd_check(ct, c->message);
+       /*
+        * Async mode
+        */
+       r = pthread_mutex_lock(&ct->lock);
+       if (r != 0) {
+               condlog(2, "rbd%d mutex lock failed with %d", ct->rbd_bus_id,
+                       r);
+               MSG(c, "rbd%d thread failed to initialize", ct->rbd_bus_id);
+               return PATH_WILD;
+       }
+
+       if (ct->running) {
+               /* Check if checker is still running */
+               if (ct->thread) {
+                       condlog(3, "rbd%d thread not finished", ct->rbd_bus_id);
+                       rbd_status = PATH_PENDING;
+               } else {
+                       /* checker done */
+                       ct->running = 0;
+                       rbd_status = ct->state;
+                       strncpy(c->message, ct->message, CHECKER_MSG_LEN);
+                       c->message[CHECKER_MSG_LEN - 1] = '\0';
+               }
+               pthread_mutex_unlock(&ct->lock);
+       } else {
+               /* Start new checker */
+               ct->state = PATH_UNCHECKED;
+               ct->fn = fn;
+               pthread_spin_lock(&ct->hldr_lock);
+               ct->holders++;
+               pthread_spin_unlock(&ct->hldr_lock);
+               setup_thread_attr(&attr, 32 * 1024, 1);
+               r = pthread_create(&ct->thread, &attr, rbd_thread, ct);
+               if (r) {
+                       pthread_mutex_unlock(&ct->lock);
+                       ct->thread = 0;
+                       ct->holders--;
+                       condlog(3, "rbd%d failed to start rbd thread, using sync mode",
+                               ct->rbd_bus_id);
+                       return fn(ct, c->message);
+               }
+               pthread_attr_destroy(&attr);
+               rbd_timeout(&tsp);
+               r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp);
+               rbd_status = ct->state;
+               strncpy(c->message, ct->message,CHECKER_MSG_LEN);
+               c->message[CHECKER_MSG_LEN -1] = '\0';
+               pthread_mutex_unlock(&ct->lock);
+
+               if (ct->thread &&
+                   (rbd_status == PATH_PENDING || rbd_status == PATH_UNCHECKED)) {
+                       condlog(3, "rbd%d thread still running",
+                               ct->rbd_bus_id);
+                       ct->running = 1;
+                       rbd_status = PATH_PENDING;
+               }
+       }
+
+       return rbd_status;
+}
+
+void libcheck_repair(struct checker * c)
+{
+       struct rbd_checker_context *ct = c->context;
+
+       if (!ct || !ct->blacklisted)
+               return;
+       rbd_exec_fn(c, rbd_repair);
+}
+
+int libcheck_check(struct checker * c)
+{
+       struct rbd_checker_context *ct = c->context;
+
+       if (!ct)
+               return PATH_UNCHECKED;
+
+       if (ct->blacklisted)
+               return PATH_DOWN;
+
+       return rbd_exec_fn(c, rbd_check);
+}
index 00e3c44cabb2838cab0a05958796b44192066ecb..68682c816ef1bcfeff1715e3af9debaedd9452f6 100644 (file)
@@ -139,6 +139,11 @@ void libcheck_free (struct checker * c)
        return;
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 static int
 do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len,
        unsigned int timeout)
index 1c2a868e842cc87ddde499bd576ac964c4e8f529..8fccb46a5bf3a683cd131d5f9c941ac9437b74ed 100644 (file)
@@ -23,6 +23,11 @@ void libcheck_free (struct checker * c)
        return;
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 int libcheck_check (struct checker * c)
 {
        unsigned char buf[4096];
index 2edc8ad4685ee56753f62c21d43fb907dfa63d67..c2ff5e9313035a9b3bc585ce9b6e7ecc583d1b97 100644 (file)
@@ -97,6 +97,11 @@ void libcheck_free (struct checker * c)
        return;
 }
 
+void libcheck_repair (struct checker * c)
+{
+       return;
+}
+
 #define TUR_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
 
 int
@@ -107,7 +112,7 @@ tur_check(int fd, unsigned int timeout, char *msg)
        unsigned char sense_buffer[32];
        int retry_tur = 5;
 
- retry:
+retry:
        memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
        memset(&sense_buffer, 0, 32);
        io_hdr.interface_id = 'S';
@@ -345,7 +350,7 @@ libcheck_check (struct checker * c)
                r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp);
                tur_status = ct->state;
                strncpy(c->message, ct->message,CHECKER_MSG_LEN);
-               c->message[CHECKER_MSG_LEN -1] = '\0';
+               c->message[CHECKER_MSG_LEN - 1] = '\0';
                pthread_mutex_unlock(&ct->lock);
                if (ct->thread &&
                    (tur_status == PATH_PENDING || tur_status == PATH_UNCHECKED)) {
index 9de5914aec8839630409c7d920a865cc911107e9..9bf27d658b62121875386646f5c414585484d597 100644 (file)
@@ -1,3 +1,7 @@
+/*
+ * If you add or modify a value also update multipath/multipath.conf.5
+ * and the TEMPLATE in libmultipath/hwtable.c
+ */
 #define DEFAULT_UID_ATTRIBUTE  "ID_SERIAL"
 #define DEFAULT_UDEVDIR                "/dev"
 #define DEFAULT_MULTIPATHDIR   "/" LIB_STRING "/multipath"
@@ -7,8 +11,8 @@
 #define DEFAULT_HWHANDLER      "0"
 #define DEFAULT_MINIO          1000
 #define DEFAULT_MINIO_RQ       1
-#define DEFAULT_PGPOLICY       GROUP_BY_PRIO
-#define DEFAULT_FAILBACK       -FAILBACK_IMMEDIATE
+#define DEFAULT_PGPOLICY       FAILOVER
+#define DEFAULT_FAILBACK       -FAILBACK_MANUAL
 #define DEFAULT_RR_WEIGHT      RR_WEIGHT_NONE
 #define DEFAULT_NO_PATH_RETRY  NO_PATH_RETRY_UNDEF
 #define DEFAULT_VERBOSITY      2
@@ -24,6 +28,9 @@
 #define DEFAULT_RETRIGGER_DELAY        10
 #define DEFAULT_RETRIGGER_TRIES        3
 #define DEFAULT_UEV_WAIT_TIMEOUT 30
+#define DEFAULT_PRIO           "const"
+#define DEFAULT_PRIO_ARGS      ""
+#define DEFAULT_CHECKER                TUR
 
 #define DEFAULT_CHECKINT       5
 #define MAX_CHECKINT(a)                (a << 2)
index 2c76d8b893fbc36ec4671c55df5d40441d1ffdf8..5eb1713b609ff54f22154fed6a2f874030f3d770 100644 (file)
@@ -243,7 +243,7 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t
 
        if (udev_wait_flag)
                        dm_udev_wait(cookie);
-       out:
+out:
        dm_task_destroy (dmt);
        return r;
 }
@@ -327,11 +327,11 @@ dm_addmap (int task, const char *target, struct multipath *mpp,
 
        if (task == DM_DEVICE_CREATE)
                        dm_udev_wait(cookie);
-       freeout:
+freeout:
        if (prefixed_uuid)
                FREE(prefixed_uuid);
 
-       addout:
+addout:
        dm_task_destroy (dmt);
 
        return r;
@@ -664,7 +664,7 @@ dm_dev_t (const char * mapname, char * dev_t, int len)
                goto out;
 
        if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
-                   goto out;
+               goto out;
 
        r = 0;
 out:
@@ -891,7 +891,7 @@ dm_flush_maps (void)
                names = (void *) names + next;
        } while (next);
 
-       out:
+out:
        dm_task_destroy (dmt);
        return r;
 }
index 4bc3b111b5c593e6460088f209c2a42bb7b8877e..442d42ef91ecb11253d3e00efa4a44f596cf5f40 100644 (file)
@@ -52,9 +52,9 @@ int dm_reassign_table(const char *name, char *old, char *new);
 int dm_setgeometry(struct multipath *mpp);
 
 #define VERSION_GE(v, minv) ( \
- (v[0] > minv[0]) || \
- ((v[0] == minv[0]) && (v[1] > minv[1])) || \
- ((v[0] == minv[0]) && (v[1] == minv[1]) && (v[2] >= minv[2])) \
      (v[0] > minv[0]) || \
      ((v[0] == minv[0]) && (v[1] > minv[1])) || \
      ((v[0] == minv[0]) && (v[1] == minv[1]) && (v[2] >= minv[2])) \
 )
 
 #endif /* _DEVMAPPER_H */
index 1933b6ddf9a5cf06e4d5fd3de4d7aac2fc961098..e8c6804f3cf60d5f98cb043fa7f4b91ac2bdce39 100644 (file)
@@ -1329,6 +1329,9 @@ snprint_deprecated (struct config *conf, char * buff, int len, void * data)
 
 #define __deprecated
 
+/*
+ * If you add or remove a keywork also update multipath/multipath.conf.5
+ */
 void
 init_keywords(vector keywords)
 {
index 1fb4db4821fe142448667e43e760d3ee9848a574..bb3116d22bf82819906d0ecf03355bd38eb76148 100644 (file)
@@ -491,7 +491,7 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen)
 {
        struct udev_device *parent = pp->udev;
        char value[16], *eptr;
-       unsigned int preferred;
+       unsigned long preferred;
 
        while (parent) {
                const char *subsys = udev_device_get_subsystem(parent);
@@ -1169,6 +1169,21 @@ scsi_sysfs_pathinfo (struct path * pp, vector hwtable)
        return 0;
 }
 
+static int
+rbd_sysfs_pathinfo (struct path * pp, vector hwtable)
+{
+       sprintf(pp->vendor_id, "Ceph");
+       sprintf(pp->product_id, "RBD");
+
+       condlog(3, "%s: vendor = %s product = %s", pp->dev, pp->vendor_id,
+               pp->product_id);
+       /*
+        * set the hwe configlet pointer
+        */
+       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
+       return 0;
+}
+
 static int
 ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
 {
@@ -1371,6 +1386,8 @@ sysfs_pathinfo(struct path * pp, vector hwtable)
                pp->bus = SYSFS_BUS_CCW;
        if (!strncmp(pp->dev,"sd", 2))
                pp->bus = SYSFS_BUS_SCSI;
+       if (!strncmp(pp->dev,"rbd", 3))
+               pp->bus = SYSFS_BUS_RBD;
 
        if (pp->bus == SYSFS_BUS_UNDEF)
                return 0;
@@ -1383,6 +1400,9 @@ sysfs_pathinfo(struct path * pp, vector hwtable)
        } else if (pp->bus == SYSFS_BUS_CCISS) {
                if (cciss_sysfs_pathinfo(pp, hwtable))
                        return 1;
+       } else if (pp->bus == SYSFS_BUS_RBD) {
+               if (rbd_sysfs_pathinfo(pp, hwtable))
+                       return 1;
        }
        return 0;
 }
@@ -1415,10 +1435,14 @@ scsi_ioctl_pathinfo (struct path * pp, int mask)
        if (!attr_path || pp->sg_id.host_no == -1)
                return 0;
 
-       if (get_vpd_sysfs(parent, 0x80, pp->serial, SERIAL_SIZE) > 0)
-               condlog(3, "%s: serial = %s",
-                       pp->dev, pp->serial);
+       if (get_vpd_sysfs(parent, 0x80, pp->serial, SERIAL_SIZE) <= 0) {
+               if (get_serial(pp->serial, SERIAL_SIZE, pp->fd)) {
+                       condlog(2, "%s: fail to get serial", pp->dev);
+                       return 0;
+               }
+       }
 
+       condlog(3, "%s: serial = %s", pp->dev, pp->serial);
        return 0;
 }
 
@@ -1539,6 +1563,53 @@ get_udev_uid(struct path * pp, char *uid_attribute)
        return len;
 }
 
+static int
+get_rbd_uid(struct path * pp)
+{
+       struct udev_device *rbd_bus_dev;
+       int ret, rbd_bus_id;
+       const char *pool, *image, *snap;
+       char sysfs_path[PATH_SIZE];
+       uint64_t snap_id, max_snap_id = -3;
+
+       ret = sscanf(pp->dev, "rbd%d", &rbd_bus_id);
+       if (ret != 1)
+               return -EINVAL;
+
+       snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d",
+                rbd_bus_id);
+       rbd_bus_dev = udev_device_new_from_syspath(udev, sysfs_path);
+       if (!rbd_bus_dev)
+               return -ENODEV;
+
+       ret = -EINVAL;
+       pool = udev_device_get_sysattr_value(rbd_bus_dev, "pool_id");
+       if (!pool)
+               goto free_dev;
+
+       image = udev_device_get_sysattr_value(rbd_bus_dev, "image_id");
+       if (!image)
+               goto free_dev;
+
+       snap = udev_device_get_sysattr_value(rbd_bus_dev, "snap_id");
+       if (!snap)
+               goto free_dev;
+       snap_id = strtoull(snap, NULL, 19);
+       if (snap_id >= max_snap_id)
+               ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s", pool, image);
+       else
+               ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s-%s", pool,
+                              image, snap);
+       if (ret >= WWID_SIZE) {
+               condlog(0, "%s: wwid overflow", pp->dev);
+               ret = -EOVERFLOW;
+       }
+
+free_dev:
+       udev_device_unref(rbd_bus_dev);
+       return ret;
+}
+
 static int
 get_vpd_uid(struct path * pp)
 {
@@ -1591,6 +1662,9 @@ get_uid (struct path * pp, int path_state)
                } else
                        len = strlen(pp->wwid);
                origin = "callout";
+       } else if (pp->bus == SYSFS_BUS_RBD) {
+               len = get_rbd_uid(pp);
+               origin = "sysfs";
        } else {
                int retrigger;
 
index a1fc3e8d7a9a7604a547a0b8a979f6ee2b615108..e518d6a84595eb0f6e9f4bcfd71f8cb4d946e49b 100644 (file)
  * the kernel side. Currently at drivers/scsi/scsi_dh.c
  */
 static struct hwentry default_hw[] = {
-       /*
-        * Compellent Technologies/DELL
-        */
-       {
-               .vendor        = "COMPELNT",
-               .product       = "Compellent Vol",
-               .pgpolicy      = MULTIBUS,
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
-       },
        /*
         * Apple
         *
@@ -40,30 +31,36 @@ static struct hwentry default_hw[] = {
         * Mail : g.shyamsundar@yahoo.co.in
         */
        {
-               .vendor        = "APPLE.*",
+               .vendor        = "APPLE",
                .product       = "Xserve RAID",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
        /*
-        * StorageWorks/HPE
+        * HPE
         */
        {
                .vendor        = "3PARdata",
                .product       = "VV",
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .hwhandler     = "1 alua",
+               .prio_name     = PRIO_ALUA,
+               .no_path_retry = 18,
        },
        {
+               /* RA8000 / ESA12000 */
                .vendor        = "DEC",
                .product       = "HSG80",
                .features      = "1 queue_if_no_path",
                .hwhandler     = "1 hp_sw",
+               .pgpolicy      = GROUP_BY_PRIO,
                .pgfailback    = FAILBACK_UNDEF,
                .checker_name  = HP_SW,
                .prio_name     = PRIO_HP_SW,
        },
        {
+               /* VIRTUAL ARRAY 7400 */
                .vendor        = "HP",
                .product       = "A6189A",
                .pgpolicy      = MULTIBUS,
@@ -71,11 +68,12 @@ static struct hwentry default_hw[] = {
                .no_path_retry = 12,
        },
        {
-               /* MSA 1000/MSA1500 EVA 3000/5000 with old firmware */
+               /* MSA 1000/1500 and EVA 3000/5000, with old firmware */
                .vendor        = "(COMPAQ|HP)",
-               .product       = "(MSA|HSV)1.0.*",
+               .product       = "(MSA|HSV)1[01]0",
                .features      = "1 queue_if_no_path",
                .hwhandler     = "1 hp_sw",
+               .pgpolicy      = GROUP_BY_PRIO,
                .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = 12,
                .minio         = 100,
@@ -86,6 +84,8 @@ static struct hwentry default_hw[] = {
                /* MSA 1000/1500 with new firmware */
                .vendor        = "(COMPAQ|HP)",
                .product       = "MSA VOLUME",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 12,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
@@ -93,62 +93,73 @@ static struct hwentry default_hw[] = {
        {
                /* EVA 3000/5000 with new firmware, EVA 4000/6000/8000 */
                .vendor        = "(COMPAQ|HP)",
-               .product       = "HSV1[01]1|HSV2[01]0|HSV3[046]0|HSV4[05]0",
+               .product       = "(HSV1[01]1|HSV2[01]0|HSV3[046]0|HSV4[05]0)",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 12,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* HP MSA2000 family with old firmware */
+               /* MSA2000 family with old firmware */
                .vendor        = "HP",
-               .product       = "MSA2[02]12fc|MSA2012i",
+               .product       = "(MSA2[02]12fc|MSA2012i)",
                .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = 18,
                .minio         = 100,
        },
        {
-               /* HP MSA2000 family with new firmware */
+               /* MSA2000 family with new firmware */
                .vendor        = "HP",
-               .product       = "MSA2012sa|MSA23(12|24)(fc|i|sa)|MSA2000s VOLUME",
+               .product       = "(MSA2012sa|MSA23(12|24)(fc|i|sa)|MSA2000s VOLUME)",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 18,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* HP MSA 1040/2040 family */
+               /* MSA 1040/2040 family */
                .vendor        = "HP",
-               .product       = "MSA (1|2)040 SA(N|S)",
+               .product       = "MSA [12]040 SA[NS]",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 18,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* HP SVSP */
+               /* SAN Virtualization Services Platform */
                .vendor        = "HP",
                .product       = "HSVX700",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 12,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* HP Smart Array */
+               /* Smart Array */
                .vendor        = "HP",
-               .product       = "LOGICAL VOLUME.*",
+               .product       = "LOGICAL VOLUME",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = 12,
        },
        {
-               /* HP P2000 family */
+               /* P2000 family */
                .vendor        = "HP",
-               .product       = "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI",
+               .product       = "(P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI)",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 18,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        /*
-        * DDN
+        * DataDirect Networks
         */
        {
                .vendor        = "DDN",
@@ -157,12 +168,10 @@ static struct hwentry default_hw[] = {
                .pgfailback    = FAILBACK_UNDEF,
        },
        /*
-        * EMC/DELL
-        *
-        * Maintainer : Edward Goggin, EMC
-        * Mail : egoggin@emc.com
+        * EMC
         */
        {
+               /* Symmetrix / DMX / VMAX */
                .vendor        = "EMC",
                .product       = "SYMMETRIX",
                .pgpolicy      = MULTIBUS,
@@ -172,15 +181,18 @@ static struct hwentry default_hw[] = {
        {
                /* DGC CLARiiON CX/AX and EMC VNX */
                .vendor        = "^DGC",
-               .product       = "^RAID|^DISK|^VRAID",
+               .product       = "^(RAID|DISK|VRAID)",
                .bl_product    = "LUNZ",
                .features      = "1 queue_if_no_path",
                .hwhandler     = "1 emc",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = (300 / DEFAULT_CHECKINT),
                .checker_name  = EMC_CLARIION,
                .prio_name     = PRIO_EMC,
        },
        {
+               /* Invista / VPLEX */
                .vendor        = "EMC",
                .product       = "Invista",
                .bl_product    = "LUNZ",
@@ -195,6 +207,52 @@ static struct hwentry default_hw[] = {
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
+       /*
+        * DELL
+        */
+       {
+               .vendor        = "COMPELNT",
+               .product       = "Compellent Vol",
+               .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
+               .no_path_retry = NO_PATH_RETRY_QUEUE,
+       },
+       {
+               .vendor        = "DELL",
+               .product       = "MD3000",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
+       },
+       {
+               .vendor        = "DELL",
+               .product       = "(MD32xx|MD36xx)",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
+       },
+       {
+               .vendor        = "DELL",
+               .product       = "(MD34xx|MD38xx)",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
+       },
        /*
         * Fujitsu
         */
@@ -208,9 +266,18 @@ static struct hwentry default_hw[] = {
                .vendor        = "FUJITSU",
                .product       = "ETERNUS_DX(H|L|M|400|8000)",
                .features      = "1 queue_if_no_path",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 10,
                .prio_name     = PRIO_ALUA,
        },
+       {
+               /* FibreCAT S80 */
+               .vendor        = "(EUROLOGC|EuroLogc)",
+               .product       = "FC2502",
+               .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
+       },
        /*
         * Hitachi
         *
@@ -218,21 +285,25 @@ static struct hwentry default_hw[] = {
         * Mail : matthias.rudolph@hds.com
         */
        {
+               /* USP-V, HUS VM, VSP, VSP G1000 and VSP GX00 families */
                .vendor        = "(HITACHI|HP)",
-               .product       = "OPEN-.*",
+               .product       = "^OPEN-",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
+               /* AMS 2000 and HUS 100 families */
                .vendor        = "HITACHI",
-               .product       = "DF.*",
+               .product       = "^DF",
                .features      = "1 queue_if_no_path",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .prio_name     = PRIO_HDS,
        },
        /*
         * IBM
         *
-        * Maintainer : Hannes Reinecke, SuSE
+        * Maintainer : Hannes Reinecke
         * Mail : hare@suse.de
         */
        {
@@ -242,130 +313,161 @@ static struct hwentry default_hw[] = {
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM FAStT 1722-600 */
+               /* DS4300 / FAStT600 */
                .vendor        = "IBM",
                .product       = "^1722-600",
                .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 300,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS4100 */
+               /* DS4100 / FAStT100 */
                .vendor        = "IBM",
                .product       = "^1724",
                .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 300,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS3200 / DS3300 / DS3400 */
+               /* DS3200 / DS3300 / DS3400 / Boot DS */
                .vendor        = "IBM",
                .product       = "^1726",
                .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 300,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS4400 / DS4500 / FAStT700 */
+               /* DS4400 / DS4500 / FAStT700 / FAStT900 */
                .vendor        = "IBM",
                .product       = "^1742",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
+               /* DS3500 / DS3512 / DS3524 */
                .vendor        = "IBM",
-               .product       = "^1745|^1746",
+               .product       = "^1746",
                .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
                .features      = "2 pg_init_retries 50",
                .hwhandler     = "1 rdac",
-               .no_path_retry = 15,
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
+       },
+       {
+               /* DCS3860 */
+               .vendor        = "IBM",
+               .product       = "^1813",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS4700 */
+               /* DS3950 / DS4200 / DS4700 / DS5020 */
                .vendor        = "IBM",
                .product       = "^1814",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS4800 */
+               /* DS4800 */
                .vendor        = "IBM",
                .product       = "^1815",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS5000 */
+               /* DS5000 / DS5100 / DS5300 / DCS3700 */
                .vendor        = "IBM",
                .product       = "^1818",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM Netfinity Fibre Channel RAID Controller Unit */
+               /* Netfinity Fibre Channel RAID Controller Unit */
                .vendor        = "IBM",
                .product       = "^3526",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               /* IBM DS4200 / FAStT200 */
+               /* DS4200 / FAStT200 */
                .vendor        = "IBM",
                .product       = "^3542",
                .pgpolicy      = GROUP_BY_SERIAL,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM ESS F20 aka Shark */
+               /* Enterprise Storage Server / Shark family */
                .vendor        = "IBM",
-               .product       = "^2105800",
+               .product       = "^2105",
                .features      = "1 queue_if_no_path",
                .pgpolicy      = GROUP_BY_SERIAL,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM ESS F20 aka Shark */
-               .vendor        = "IBM",
-               .product       = "^2105F20",
-               .features      = "1 queue_if_no_path",
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = FAILBACK_UNDEF,
-       },
-       {
-               /* IBM DS6000 */
+               /* DS6000 */
                .vendor        = "IBM",
                .product       = "^1750500",
                .features      = "1 queue_if_no_path",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* IBM DS8000 */
+               /* DS8000 */
                .vendor        = "IBM",
                .product       = "^2107900",
                .features      = "1 queue_if_no_path",
@@ -373,146 +475,130 @@ static struct hwentry default_hw[] = {
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM SAN Volume Controller */
+               /* Storwize family / SAN Volume Controller / Flex System V7000 */
                .vendor        = "IBM",
                .product       = "^2145",
                .features      = "1 queue_if_no_path",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* IBM S/390 ECKD DASD */
                .vendor        = "IBM",
                .product       = "S/390 DASD ECKD",
-               .bl_product    = "S/390.*",
+               .bl_product    = "S/390",
                .uid_attribute = "ID_UID",
                .features      = "1 queue_if_no_path",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM S/390 FBA DASD */
                .vendor        = "IBM",
                .product       = "S/390 DASD FBA",
-               .bl_product    = "S/390.*",
+               .bl_product    = "S/390",
                .uid_attribute = "ID_UID",
                .features      = "1 queue_if_no_path",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
-               /* IBM IPR */
+               /* Power RAID */
                .vendor        = "IBM",
-               .product       = "^IPR.*",
+               .product       = "^IPR",
                .features      = "1 queue_if_no_path",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* IBM RSSM */
+               /* SAS RAID Controller Module (RSSM) */
                .vendor        = "IBM",
                .product       = "1820N00",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = NO_PATH_RETRY_QUEUE,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
        {
-               /* IBM XIV Storage System */
+               /* XIV Storage System */
                .vendor        = "IBM",
                .product       = "2810XIV",
                .features      = "1 queue_if_no_path",
                .pgpolicy      = MULTIBUS,
-               .pgfailback    = 15,
+               .pgfailback    = FAILBACK_UNDEF,
                .minio         = 15,
        },
-       /*
-        * IBM Power Virtual SCSI Devices
-        *
-        * Maintainer : Brian King, IBM
-        * Mail : brking@linux.vnet.ibm.com
-        */
+               /*
+                * IBM Power Virtual SCSI Devices
+                *
+                * Maintainer : Brian King
+                * Mail : brking@linux.vnet.ibm.com
+                */
        {
-               /* AIX VDASD */
                .vendor        = "AIX",
                .product       = "VDASD",
                .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = (300 / DEFAULT_CHECKINT),
        },
        {
-               /* IBM 3303 NVDISK */
+               /* 3303 NVDISK */
                .vendor        = "IBM",
-               .product       = "3303      NVDISK",
+               .product       = "3303[ ]+NVDISK",
+               .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = (300 / DEFAULT_CHECKINT),
-               .pgpolicy      = FAILOVER,
        },
        {
-               /* AIX NVDISK */
                .vendor        = "AIX",
                .product       = "NVDISK",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = (300 / DEFAULT_CHECKINT),
                .prio_name     = PRIO_ALUA,
        },
        /*
-        * DELL
-        */
-       {
-               /* DELL MD3000 */
-               .vendor        = "DELL",
-               .product       = "MD3000",
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 15,
-               .checker_name  = RDAC,
-               .prio_name     = PRIO_RDAC,
-       },
-       {
-               /* DELL MD32xx/MD36xx */
-               .vendor        = "DELL",
-               .product       = "MD32xx|MD36xx",
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 15,
-               .checker_name  = RDAC,
-               .prio_name     = PRIO_RDAC,
-       },
-       {
-               /* DELL MD34xx/MD38xx */
-               .vendor        = "DELL",
-               .product       = "MD34xx|MD38xx",
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = 15,
-               .checker_name  = RDAC,
-               .prio_name     = PRIO_RDAC,
-       },
-       /*
-        * NETAPP ONTAP family
-        *
-        * Maintainer : Martin George
-        * Mail : marting@netapp.com
+        * NetApp
         */
        {
+               /*
+                * ONTAP family
+                *
+                * Maintainer : Martin George
+                * Mail : marting@netapp.com
+                */
                .vendor        = "NETAPP",
-               .product       = "LUN.*",
+               .product       = "LUN",
                .features      = "3 queue_if_no_path pg_init_retries 50",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .flush_on_last_del = FLUSH_ENABLED,
                .minio         = 128,
                .dev_loss      = MAX_DEV_LOSS_TMO,
                .prio_name     = PRIO_ONTAP,
        },
        {
-               /* IBM NSeries */
-               .vendor        = "IBM",
-               .product       = "Nseries.*",
-               .features      = "1 queue_if_no_path",
-               .minio         = 128,
-               .prio_name     = PRIO_ONTAP,
+               /*
+                * SANtricity(RDAC) family
+                *
+                * Maintainer : Sean Stewart
+                * Mail : sean.stewart@netapp.com
+                */
+               .vendor        = "(NETAPP|LSI|ENGENIO)",
+               .product       = "INF-01-00",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        /*
-        * NEXENTA
+        * Nexenta
         *
         * Maintainer : Yacine Kheddache
         * Mail : yacine@alyseo.com
@@ -522,48 +608,43 @@ static struct hwentry default_hw[] = {
                .product       = "COMSTAR",
                .features      = "1 queue_if_no_path",
                .pgpolicy      = GROUP_BY_SERIAL,
+               .pgfailback    = FAILBACK_UNDEF,
                .no_path_retry = 30,
                .minio         = 128,
        },
-       /*
-        * Pillar Data/Oracle
-        *
-        * Maintainer : Srinivasan Ramani
-        * Mail : srinivas.ramani@oracle.com
-        */
-       {
-               .vendor        = "Pillar",
-               .product       = "Axiom.*",
-               .pgfailback    = FAILBACK_UNDEF,
-               .prio_name     = PRIO_ALUA,
-       },
        /*
         * SGI
         */
        {
                .vendor        = "SGI",
-               .product       = "TP9[13]00",
+               .product       = "TP9100",
                .pgpolicy      = MULTIBUS,
                .pgfailback    = FAILBACK_UNDEF,
        },
        {
                .vendor        = "SGI",
-               .product       = "TP9[45]00",
+               .product       = "TP9[345]00",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
+               /* InfiniteStorage ??? */
                .vendor        = "SGI",
-               .product       = "IS.*",
+               .product       = "IS",
                .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
                .features      = "2 pg_init_retries 50",
                .hwhandler     = "1 rdac",
-               .no_path_retry = 15,
-               .checker_name  = RDAC,
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        /*
         * NEC
@@ -573,22 +654,58 @@ static struct hwentry default_hw[] = {
                .vendor        = "NEC",
                .product       = "DISK ARRAY",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .prio_name     = PRIO_ALUA,
        },
        /*
-        * STK/Oracle
+        * Oracle
         */
+               /*
+                * Pillar Data / Oracle FS
+                *
+                * Maintainer : Srinivasan Ramani
+                * Mail : srinivas.ramani@oracle.com
+                */
+       {
+               .vendor        = "^Pillar",
+               .product       = "^Axiom",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .prio_name     = PRIO_ALUA,
+       },
+       {
+               .vendor        = "^Oracle",
+               .product       = "^Oracle FS",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .prio_name     = PRIO_ALUA,
+       },
+               /* Sun - StorageTek */
        {
                .vendor        = "STK",
                .product       = "OPENstorage D280",
                .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
                .hwhandler     = "1 rdac",
+               .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
+       },
+       {
+               .vendor        = "STK",
+               .product       = "FLEXLINE 380",
+               .bl_product    = "Universal Xport",
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
-       /*
-        * SUN/Oracle
-        */
        {
                .vendor        = "SUN",
                .product       = "(StorEdge 3510|T4)",
@@ -599,171 +716,162 @@ static struct hwentry default_hw[] = {
                .vendor        = "SUN",
                .product       = "STK6580_6780",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
        {
-               .vendor        = "EUROLOGC",
-               .product       = "FC2502",
-               .pgfailback    = FAILBACK_UNDEF,
-       },
-       /*
-        * Pivot3
-        *
-        * Maintainer : Bart Brooks, Pivot3
-        * Mail : bartb@pivot3.com
-        */
-       {
-               .vendor        = "PIVOT3",
-               .product       = "RAIGE VOLUME",
-               .features      = "1 queue_if_no_path",
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .minio         = 100,
-       },
-       {
+               /* 6140 */
                .vendor        = "SUN",
                .product       = "CSM200_R",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
-       /* SUN/LSI 2510, 2540, 2530, 2540 */
        {
+               /* 2510 / 2530 / 2540 */
                .vendor        = "SUN",
                .product       = "LCSM100_[IEFS]",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
+               .features      = "2 pg_init_retries 50",
+               .hwhandler     = "1 rdac",
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
-       /* StorageTek 6180 */
        {
                .vendor        = "SUN",
                .product       = "SUN_6180",
                .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
+               .pgpolicy      = GROUP_BY_PRIO,
                .checker_name  = RDAC,
-               .prio_name     = PRIO_RDAC,
-       },
-       /* LSI/Engenio/NetApp RDAC
-        *
-        * Maintainer : Sean Stewart
-        * Mail : sean.stewart@netapp.com
-        */
-       {
-               .vendor        = "(NETAPP|LSI|ENGENIO)",
-               .product       = "INF-01-00",
-               .bl_product    = "Universal Xport",
                .features      = "2 pg_init_retries 50",
                .hwhandler     = "1 rdac",
-               .no_path_retry = 30,
-               .checker_name  = RDAC,
                .prio_name     = PRIO_RDAC,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .no_path_retry = 30,
        },
+       /*
+        * Pivot3
+        *
+        * Maintainer : Bart Brooks
+        * Mail : bartb@pivot3.com
+        */
        {
-               .vendor        = "STK",
-               .product       = "FLEXLINE 380",
-               .bl_product    = "Universal Xport",
-               .hwhandler     = "1 rdac",
-               .no_path_retry = NO_PATH_RETRY_QUEUE,
-               .checker_name  = RDAC,
-               .prio_name     = PRIO_RDAC,
+               .vendor        = "PIVOT3",
+               .product       = "RAIGE VOLUME",
+               .features      = "1 queue_if_no_path",
+               .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
+               .minio         = 100,
        },
+       /*
+        * Intel
+        */
        {
-               .vendor        = "Intel",
+               .vendor        = "(Intel|INTEL)",
                .product       = "Multi-Flex",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = NO_PATH_RETRY_QUEUE,
                .prio_name     = PRIO_ALUA,
        },
+       /*
+        * Linux-IO Target
+        */
        {
                .vendor        = "(LIO-ORG|SUSE)",
                .product       = "RBD",
                .hwhandler     = "1 alua",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = 12,
                .minio         = 100,
                .prio_name     = PRIO_ALUA,
        },
+       /*
+        * DataCore
+        */
        {
                .vendor        = "DataCore",
                .product       = "SANmelody",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = NO_PATH_RETRY_QUEUE,
                .prio_name     = PRIO_ALUA,
        },
        {
                .vendor        = "DataCore",
                .product       = "Virtual Disk",
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
                .no_path_retry = NO_PATH_RETRY_QUEUE,
                .prio_name     = PRIO_ALUA,
        },
+       /*
+        * Pure Storage
+        */
        {
                .vendor        = "PURE",
                .product       = "FlashArray",
                .selector      = "queue-length 0",
                .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
                .fast_io_fail  = 10,
-               .no_path_retry = 0,
                .dev_loss      = 60,
        },
-       {
-               .vendor        = "HUAWEI",
-               .product       = "XSG1",
-               .pgpolicy      = MULTIBUS,
-       },
        /*
-        * Violin Memory
+        * Huawei
         */
        {
-               .vendor        = "VIOLIN",
-               .product       = "CONCERTO ARRAY",
-               .selector      = "round-robin 0",
+               /* OceanStor V3 */
+               .vendor        = "(HUAWEI|HUASY)",
+               .product       = "XSG1",
                .pgpolicy      = MULTIBUS,
-               .prio_name     = PRIO_ALUA,
-               .minio         = 100,
-               .rr_weight     = RR_WEIGHT_PRIO,
-               .features      = "1 queue_if_no_path",
-               .no_path_retry = 300,
+               .pgfailback    = FAILBACK_UNDEF,
        },
        /*
-        * Infinidat
+        * Red Hat
+        *
+        * Maintainer: Mike Christie
+        * Mail: mchristi@redhat.com
         */
        {
-               .vendor        = "NFINIDAT",
-               .product       = "InfiniBox.*",
-               .prio_name     = PRIO_ALUA,
-               .selector      = "round-robin 0",
-               .pgfailback    = 30,
-               .rr_weight     = RR_WEIGHT_PRIO,
+               .vendor        = "Ceph",
+               .product       = "RBD",
                .no_path_retry = NO_PATH_RETRY_FAIL,
-               .flush_on_last_del = FLUSH_ENABLED,
-               .dev_loss      = 30,
+               .checker_name  = RBD,
+               .deferred_remove = DEFERRED_REMOVE_ON,
        },
        /*
-        * Tegile Systems
+        * Kove
         */
        {
-               .vendor        = "TEGILE",
-               .product       = "ZEBI-(FC|ISCSI)|INTELLIFLASH",
-               .hwhandler     = "1 alua",
-               .selector      = "round-robin 0",
-               .no_path_retry = 10,
-               .dev_loss      = 50,
-               .prio_name     = PRIO_ALUA,
-               .pgfailback    = 30,
-               .minio         = 128,
+               .vendor        = "KOVE",
+               .product       = "XPD",
+               .pgpolicy      = MULTIBUS,
+               .pgfailback    = FAILBACK_UNDEF,
        },
 #if 0
        /*
         * Copy this TEMPLATE to add new hardware.
         *
         * Keep only mandatory and modified attributes.
-        * Standard attributes must be removed.
+        * Attributes with default values must be removed.
+        * Only .vendor and .product are mandatory, all other are optional.
+        * .vendor, .product, .revision and .bl_product are POSIX Extended regex
         *
         * COMPANY_NAME
         *
@@ -771,11 +879,12 @@ static struct hwentry default_hw[] = {
         * Mail : XXX
         */
        {
-               .vendor        = "VENDOR", (Mandatory)
-               .product       = "PRODUCT", (Mandatory)
+               /* If product-ID is different from marketing name add a comment */
+               .vendor        = "VENDOR",
+               .product       = "PRODUCT",
                .revision      = "REVISION",
                .bl_product    = "BL_PRODUCT",
-               .pgpolicy      = GROUP_BY_PRIO,
+               .pgpolicy      = FAILOVER,
                .uid_attribute = "ID_SERIAL",
                .selector      = "service-time 0",
                .checker_name  = TUR,
@@ -783,7 +892,7 @@ static struct hwentry default_hw[] = {
                .hwhandler     = "0",
                .prio_name     = "const",
                .prio_args     = "",
-               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .pgfailback    = -FAILBACK_MANUAL,
                .rr_weight     = RR_WEIGHT_NONE,
                .no_path_retry = NO_PATH_RETRY_UNDEF,
                .minio         = 1000,
@@ -804,18 +913,6 @@ static struct hwentry default_hw[] = {
        {
                .vendor        = NULL,
                .product       = NULL,
-               .features      = NULL,
-               .hwhandler     = NULL,
-               .selector      = NULL,
-               .pgpolicy      = 0,
-               .pgfailback    = 0,
-               .rr_weight     = 0,
-               .no_path_retry = 0,
-               .minio         = 0,
-               .minio_rq      = 0,
-               .checker_name  = NULL,
-               .prio_name     = NULL,
-               .prio_args     = NULL,
        },
 };
 
index ec53a5e187b1f9966ba6dd5369953109af4222d8..72c70e34686d995721d1e66a28d95d64f0b00008 100644 (file)
@@ -1,8 +1,8 @@
-#include <pthread.h>
 #include "lock.h"
-#include <stdio.h>
 
 void cleanup_lock (void * data)
 {
-       unlock ((*(struct mutex_lock *)data));
+       struct mutex_lock *lock = data;
+
+       unlock(lock);
 }
index 97af0f4666272d7205c3a60a6181697c97c36a72..a170efe9e4a29860932f1761104b4eb938a39350 100644 (file)
@@ -1,32 +1,28 @@
 #ifndef _LOCK_H
 #define _LOCK_H
 
-#include <signal.h>
+#include <pthread.h>
 
-/*
- * Wrapper for the mutex. Includes a ref-count to keep
- * track of how many there are out-standing threads blocking
- * on a mutex. */
 struct mutex_lock {
-       pthread_mutex_t *mutex;
-       int depth;
+       pthread_mutex_t mutex;
 };
 
-#ifdef LCKDBG
-#define lock(a) \
-               fprintf(stderr, "%s:%s(%i) lock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
-               a.depth++; pthread_mutex_lock(a.mutex)
-#define unlock(a) \
-               fprintf(stderr, "%s:%s(%i) unlock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
-       a.depth--; pthread_mutex_unlock(a.mutex)
-#define lock_cleanup_pop(a) \
-               fprintf(stderr, "%s:%s(%i) unlock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
-       pthread_cleanup_pop(1)
-#else
-#define lock(a) a.depth++; pthread_mutex_lock(a.mutex)
-#define unlock(a) a.depth--; pthread_mutex_unlock(a.mutex)
+static inline void lock(struct mutex_lock *a)
+{
+       pthread_mutex_lock(&a->mutex);
+}
+
+static inline int timedlock(struct mutex_lock *a, struct timespec *tmo)
+{
+       return pthread_mutex_timedlock(&a->mutex, tmo);
+}
+
+static inline void unlock(struct mutex_lock *a)
+{
+       pthread_mutex_unlock(&a->mutex);
+}
+
 #define lock_cleanup_pop(a) pthread_cleanup_pop(1)
-#endif
 
 void cleanup_lock (void * data);
 
index 1366f453789d77b7d134e95b9dc2978af069ae69..5441e6aa7678e0617c4dd9f414d6ef71cf898dfb 100644 (file)
 
 #include "memory.h"
 
-/* Global var */
-unsigned long mem_allocated;   /* Total memory used in Bytes */
-
-void *
-xalloc(unsigned long size)
-{
-       void *mem;
-       if ((mem = malloc(size)))
-               mem_allocated += size;
-       return mem;
-}
-
-void *
-zalloc(unsigned long size)
-{
-       void *mem;
-       if ((mem = malloc(size))) {
-               memset(mem, 0, size);
-               mem_allocated += size;
-       }
-       return mem;
-}
-
-void
-xfree(void *p)
-{
-       mem_allocated -= sizeof (p);
-       free(p);
-       p = NULL;
-}
-
 /*
  * Memory management. in debug mode,
  * help finding eventual memory leak.
index 8573f6f1268c1b41a7eb14c879083f21550cc2a7..29a75edc36cc08e1a7d74eb685a24947c0999580 100644 (file)
 #include <string.h>
 #include <assert.h>
 
-/* extern types */
-extern unsigned long mem_allocated;
-extern void *xalloc(unsigned long size);
-extern void *zalloc(unsigned long size);
-extern void xfree(void *p);
-
-/* Global alloc macro */
-#define ALLOC(n) (xalloc(n))
-
 /* Local defines */
 #ifdef _DEBUG_
 
@@ -63,8 +54,8 @@ extern void dbg_free_final(char *);
 
 #else
 
-#define MALLOC(n)    (zalloc(n))
-#define FREE(p)      (xfree(p))
+#define MALLOC(n)    (calloc(1,(n)))
+#define FREE(p)      do { free(p); p = NULL; } while(0)
 #define REALLOC(p,n) (realloc((p),(n)))
 #define STRDUP(n)    (strdup(n))
 
index dd955f397c086dfa24ad684b7176523fa50174a3..c47d891ec3692355f77ca0ac131619b8c492f2db 100644 (file)
@@ -171,7 +171,7 @@ snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, void *data)
                        r = kw->print(conf, buff + fwd, len - fwd, data);
                        put_multipath_config(conf);
                        if (!r) { /* no output if no value */
-                               buff = '\0';
+                               buff[0] = '\0';
                                return 0;
                        }
                        fwd += r;
index f4404410a3f2c0a60b99666a0d03e0ecccada547..3064aabe291a1263de54f20127bd1fb86c4f0b63 100644 (file)
@@ -123,11 +123,11 @@ group_by_node_name (struct multipath * mp) {
                        goto out1;
 
                if (store_pathgroup(mp->pg, pgp))
-                       goto out1;
+                       goto out2;
 
                /* feed the first path */
                if (store_path(pgp->paths, pp))
-                       goto out1;
+                       goto out2;
 
                bitmap[i] = 1;
 
@@ -141,7 +141,7 @@ group_by_node_name (struct multipath * mp) {
                        if (!strncmp(pp->tgt_node_name, pp2->tgt_node_name,
                                        NODE_NAME_SIZE)) {
                                if (store_path(pgp->paths, pp2))
-                                       goto out1;
+                                       goto out2;
 
                                bitmap[j] = 1;
                        }
@@ -152,6 +152,8 @@ group_by_node_name (struct multipath * mp) {
        free_pathvec(mp->paths, KEEP_PATHS);
        mp->paths = NULL;
        return 0;
+out2:
+       free_pathgroup(pgp, KEEP_PATHS);
 out1:
        FREE(bitmap);
 out:
@@ -197,11 +199,11 @@ group_by_serial (struct multipath * mp) {
                        goto out1;
 
                if (store_pathgroup(mp->pg, pgp))
-                       goto out1;
+                       goto out2;
 
                /* feed the first path */
                if (store_path(pgp->paths, pp))
-                       goto out1;
+                       goto out2;
 
                bitmap[i] = 1;
 
@@ -214,7 +216,7 @@ group_by_serial (struct multipath * mp) {
 
                        if (0 == strcmp(pp->serial, pp2->serial)) {
                                if (store_path(pgp->paths, pp2))
-                                       goto out1;
+                                       goto out2;
 
                                bitmap[j] = 1;
                        }
@@ -225,6 +227,8 @@ group_by_serial (struct multipath * mp) {
        free_pathvec(mp->paths, KEEP_PATHS);
        mp->paths = NULL;
        return 0;
+out2:
+       free_pathgroup(pgp, KEEP_PATHS);
 out1:
        FREE(bitmap);
 out:
@@ -254,15 +258,17 @@ one_path_per_group (struct multipath * mp)
                        goto out;
 
                if (store_pathgroup(mp->pg, pgp))
-                       goto out;
+                       goto out1;
 
                if (store_path(pgp->paths, pp))
-                       goto out;
+                       goto out1;
        }
        sort_pathgroups(mp);
        free_pathvec(mp->paths, KEEP_PATHS);
        mp->paths = NULL;
        return 0;
+out1:
+       free_pathgroup(pgp, KEEP_PATHS);
 out:
        free_pgvec(mp->pg, KEEP_PATHS);
        mp->pg = NULL;
@@ -290,14 +296,17 @@ one_group (struct multipath * mp) /* aka multibus */
                        goto out;
 
                vector_free(pgp->paths);
-               pgp->paths = mp->paths;
-               mp->paths = NULL;
 
                if (store_pathgroup(mp->pg, pgp))
-                       goto out;
+                       goto out1;
+
+               pgp->paths = mp->paths;
+               mp->paths = NULL;
        }
 
        return 0;
+out1:
+       free_pathgroup(pgp, KEEP_PATHS);
 out:
        free_pgvec(mp->pg, KEEP_PATHS);
        mp->pg = NULL;
@@ -311,6 +320,7 @@ group_by_prio (struct multipath * mp)
        unsigned int prio;
        struct path * pp;
        struct pathgroup * pgp;
+       vector pathvec = NULL;
 
        if (!mp->pg)
                mp->pg = vector_alloc();
@@ -318,8 +328,18 @@ group_by_prio (struct multipath * mp)
        if (!mp->pg)
                return 1;
 
-       while (VECTOR_SIZE(mp->paths) > 0) {
-               pp = VECTOR_SLOT(mp->paths, 0);
+       pathvec = vector_alloc();
+       if (!pathvec)
+               goto out;
+
+       vector_foreach_slot(mp->paths, pp, i) {
+               if (!vector_alloc_slot(pathvec))
+                       goto out1;
+               vector_set_slot(pathvec, pp);
+       }
+
+       while (VECTOR_SIZE(pathvec) > 0) {
+               pp = VECTOR_SLOT(pathvec, 0);
                prio = pp->priority;
 
                /*
@@ -339,46 +359,45 @@ group_by_prio (struct multipath * mp)
                pgp = alloc_pathgroup();
 
                if (!pgp)
-                       goto out;
+                       goto out1;
 
-               if (store_path(pgp->paths, VECTOR_SLOT(mp->paths, 0))) {
-                       free_pathgroup(pgp, KEEP_PATHS);
-                       goto out;
-               }
+               if (store_path(pgp->paths, VECTOR_SLOT(pathvec, 0)))
+                       goto out2;
 
-               vector_del_slot(mp->paths, 0);
+               vector_del_slot(pathvec, 0);
 
                /*
                 * Store the new path group into the vector.
                 */
                if (i < VECTOR_SIZE(mp->pg)) {
-                       if (!vector_insert_slot(mp->pg, i, pgp)) {
-                               free_pathgroup(pgp, KEEP_PATHS);
-                               goto out;
-                       }
+                       if (!vector_insert_slot(mp->pg, i, pgp))
+                               goto out2;
                } else {
-                       if (store_pathgroup(mp->pg, pgp)) {
-                               free_pathgroup(pgp, KEEP_PATHS);
-                               goto out;
-                       }
+                       if (store_pathgroup(mp->pg, pgp))
+                               goto out2;
                }
 
                /*
                 * add the other paths with the same prio
                 */
-               vector_foreach_slot(mp->paths, pp, i) {
+               vector_foreach_slot(pathvec, pp, i) {
                        if (pp->priority == prio) {
                                if (store_path(pgp->paths, pp))
-                                       goto out;
+                                       goto out2;
 
-                               vector_del_slot(mp->paths, i);
+                               vector_del_slot(pathvec, i);
                                i--;
                        }
                }
        }
+       free_pathvec(pathvec, KEEP_PATHS);
        free_pathvec(mp->paths, KEEP_PATHS);
        mp->paths = NULL;
        return 0;
+out2:
+       free_pathgroup(pgp, KEEP_PATHS);
+out1:
+       free_pathvec(pathvec, KEEP_PATHS);
 out:
        free_pgvec(mp->pg, KEEP_PATHS);
        mp->pg = NULL;
index 7c556b3f55a6d40333e33547fec015b5d8e46c5b..94d6384d5f801a6756fbe64ccb8953d49609921a 100644 (file)
@@ -503,7 +503,7 @@ snprint_path_size (char * buff, size_t len, struct path * pp)
        return snprint_size(buff, len, pp->size);
 }
 
-static int
+int
 snprint_path_serial (char * buff, size_t len, struct path * pp)
 {
        return snprint_str(buff, len, pp->serial);
index 9306e50bf0f472fca7145a819110d62249111579..6839fc74823277ae3488175c2d2969b908d50e15 100644 (file)
@@ -112,6 +112,7 @@ int snprint_devices (struct config *, char *, int, struct vectors *);
 int snprint_hwtable (struct config *, char *, int, vector);
 int snprint_mptable (struct config *, char *, int, vector);
 int snprint_overrides (struct config *, char *, int, struct hwentry *);
+int snprint_path_serial (char *, size_t, struct path *);
 int snprint_host_wwnn (char *, size_t, struct path *);
 int snprint_host_wwpn (char *, size_t, struct path *);
 int snprint_tgt_wwnn (char *, size_t, struct path *);
index 032028ed25abc607a1990fc5f6f1b6ebb4bb61bb..261105b4896f429164be0918a88dd7072bf83e34 100644 (file)
@@ -12,9 +12,7 @@ struct path;
 
 #include "list.h"
 #include "memory.h"
-
-#define DEFAULT_PRIO "const"
-#define DEFAULT_PRIO_ARGS ""
+#include "defaults.h"
 
 /*
  * Known prioritizers for use in hwtable.c
index bb767006ab9536c1bf3f98f57b6cdc4e39f51bd4..36b42e4189e98772c2d47aea3c78e9060f5d7ca7 100644 (file)
@@ -1,9 +1,11 @@
-# Makefile
 #
 # Copyright (C) 2007 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
 include ../../Makefile.inc
 
+CFLAGS += -I..
+
+# If you add or remove a prioritizer also update multipath/multipath.conf.5
 LIBS = \
        libprioalua.so \
        libprioconst.so \
@@ -18,8 +20,6 @@ LIBS = \
        libprioweightedpath.so \
        libpriosysfs.so
 
-CFLAGS += -I..
-
 all: $(LIBS)
 
 libprioalua.so: alua.o alua_rtpg.o
index a1c59fd0c2a83644eaa4b00fb04695604b59615f..5636974287327f1972c980b1a2b260d441aa5fb2 100644 (file)
@@ -107,37 +107,37 @@ int getprio (struct path * pp, char * args, unsigned int timeout)
                aas = (rc & 0x0f);
                priopath = (rc & 0x80);
                switch(aas) {
-                       case AAS_OPTIMIZED:
-                               rc = 50;
-                               break;
-                       case AAS_NON_OPTIMIZED:
-                               rc = 10;
-                               break;
-                       case AAS_LBA_DEPENDENT:
-                               rc = 5;
-                               break;
-                       case AAS_STANDBY:
-                               rc = 1;
-                               break;
-                       default:
-                               rc = 0;
+               case AAS_OPTIMIZED:
+                       rc = 50;
+                       break;
+               case AAS_NON_OPTIMIZED:
+                       rc = 10;
+                       break;
+               case AAS_LBA_DEPENDENT:
+                       rc = 5;
+                       break;
+               case AAS_STANDBY:
+                       rc = 1;
+                       break;
+               default:
+                       rc = 0;
                }
                if (priopath && (aas != AAS_OPTIMIZED || exclusive_pref))
                        rc += 80;
        } else {
                switch(-rc) {
-                       case ALUA_PRIO_NOT_SUPPORTED:
-                               condlog(0, "%s: alua not supported", pp->dev);
-                               break;
-                       case ALUA_PRIO_RTPG_FAILED:
-                               condlog(0, "%s: couldn't get target port group", pp->dev);
-                               break;
-                       case ALUA_PRIO_GETAAS_FAILED:
-                               condlog(0, "%s: couldn't get asymmetric access state", pp->dev);
-                               break;
-                       case ALUA_PRIO_TPGS_FAILED:
-                               condlog(3, "%s: couldn't get supported alua states", pp->dev);
-                               break;
+               case ALUA_PRIO_NOT_SUPPORTED:
+                       condlog(0, "%s: alua not supported", pp->dev);
+                       break;
+               case ALUA_PRIO_RTPG_FAILED:
+                       condlog(0, "%s: couldn't get target port group", pp->dev);
+                       break;
+               case ALUA_PRIO_GETAAS_FAILED:
+                       condlog(0, "%s: couldn't get asymmetric access state", pp->dev);
+                       break;
+               case ALUA_PRIO_TPGS_FAILED:
+                       condlog(3, "%s: couldn't get supported alua states", pp->dev);
+                       break;
                }
        }
        return rc;
index 253fd518b49a340403b82c13dc4578c0acee5c74..6b0ed39800d4120d232e31e17fdf9b56fa172199 100644 (file)
@@ -48,7 +48,7 @@ int hp_sw_prio(const char *dev, int fd, unsigned int timeout)
        io_hdr.sbp = sb;
        io_hdr.timeout = get_prio_timeout(timeout, 60000);
        io_hdr.pack_id = 0;
- retry:
+retry:
        if (ioctl(fd, SG_IO, &io_hdr) < 0) {
                pp_hp_sw_log(0, "sending tur command failed");
                goto out;
index 747dfb53d514fe1a74fd43019a4a09d57558aca2..4084c6534aab75dd2d1fab51a06abfe4324f2a8a 100644 (file)
@@ -113,7 +113,7 @@ static int send_gva(const char *dev, int fd, unsigned char pg,
                goto out;
        }
        ret = 0;
- out:
+out:
        return(ret);
 }
 
@@ -171,7 +171,7 @@ static int get_proxy(const char *dev, int fd, unsigned int timeout)
        }
        ret = (results[19] & 0x02) >> 1;
 
- out:
+out:
        return(ret);
 }
 
@@ -221,13 +221,13 @@ static int ontap_prio(const char *dev, int fd, unsigned int timeout)
                return 0;
        }
 
- try_fcp_proxy:
+try_fcp_proxy:
        rc = get_proxy(dev, fd, timeout);
        if (rc >= 0) {
                is_proxy = rc;
        }
 
- prio_select:
+prio_select:
        if (is_iscsi_hardware) {
                return 3;
        } else if (is_iscsi_software) {
index e8168fe30177b057c66050a8d1b3e069e817c684..a62b86e7927b5f83edc7f5ce69d8cc81c982b9a7 100644 (file)
@@ -52,6 +52,16 @@ do { \
        } \
 } while(0)
 
+static int
+build_serial_path(struct path *pp, char *str, int len)
+{
+       char *p = str;
+
+       p += snprint_path_serial(p, str + len - p, pp);
+       CHECK_LEN;
+       return 0;
+}
+
 static int
 build_wwn_path(struct path *pp, char *str, int len)
 {
@@ -103,6 +113,11 @@ int prio_path_weight(struct path *pp, char *prio_args)
                        pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
        } else if (!strcmp(regex, DEV_NAME)) {
                strcpy(path, pp->dev);
+       } else if (!strcmp(regex, SERIAL)) {
+               if (build_serial_path(pp, path, FILE_NAME_SIZE) != 0) {
+                       FREE(arg);
+                       return priority;
+               }
        } else if (!strcmp(regex, WWN)) {
                if (build_wwn_path(pp, path, FILE_NAME_SIZE) != 0) {
                        FREE(arg);
index 93d8c43ee89fbe5d639908540669862ba6cb062e..a1b268fe4006fdec88e52bfcefc5f274b9705cfe 100644 (file)
@@ -4,6 +4,7 @@
 #define PRIO_WEIGHTED_PATH "weightedpath"
 #define HBTL "hbtl"
 #define DEV_NAME "devname"
+#define SERIAL "serial"
 #define WWN "wwn"
 #define DEFAULT_PRIORITY 0
 
index 0caf26968dac87fc112ea3396f695c886d1cb365..16259900bd7f1d2b18fda8a7ff3d5a06bbf71320 100644 (file)
@@ -459,7 +459,7 @@ out:
                condlog(3, "%s: no_path_retry = %s %s", mp->alias, buff,
                        origin);
        else if (mp->no_path_retry != NO_PATH_RETRY_UNDEF)
-               condlog(3, "%s: no_path_retry = %s (inheritied setting)",
+               condlog(3, "%s: no_path_retry = %s (inherited setting)",
                        mp->alias, buff);
        else
                condlog(3, "%s: no_path_retry = undef (internal default)",
index 9f216df04464b81df6ce846d1c128b9ceec3e7c5..cb5d53284577022abc38889c16d5361be6e57070 100644 (file)
@@ -52,6 +52,7 @@ enum sysfs_buses {
        SYSFS_BUS_IDE,
        SYSFS_BUS_CCW,
        SYSFS_BUS_CCISS,
+       SYSFS_BUS_RBD,
 };
 
 enum pathstates {
@@ -167,10 +168,10 @@ struct sg_id {
 #  define HDIO_GETGEO  0x0301  /* get device geometry */
 
 struct hd_geometry {
-      unsigned char heads;
-      unsigned char sectors;
-      unsigned short cylinders;
-      unsigned long start;
+       unsigned char heads;
+       unsigned char sectors;
+       unsigned short cylinders;
+       unsigned long start;
 };
 #endif
 
index adb1911e0b8c5b1355f4475945f5711c9cf19fd2..a0c8869ee9440beade42897bd4cd69231d3407f7 100644 (file)
@@ -409,10 +409,12 @@ __setup_multipath (struct vectors * vecs, struct multipath * mpp,
                        mpp->alias);
        }
        if (reset) {
+               conf = get_multipath_config();
                select_rr_weight(conf, mpp);
                select_pgfailback(conf, mpp);
                set_no_path_retry(conf, mpp);
                select_flush_on_last_del(conf, mpp);
+               put_multipath_config(conf);
                if (VECTOR_SIZE(mpp->paths) != 0)
                        dm_cancel_deferred_remove(mpp);
        }
index 8ef547da00b29173deb38282c1ab3ca98057b1d6..46f30afe02bcea40aee6f6658bf67f05a4d324cc 100644 (file)
@@ -4,11 +4,7 @@
 #include "vector.h"
 #include "config.h"
 #include "lock.h"
-/*
-struct mutex_lock {
-       pthread_mutex_t *mutex;
-       int depth;
-}; */
+
 struct vectors {
        struct mutex_lock lock; /* defined in lock.h */
        vector pathvec;
index 5f3204bc282a2ea454d86a76be7797d26b3a23d2..6247898cbf72b62cf5298b1f84bc04c3b830cf0e 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/types.h>
 #include <linux/netlink.h>
 #include <pthread.h>
-#include <signal.h>
 #include <limits.h>
 #include <sys/mman.h>
 #include <libudev.h>
index 257912c61e0ea6ff8a019bc9d8d14fe757ccdbae..886108547611d23c4f03bf8ea46b7fa17a31ccf1 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _UTIL_H
 #define _UTIL_H
 
+#include <sys/types.h>
+
 size_t strchop(char *);
 int basenamecpy (const char * src, char * dst, int);
 int filepresent (char * run);
index 09d725daea3b4cacf0abf40cb434f74593a7b9ae..dea59fed04570c578bf36005ca1292f7e9efe606 100644 (file)
@@ -20,8 +20,8 @@
 #ifndef _VERSION_H
 #define _VERSION_H
 
-#define VERSION_CODE 0x000602
-#define DATE_CODE    0x071610
+#define VERSION_CODE 0x000603
+#define DATE_CODE    0x080f10
 
 #define PROG    "multipath-tools"
 
index 06995b6ff2338aff69185913515939936ecd8c53..995ea1adae961f9615400ccfb39c2f53c02e6c7e 100644 (file)
@@ -24,7 +24,7 @@
 
 pthread_attr_t waiter_attr;
 
-struct event_thread *alloc_waiter (void)
+static struct event_thread *alloc_waiter (void)
 {
 
        struct event_thread *wp;
@@ -35,7 +35,7 @@ struct event_thread *alloc_waiter (void)
        return wp;
 }
 
-void free_waiter (void *data)
+static void free_waiter (void *data)
 {
        struct event_thread *wp = (struct event_thread *)data;
 
@@ -67,7 +67,7 @@ void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs)
  * returns the reschedule delay
  * negative means *stop*
  */
-int waiteventloop (struct event_thread *waiter)
+static int waiteventloop (struct event_thread *waiter)
 {
        sigset_t set, oldset;
        int event_nr;
@@ -138,7 +138,7 @@ int waiteventloop (struct event_thread *waiter)
                 * 5) a switch group : nothing to do
                 */
                pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
-               lock(waiter->vecs->lock);
+               lock(&waiter->vecs->lock);
                pthread_testcancel();
                r = update_multipath(waiter->vecs, waiter->mapname, 1);
                lock_cleanup_pop(waiter->vecs->lock);
@@ -159,7 +159,7 @@ int waiteventloop (struct event_thread *waiter)
        return -1; /* never reach there */
 }
 
-void *waitevent (void *et)
+static void *waitevent (void *et)
 {
        int r;
        struct event_thread *waiter;
index a1f57fbba7c4357367d181b4ab673b128080f5e2..0cfae46fb8899d55f19a0571d803c830b4db07d2 100644 (file)
@@ -11,11 +11,7 @@ struct event_thread {
        struct vectors *vecs;
 };
 
-struct event_thread * alloc_waiter (void);
-void free_waiter (void *data);
 void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs);
 int start_waiter_thread (struct multipath *mpp, struct vectors *vecs);
-int waiteventloop (struct event_thread *waiter);
-void *waitevent (void *et);
 
 #endif /* _WAITER_H */
index a7c3249c4629573a7b01f6a2839cb5c8fbd44117..babf149aee747d5535280d51e2008a5d0ac52aae 100644 (file)
@@ -273,7 +273,7 @@ out:
 int
 should_multipath(struct path *pp1, vector pathvec)
 {
-       int i, ignore_new_devs;;
+       int i, ignore_new_devs;
        struct path *pp2;
        struct config *conf;
 
index a458c4d0014e82d8b9b16a28b2389b9c6b7a70ca..d545514b639982ac218e0cc39450fb09cd97d106 100644 (file)
@@ -1,14 +1,14 @@
-# Makefile
-#
 include ../Makefile.inc
 
-OBJS = main.o
-
 CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
-LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -L$(mpathcmddir) -lmpathcmd -lmultipath -ludev
+
+LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist \
+          -L$(multipathdir) -L$(mpathcmddir) -lmpathcmd -lmultipath -ludev
 
 EXEC = mpathpersist
 
+OBJS = main.o
+
 all: $(EXEC)
 
 $(EXEC): $(OBJS)
@@ -22,8 +22,7 @@ install:
        $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
 
 clean:
-       $(RM) *.o $(EXEC)
-       $(RM) mpathpersist.8.gz
+       $(RM) core *.o $(EXEC) *.gz
 
 uninstall:
        $(RM) $(DESTDIR)$(bindir)/$(EXEC)
index bf9c7214a7d94c795446c0df32b1b42b4bf46ba4..a55865f8720fa798422dbd9b0c17814e88606369 100644 (file)
@@ -662,7 +662,7 @@ void mpath_print_buf_readfullstat( struct prin_resp *pr_buff)
 
                if (pr_buff->prin_descriptor.prin_readfd.descriptors[i]->flag & 0x1) {
                        printf("      << Reservation holder >>\n");
-                       j = ((pr_buff->prin_descriptor.prin_readfd.descriptors[i]->scope_type>> 4) & 0xf);
+                       j = ((pr_buff->prin_descriptor.prin_readfd.descriptors[i]->scope_type >> 4) & 0xf);
                        if (0 == j)
                                printf("      scope: LU_SCOPE, ");
                        else
@@ -675,7 +675,7 @@ void mpath_print_buf_readfullstat( struct prin_resp *pr_buff)
        }
 }
 
-static void usage()
+static void usage(void)
 {
        fprintf(stderr,
                        "Usage: mpathpersist [OPTIONS] [DEVICE]\n"
@@ -720,37 +720,37 @@ void
 mpath_print_transport_id(struct prin_fulldescr *fdesc)
 {
        switch (fdesc->trnptid.protocol_id) {
-               case MPATH_PROTOCOL_ID_FC:
-                       printf("   FCP-2 ");
-                       if (0 != fdesc->trnptid.format_code)
-                               printf(" [Unexpected format code: %d]\n",
-                                               fdesc->trnptid.format_code);
-                       dumpHex((const char *)fdesc->trnptid.n_port_name, 8, 0);
-                       break;
-               case MPATH_PROTOCOL_ID_ISCSI:
-                       printf("   iSCSI ");
-                       if (0 == fdesc->trnptid.format_code) {
-                               printf("name: %.*s\n", (int)sizeof(fdesc->trnptid.iscsi_name),
+       case MPATH_PROTOCOL_ID_FC:
+               printf("   FCP-2 ");
+               if (0 != fdesc->trnptid.format_code)
+                       printf(" [Unexpected format code: %d]\n",
+                                       fdesc->trnptid.format_code);
+               dumpHex((const char *)fdesc->trnptid.n_port_name, 8, 0);
+               break;
+       case MPATH_PROTOCOL_ID_ISCSI:
+               printf("   iSCSI ");
+               if (0 == fdesc->trnptid.format_code) {
+                       printf("name: %.*s\n", (int)sizeof(fdesc->trnptid.iscsi_name),
+                               fdesc->trnptid.iscsi_name);
+               }else if (1 == fdesc->trnptid.format_code){
+                       printf("world wide unique port id: %.*s\n",
+                                       (int)sizeof(fdesc->trnptid.iscsi_name),
                                        fdesc->trnptid.iscsi_name);
-                       }else if (1 == fdesc->trnptid.format_code){
-                               printf("world wide unique port id: %.*s\n",
-                                               (int)sizeof(fdesc->trnptid.iscsi_name),
-                                               fdesc->trnptid.iscsi_name);
-                       }else {
-                               printf("  [Unexpected format code: %d]\n", fdesc->trnptid.format_code);
-                               dumpHex((const char *)fdesc->trnptid.iscsi_name,
-                                        (int)sizeof(fdesc->trnptid.iscsi_name), 0);
-                       }
-                       break;
-               case MPATH_PROTOCOL_ID_SAS:
-                       printf("   SAS ");
-                        if (0 != fdesc->trnptid.format_code)
-                               printf(" [Unexpected format code: %d]\n",
-                                               fdesc->trnptid.format_code);
-                       dumpHex((const char *)fdesc->trnptid.sas_address, 8, 0);
-                       break;
-               default:
-                       return;
+               }else {
+                       printf("  [Unexpected format code: %d]\n", fdesc->trnptid.format_code);
+                       dumpHex((const char *)fdesc->trnptid.iscsi_name,
+                                (int)sizeof(fdesc->trnptid.iscsi_name), 0);
+               }
+               break;
+       case MPATH_PROTOCOL_ID_SAS:
+               printf("   SAS ");
+               if (0 != fdesc->trnptid.format_code)
+                       printf(" [Unexpected format code: %d]\n",
+                                       fdesc->trnptid.format_code);
+               dumpHex((const char *)fdesc->trnptid.sas_address, 8, 0);
+               break;
+       default:
+               return;
        }
 }
 
index 9c57d3bc7cc3e53d9c2dbf36157a46f4d90839ad..b125ae3bb2dcd44f3a07a21efaedd81a32247cda 100644 (file)
@@ -1,17 +1,17 @@
-# Makefile
 #
 # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
 #
 include ../Makefile.inc
 
-OBJS = main.o
-
 CFLAGS += -I$(multipathdir) -I$(mpathcmddir)
+
 LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath -ludev \
-       -L$(mpathcmddir) -lmpathcmd
+          -L$(mpathcmddir) -lmpathcmd
 
 EXEC = multipath
 
+OBJS = main.o
+
 all: $(EXEC)
 
 $(EXEC): $(OBJS)
index 6ccece755e82b21a3eb6c69d84d6497f1e5bed72..ee00fdbd8c205d62352fcff229377b108c17dc8a 100644 (file)
@@ -212,7 +212,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
                /*
                 * discard out of scope maps
                 */
-               if (mpp->wwid && refwwid &&
+               if (refwwid && strlen(refwwid) &&
                    strncmp(mpp->wwid, refwwid, WWID_SIZE)) {
                        condlog(3, "skip map %s: out of scope", mpp->alias);
                        free_multipath(mpp, KEEP_PATHS);
@@ -511,7 +511,7 @@ main (int argc, char *argv[])
        extern int optind;
        int r = 1;
        enum mpath_cmds cmd = CMD_CREATE;
-       enum devtypes dev_type;
+       enum devtypes dev_type = DEV_NONE;
        char *dev = NULL;
        struct config *conf;
 
index f542d3f20a78b4a87b7ec1ba60ef6ccd671ed6c0..55fde22062d8174e6ec60625b7fd12d50280dc98 100644 (file)
@@ -1,13 +1,37 @@
-.TH MULTIPATH.CONF 5 2016-07-08 "Linux"
+.\" ----------------------------------------------------------------------------
+.\" Update the date below if you make any significant change.
+.\" Make sure there are no errors with:
+.\" groff -z -wall -b -e -t multipath/multipath.conf.5
+.\"
+.\" TODO: Look for XXX
+.\"
+.\" ----------------------------------------------------------------------------
+.
+.TH MULTIPATH.CONF 5 2016-08-07 "Linux"
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH NAME
+.\" ----------------------------------------------------------------------------
+.
 multipath.conf \- multipath daemon configuration file.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH DESCRIPTION
+.\" ----------------------------------------------------------------------------
+.
 .B "/etc/multipath.conf"
 is the configuration file for the multipath daemon. It is used to
 overwrite the built-in configuration table of \fBmultipathd\fP.
 Any line whose first non-white-space character is a '#' is considered
 a comment line. Empty lines are ignored.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH SYNTAX
+.\" ----------------------------------------------------------------------------
+.
 The configuration file contains entries of the form:
 .RS
 .nf
@@ -38,6 +62,8 @@ Each \fIsection\fP contains one or more attributes or subsections. The
 recognized keywords for attributes or subsections depend on the
 section in which they occur.
 .LP
+.
+.
 The following \fIsection\fP keywords are recognized:
 .TP 17
 .B defaults
@@ -52,8 +78,7 @@ multipath topology discovery.
 .B blacklist_exceptions
 This section defines which devices should be included in the
 multipath topology discovery, despite being listed in the
-.I blacklist
-section.
+\fIblacklist\fR section.
 .TP
 .B multipaths
 This section defines the multipath topologies. They are indexed by a
@@ -68,10 +93,15 @@ This section defines values for attributes that should override the
 device-specific settings for all devices.
 .RE
 .LP
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "defaults section"
-The
-.I defaults
-section recognizes the following keywords:
+.\" ----------------------------------------------------------------------------
+.
+The \fIdefaults\fR section recognizes the following keywords:
+.
+.
 .TP 17
 .B verbosity
 Default verbosity. Higher values increase the verbosity level. Valid
@@ -80,18 +110,20 @@ levels are between 0 and 6.
 .TP
 Default value is: \fB2\fR
 .RE
+.
+.
 .TP
 .B polling_interval
 Interval between two path checks in seconds. For properly functioning paths,
-the interval between checks will gradually increase to
-.I max_polling_interval.
-This value will be overridden by the
-.I WatchdogSec
+the interval between checks will gradually increase to \fImax_polling_interval\fR.
+This value will be overridden by the \fIWatchdogSec\fR
 setting in the multipathd.service definition if systemd is used.
 .RS
 .TP
 Default value is: \fB5\fR
 .RE
+.
+.
 .TP
 .B max_polling_interval
 Maximal interval between two path checks in seconds.
@@ -99,6 +131,8 @@ Maximal interval between two path checks in seconds.
 .TP
 Default value is: \fB4 * polling_interval\fR
 .RE
+.
+.
 .TP
 .B reassign_maps
 Enable reassigning of device-mapper maps. With this option multipathd
@@ -109,13 +143,18 @@ device, not the underlying block devices. Possible values are
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B multipath_dir
 Directory where the dynamic shared objects are stored.
 .RS
 .TP
-Default value is: \fB<system dependent>\fR, commonly \fI/lib64/multipath/\fR
+Default value is: \fB<system dependent>\fR. Defined at compile time, commonly
+\fI/lib64/multipath/\fR.
 .RE
+.
+.
 .TP
 .B path_selector
 The default path selector algorithm to use; they are offered by the
@@ -135,6 +174,8 @@ to the path and its relative throughput.
 .TP
 Default value is: \fBservice-time 0\fR
 .RE
+.
+.
 .TP
 .B path_grouping_policy
 The default path grouping policy to apply to unspecified
@@ -159,28 +200,33 @@ per-multipath option in the configuration file.
 One priority group per target node name. Target node names are fetched
 in \fI/sys/class/fc_transport/target*/node_name\fR.
 .TP
-Default value is: \fBgroup_by_prio\fR
+Default value is: \fBfailover\fR
 .RE
+.
+.
 .TP
 .B uid_attribute
 The udev attribute providing a unique path identifier.
 .RS
 .TP
-Default value is: \fBID_SERIAL\fR for SCSI devices
+Default value is: for SCSI devices \fBID_SERIAL\fR
 .TP
-Default value is: \fBID_UID\fR for DASD devices
+Default value is: for DASD devices \fBID_UID\fR
 .RE
+.
+.
 .TP
 .B getuid_callout
-(Deprecated) The default program and args to callout to obtain a unique path
-identifier. Should be specified with an absolute path.
+(Superseded by \fIuid_attribute\fR) The default program and args to callout
+to obtain a unique path identifier. Should be specified with an absolute path.
 .TP
+.
+.
 .B prio
 The name of the path priority routine. The specified routine
 should return a numeric value specifying the relative priority
 of this path. Higher number have a higher priority.
-.I "none"
-is a valid value. Currently the following path priority routines
+\fI"none"\fR is a valid value. Currently the following path priority routines
 are implemented:
 .RS
 .TP 12
@@ -190,7 +236,7 @@ Return a constant priority of \fI1\fR.
 .I sysfs
 Use the sysfs attributes \fIaccess_state\fR and \fIpreferred_path\fR to
 generate the path priority. This prioritizer accepts the optional prio_arg
-.I exclusive_pref_bit
+\fIexclusive_pref_bit\fR
 .TP
 .I emc
 (Hardware-dependent)
@@ -208,8 +254,8 @@ Generate the path priority for NetApp ONTAP class and OEM arrays as IBM NSeries.
 .TP
 .I rdac
 (Hardware-dependent)
-Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp E/EF
-Series, and OEM arrays from IBM DELL SGI STK and SUN.
+Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp SANtricity
+E/EF Series, and OEM arrays from IBM DELL SGI STK and SUN.
 .TP
 .I hp_sw
 (Hardware-dependent)
@@ -218,23 +264,27 @@ Active/Standby mode exclusively.
 .TP
 .I hds
 (Hardware-dependent)
-Generate the path priority for Hitachi HDS Modular storage arrays.
+Generate the path priority for Hitachi AMS 2000 and HUS 100 families of arrays.
 .TP
 .I random
 Generate a random priority between 1 and 10.
-.TP 12
+.TP
 .I weightedpath
 Generate the path priority based on the regular expression and the
 priority provided as argument. Requires prio_args keyword.
 .TP
 .I datacore
+.\" XXX
 ???. Requires prio_args keyword.
 .TP
 .I iet
+.\" XXX
 ???. Requires prio_args keyword.
 .TP
 Default value is: \fBconst\fR
 .RE
+.
+.
 .TP
 .B prio_args
 Arguments to pass to to the prio function. This only applies to certain
@@ -243,48 +293,52 @@ prioritizers:
 .TP 12
 .I weighted
 Needs a value of the form
-.I "<hbtl|devname|wwn> <regex1> <prio1> <regex2> <prio2> ..."
+\fI"<hbtl|devname|serial|wwn> <regex1> <prio1> <regex2> <prio2> ..."\fR
+.RS
+.TP 8
 .I hbtl
-regex can be of SCSI H:B:T:L format  Ex: 1:0:.:. , *:0:0:.
+regex can be of SCSI H:B:T:L format. For example: 1:0:.:. , *:0:0:.
+.TP
 .I devname
-regex can be of device name format  Ex: sda , sd.e
-.I wwn
-regex can be of the form
-.I "host_wwnn:host_wwpn:target_wwnn:target_wwpn"
-these values can be looked up through sysfs or by running
-.I mulitpathd show paths format "%N:%R:%n:%r" Ex: 0x200100e08ba0aea0:0x210100e08ba0aea0:.*:.* , .*:.*:iqn.2009-10.com.redhat.msp.lab.ask-06:.*
+regex can be of device name format. For example: sda , sd.e
+.TP
+.I serial
+regex can be of serial number format. For example: .*J1FR.*324 . The serial can
+be looked up through sysfs or by running multipathd show paths format "%z". For
+example: 0395J1FR904324
 .TP
+.I wwn
+regex can be of the form \fI"host_wwnn:host_wwpn:target_wwnn:target_wwpn"\fR
+these values can be looked up through sysfs or by running \fImultipathd show paths format
+"%N:%R:%n:%r"\fR. For example: 0x200100e08ba0aea0:0x210100e08ba0aea0:.*:.* , .*:.*:iqn.2009-10.com.redhat.msp.lab.ask-06:.*
+.RE
+.TP 12
 .I alua
-If
-.I exclusive_pref_bit
-is set, paths with the \fIpreferred path\fR bit set will always
-be in their own path group.
+If \fIexclusive_pref_bit\fR is set, paths with the \fIpreferred path\fR bit
+set will always be in their own path group.
 .TP
 .I datacore
-.I preferredsds
-???.
+.\" XXX
+\fIpreferredsds\fR ???.
 .TP
 .I iet
-.I preferredip
-???.
+.\" XXX
+\fIpreferredip\fR ???.
 .TP
 Default value is: \fB<unset>\fR
 .RE
+.
+.
 .TP
 .B features
-Specify any device-mapper features to be used. Syntax is
-.I num list
-where
-.I num
-is the number, between 0 and 6, of features in
-.I list.
+Specify any device-mapper features to be used. Syntax is \fInum list\fR
+where \fInum\fR is the number, between 0 and 6, of features in \fIlist\fR.
 Possible values for the feature list are:
 .RS
 .TP 12
 .I queue_if_no_path
-Queue IO if no path is active; identical to the
-.I no_path_retry
-keyword.
+(Superseded by \fIno_path_retry\fR) Queue IO if no path is active. Identical to
+the \fIno_path_retry\fR with \fIqueue\fR value. See KNOWN ISSUES.
 .TP
 .I no_partitions
 Disable automatic partitions generation via kpartx.
@@ -297,6 +351,8 @@ Number of msecs before pg_init retry, it must be between 0 and 60000.
 .TP
 Default value is: \fB0\fR
 .RE
+.
+.
 .TP
 .B path_checker
 The default method used to determine the paths state. Possible values
@@ -308,9 +364,7 @@ are:
 deprecated, please use \fItur\fR instead.
 .TP
 .I tur
-Issue a
-.I TEST UNIT READY
-command to the device.
+Issue a \fITEST UNIT READY\fR command to the device.
 .TP
 .I emc_clariion
 (Hardware-dependent)
@@ -324,7 +378,7 @@ Active/Standby mode exclusively.
 .TP
 .I rdac
 (Hardware-dependent)
-Check the path state for LSI/Engenio/NetApp RDAC class as NetApp E/EF
+Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF
 Series, and OEM arrays from IBM DELL SGI STK and SUN.
 .TP
 .I directio
@@ -336,8 +390,13 @@ Please use \fItur\fR instead.
 (Hardware-dependent)
 Check the path state for HP/COMPAQ Smart Array(CCISS) controllers.
 .TP
+.I rbd
+Check if the path is in the Ceph blacklist and remap the path if it is.
+.TP
 Default value is: \fBtur\fR
 .RE
+.
+.
 .TP
 .B alias_prefix
 The \fIuser_friendly_names\fR prefix.
@@ -345,6 +404,8 @@ The \fIuser_friendly_names\fR prefix.
 .TP
 Default value is: \fBmpath\fR
 .RE
+.
+.
 .TP
 .B failback
 Tell multipathd how to manage path group failback.
@@ -358,15 +419,18 @@ active paths.
 Do not perform automatic failback.
 .TP
 .I followover
-Only perform automatic failback when the first path of a pathgroup
-becomes active. This keeps a node from automatically failing back when
+Used to deal with multiple computers accessing the same Active/Passive storage
+devices. Only perform automatic failback when the first path of a pathgroup
+becomes active. This keeps a cluster node from automatically failing back when
 another node requested the failover.
 .TP
 .I values > 0
 Deferred failback (time to defer in seconds).
 .TP
-Default value is: \fBimmediate\fR
+Default value is: \fBmanual\fR
 .RE
+.
+.
 .TP
 .B  rr_min_io
 The number of IO to route to a path before switching to the next in
@@ -375,6 +439,8 @@ the same path group. This is only for BIO based multipath.
 .TP
 Default value is: \fB1000\fR
 .RE
+.
+.
 .TP
 .B rr_min_io_rq
 The number of IO requests to route to a path before switching to the
@@ -383,10 +449,12 @@ next in the same path group. This is only for request based multipath.
 .TP
 Default value is: \fB1\fR
 .RE
+.
+.
 .TP
 .B max_fds
 Specify the maximum number of file descriptors that can be opened by multipath
-and multipathd.  This is equivalent to ulimit \-n. A value of \fImax\fR will set
+and multipathd. This is equivalent to ulimit \-n. A value of \fImax\fR will set
 this to the system limit from \fI/proc/sys/fs/nr_open\fR. If this is not set, the
 maximum number of open fds is taken from the calling process. It is usually
 1024. To be safe, this should be set to the maximum number of paths plus 32,
@@ -395,34 +463,40 @@ if that number is greated than 1024.
 .TP
 Default value is: \fBmax\fR
 .RE
+.
+.
 .TP
 .B rr_weight
 If set to \fIpriorities\fR the multipath configurator will assign
 path weights as "path prio * rr_min_io". Possible values are
 .I priorities
 or
-.IR uniform .
+.I uniform .
 .RS
 .TP
 Default value is: \fBuniform\fR
 .RE
+.
+.
 .TP
 .B no_path_retry
 Specify the number of retries until disable queueing, or
 .I fail
 for immediate failure (no queueing),
 .I queue
-for never stop queueing. If unset no queueing is attempted.
+for never stop queueing. If unset no queueing is attempted. See KNOWN ISSUES.
 .RS
 .TP
 Default value is: \fB<unset>\fR
 .RE
+.
+.
 .TP
 .B queue_without_daemon
 If set to
 .I no
 , when multipathd stops, queueing will be turned off for all devices.
-This is useful for devices that set no_path_retry.  If a machine is
+This is useful for devices that set no_path_retry. If a machine is
 shut down while all paths to a device are down, it is possible to hang waiting
 for IO to return from the device after multipathd has been stopped. Without
 multipathd running, access to the paths cannot be restored, and the kernel
@@ -433,6 +507,8 @@ cannot be told to stop queueing IO. Setting queue_without_daemon to
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B checker_timeout
 Specify the timeout to use for path checkers and prioritizers that issue SCSI
@@ -441,6 +517,8 @@ commands with an explicit timeout, in seconds.
 .TP
 Default value is: in \fB/sys/block/sd<x>/device/timeout\fR
 .RE
+.
+.
 .TP
 .B flush_on_last_del
 If set to
@@ -451,14 +529,14 @@ deleted.
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B user_friendly_names
 If set to
 .I yes
-, using the bindings file
-.I /etc/multipath/bindings
-to assign a persistent and unique alias to the multipath, in the form of mpath<n>.
-If set to
+, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent
+and unique alias to the multipath, in the form of mpath<n>. If set to
 .I no
 use the WWID as the alias. In either case this be will
 be overridden by any specific aliases in the \fImultipaths\fR section.
@@ -466,6 +544,8 @@ be overridden by any specific aliases in the \fImultipaths\fR section.
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B fast_io_fail_tmo
 Specify the number of seconds the SCSI layer will wait after a problem has been
@@ -477,29 +557,35 @@ will disable the timeout.
 .TP
 Default value is: in \fB5\fR
 .RE
+.
+.
 .TP
 .B dev_loss_tmo
 Specify the number of seconds the SCSI layer will wait after a problem has
 been detected on a FC remote port before removing it from the system. This
 can be set to "infinity" which sets it to the max value of 2147483647
 seconds, or 68 years. It will be automatically adjusted to the overall
-retry interval
-\fIno_path_retry\fR * \fIpolling_interval\fR
+retry interval \fIno_path_retry\fR * \fIpolling_interval\fR
 if a number of retries is given with \fIno_path_retry\fR and the
 overall retry interval is longer than the specified \fIdev_loss_tmo\fR value.
 The Linux kernel will cap this value to \fI300\fR if \fIfast_io_fail_tmo\fR
-is not set.
+is not set. See KNOWN ISSUES.
 .RS
 .TP
 Default value is: \fB600\fR
 .RE
+.
+.
 .TP
 .B bindings_file
-The full pathname of the binding file to be used when the user_friendly_names option is set.
+The full pathname of the binding file to be used when the user_friendly_names
+option is set.
 .RS
 .TP
 Default value is: \fB/etc/multipath/bindings\fR
 .RE
+.
+.
 .TP
 .B wwids_file
 The full pathname of the WWIDs file, which is used by multipath to keep track
@@ -508,6 +594,8 @@ of the WWIDs for LUNs it has created multipath devices on in the past.
 .TP
 Default value is: \fB/etc/multipath/wwids\fR
 .RE
+.
+.
 .TP
 .B log_checker_err
 If set to
@@ -520,9 +608,11 @@ errors are logged at level 3 until the device is restored. If set to
 .TP
 Default value is: \fBalways\fR
 .RE
+.
+.
 .TP
 .B reservation_key
-This is the service action reservation key used by mpathpersist.  It must be
+This is the service action reservation key used by mpathpersist. It must be
 set for all multipath devices using persistent reservations, and it must be
 the same as the RESERVATION KEY field of the PERSISTENT RESERVE OUT parameter
 list which contains an 8-byte value provided by the application client to the
@@ -531,6 +621,8 @@ device server to identify the I_T nexus.
 .TP
 Default value is: \fB<unset>\fR
 .RE
+.
+.
 .TP
 .B retain_attached_hw_handler
 If set to
@@ -543,26 +635,24 @@ multipath will continue to use its configured hardware handler.
 .TP
 Default value is: \fByes\fR
 .RE
+.
+.
 .TP
 .B detect_prio
 If set to
 .I yes
 , multipath will try to detect if the device supports SCSI-3 ALUA. If so, the
-device will automatically use the
-.I sysfs
-prioritizer if the required sysfs attributes
-.I access_state
-and
-.I preferred_path
-are supported, or the
-.I alua
-prioritizer if not. If set to
+device will automatically use the \fIsysfs\fR prioritizer if the required sysf
+attributes \fIaccess_state\fR and \fIpreferred_path\fR are supported, or the
+\fIalua\fR prioritizer if not. If set to
 .I no
 , the prioritizer will be selected as usual.
 .RS
 .TP
 Default value is: \fByes\fR
 .RE
+.
+.
 .TP
 .B force_sync
 If set to
@@ -574,22 +664,24 @@ multipathd checkers running in parallel causes significant CPU pressure.
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B strict_timinig
 If set to
 .I yes
 , multipathd will start a new path checker loop after exactly one second,
-so that each path check will occur at exactly
-.I polling_interval
+so that each path check will occur at exactly \fIpolling_interval\fR
 seconds. On busy systems path checks might take longer than one second;
 here the missing ticks will be accounted for on the next round.
-A warning will be printed if path checks take longer than
-.I polling_interval
+A warning will be printed if path checks take longer than \fIpolling_interval\fR
 seconds.
 .RS
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B deferred_remove
 If set to
@@ -603,6 +695,8 @@ will be canceled.
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B partition_delimiter
 If this value is not set, when multipath renames a device, it will act just
@@ -613,6 +707,8 @@ the \fI-p\fR option is used, and always add delimiter.
 .TP
 Default value is: \fB<unset>\fR
 .RE
+.
+.
 .TP
 .B config_dir
 If set to anything other than "", multipath will search this directory
@@ -623,31 +719,32 @@ config_dir must either be "" or a fully qualified directory name.
 .TP
 Default value is: \fB/etc/multipath/conf.d/\fR
 .RE
+.
+.
 .TP
 .B delay_watch_checks
 If set to a value greater than 0, multipathd will watch paths that have
-recently become valid for this many checks.  If they fail again while they are
+recently become valid for this many checks. If they fail again while they are
 being watched, when they next become valid, they will not be used until they
-have stayed up for
-.I delay_wait_checks
-checks.
+have stayed up for \fIdelay_wait_checks\fR checks.
 .RS
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B delay_wait_checks
 If set to a value greater than 0, when a device that has recently come back
-online fails again within
-.I delay_watch_checks
-checks, the next time it comes back online, it will marked and delayed, and not
-used until it has passed
-.I delay_wait_checks
-checks.
+online fails again within \fIdelay_watch_checks\fR checks, the next time it
+comes back online, it will marked and delayed, and not used until it has passed
+\fIdelay_wait_checks\fR checks.
 .RS
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B find_multipaths
 If set to
@@ -673,6 +770,8 @@ multipath devices, without having to edit the blacklist.
 .TP
 Default value is: \fBno\fR
 .RE
+.
+.
 .TP
 .B uxsock_timeout
 CLI receive timeout in milliseconds. For larger systems CLI commands
@@ -685,6 +784,8 @@ those issues.
 .TP
 Default value is: \fB1000\fR
 .RE
+.
+.
 .TP
 .B retrigger_tries
 Sets the number of times multipathd will try to retrigger a uevent to get the
@@ -693,6 +794,8 @@ WWID.
 .TP
 Default value is: \fB3\fR
 .RE
+.
+.
 .TP
 .B retrigger_delay
 Sets the amount of time, in seconds, to wait between retriggers.
@@ -700,6 +803,8 @@ Sets the amount of time, in seconds, to wait between retriggers.
 .TP
 Default value is: \fB10\fR
 .RE
+.
+.
 .TP
 .B missing_uev_wait_timeout
 Controls how many seconds multipathd will wait, after a new multipath device
@@ -711,13 +816,17 @@ on a device until it receives a change uevent from the initial table load.
 Default value is: \fB30\fR
 .RE
 .
+.
+.\" ----------------------------------------------------------------------------
 .SH "blacklist section"
-The
-.I blacklist
-section is used to exclude specific device from inclusion in the
-multipath topology. It is most commonly used to exclude local disks or
-LUNs for the array controller.
+.\" ----------------------------------------------------------------------------
+.
+The \fIblacklist\fR section is used to exclude specific device from inclusion in
+the multipath topology. It is most commonly used to exclude local disks or LUNs
+for the array controller.
 .LP
+.
+.
 The following keywords are recognized:
 .TP 17
 .B devnode
@@ -735,19 +844,20 @@ Subsection for the device description. This subsection recognizes the
 and
 .B product
 keywords. For a full description of these keywords please see the
-.I devices
-section description.
+\fIdevices\fR section description.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "blacklist_exceptions section"
-The
-.I blacklist_exceptions
-section is used to revert the actions of the
-.I blacklist
-section, for example to include specific device in the
+.\" ----------------------------------------------------------------------------
+.
+The \fIblacklist_exceptions\fR section is used to revert the actions of the
+\fIblacklist\fR section. For example to include specific device in the
 multipath topology. This allows one to selectively include devices which
-would normally be excluded via the
-.I blacklist
-section.
+would normally be excluded via the \fIblacklist\fR section.
 .LP
+.
+.
 The following keywords are recognized:
 .TP 17
 .B devnode
@@ -768,42 +878,36 @@ Subsection for the device description. This subsection recognizes the
 .B vendor
 and
 .B product
-keywords. For a full description of these keywords please see the
-.I devices
+keywords. For a full description of these keywords please see the \fIdevices\fR
 section description.
 .LP
-The
-.I property
-blacklist and whitelist handling is different from the usual handling
-in the sense that the whitelist
-.I has
-to be set, otherwise the device will be blacklisted.
-In these cases the message
-.I blacklisted, udev property missing
-will be displayed.
+The \fIproperty\fR blacklist and whitelist handling is different from the usual
+handling in the sense that the whitelist \fIhas\fR to be set, otherwise the
+device will be blacklisted. In these cases the message \fIblacklisted, udev
+property missing\fR will be displayed.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "multipaths section"
-The only recognized attribute for the
-.I multipaths
-section is the
-.I multipath
-subsection.
+.\" ----------------------------------------------------------------------------
+.
+The only recognized attribute for the \fImultipaths\fR section is the
+\fImultipath\fR subsection.
 .LP
-The
-.I multipath
-subsection recognizes the following attributes:
+.
+.
+The \fImultipath\fR subsection recognizes the following attributes:
 .TP 17
 .B wwid
 (Mandatory) Index of the container.
 .TP
 .B alias
-(Optional) Symbolic name for the multipath map.
+Symbolic name for the multipath map.
 .LP
+.
+.
 The following attributes are optional; if not set the default values
-are taken from the
-.I defaults
-or
-.I devices
-section:
+are taken from the \fIdefaults\fR or \fIdevices\fR section:
 .sp 1
 .PD .1v
 .RS
@@ -842,16 +946,20 @@ section:
 .RE
 .PD
 .LP
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "devices section"
-The only recognized attribute for the
-.I devices
-section is the
-.I device
+.\" ----------------------------------------------------------------------------
+.
+The only recognized attribute for the \fIdevices\fR section is the \fIdevice\fR
 subsection.
 .LP
-The
-.I device
-subsection recognizes the following attributes:
+.
+.
+The \fIdevice\fR subsection recognizes the following attributes:
+.TP
+vendor, product, revision and product_blacklist are POSIX Extended regex.
 .TP 17
 .B vendor
 (Mandatory) Vendor identifier.
@@ -860,17 +968,17 @@ subsection recognizes the following attributes:
 (Mandatory) Product identifier.
 .TP
 .B revision
-(Optional) Revision identfier.
+Revision identfier.
 .TP
 .B product_blacklist
-(Optional) Product strings to blacklist for this vendor.
+Product strings to blacklist for this vendor.
 .TP
 .B alias_prefix
-(Optional) The user_friendly_names prefix to use for this
+The user_friendly_names prefix to use for this
 device type, instead of the default "mpath".
 .TP
 .B hardware_handler
-(Optional) The hardware handler to use for this device type.
+The hardware handler to use for this device type.
 The following hardware handler are implemented:
 .RS
 .TP 12
@@ -880,7 +988,7 @@ Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX families.
 .TP
 .I 1 rdac
 (Hardware-dependent)
-Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp E/EF
+Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF
 Series, and OEM arrays from IBM DELL SGI STK and SUN.
 .TP
 .I 1 hp_sw
@@ -894,10 +1002,11 @@ Hardware handler for SCSI-3 ALUA compatible arrays.
 .TP
 Default value is: \fB<unset>\fR
 .RE
+.
+.
 .LP
 The following attributes are optional; if not set the default values
-are taken from the
-.I defaults
+are taken from the \fIdefaults\fR
 section:
 .sp 1
 .PD .1v
@@ -945,13 +1054,14 @@ section:
 .RE
 .PD
 .LP
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "overrides section"
+.\" ----------------------------------------------------------------------------
+.
 The overrides section recognizes the following optional attributes; if not set
-the values are taken from the
-.I devices
-or
-.I defaults
-sections:
+the values are taken from the \fIdevices\fR or \fIdefaults\fR sections:
 .sp 1
 .PD .1v
 .RS
@@ -1004,7 +1114,12 @@ sections:
 .RE
 .PD
 .LP
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "WWID generation"
+.\" ----------------------------------------------------------------------------
+.
 Multipath uses a \fIWorld Wide Identification\fR (WWID) to determine
 which paths belong to the same device. Each path presenting the same
 WWID is assumed to point to the same device.
@@ -1028,35 +1143,37 @@ variable.
 If none of the \fIgetuid_callout\fR or \fIuid_attribute\fR parameters
 are present multipath will try to use the sysfs attribute
 \fIvpd_pg83\fR to generate the WWID.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "KNOWN ISSUES"
-The usage of
-.I queue_if_no_path
-option can lead to
-.I D state
-processes being hung and not killable in situations where all the paths to the LUN go offline.
-It is advisable to use the
-.I no_path_retry
-option instead.
+.\" ----------------------------------------------------------------------------
+.
+The usage of \fIqueue_if_no_path\fR option can lead to \fID state\fR
+processes being hung and not killable in situations where all the paths to the
+LUN go offline. It is advisable to use the \fIno_path_retry\fR option instead.
 .P
-The use of
-.I queue_if_no_path
-or
-.I no_path_retry
-might lead to a deadlock if the
-.I dev_loss_tmo
-setting results in a device being removed while I/O is still queued.
-The multipath daemon will update the
-.I dev_loss_tmo
+The use of \fIqueue_if_no_path\fR or \fIno_path_retry\fR might lead to a
+deadlock if the \fIdev_loss_tmo\fR setting results in a device being removed
+while I/O is still queued. The multipath daemon will update the \fIdev_loss_tmo\fR
 setting accordingly to avoid this deadlock. Hence if both values are
-specified the order of precedence is
-.I no_path_retry, queue_if_no_path, dev_loss_tmo.
-
+specified the order of precedence is \fIno_path_retry, queue_if_no_path, dev_loss_tmo\fR.
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH "SEE ALSO"
+.\" ----------------------------------------------------------------------------
+.
 .BR udev (8),
 .BR dmsetup (8),
 .BR multipath (8),
 .BR multipathd (8).
-
+.
+.
+.\" ----------------------------------------------------------------------------
 .SH AUTHORS
-.I multipath-tools
-was developed by Christophe Varoqui, <christophe.varoqui@opensvc.com> and others.
+.\" ----------------------------------------------------------------------------
+.
+\fImultipath-tools\fR was developed by Christophe Varoqui, <christophe.varoqui@opensvc.com>
+and others.
+.\" EOF
index 092b74bc98cc42f1db0ce462aeafd3bdbffbc64a..03d7815041cba3d45f5c59b5a8d458032e866e06 100644 (file)
@@ -1,42 +1,30 @@
-EXEC = multipathd
-
 include ../Makefile.inc
 
 #
-# basic flags setting
+# debuging stuff
 #
+#CFLAGS += -DLCKDBG
+#CFLAGS += -D_DEBUG_
+#CFLAGS += -DLOGDBG
 CFLAGS += -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir)
+
+LDFLAGS += -ludev -ldl -L$(multipathdir) -lmultipath -L$(mpathpersistdir) \
+          -lmpathpersist -L$(mpathcmddir) -lmpathcmd -lurcu -lpthread \
+          -ldevmapper -lreadline
+
 ifdef SYSTEMD
        CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD)
-endif
-LDFLAGS += -lurcu -lpthread -ldevmapper -lreadline
-ifdef SYSTEMD
        ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1)
                LDFLAGS += -lsystemd
        else
                LDFLAGS += -lsystemd-daemon
        endif
 endif
-LDFLAGS += -ludev -ldl \
-       -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \
-       -L$(mpathcmddir) -lmpathcmd
-
-#
-# debuging stuff
-#
-#CFLAGS += -DLCKDBG
-#CFLAGS += -D_DEBUG_
-#CFLAGS += -DLOGDBG
 
-#
-# object files
-#
 OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o
 
+EXEC = multipathd
 
-#
-# directives
-#
 all : $(EXEC)
 
 $(EXEC): $(OBJS)
index 3663c0aaf2ef34d81efabfcb75cf07d31a796543..9a197282dee18a1fdeb33721307d082fe30e2de0 100644 (file)
@@ -487,10 +487,9 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
 
                pthread_cleanup_push(cleanup_lock, &vecs->lock);
                if (tmo.tv_sec) {
-                       vecs->lock.depth++;
-                       r = pthread_mutex_timedlock(vecs->lock.mutex, &tmo);
+                       r = timedlock(&vecs->lock, &tmo);
                } else {
-                       lock(vecs->lock);
+                       lock(&vecs->lock);
                        r = 0;
                }
                if (r == 0) {
index 87843070ad177150da1f6f5aa9c338c1f9e6d913..001eb8c3c8adbc8c4aa179ccb360c184d2b93178 100644 (file)
@@ -117,6 +117,11 @@ struct udev * udev;
 
 struct config *multipath_conf;
 
+/* Local variables */
+static volatile sig_atomic_t exit_sig;
+static volatile sig_atomic_t reconfig_sig;
+static volatile sig_atomic_t log_reset_sig;
+
 const char *
 daemon_status(void)
 {
@@ -446,7 +451,7 @@ uev_add_map (struct uevent * uev, struct vectors * vecs)
                }
        }
        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-       lock(vecs->lock);
+       lock(&vecs->lock);
        pthread_testcancel();
        rc = ev_add_map(uev->kernel, alias, vecs);
        lock_cleanup_pop(vecs->lock);
@@ -552,7 +557,7 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
        minor = uevent_get_minor(uev);
 
        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-       lock(vecs->lock);
+       lock(&vecs->lock);
        pthread_testcancel();
        mpp = find_mp_by_minor(vecs->mpvec, minor);
 
@@ -613,7 +618,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
        }
 
        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-       lock(vecs->lock);
+       lock(&vecs->lock);
        pthread_testcancel();
        pp = find_path_by_dev(vecs->pathvec, uev->kernel);
        if (pp) {
@@ -663,7 +668,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
                return 1;
        }
        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-       lock(vecs->lock);
+       lock(&vecs->lock);
        pthread_testcancel();
        ret = store_path(vecs->pathvec, pp);
        if (!ret) {
@@ -826,7 +831,7 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs)
 
        condlog(2, "%s: remove path (uevent)", uev->kernel);
        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-       lock(vecs->lock);
+       lock(&vecs->lock);
        pthread_testcancel();
        pp = find_path_by_dev(vecs->pathvec, uev->kernel);
        if (pp)
@@ -952,7 +957,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
                condlog(2, "%s: update path write_protect to '%d' (uevent)",
                        uev->kernel, ro);
                pthread_cleanup_push(cleanup_lock, &vecs->lock);
-               lock(vecs->lock);
+               lock(&vecs->lock);
                pthread_testcancel();
                /*
                 * pthread_mutex_lock() and pthread_mutex_unlock()
@@ -1126,10 +1131,9 @@ out:
        return r;
 }
 
-static void *rcu_unregister(void *param)
+static void rcu_unregister(void *param)
 {
        rcu_unregister_thread();
-       return NULL;
 }
 
 static void *
@@ -1438,6 +1442,16 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
        return 0;
 }
 
+void repair_path(struct path * pp)
+{
+       if (pp->state != PATH_DOWN)
+               return;
+
+       checker_repair(&pp->checker);
+       if (strlen(checker_message(&pp->checker)))
+               LOG_MSG(1, checker_message(&pp->checker));
+}
+
 /*
  * Returns '1' if the path has been checked, '-1' if it was blacklisted
  * and '0' otherwise
@@ -1602,6 +1616,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
                        pp->mpp->failback_tick = 0;
 
                        pp->mpp->stat_path_failures++;
+                       repair_path(pp);
                        return 1;
                }
 
@@ -1696,7 +1711,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
        }
 
        pp->state = newstate;
-
+       repair_path(pp);
 
        if (pp->mpp->wait_for_udev)
                return 1;
@@ -1782,7 +1797,7 @@ checkerloop (void *ap)
                }
                if (vecs->pathvec) {
                        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-                       lock(vecs->lock);
+                       lock(&vecs->lock);
                        pthread_testcancel();
                        vector_foreach_slot (vecs->pathvec, pp, i) {
                                rc = check_path(vecs, pp, ticks);
@@ -1797,7 +1812,7 @@ checkerloop (void *ap)
                }
                if (vecs->mpvec) {
                        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-                       lock(vecs->lock);
+                       lock(&vecs->lock);
                        pthread_testcancel();
                        defered_failback_tick(vecs->mpvec);
                        retry_count_tick(vecs->mpvec);
@@ -1808,7 +1823,7 @@ checkerloop (void *ap)
                        count--;
                else {
                        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-                       lock(vecs->lock);
+                       lock(&vecs->lock);
                        pthread_testcancel();
                        condlog(4, "map garbage collection");
                        mpvec_garbage_collector(vecs);
@@ -2032,21 +2047,9 @@ init_vecs (void)
        if (!vecs)
                return NULL;
 
-       vecs->lock.mutex =
-               (pthread_mutex_t *)MALLOC(sizeof(pthread_mutex_t));
-
-       if (!vecs->lock.mutex)
-               goto out;
-
-       pthread_mutex_init(vecs->lock.mutex, NULL);
-       vecs->lock.depth = 0;
+       pthread_mutex_init(&vecs->lock.mutex, NULL);
 
        return vecs;
-
-out:
-       FREE(vecs);
-       condlog(0, "failed to init paths");
-       return NULL;
 }
 
 static void *
@@ -2071,6 +2074,10 @@ signal_set(int signo, void (*func) (int))
 void
 handle_signals(void)
 {
+       if (exit_sig) {
+               condlog(2, "exit (signal)");
+               exit_daemon();
+       }
        if (reconfig_sig) {
                condlog(2, "reconfigure (signal)");
                set_config_state(DAEMON_CONFIGURE);
@@ -2081,6 +2088,7 @@ handle_signals(void)
                log_reset("multipathd");
                pthread_mutex_unlock(&logq_lock);
        }
+       exit_sig = 0;
        reconfig_sig = 0;
        log_reset_sig = 0;
 }
@@ -2094,7 +2102,7 @@ sighup (int sig)
 static void
 sigend (int sig)
 {
-       exit_daemon();
+       exit_sig = 1;
 }
 
 static void
@@ -2115,11 +2123,8 @@ signal_init(void)
        sigset_t set;
 
        sigemptyset(&set);
-       sigaddset(&set, SIGHUP);
-       sigaddset(&set, SIGUSR1);
-       sigaddset(&set, SIGUSR2);
-       sigaddset(&set, SIGALRM);
-       pthread_sigmask(SIG_BLOCK, &set, NULL);
+       sigaddset(&set, SIGPIPE);
+       pthread_sigmask(SIG_SETMASK, &set, NULL);
 
        signal_set(SIGHUP, sighup);
        signal_set(SIGUSR1, sigusr1);
@@ -2245,7 +2250,7 @@ child (void * param)
        if (ignore_new_devs)
                conf->ignore_new_devs = ignore_new_devs;
        uxsock_timeout = conf->uxsock_timeout;
-       multipath_conf = conf;
+       rcu_assign_pointer(multipath_conf, conf);
        dm_init(conf->verbosity);
        dm_drv_version(conf->version, TGT_MPATH);
        if (init_checkers(conf->multipath_dir)) {
@@ -2312,6 +2317,11 @@ child (void * param)
                use_watchdog = conf->checkint;
        }
 #endif
+       /*
+        * Startup done, invalidate configuration
+        */
+       conf = NULL;
+
        /*
         * Signal start of configuration
         */
@@ -2357,44 +2367,45 @@ child (void * param)
                pthread_cleanup_pop(1);
                if (running_state == DAEMON_CONFIGURE) {
                        pthread_cleanup_push(cleanup_lock, &vecs->lock);
-                       lock(vecs->lock);
+                       lock(&vecs->lock);
                        pthread_testcancel();
                        if (!need_to_delay_reconfig(vecs)) {
                                reconfigure(vecs);
                        } else {
+                               conf = get_multipath_config();
                                conf->delayed_reconfig = 1;
+                               put_multipath_config(conf);
                        }
                        lock_cleanup_pop(vecs->lock);
                        post_config_state(DAEMON_IDLE);
                }
        }
 
-       lock(vecs->lock);
+       lock(&vecs->lock);
+       conf = get_multipath_config();
        if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
                vector_foreach_slot(vecs->mpvec, mpp, i)
                        dm_queue_if_no_path(mpp->alias, 0);
+       put_multipath_config(conf);
        remove_maps_and_stop_waiters(vecs);
-       unlock(vecs->lock);
+       unlock(&vecs->lock);
 
        pthread_cancel(check_thr);
        pthread_cancel(uevent_thr);
        pthread_cancel(uxlsnr_thr);
        pthread_cancel(uevq_thr);
 
-       lock(vecs->lock);
+       pthread_join(check_thr, NULL);
+       pthread_join(uevent_thr, NULL);
+       pthread_join(uxlsnr_thr, NULL);
+       pthread_join(uevq_thr, NULL);
+
+       lock(&vecs->lock);
        free_pathvec(vecs->pathvec, FREE_PATHS);
        vecs->pathvec = NULL;
-       unlock(vecs->lock);
-       /* Now all the waitevent threads will start rushing in. */
-       while (vecs->lock.depth > 0) {
-               sleep (1); /* This is weak. */
-               condlog(3, "Have %d wait event checkers threads to de-alloc,"
-                       " waiting...", vecs->lock.depth);
-       }
-       pthread_mutex_destroy(vecs->lock.mutex);
-       FREE(vecs->lock.mutex);
-       vecs->lock.depth = 0;
-       vecs->lock.mutex = NULL;
+       unlock(&vecs->lock);
+
+       pthread_mutex_destroy(&vecs->lock.mutex);
        FREE(vecs);
        vecs = NULL;
 
@@ -2418,8 +2429,9 @@ child (void * param)
         * because logging functions like dlog() and dm_write_log()
         * reference the config.
         */
-       free_config(conf);
-       conf = NULL;
+       conf = rcu_dereference(multipath_conf);
+       rcu_assign_pointer(multipath_conf, NULL);
+       call_rcu(&conf->rcu, rcu_free_config);
        udev_unref(udev);
        udev = NULL;
        pthread_attr_destroy(&waiter_attr);
@@ -2520,7 +2532,7 @@ main (int argc, char *argv[])
        udev = udev_new();
 
        while ((arg = getopt(argc, argv, ":dsv:k::Bn")) != EOF ) {
-       switch(arg) {
+               switch(arg) {
                case 'd':
                        foreground = 1;
                        if (logsink > 0)
index 10b3a6dfd78010d6a0758500bbb90c2a18826cb8..f72580dd1d944f63ddd2c456eb0896d724ed3e71 100644 (file)
@@ -4,12 +4,12 @@
 #define MAPGCINT 5
 
 enum daemon_status {
-    DAEMON_INIT,
-    DAEMON_START,
-    DAEMON_CONFIGURE,
-    DAEMON_IDLE,
-    DAEMON_RUNNING,
-    DAEMON_SHUTDOWN,
+       DAEMON_INIT,
+       DAEMON_START,
+       DAEMON_CONFIGURE,
+       DAEMON_IDLE,
+       DAEMON_RUNNING,
+       DAEMON_SHUTDOWN,
 };
 
 struct prout_param_descriptor;
index 9bac1dd6856addbc5a956affc1b47e75475f9c94..47d18e2ce91801ebb11c99d6f00e43d4568ee493 100644 (file)
@@ -1,11 +1,9 @@
 #include <sys/types.h> /* for pid_t */
 #include <sys/stat.h>  /* for open */
-#include <signal.h>    /* for kill() */
-#include <errno.h>     /* for ESHRC */
-#include <stdio.h>     /* for f...() */
+#include <errno.h>     /* for EACCESS and EAGAIN */
+#include <stdio.h>     /* for snprintf() */
 #include <string.h>    /* for memset() */
-#include <stdlib.h>    /* for atoi() */
-#include <unistd.h>    /* for unlink() */
+#include <unistd.h>    /* for ftruncate() */
 #include <fcntl.h>     /* for fcntl() */
 
 #include "debug.h"
index 62ff6f4c3b86585ab3fb3248fccadf36043ec7b1..c5c32eacb3802f4c49b9b8e5fac4f7377373a87a 100644 (file)
@@ -28,6 +28,9 @@
 
 static void print_reply(char *s)
 {
+       if (!s)
+               return;
+
        if (isatty(1)) {
                printf("%s", s);
                return;
index 015964811cd42867503af6062dbed79a3355e9da..7a9faf38e0888b43411aa1588c4d73c3a8f30d18 100644 (file)
@@ -49,8 +49,6 @@ struct client {
 LIST_HEAD(clients);
 pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER;
 struct pollfd *polls;
-volatile sig_atomic_t reconfig_sig = 0;
-volatile sig_atomic_t log_reset_sig = 0;
 
 /*
  * handle a new client joining
@@ -147,14 +145,16 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
        pthread_cleanup_push(uxsock_cleanup, NULL);
 
        condlog(3, "uxsock: startup listener");
-       polls = (struct pollfd *)MALLOC(MIN_POLLS + 1);
+       polls = (struct pollfd *)MALLOC((MIN_POLLS + 1) * sizeof(struct pollfd));
        if (!polls) {
                condlog(0, "uxsock: failed to allocate poll fds");
                return NULL;
        }
-       pthread_sigmask(SIG_SETMASK, NULL, &mask);
-       sigdelset(&mask, SIGHUP);
-       sigdelset(&mask, SIGUSR1);
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGINT);
+       sigaddset(&mask, SIGTERM);
+       sigaddset(&mask, SIGHUP);
+       sigaddset(&mask, SIGUSR1);
        while (1) {
                struct client *c, *tmp;
                int i, poll_count, num_clients;
@@ -167,9 +167,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                }
                if (num_clients != old_clients) {
                        struct pollfd *new;
-                       if (num_clients < MIN_POLLS) {
+                       if (num_clients <= MIN_POLLS && old_clients > MIN_POLLS) {
                                new = REALLOC(polls, (1 + MIN_POLLS) *
                                                sizeof(struct pollfd));
+                       } else if (num_clients <= MIN_POLLS && old_clients <= MIN_POLLS) {
+                               new = polls;
                        } else {
                                new = REALLOC(polls, (1+num_clients) *
                                                sizeof(struct pollfd));
@@ -181,7 +183,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                                pthread_yield();
                                continue;
                        }
-                       num_clients = old_clients;
+                       old_clients = num_clients;
                        polls = new;
                }
                polls[0].fd = ux_sock;
@@ -210,8 +212,10 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                        break;
                }
 
-               if (poll_count == 0)
+               if (poll_count == 0) {
+                       handle_signals();
                        continue;
+               }
 
                /* see if a client wants to speak to us */
                for (i = 1; i < num_clients + 1; i++) {
@@ -239,6 +243,10 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                                        dead_client(c);
                                        continue;
                                }
+                               if (!inbuf) {
+                                       condlog(4, "recv_packet get null request");
+                                       continue;
+                               }
                                condlog(4, "cli[%d]: Got request [%s]",
                                        i, inbuf);
                                uxsock_trigger(inbuf, &reply, &rlen,
index 7839fce6cef5aad97f7a389d05cf3fc8cfa520a5..4ef47d5f9f16e3986ce70e27a219a885111dc1e7 100644 (file)
@@ -6,7 +6,4 @@ typedef int (uxsock_trigger_fn)(char *, char **, int *, void *);
 void * uxsock_listen(uxsock_trigger_fn uxsock_trigger,
                     void * trigger_data);
 
-extern volatile sig_atomic_t reconfig_sig;
-extern volatile sig_atomic_t log_reset_sig;
-
 #endif