diff options
46 files changed, 271 insertions, 3392 deletions
@@ -1,8 +1,7 @@ # Makefile # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> - -BUILD = glibc +# # # Try to supply the linux kernel headers. @@ -20,7 +19,14 @@ endif export KRNLSRC export KRNLOBJ -BUILDDIRS = $(shell find . -mindepth 2 -name Makefile -exec dirname {} \; | grep -vE '^lib|/\.') +BUILDDIRS = \ + libmultipath \ + libcheckers \ + libprio \ + multipath \ + multipathd \ + devmap_name \ + kpartx ifeq ($(MULTIPATH_VERSION),) VERSION = $(shell basename ${PWD} | cut -d'-' -f3) diff --git a/Makefile.inc b/Makefile.inc index 1b07ab0..3bc8a4d 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -13,12 +13,6 @@ ifeq ($(TOPDIR),) TOPDIR = .. endif -ifeq ($(strip $(BUILD)),klibc) - CC = klcc - klibcdir = /usr/lib/klibc - libdm = $(klibcdir)/lib/libdevmapper.a -endif - prefix = exec_prefix = $(prefix) bindir = $(exec_prefix)/sbin @@ -29,16 +23,12 @@ multipathdir = $(TOPDIR)/libmultipath mandir = $(prefix)/usr/share/man/man8 man5dir = $(prefix)/usr/share/man/man5 rcdir = $(prefix)/etc/init.d +libdir = $(prefix)/lib/multipath GZIP = /bin/gzip -9 -c +INSTALL_PROGRAM = install -CHECKERSLIB = $(checkersdir)/libcheckers -MULTIPATHLIB = $(multipathdir)/libmultipath -LIBPRIO = $(libpriodir)/libprio - -INSTALL_PROGRAM = install -s - -OPTFLAGS = -pipe -g -Wall -Wunused -Wstrict-prototypes +OPTFLAGS = -pipe -g -Wall -Wunused -Wstrict-prototypes -fPIC CFLAGS = $(OPTFLAGS) %.o: %.c diff --git a/devmap_name/Makefile b/devmap_name/Makefile index d8d8b09..a167537 100644 --- a/devmap_name/Makefile +++ b/devmap_name/Makefile @@ -1,38 +1,25 @@ # Makefile # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> -BUILD = glibc - +# include ../Makefile.inc -OBJS = devmap_name.o - -ifeq ($(strip $(BUILD)),klibc) - OBJS += $(libdm) -else - LDFLAGS = -ldevmapper -endif - EXEC = devmap_name +OBJS = devmap_name.o -all: $(BUILD) +LDFLAGS = -ldevmapper -prepare: - rm -f core *.o *.gz +all: $(EXEC) -glibc: prepare $(OBJS) +$(EXEC): $(OBJS) $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(GZIP) $(EXEC).8 > $(EXEC).8.gz -klibc: prepare $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - install: $(EXEC) $(EXEC).8 - install -d $(DESTDIR)$(bindir) - install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - install -d $(DESTDIR)$(mandir) - install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) uninstall: rm $(DESTDIR)$(bindir)/$(EXEC) diff --git a/kpartx/Makefile b/kpartx/Makefile index b4cca6c..21e4ad4 100644 --- a/kpartx/Makefile +++ b/kpartx/Makefile @@ -2,49 +2,30 @@ # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> # -BUILD=glibc - include ../Makefile.inc CFLAGS += -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ifeq ($(strip $(BUILD)),klibc) - OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o gpt.o crc32.o \ - lopart.o xstrncpy.o devmapper.o dasd.o mac.o sun.o \ - $(MULTIPATHLIB)-$(BUILD).a $(libdm) -else - LDFLAGS = -ldevmapper - OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ - gpt.o mac.o crc32.o lopart.o xstrncpy.o devmapper.o -endif - +LDFLAGS = -ldevmapper +OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ + gpt.o mac.o crc32.o lopart.o xstrncpy.o devmapper.o EXEC = kpartx -all: $(BUILD) - -prepare: - rm -f core *.o *.gz +all: $(EXEC) -glibc: prepare $(OBJS) +$(EXEC): $(OBJS) $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(GZIP) $(EXEC).8 > $(EXEC).8.gz -klibc: prepare $(OBJS) - $(CC) -static -o $(EXEC) $(CRT0) $(OBJS) $(KLIBC) $(LIBGCC) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - -$(MULTIPATHLIB)-$(BUILD).a: - make -C $(multipathdir) BUILD=$(BUILD) - install: $(EXEC) $(EXEC).8 - install -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) - install -d $(DESTDIR)$(libudevdir) - install -m 755 kpartx_id $(DESTDIR)$(libudevdir) - install -d $(DESTDIR)/etc/udev/rules.d - install -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/ - install -d $(DESTDIR)$(mandir) - install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) + $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) + $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d + $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) uninstall: rm -f $(DESTDIR)$(bindir)/$(EXEC) diff --git a/libcheckers/Makefile b/libcheckers/Makefile index 6340a68..06c309e 100644 --- a/libcheckers/Makefile +++ b/libcheckers/Makefile @@ -2,26 +2,23 @@ # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> # -BUILD = glibc - include ../Makefile.inc +LIBS = libcheckers.so OBJS = libsg.o checkers.o readsector0.o tur.o directio.o emc_clariion.o hp_sw.o rdac.o -all: $(BUILD) - -prepare: - @file *-$(BUILD).a >/dev/null 2>&1 || rm -f core *.o *.gz +SHARED_FLAGS = -shared -klibc: prepare $(OBJS) - ar rs libcheckers-klibc.a *.o +all: $(LIBS) -glibc: prepare $(OBJS) - ar rs libcheckers-glibc.a *.o +$(LIBS): $(OBJS) + $(CC) $(SHARED_FLAGS) -o $@ $^ install: + $(INSTALL_PROGRAM) -o root -g root -m 755 $(LIBS) $(libdir) uninstall: + rm -f $(libdir)/$(LIBS) clean: - rm -f core *.a *.o *.gz + rm -f core *.a *.o *.gz *.so diff --git a/libmultipath/Makefile b/libmultipath/Makefile index 04761e4..bdbaa2c 100644 --- a/libmultipath/Makefile +++ b/libmultipath/Makefile @@ -2,11 +2,11 @@ # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> # -BUILD = glibc - include ../Makefile.inc +LIBS = libmultipath.so CFLAGS += -I$(checkersdir) -I$(libpriodir) +SHARED_FLAGS += -shared OBJS = memory.o parser.o vector.o devmapper.o callout.o \ hwtable.o blacklist.o util.o dmparser.o config.o \ @@ -15,15 +15,10 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ switchgroup.o uxsock.o print.o alias.o log_pthread.o \ log.o configure.o structs_vec.o sysfs.o -PREVBUILD = $(shell nm debug.o 2> /dev/null|grep log_safe) - -ifeq ($(strip $(DAEMON)),1) +#ifeq ($(strip $(DAEMON)),1) OBJS += lock.o waiter.o CFLAGS += -DDAEMON - CLEAN = $(shell if [ "x$(PREVBUILD)" = "x" ]; then echo clean; fi) -else - CLEAN = $(shell if [ ! "x$(PREVBUILD)" = "x" ]; then echo clean; fi) -endif +#endif LIBDM_API_FLUSH = $(shell objdump -T /lib/libdevmapper.so.* | grep -c dm_task_no_flush) @@ -31,21 +26,17 @@ ifeq ($(strip $(LIBDM_API_FLUSH)),1) CFLAGS += -DLIBDM_API_FLUSH endif -all: $(BUILD) - -prepare: $(CLEAN) - @file *-$(BUILD).a >/dev/null 2>&1 || rm -f core *.o *.gz - @rm -f *-$(BUILD).a - -klibc: $(OBJS) - ar rs libmultipath-klibc.a *.o +all: $(LIBS) -glibc: $(OBJS) - ar rs libmultipath-glibc.a *.o +$(LIBS): $(OBJS) + $(CC) $(SHARED_FLAGS) $(CFLAGS) -o $@ $(OBJS) install: + $(INSTALL_PROGRAM) -o root -g root -m 755 -d $(libdir) + $(INSTALL_PROGRAM) -o root -g root -m 755 $(LIBS) $(libdir)/$(LIBS) uninstall: + rm -f $(libdir)/$(LIBS) clean: - rm -f core *.a *.o *.gz + rm -f core *.a *.o *.gz *.so diff --git a/libmultipath/configure.c b/libmultipath/configure.c index 3b58af7..72148c9 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -453,7 +453,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid) if (!mpp->paths) { condlog(0, "%s: skip coalesce (no paths)", mpp->alias); - remove_map(mpp, vecs, NULL, 0); + remove_map(mpp, vecs, 0); continue; } @@ -481,7 +481,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid) verify_paths(mpp, vecs, NULL); if (setup_map(mpp)) { - remove_map(mpp, vecs, NULL, 0); + remove_map(mpp, vecs, 0); continue; } @@ -495,7 +495,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid) "for create/reload map", mpp->alias, r); if (r == DOMAP_FAIL) { - remove_map(mpp, vecs, NULL, 0); + remove_map(mpp, vecs, 0); continue; } else /* if (r == DOMAP_RETRY) */ return r; @@ -523,7 +523,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid) vector_set_slot(newmp, mpp); } else - remove_map(mpp, vecs, NULL, 0); + remove_map(mpp, vecs, 0); } } /* @@ -543,7 +543,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid) if ((j = find_slot(newmp, (void *)mpp)) != -1) vector_del_slot(newmp, j); - remove_map(mpp, vecs, NULL, 0); + remove_map(mpp, vecs, 0); if (dm_flush_map(mpp->alias, DEFAULT_TARGET)) condlog(2, "%s: remove failed (dead)", diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index 80b8dd2..0b644ed 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c @@ -655,6 +655,7 @@ setup_default_hwtable (vector hw) while (hwe->vendor) { hwe->checker = checker_lookup(hwe->checker_name); + hwe->prio = prio_lookup(hwe->prio_name); r += store_hwe(hw, hwe); hwe++; } diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index 807d7ab..8f8406c 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -8,6 +8,7 @@ #include "vector.h" #include "defaults.h" #include "debug.h" +#include "waiter.h" #include "structs.h" #include "structs_vec.h" #include "devmapper.h" @@ -16,7 +17,6 @@ #include "propsel.h" #include "sysfs.h" #include "discovery.h" -#include "waiter.h" /* * creates or updates mpp->paths reading mpp->pg @@ -112,9 +112,14 @@ set_multipath_wwid (struct multipath * mpp) dm_get_uuid(mpp->alias, mpp->wwid); } -extern void -remove_map (struct multipath * mpp, struct vectors * vecs, - stop_waiter_thread_func *stop_waiter, int purge_vec) +#define KEEP_WAITER 0 +#define STOP_WAITER 1 +#define KEEP_VEC 1 +#define PURGE_VEC 1 + +static void +_remove_map (struct multipath * mpp, struct vectors * vecs, + int stop_waiter, int purge_vec) { int i; @@ -124,7 +129,7 @@ remove_map (struct multipath * mpp, struct vectors * vecs, * stop the DM event waiter thread */ if (stop_waiter) - stop_waiter(mpp, vecs); + stop_waiter_thread(mpp, vecs); /* * clear references to this map @@ -142,14 +147,26 @@ remove_map (struct multipath * mpp, struct vectors * vecs, } extern void -remove_maps (struct vectors * vecs, - stop_waiter_thread_func *stop_waiter) +remove_map (struct multipath * mpp, struct vectors * vecs, int purge_vec) +{ + _remove_map(mpp, vecs, KEEP_WAITER, purge_vec); +} + +extern void +remove_map_and_stop_waiter (struct multipath * mpp, struct vectors * vecs, + int purge_vec) +{ + _remove_map(mpp, vecs, STOP_WAITER, purge_vec); +} + +static void +_remove_maps (struct vectors * vecs, int stop_waiter) { int i; struct multipath * mpp; vector_foreach_slot (vecs->mpvec, mpp, i) { - remove_map(mpp, vecs, stop_waiter, 1); + _remove_map(mpp, vecs, stop_waiter, 1); i--; } @@ -157,6 +174,18 @@ remove_maps (struct vectors * vecs, vecs->mpvec = NULL; } +extern void +remove_maps (struct vectors * vecs) +{ + _remove_maps(vecs, KEEP_WAITER); +} + +extern void +remove_maps_and_stop_waiters (struct vectors * vecs) +{ + _remove_maps(vecs, STOP_WAITER); +} + static struct hwentry * extract_hwe_from_path(struct multipath * mpp) { @@ -294,14 +323,13 @@ retry: return 0; out: - remove_map(mpp, vecs, NULL, 1); + remove_map(mpp, vecs, PURGE_VEC); return 1; } extern struct multipath * add_map_without_path (struct vectors * vecs, - int minor, char * alias, - start_waiter_thread_func *start_waiter) + int minor, char * alias) { struct multipath * mpp = alloc_multipath(); @@ -321,12 +349,12 @@ add_map_without_path (struct vectors * vecs, vector_set_slot(vecs->mpvec, mpp); - if (start_waiter(mpp, vecs)) + if (start_waiter_thread(mpp, vecs)) goto out; return mpp; out: - remove_map(mpp, vecs, NULL, 1); + remove_map(mpp, vecs, PURGE_VEC); return NULL; } @@ -359,7 +387,7 @@ add_map_with_path (struct vectors * vecs, return mpp; out: - remove_map(mpp, vecs, NULL, add_vec); + remove_map(mpp, vecs, PURGE_VEC); return NULL; } diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h index 81d9eaa..b8a416f 100644 --- a/libmultipath/structs_vec.h +++ b/libmultipath/structs_vec.h @@ -9,9 +9,6 @@ struct vectors { vector mpvec; }; -typedef void (stop_waiter_thread_func) (struct multipath *, struct vectors *); -typedef int (start_waiter_thread_func) (struct multipath *, struct vectors *); - void set_no_path_retry(struct multipath *mpp); int adopt_paths (vector pathvec, struct multipath * mpp); @@ -23,14 +20,13 @@ int update_mpp_paths(struct multipath * mpp, vector pathvec); int setup_multipath (struct vectors * vecs, struct multipath * mpp); int update_multipath_strings (struct multipath *mpp, vector pathvec); -void remove_map (struct multipath * mpp, struct vectors * vecs, - stop_waiter_thread_func *stop_waiter, int purge_vec); -void remove_maps (struct vectors * vecs, - stop_waiter_thread_func *stop_waiter); +void remove_map (struct multipath * mpp, struct vectors * vecs, int purge_vec); +void remove_map_and_stop_waiter (struct multipath * mpp, struct vectors * vecs, int purge_vec); +void remove_maps (struct vectors * vecs); +void remove_maps_and_stop_waiters (struct vectors * vecs); struct multipath * add_map_without_path (struct vectors * vecs, - int minor, char * alias, - start_waiter_thread_func *start_waiter); + int minor, char * alias); struct multipath * add_map_with_path (struct vectors * vecs, struct path * pp, int add_vec); int update_multipath (struct vectors *vecs, char *mapname); diff --git a/libprio/Makefile b/libprio/Makefile index 177a67b..ee86294 100644 --- a/libprio/Makefile +++ b/libprio/Makefile @@ -2,28 +2,38 @@ # # Copyright (C) 2007 Christophe Varoqui, <christophe.varoqui@free.fr> # -BUILD = glibc - include ../Makefile.inc -OBJS = libprio.o random.o const.o hp_sw.o emc.o rdac.o alua.o alua_rtpg.o netapp.o hds.o +LIBS = \ + libprio.so \ + libpriorandom.so \ + libprioconst.so \ + libpriohp_sw.so \ + libprioemc.so \ + libpriordac.so \ + libprioalua.so \ + libprionetapp.so \ + libpriohds.so CFLAGS += -I$(multipathdir) +SHARED_FLAGS += -shared -fPIC -all: $(BUILD) +all: $(LIBS) -prepare: - @file *-$(BUILD).a >/dev/null 2>&1 || rm -f core *.o *.gz +libprioalua.so: alua.o alua_rtpg.o + $(CC) $(SHARED_FLAGS) -o $@ $^ -klibc: prepare $(OBJS) - ar rs libprio-klibc.a *.o +%.so: %.o + $(CC) $(SHARED_FLAGS) -o $@ $^ -glibc: prepare $(OBJS) - ar rs libprio-glibc.a *.o +libprio%.so: %.o + $(CC) $(SHARED_FLAGS) -o $@ $^ -install: +install: $(LIBS) + install -m 755 libprio*.so $(libdir) uninstall: + rm -f $(libdir)/libprio*.so clean: - rm -f core *.a *.o *.gz + rm -f core *.a *.o *.gz *.so diff --git a/libprio/alua.c b/libprio/alua.c index 64f41f7..a19d691 100644 --- a/libprio/alua.c +++ b/libprio/alua.c @@ -17,6 +17,7 @@ #include <debug.h> #include "libprio.h" +#include "alua.h" #define ALUA_PRIO_NOT_SUPPORTED 1 #define ALUA_PRIO_RTPG_FAILED 2 @@ -56,7 +57,7 @@ get_alua_info(int fd) return rc; } -int prio_alua(struct path * pp) +int getprio (struct path * pp) { int rc = get_alua_info(pp->fd); if (rc >= 0) { diff --git a/libprio/const.c b/libprio/const.c index 5e2ef23..9951f55 100644 --- a/libprio/const.c +++ b/libprio/const.c @@ -2,7 +2,7 @@ #include "libprio.h" -int prio_const(struct path * pp) +int getprio (struct path * pp) { return 1; } diff --git a/libprio/emc.c b/libprio/emc.c index 047269d..f230d52 100644 --- a/libprio/emc.c +++ b/libprio/emc.c @@ -74,7 +74,7 @@ out: return(ret); } -int prio_emc(struct path * pp) +int getprio (struct path * pp) { return emc_clariion_prio(pp->dev, pp->fd); } diff --git a/libprio/hds.c b/libprio/hds.c index d79e514..bdce175 100644 --- a/libprio/hds.c +++ b/libprio/hds.c @@ -165,7 +165,7 @@ int hds_modular_prio (const char *dev, int fd) return -1; } -int prio_hds(struct path * pp) +int getprio (struct path * pp) { return hds_modular_prio(pp->dev, pp->fd); } diff --git a/libprio/hp_sw.c b/libprio/hp_sw.c index f46a1cf..7230e48 100644 --- a/libprio/hp_sw.c +++ b/libprio/hp_sw.c @@ -95,7 +95,7 @@ out: return(ret); } -int prio_hp_sw(struct path * pp) +int getprio (struct path * pp) { return hp_sw_prio(pp->dev, pp->fd); } diff --git a/libprio/libprio.c b/libprio/libprio.c index 0ff33dc..195a2a8 100644 --- a/libprio/libprio.c +++ b/libprio/libprio.c @@ -1,59 +1,88 @@ #include <stdio.h> #include <string.h> +#include <stddef.h> +#include <dlfcn.h> +#include <debug.h> #include "libprio.h" -static struct prio prioritizers[] = { - { - .name = PRIO_CONST, - .getprio = prio_const - }, - { - .name = PRIO_RANDOM, - .getprio = prio_random - }, - { - .name = PRIO_ALUA, - .getprio = prio_alua - }, - { - .name = PRIO_EMC, - .getprio = prio_emc - }, - { - .name = PRIO_RDAC, - .getprio = prio_rdac - }, - { - .name = PRIO_NETAPP, - .getprio = prio_netapp - }, - { - .name = PRIO_HDS, - .getprio = prio_hds - }, - { - .name = PRIO_HP_SW, - .getprio = prio_hp_sw - }, - { - .name = "", - .getprio = NULL - }, -}; +static LIST_HEAD(prioritizers); + +int init_prio (void) +{ + INIT_LIST_HEAD(&prioritizers); + if (!add_prio(DEFAULT_PRIO)) + return 1; + return 0; +} + +struct prio * alloc_prio (void) +{ + return zalloc(sizeof(struct prio)); +} + +void free_prio (struct prio * p) +{ + free(p); +} + +void cleanup_prio(void) +{ + struct prio * prio_loop; + struct prio * prio_temp; + + list_for_each_entry_safe(prio_loop, prio_temp, &prioritizers, node) { + list_del(&prio_loop->node); + free(prio_loop); + } +} struct prio * prio_lookup (char * name) { - struct prio * p = &prioritizers[0]; - - while (p->getprio) { + struct prio * p; + + list_for_each_entry(p, &prioritizers, node) { if (!strncmp(name, p->name, PRIO_NAME_LEN)) return p; - p++; } + p = add_prio(name); + if (p) + return p; return prio_default(); } +struct prio * add_prio (char * name) +{ + char libname[LIB_PRIO_NAMELEN]; + void * handle; + struct prio * p; + char *errstr; + + p = alloc_prio(); + if (!p) + return NULL; + snprintf(libname, LIB_PRIO_NAMELEN, "libprio%s.so", name); + condlog(0, "loading %s prioritizer", libname); + handle = dlopen(libname, RTLD_NOW); + errstr = dlerror(); + if (errstr != NULL) + condlog(0, "A dynamic linking error occurred: (%s)", errstr); + if (!handle) + goto out; + p->getprio = (int (*)(struct path *)) dlsym(handle, "getprio"); + errstr = dlerror(); + if (errstr != NULL) + condlog(0, "A dynamic linking error occurred: (%s)", errstr); + if (!p->getprio) + goto out; + snprintf(p->name, PRIO_NAME_LEN, "%s", name); + list_add(&p->node, &prioritizers); + return p; +out: + free_prio(p); + return NULL; +} + int prio_getprio (struct prio * p, struct path * pp) { return p->getprio(pp); diff --git a/libprio/libprio.h b/libprio/libprio.h index 978e14e..4a0900d 100644 --- a/libprio/libprio.h +++ b/libprio/libprio.h @@ -7,17 +7,22 @@ #include "../libcheckers/checkers.h" #include "../libmultipath/vector.h" #include "../libmultipath/structs.h" +#include "../libmultipath/list.h" +#include "../libmultipath/memory.h" -#include "const.h" -#include "random.h" -#include "hp_sw.h" -#include "alua.h" -#include "emc.h" -#include "netapp.h" -#include "hds.h" -#include "rdac.h" +#define DEFAULT_PRIO "const" -#define DEFAULT_PRIO PRIO_CONST +/* + * Known prioritizers for use in hwtable.c + */ +#define PRIO_ALUA "alua" +#define PRIO_CONST "const" +#define PRIO_EMC "emc" +#define PRIO_HDS "hds" +#define PRIO_HP_SW "hp_sw" +#define PRIO_NETAPP "netapp" +#define PRIO_RANDOM "random" +#define PRIO_RDAC "rdac" /* * Value used to mark the fact prio was not defined @@ -27,14 +32,17 @@ /* * strings lengths */ +#define LIB_PRIO_NAMELEN 255 #define PRIO_NAME_LEN 16 -#define PRIO_DEV_LEN 256 struct prio { + struct list_head node; char name[PRIO_NAME_LEN]; int (*getprio)(struct path *); }; +int init_prio (void); +struct prio * add_prio (char *); struct prio * prio_lookup (char *); int prio_getprio (struct prio *, struct path *); char * prio_name (struct prio *); diff --git a/libprio/netapp.c b/libprio/netapp.c index f1da1f2..59718f8 100644 --- a/libprio/netapp.c +++ b/libprio/netapp.c @@ -238,7 +238,7 @@ static int netapp_prio(const char *dev, int fd) } } -int prio_netapp(struct path * pp) +int getprio (struct path * pp) { return netapp_prio(pp->dev, pp->fd); } diff --git a/libprio/random.c b/libprio/random.c index 68441c1..4ee2995 100644 --- a/libprio/random.c +++ b/libprio/random.c @@ -5,7 +5,7 @@ #include "libprio.h" -int prio_random(struct path * pp) +int getprio (struct path * pp) { struct timeval tv; diff --git a/libprio/rdac.c b/libprio/rdac.c index d7c19a9..71efae2 100644 --- a/libprio/rdac.c +++ b/libprio/rdac.c @@ -85,7 +85,7 @@ out: return(ret); } -int prio_rdac(struct path * pp) +int getprio (struct path * pp) { return rdac_prio(pp->dev, pp->fd); } diff --git a/multipath/Makefile b/multipath/Makefile index e7e557e..b01cca8 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -1,55 +1,35 @@ # Makefile # # Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> -BUILD = glibc - +# include ../Makefile.inc -OBJS = main.o $(MULTIPATHLIB)-$(BUILD).a $(CHECKERSLIB)-$(BUILD).a $(LIBPRIO)-$(BUILD).a +OBJS = main.o CFLAGS += -I$(multipathdir) -I$(checkersdir) -I$(libpriodir) -LDFLAGS += -laio - -ifeq ($(strip $(BUILD)),klibc) - OBJS += $(libdm) -else - LDFLAGS += -ldevmapper -endif +LDFLAGS += -laio -ldevmapper -lpthread \ + -lmultipath -L$(multipathdir) \ + -lcheckers -L$(checkersdir) \ + -lprio -L$(libpriodir) \ EXEC = multipath -all: $(BUILD) +all: $(EXEC) -prepare: - make -C $(multipathdir) prepare - rm -f core *.o *.gz +$(EXEC): $(OBJS) + $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(GZIP) $(EXEC).8 > $(EXEC).8.gz $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz -glibc: prepare $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) - -klibc: prepare $(OBJS) - $(CC) -static -o $(EXEC) $(CRT0) $(OBJS) $(KLIBC) $(LIBGCC) - -$(LIBPRIO)-$(BUILD).a: - make -C $(libpriodir) BUILD=$(BUILD) $(BUILD) - -$(CHECKERSLIB)-$(BUILD).a: - make -C $(checkersdir) BUILD=$(BUILD) $(BUILD) - -$(MULTIPATHLIB)-$(BUILD).a: - make -C $(multipathdir) BUILD=$(BUILD) $(BUILD) - install: - install -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - install -d $(DESTDIR)/etc/udev/rules.d - install -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/ - install -d $(DESTDIR)$(mandir) - install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) - install -d $(DESTDIR)$(man5dir) - install -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) + $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d + $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) uninstall: rm $(DESTDIR)/etc/udev/rules.d/multipath.rules diff --git a/multipath/main.c b/multipath/main.c index 922e0f9..f196ee7 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -324,6 +324,10 @@ main (int argc, char *argv[]) if (dm_prereq(DEFAULT_TARGET)) exit(1); + if (init_prio()) { + condlog(0, "failed to initialize prioritizers"); + exit(1); + } if (load_config(DEFAULT_CONFIGFILE)) exit(1); diff --git a/multipathd/Makefile b/multipathd/Makefile index b82f159..d5525aa 100644 --- a/multipathd/Makefile +++ b/multipathd/Makefile @@ -1,4 +1,3 @@ -BUILD = glibc EXEC = multipathd include ../Makefile.inc @@ -6,8 +5,11 @@ include ../Makefile.inc # # basic flags setting # -CFLAGS += -DDAEMON -I$(multipathdir) -I$(checkersdir) -LDFLAGS = -lpthread -ldevmapper -lreadline -lncurses -laio +CFLAGS += -DDAEMON -I$(multipathdir) -I$(checkersdir) -I$(libpriodir) +LDFLAGS += -lpthread -ldevmapper -lreadline -lncurses -laio \ + -lmultipath -L$(multipathdir) \ + -lcheckers -L$(checkersdir) \ + -lprio -L$(libpriodir) # # debuging stuff @@ -19,40 +21,24 @@ LDFLAGS = -lpthread -ldevmapper -lreadline -lncurses -laio # # object files # -OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o \ - $(MULTIPATHLIB)-glibc.a $(CHECKERSLIB)-glibc.a \ - $(LIBPRIO)-glibc.a +OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o # # directives # -all : $(BUILD) +all : $(EXEC) -glibc: $(EXEC) - -klibc: - $(MAKE) BUILD=glibc glibc - -$(EXEC): clean $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) +$(EXEC): $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(EXEC) $(OBJS) $(GZIP) $(EXEC).8 > $(EXEC).8.gz -$(LIBPRIO)-glibc.a: - $(MAKE) -C $(libpriodir) BUILD=glibc glibc - -$(CHECKERSLIB)-glibc.a: - $(MAKE) -C $(checkersdir) BUILD=glibc glibc - -$(MULTIPATHLIB)-glibc.a: - $(MAKE) -C $(multipathdir) DAEMON=1 BUILD=glibc glibc - install: - install -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) - install -d $(DESTDIR)$(rcdir) - install -d $(DESTDIR)$(mandir) - install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) uninstall: rm -f $(DESTDIR)$(bindir)/$(EXEC) @@ -60,6 +46,5 @@ uninstall: rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz clean: - $(MAKE) -C $(multipathdir) prepare DAEMON=1 rm -f core *.o $(EXEC) *.gz diff --git a/multipathd/main.c b/multipathd/main.c index d30ba83..8947ba4 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -19,6 +19,7 @@ * libcheckers */ #include <checkers.h> +#include <libprio.h> /* * libmultipath @@ -199,7 +200,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) } orphan_paths(vecs->pathvec, mpp); - remove_map(mpp, vecs, stop_waiter_thread, 1); + remove_map_and_stop_waiter(mpp, vecs, 1); return 0; } @@ -255,8 +256,7 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs) /* * now we can register the map */ - if (map_present && (mpp = add_map_without_path(vecs, minor, alias, - start_waiter_thread))) { + if (map_present && (mpp = add_map_without_path(vecs, minor, alias))) { sync_map_state(mpp); condlog(3, "%s: devmap %s added", alias, dev->kernel); return 0; @@ -437,7 +437,7 @@ rescan: return 0; out: - remove_map(mpp, vecs, NULL, 1); + remove_map(mpp, vecs, 1); return 1; } @@ -563,7 +563,7 @@ ev_remove_path (char * devname, struct vectors * vecs) return 0; out: - remove_map(mpp, vecs, stop_waiter_thread, 1); + remove_map_and_stop_waiter(mpp, vecs, 1); return 1; } @@ -811,7 +811,7 @@ mpvec_garbage_collector (struct vectors * vecs) vector_foreach_slot (vecs->mpvec, mpp, i) { if (mpp && mpp->alias && !dm_map_present(mpp->alias)) { condlog(2, "%s: remove dead map", mpp->alias); - remove_map(mpp, vecs, stop_waiter_thread, 1); + remove_map_and_stop_waiter(mpp, vecs, 1); i--; } } @@ -1095,7 +1095,7 @@ configure (struct vectors * vecs, int start_waiters) /* * purge dm of old maps */ - remove_maps(vecs, NULL); + remove_maps(vecs); /* * save new set of maps formed by considering current path state @@ -1125,7 +1125,7 @@ reconfigure (struct vectors * vecs) * free old map and path vectors ... they use old conf state */ if (VECTOR_SIZE(vecs->mpvec)) - remove_maps(vecs, stop_waiter_thread); + remove_maps_and_stop_waiters(vecs); if (VECTOR_SIZE(vecs->pathvec)) free_pathvec(vecs->pathvec, FREE_PATHS); @@ -1272,6 +1272,10 @@ child (void * param) condlog(2, "--------start up--------"); condlog(2, "read " DEFAULT_CONFIGFILE); + if (init_prio()) { + condlog(0, "failed to initialize prioritizers"); + exit(1); + } if (load_config(DEFAULT_CONFIGFILE)) exit(1); @@ -1344,7 +1348,7 @@ child (void * param) * exit path */ lock(vecs->lock); - remove_maps(vecs, stop_waiter_thread); + remove_maps_and_stop_waiters(vecs); free_pathvec(vecs->pathvec, FREE_PATHS); pthread_cancel(check_thr); diff --git a/path_priority/pp_alua/LICENSE b/path_priority/pp_alua/LICENSE deleted file mode 100644 index 9e31bbf..0000000 --- a/path_priority/pp_alua/LICENSE +++ /dev/null @@ -1,483 +0,0 @@ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/path_priority/pp_alua/Makefile b/path_priority/pp_alua/Makefile deleted file mode 100644 index 6f356a1..0000000 --- a/path_priority/pp_alua/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -#============================================================================== -# (C) Copyright IBM Corp. 2004, 2005 All Rights Reserved. -# -# Makefile -# -# Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access. -# It determines the ALUA state of a device and prints a priority value to -# stdout. -# -# Author(s): Jan Kunigk -# S. Bader <shbader@de.ibm.com> -# -# This file is released under the GPL. -#============================================================================== -EXEC = mpath_prio_alua -BUILD = glibc -DEBUG = 0 -DEBUG_DUMPHEX = 0 -OBJS = main.o rtpg.o -INSTALL = install -D - -TOPDIR = ../.. - -ifneq ($(shell ls $(TOPDIR)/Makefile.inc 2>/dev/null),) -include $(TOPDIR)/Makefile.inc -endif - -CFLAGS += -DDEBUG=$(DEBUG) - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) $(EXEC).8.gz - $(INSTALL) -s -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - $(INSTALL) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)/$(EXEC).8.gz - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) - rm $(DESTDIR)$(mandir)/$(EXEC).8.gz - -clean: - rm -f *.o *.gz $(EXEC) - -$(EXEC).8.gz: $(EXEC).8 - $(GZIP) $< >$@ - -main.o: main.c rtpg.h spc3.h - -rtpg.o: rtpg.c rtpg.h spc3.h diff --git a/path_priority/pp_alua/main.c b/path_priority/pp_alua/main.c deleted file mode 100644 index ba8da99..0000000 --- a/path_priority/pp_alua/main.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * (C) Copyright IBM Corp. 2004, 2005 All Rights Reserved. - * - * main.c - * - * Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access. - * It determines the ALUA state of a device and prints a priority value to - * stdout. - * - * Author(s): Jan Kunigk - * S. Bader <shbader@de.ibm.com> - * - * This file is released under the GPL. - */ -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <limits.h> -#include <stdlib.h> -#include <unistd.h> -#include <strings.h> - -#include "rtpg.h" - -#define ALUA_PRIO_SUCCESS 0 -#define ALUA_PRIO_INVALID_COMMANDLINE 1 -#define ALUA_PRIO_OPEN_FAILED 2 -#define ALUA_PRIO_NOT_SUPPORTED 3 -#define ALUA_PRIO_RTPG_FAILED 4 -#define ALUA_PRIO_GETAAS_FAILED 5 - -#define ALUA_PRIO_MAJOR 0 -#define ALUA_PRIO_MINOR 6 - -#define PRINT_ERROR(f, a...) \ - if (verbose) \ - fprintf(stderr, "ERROR: " f, ##a) -#define PRINT_VERBOSE(f, a...) \ - if (verbose) \ - printf(f, ##a) - -char * devicename = NULL; -int verbose = 0; - -char *basename(char *p) -{ - char *r; - - for(r = p; *r != '\0'; r++); - for(; r > p && *(r - 1) != '/'; r--); - - return r; -} - -void -print_help(char *command) -{ - printf("Usage: %s <options> <device> [<device> [...]]\n\n", - basename(command)); - printf("Options are:\n"); - - printf("\t-d <device directory>\n"); - printf("\t\tSets the directory prefix for relative path names and"); - printf(" created\n\t\tpath names. (default = \"/dev\")\n"); - - printf("\t-h\n"); - printf("\t\tPrint this help.\n"); - - printf("\t-v\n"); - printf("\t\tTurn on verbose output.\n"); - - printf("\t-V\n"); - printf("\t\tPrints the version number and exits.\n"); - - printf("\nDevice may be an absolute or relative path to a device "); - printf("node or a major and\nminor number seperated by a colon (:)."); - printf(" In this case a temporary device node\nwill be created in "); - printf("the device directory.\n"); -} - -void -print_version(char *command) -{ - printf("(C) Copyright IBM Corp. 2004, 2005 All Rights Reserved.\n"); - printf("This is %s version %u.%u\n", - basename(command), - ALUA_PRIO_MAJOR, - ALUA_PRIO_MINOR - ); -} - -int -open_block_device(char *name) -{ - int fd; - struct stat st; - - if (stat(name, &st) != 0) { - PRINT_ERROR("Cannot get file status from %s (errno = %i)!\n", - name, errno); - return -ALUA_PRIO_OPEN_FAILED; - } - if (!S_ISBLK(st.st_mode)) { - PRINT_ERROR("%s is not a block device!\n", name); - return -ALUA_PRIO_OPEN_FAILED; - } - fd = open(name, O_RDONLY); - if (fd < 0) { - PRINT_ERROR("Couldn't open %s (errno = %i)!\n", name, errno); - return -ALUA_PRIO_OPEN_FAILED; - } - return fd; -} - -int -close_block_device(int fd) -{ - return close(fd); -} - -int -get_alua_info(int fd) -{ - char * aas_string[] = { - [AAS_OPTIMIZED] = "active/optimized", - [AAS_NON_OPTIMIZED] = "active/non-optimized", - [AAS_STANDBY] = "standby", - [AAS_UNAVAILABLE] = "unavailable", - [AAS_TRANSITIONING] = "transitioning between states", - }; - int rc; - int tpg; - - rc = get_target_port_group_support(fd); - if (rc < 0) - return rc; - - if (verbose) { - printf("Target port groups are "); - switch(rc) { - case TPGS_NONE: - printf("not"); - break; - case TPGS_IMPLICIT: - printf("implicitly"); - break; - case TPGS_EXPLICIT: - printf("explicitly"); - break; - case TPGS_BOTH: - printf("implicitly and explicitly"); - break; - } - printf(" supported.\n"); - } - - if (rc == TPGS_NONE) - return -ALUA_PRIO_NOT_SUPPORTED; - - tpg = get_target_port_group(fd); - if (tpg < 0) { - PRINT_ERROR("Couldn't get target port group!\n"); - return -ALUA_PRIO_RTPG_FAILED; - } - PRINT_VERBOSE("Reported target port group is %i", tpg); - - rc = get_asymmetric_access_state(fd, tpg); - if (rc < 0) { - PRINT_VERBOSE(" [get AAS failed]\n"); - PRINT_ERROR("Couln't get asymmetric access state!\n"); - return -ALUA_PRIO_GETAAS_FAILED; - } - PRINT_VERBOSE(" [%s]\n", - (aas_string[rc]) ? aas_string[rc] : "invalid/reserved" - ); - - return rc; -} - -int -main (int argc, char **argv) -{ - char devicepath[PATH_MAX]; - char * devicedir; - char * s_opts = "d:hvV"; - char * pos; - int fd; - int rc; - int c; - - devicedir = "/dev"; - while ((c = getopt(argc, argv, s_opts)) >= 0) { - switch(c) { - case 'd': - devicedir = optarg; - break; - case 'h': - print_help(argv[0]); - return ALUA_PRIO_SUCCESS; - case 'V': - print_version(argv[0]); - return ALUA_PRIO_SUCCESS; - case 'v': - verbose = 1; - break; - case '?': - case ':': - default: - return ALUA_PRIO_INVALID_COMMANDLINE; - } - } - - if (optind == argc) { - print_help(argv[0]); - printf("\n"); - PRINT_ERROR("No device specified!\n"); - return ALUA_PRIO_INVALID_COMMANDLINE; - } - - rc = ALUA_PRIO_SUCCESS; - for(c = optind; c < argc && !rc; c++) { - if (argv[c][0] == '/') { - pos = NULL; - sprintf(devicepath, "%s", argv[c]); - } else if ((pos = index(argv[c], ':')) == NULL) { - sprintf(devicepath, "%s/%s", devicedir, argv[c]); - } else { - int major; - int minor; - - major = atoi(argv[c]); - minor = atoi(++pos); - sprintf(devicepath, "%s/tmpdev-%u:%u-%u", - devicedir, major, minor, getpid() - ); - mknod( - devicepath, - S_IFBLK|S_IRUSR|S_IWUSR, - makedev(major, minor) - ); - - } - - fd = open_block_device(devicepath); - if (fd < 0) { - if (pos != NULL) - unlink(devicepath); - return -fd; - } - rc = get_alua_info(fd); - if (rc >= 0) { - switch(rc) { - case AAS_OPTIMIZED: - rc = 50; - break; - case AAS_NON_OPTIMIZED: - rc = 10; - break; - case AAS_STANDBY: - rc = 1; - break; - default: - rc = 0; - } - printf("%u\n", rc); - rc = ALUA_PRIO_SUCCESS; - } - close_block_device(fd); - - /* The path was created before. */ - if (pos != NULL) - unlink(devicepath); - } - - return -rc; -} diff --git a/path_priority/pp_alua/mpath_prio_alua.8 b/path_priority/pp_alua/mpath_prio_alua.8 deleted file mode 100644 index 58568a5..0000000 --- a/path_priority/pp_alua/mpath_prio_alua.8 +++ /dev/null @@ -1,162 +0,0 @@ -.TH MPATH_PRIO_ALUA 8 "July 2006" "multipath-tools" \ -"Linux Administrator's Manual" -.SH NAME -mpath_prio_alua \- Path priority tool based on Asymmetric LUn Access -.SH SYNOPSIS -.B mpath_prio_alua -.RB [\| \-d\ \c -.IR directory \|] -.RB [\| \-h \|] -.RB [\| \-v \|] -.RB [\| \-V \|] -.IR device " \|[ " device " \|[ " ... " \|]\|]" -.SH DESCRIPTION -.B mpath_prio_alua -is used as a priority callout for the multipath command. It returns a number -that is used by multipath to group devices with the same priority together. -.SH OPTIONS -.TP -.BI \-d " directory" -target directory for devices given as relative device names or devices given -as -.IR major : minor \c - number. -Default is "/dev". -.TP -.B \-h -displays the command line help. -.TP -.B \-v -turns on verbose output. This shows all results in human readable format. -This includes information about the port group the device is in and its -current state. -.TP -.B \-V -shows the version number and exits. -.TP -.BI device -specifies the device to query (the device must be a SCSI device that supports -the \*[lq]Report Target Port Groups\*[rq] command). -One of the following three formats may be used: -.RS -.IP \(bu 2 -The full path name that starts with '/' (e.g. /dev/sda). -.IP \(bu -The device name only. This will prefix the directory name given by the -\-d option (e.g. sda). -.IP \(bu -The major and minor number of the device separated by ':'. This will -create a temporary device node in the device directory (e.g. 8:0). The -temporary name will be -.RB \*[lq] tmpdev-<major>:<minor>-<pid> \*[rq]. -.SH "RETURN VALUE" -The mpath_prio_alua command returns the following values: -.IP \fB0 -on success. In this case the priority for the device is printed to -stdout. The priority value is: -.RS -.IP \fB50\fP -for devices that are in the active, optimized group -.IP \fB10 -for devices that are in an active but non-optimized group -.IP \fB1 -for devices that are in the standby group -.IP \fB0 -for all other groups -.RE -.IP "" -The reason for the widely spaced priority values is the way multipath handles -them. It will multiply the number of paths in a group with the priority value -and select the group with the highest result. Thus, if there are six paths in -the active, non-optimized group and only one in the active, optimized one, -the non-optimized group would be used. -.IP \fB1 -Indicates an error parsing the command line. -.IP \fB2 -The given devices could not be opened for reading. -.IP \fB3 -The device does not support target port groups. -.IP \fB4 -The inquiry command did not return a target port group for the given device. -.IP \fB5 -The report target port group command failed or did not return a target -port group that was obtained from the inquiry command. -.SH "EXAMPLES" -This example queries a device directly and returns the priority string: -.P -.RS -.B #> mpath_prio_alua /dev/sda -.br -50 -.RE -.P -Now the major and minor number is used to specify the device and verbose -output is selected: -.P -.RS -.B #> mpath_prio_alua -v 8:0 -.br -Target port groups are implicitly supported. -.br -Reported target port group is 0 [active/optimized] -.br -50 -.RE -.P -The following example shows the entries in the devices section of the -.RI "multipath-tool configuration file (" /etc/multipath.conf ) -to support an IBM DS6000 storage system: -.P -.RS -.PD 0 -device { -.RS -.TP 22 -.B vendor -"IBM " -.TP -.B product -"1750500 " -.TP -.B path_grouping_policy -group_by_prio -.TP -.B prio_callout -"/sbin/mpath_prio_alua -d/tmp %d" -.TP -.B features -"1 queue_if_no_path" -.TP -.B path_checker -tur -.RE -} -.PD -.RE -.TP -.B Notes: -.IP \(bu 2 -Depending on your default configuration not all keywords are required -.RB "(e.g. if your " path_checker " is set to tur you don't have to" -.RB "use the " path_checker " statement in the device section)." -.IP \(bu -.RB "The entries for " vendor " and " product " must be strings that are 8" -.RB "characters long (for " vendor ") and 16 characters long (for " product ")." -The strings have to be padded with blanks if necessary. -.IP \(bu -If you are working with hotpluggable devices whose device nodes are created -by udev you should use the %d flag in the -.BR prio_callout " statement." -This is because a short time elapses between the devices being available -and udev creating the device nodes. -.IP \(bu -If under certain circumstances your storage subsystem temporarily reports -.RB "failures on all paths, you should use the " features " statement showed" -in the example. -This will configure the multipath volume to requeue I/O until a path becomes -available again, instead of reporting failures in that case. -.SH "SEE ALSO" -.BR multipath (8), -.SH AUTHORS -.B mpath_prio_alua -was developed by Jan Kunigk and adapted by Stefan Bader <shbader@de.ibm.com> diff --git a/path_priority/pp_alua/rtpg.c b/path_priority/pp_alua/rtpg.c deleted file mode 100644 index 701f9d5..0000000 --- a/path_priority/pp_alua/rtpg.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * (C) Copyright IBM Corp. 2004, 2005 All Rights Reserved. - * - * rtpg.c - * - * Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access. - * It determines the ALUA state of a device and prints a priority value to - * stdout. - * - * Author(s): Jan Kunigk - * S. Bader <shbader@de.ibm.com> - * - * This file is released under the GPL. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <inttypes.h> - -#define __user -#include <scsi/sg.h> - -#include "rtpg.h" - -#define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 300000 - -/* - * Macro used to print debug messaged. - */ -#if DEBUG > 0 -#define PRINT_DEBUG(f, a...) \ - fprintf(stderr, "DEBUG: " f, ##a) -#else -#define PRINT_DEBUG(f, a...) -#endif - -/* - * Optionally print the commands sent and the data received a hex dump. - */ -#if DEBUG > 0 -#if DEBUG_DUMPHEX > 0 -#define PRINT_HEX(p, l) print_hex(p, l) -void -print_hex(unsigned char *p, unsigned long len) -{ - int i; - - for(i = 0; i < len; i++) { - if (i % 16 == 0) - printf("%04x: ", i); - printf("%02x%s", p[i], (((i + 1) % 16) == 0) ? "\n" : " "); - } - printf("\n"); -} -#else -#define PRINT_HEX(p, l) -#endif -#else -#define PRINT_HEX(p, l) -#endif - -/* - * Returns 0 if the SCSI command either was successful or if the an error was - * recovered, otherwise 1. (definitions taken from sg_err.h) - */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 -#define RECOVERED_ERROR 0x01 - -static int -scsi_error(struct sg_io_hdr *hdr) -{ - /* Treat SG_ERR here to get rid of sg_err.[ch] */ - hdr->status &= 0x7e; - - if ( - (hdr->status == 0) && - (hdr->host_status == 0) && - (hdr->driver_status == 0) - ) { - return 0; - } - - if ( - (hdr->status == SCSI_CHECK_CONDITION) || - (hdr->status == SCSI_COMMAND_TERMINATED) || - ((hdr->driver_status & 0xf) == SG_ERR_DRIVER_SENSE) - ) { - if (hdr->sbp && (hdr->sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = hdr->sbp; - - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - - if (sense_key == RECOVERED_ERROR) - return 0; - } - } - - return 1; -} - -/* - * Helper function to setup and run a SCSI inquiry command. - */ -int -do_inquiry(int fd, int evpd, unsigned int codepage, void *resp, int resplen) -{ - struct inquiry_command cmd; - struct sg_io_hdr hdr; - unsigned char sense[SENSE_BUFF_LEN]; - - memset(&cmd, 0, sizeof(cmd)); - cmd.op = OPERATION_CODE_INQUIRY; - if (evpd) { - inquiry_command_set_evpd(&cmd); - cmd.page = codepage; - } - set_uint16(cmd.length, resplen); - PRINT_HEX((unsigned char *) &cmd, sizeof(cmd)); - - memset(&hdr, 0, sizeof(hdr)); - hdr.interface_id = 'S'; - hdr.cmdp = (unsigned char *) &cmd; - hdr.cmd_len = sizeof(cmd); - hdr.dxfer_direction = SG_DXFER_FROM_DEV; - hdr.dxferp = resp; - hdr.dxfer_len = resplen; - hdr.sbp = sense; - hdr.mx_sb_len = sizeof(sense); - hdr.timeout = DEF_TIMEOUT; - - if (ioctl(fd, SG_IO, &hdr) < 0) { - PRINT_DEBUG("do_inquiry: IOCTL failed!\n"); - return -RTPG_INQUIRY_FAILED; - } - - if (scsi_error(&hdr)) { - PRINT_DEBUG("do_inquiry: SCSI error!\n"); - return -RTPG_INQUIRY_FAILED; - } - PRINT_HEX((unsigned char *) resp, resplen); - - return 0; -} - -/* - * This function returns the support for target port groups by evaluating the - * data returned by the standard inquiry command. - */ -int -get_target_port_group_support(int fd) -{ - struct inquiry_data inq; - int rc; - - rc = do_inquiry(fd, 0, 0x00, &inq, sizeof(inq)); - if (!rc) { - rc = inquiry_data_get_tpgs(&inq); - } - - return rc; -} - -int -get_target_port_group(int fd) -{ - unsigned char buf[128]; - struct vpd83_data * vpd83; - struct vpd83_dscr * dscr; - int rc; - - rc = do_inquiry(fd, 1, 0x83, buf, sizeof(buf)); - if (!rc) { - vpd83 = (struct vpd83_data *) buf; - - rc = -RTPG_NO_TPG_IDENTIFIER; - FOR_EACH_VPD83_DSCR(vpd83, dscr) { - if ((((char *) dscr) - ((char *) vpd83)) > sizeof(buf)) - break; - - if (vpd83_dscr_istype(dscr, IDTYPE_TARGET_PORT_GROUP)) { - struct vpd83_tpg_dscr * p; - - if (rc != -RTPG_NO_TPG_IDENTIFIER) { - PRINT_DEBUG("get_target_port_group: " - "more than one TPG identifier " - "found!\n"); - continue; - } - - p = (struct vpd83_tpg_dscr *) dscr->data; - rc = get_uint16(p->tpg); - } - } - if (rc == -RTPG_NO_TPG_IDENTIFIER) { - PRINT_DEBUG("get_target_port_group: " - "no TPG identifier found!\n"); - } - } - - return rc; -} - -int -do_rtpg(int fd, void* resp, long resplen) -{ - struct rtpg_command cmd; - struct sg_io_hdr hdr; - unsigned char sense[SENSE_BUFF_LEN]; - - memset(&cmd, 0, sizeof(cmd)); - cmd.op = OPERATION_CODE_RTPG; - rtpg_command_set_service_action(&cmd); - set_uint32(cmd.length, resplen); - PRINT_HEX((unsigned char *) &cmd, sizeof(cmd)); - - memset(&hdr, 0, sizeof(hdr)); - hdr.interface_id = 'S'; - hdr.cmdp = (unsigned char *) &cmd; - hdr.cmd_len = sizeof(cmd); - hdr.dxfer_direction = SG_DXFER_FROM_DEV; - hdr.dxferp = resp; - hdr.dxfer_len = resplen; - hdr.mx_sb_len = sizeof(sense); - hdr.sbp = sense; - hdr.timeout = DEF_TIMEOUT; - - if (ioctl(fd, SG_IO, &hdr) < 0) - return -RTPG_RTPG_FAILED; - - if (scsi_error(&hdr)) { - PRINT_DEBUG("do_rtpg: SCSI error!\n"); - return -RTPG_RTPG_FAILED; - } - PRINT_HEX(resp, resplen); - - return 0; -} - -int -get_asymmetric_access_state(int fd, unsigned int tpg) -{ - unsigned char *buf; - struct rtpg_data * tpgd; - struct rtpg_tpg_dscr * dscr; - int rc; - int buflen; - uint32_t scsi_buflen; - - buflen = 128; /* Initial value from old code */ - buf = (unsigned char *)malloc(buflen); - if (!buf) { - PRINT_DEBUG ("malloc failed: could not allocate" - "%u bytes\n", buflen); - return -RTPG_RTPG_FAILED; - } - rc = do_rtpg(fd, buf, buflen); - if (rc < 0) - return rc; - scsi_buflen = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; - if (buflen < (scsi_buflen + 4)) { - free(buf); - buf = (unsigned char *)malloc(scsi_buflen); - if (!buf) { - PRINT_DEBUG ("malloc failed: could not allocate" - "%u bytes\n", scsi_buflen); - return -RTPG_RTPG_FAILED; - } - buflen = scsi_buflen; - rc = do_rtpg(fd, buf, buflen); - if (rc < 0) - goto out; - } - - - tpgd = (struct rtpg_data *) buf; - rc = -RTPG_TPG_NOT_FOUND; - RTPG_FOR_EACH_PORT_GROUP(tpgd, dscr) { - if (get_uint16(dscr->tpg) == tpg) { - if (rc != -RTPG_TPG_NOT_FOUND) { - PRINT_DEBUG("get_asymmetric_access_state: " - "more than one entry with same port " - "group.\n"); - } else { - PRINT_DEBUG("pref=%i\n", dscr->pref); - rc = rtpg_tpg_dscr_get_aas(dscr); - } - } - } -out: - free(buf); - return rc; -} - diff --git a/path_priority/pp_alua/rtpg.h b/path_priority/pp_alua/rtpg.h deleted file mode 100644 index 3c5dcf1..0000000 --- a/path_priority/pp_alua/rtpg.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * (C) Copyright IBM Corp. 2004, 2005 All Rights Reserved. - * - * rtpg.h - * - * Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access. - * It determines the ALUA state of a device and prints a priority value to - * stdout. - * - * Author(s): Jan Kunigk - * S. Bader <shbader@de.ibm.com> - * - * This file is released under the GPL. - */ -#ifndef __RTPG_H__ -#define __RTPG_H__ -#include "spc3.h" - -#define RTPG_SUCCESS 0 -#define RTPG_INQUIRY_FAILED 1 -#define RTPG_NO_TPG_IDENTIFIER 2 -#define RTPG_RTPG_FAILED 3 -#define RTPG_TPG_NOT_FOUND 4 - -int get_target_port_group_support(int fd); -int get_target_port_group(int fd); -int get_asymmetric_access_state(int fd, unsigned int tpg); - -#endif /* __RTPG_H__ */ - diff --git a/path_priority/pp_alua/spc3.h b/path_priority/pp_alua/spc3.h deleted file mode 100644 index bddbbdd..0000000 --- a/path_priority/pp_alua/spc3.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * (C) Copyright IBM Corp. 2004, 2005 All Rights Reserved. - * - * spc3.h - * - * Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access. - * It determines the ALUA state of a device and prints a priority value to - * stdout. - * - * Author(s): Jan Kunigk - * S. Bader <shbader@de.ibm.com> - * - * This file is released under the GPL. - */ -#ifndef __SPC3_H__ -#define __SPC3_H__ -/*============================================================================= - * Some helper functions for getting and setting 16 and 32 bit values. - *============================================================================= - */ -static inline unsigned short -get_uint16(unsigned char *p) -{ - return (p[0] << 8) + p[1]; -} - -static inline void -set_uint16(unsigned char *p, unsigned short v) -{ - p[0] = (v >> 8) & 0xff; - p[1] = v & 0xff; -} - -static inline unsigned int -get_uint32(unsigned char *p) -{ - return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; -} - -static inline void -set_uint32(unsigned char *p, unsigned int v) -{ - p[0] = (v >> 24) & 0xff; - p[1] = (v >> 16) & 0xff; - p[2] = (v >> 8) & 0xff; - p[3] = v & 0xff; -} - -/*============================================================================= - * Definitions to support the standard inquiry command as defined in SPC-3. - * If the evpd (enable vital product data) bit is set the data that will be - * returned is selected by the page field. This field must be 0 if the evpd - * bit is not set. - *============================================================================= - */ -#define OPERATION_CODE_INQUIRY 0x12 - -struct inquiry_command { - unsigned char op; - unsigned char b1; /* xxxxxx.. = reserved */ - /* ......x. = obsolete */ - /* .......x = evpd */ - unsigned char page; - unsigned char length[2]; - unsigned char control; -} __attribute__((packed)); - -static inline void -inquiry_command_set_evpd(struct inquiry_command *ic) -{ - ic->b1 |= 1; -} - -/*----------------------------------------------------------------------------- - * Data returned by the standard inquiry command. - *----------------------------------------------------------------------------- - * - * Peripheral qualifier codes. - */ -#define PQ_CONNECTED 0x0 -#define PQ_DISCONNECTED 0x1 -#define PQ_UNSUPPORTED 0x3 - -/* Defined peripheral device types. */ -#define PDT_DIRECT_ACCESS 0x00 -#define PDT_SEQUENTIAL_ACCESS 0x01 -#define PDT_PRINTER 0x02 -#define PDT_PROCESSOR 0x03 -#define PDT_WRITE_ONCE 0x04 -#define PDT_CD_DVD 0x05 -#define PDT_SCANNER 0x06 -#define PDT_OPTICAL_MEMORY 0x07 -#define PDT_MEDIUM_CHANGER 0x08 -#define PDT_COMMUNICATIONS 0x09 -#define PDT_STORAGE_ARRAY_CONTROLLER 0x0c -#define PDT_ENCLOSURE_SERVICES 0x0d -#define PDT_SIMPLIFIED_DIRECT_ACCESS 0x0e -#define PDT_OPTICAL_CARD_READER_WRITER 0x0f -#define PDT_BRIDGE_CONTROLLER 0x10 -#define PDT_OBJECT_BASED 0x11 -#define PDT_AUTOMATION_INTERFACE 0x12 -#define PDT_LUN 0x1e -#define PDT_UNKNOWN 0x1f - -/* Defined version codes. */ -#define VERSION_NONE 0x00 -#define VERSION_SPC 0x03 -#define VERSION_SPC2 0x04 -#define VERSION_SPC3 0x05 - -/* Defined TPGS field values. */ -#define TPGS_NONE 0x0 -#define TPGS_IMPLICIT 0x1 -#define TPGS_EXPLICIT 0x2 -#define TPGS_BOTH 0x3 - -struct inquiry_data { - unsigned char b0; /* xxx..... = peripheral_qualifier */ - /* ...xxxxx = peripheral_device_type */ - unsigned char b1; /* x....... = removable medium */ - /* .xxxxxxx = reserverd */ - unsigned char version; - unsigned char b3; /* xx...... = obsolete */ - /* ..x..... = normal aca supported */ - /* ...x.... = hirarchichal lun supp. */ - /* ....xxxx = response format */ - /* 2 is spc-3 format */ - unsigned char length; - unsigned char b5; /* x....... = storage controller */ - /* component supported */ - /* .x...... = access controls coord. */ - /* ..xx.... = target port group supp.*/ - /* ....x... = third party copy supp. */ - /* .....xx. = reserved */ - /* .......x = protection info supp. */ - unsigned char b6; /* x....... = bque */ - /* .x...... = enclosure services sup.*/ - /* ..x..... = vs1 */ - /* ...x.... = multiport support */ - /* ....x... = medium changer */ - /* .....xx. = obsolete */ - /* .......x = add16 */ - unsigned char b7; /* xx...... = obsolete */ - /* ..x..... = wbus16 */ - /* ...x.... = sync */ - /* ....x... = linked commands supp. */ - /* .....x.. = obsolete */ - /* ......x. = command queue support */ - /* .......x = vs2 */ - unsigned char vendor_identification[8]; - unsigned char product_identification[16]; - unsigned char product_revision[4]; - unsigned char vendor_specific[20]; - unsigned char b56; /* xxxx.... = reserved */ - /* ....xx.. = clocking */ - /* ......x. = qas */ - /* .......x = ius */ - unsigned char reserved4; - unsigned char version_descriptor[8][2]; - unsigned char reserved5[22]; - unsigned char vendor_parameters[0]; -} __attribute__((packed)); - -static inline int -inquiry_data_get_tpgs(struct inquiry_data *id) -{ - return (id->b5 >> 4) & 3; -} - -/*----------------------------------------------------------------------------- - * Inquiry data returned when requesting vital product data page 0x83. - *----------------------------------------------------------------------------- - */ -#define CODESET_BINARY 0x1 -#define CODESET_ACSII 0x2 -#define CODESET_UTF8 0x3 - -#define ASSOCIATION_UNIT 0x0 -#define ASSOCIATION_PORT 0x1 -#define ASSOCIATION_DEVICE 0x2 - -#define IDTYPE_VENDOR_SPECIFIC 0x0 -#define IDTYPE_T10_VENDOR_ID 0x1 -#define IDTYPE_EUI64 0x2 -#define IDTYPE_NAA 0x3 -#define IDTYPE_RELATIVE_TPG_ID 0x4 -#define IDTYPE_TARGET_PORT_GROUP 0x5 -#define IDTYPE_LUN_GROUP 0x6 -#define IDTYPE_MD5_LUN_ID 0x7 -#define IDTYPE_SCSI_NAME_STRING 0x8 - -struct vpd83_tpg_dscr { - unsigned char reserved1[2]; - unsigned char tpg[2]; -} __attribute__((packed)); - -struct vpd83_dscr { - unsigned char b0; /* xxxx.... = protocol id */ - /* ....xxxx = codeset */ - unsigned char b1; /* x....... = protocol id valid */ - /* .x...... = reserved */ - /* ..xx.... = association */ - /* ....xxxx = id type */ - unsigned char reserved2; - unsigned char length; /* size-4 */ - unsigned char data[0]; -} __attribute__((packed)); - -static inline int -vpd83_dscr_istype(struct vpd83_dscr *d, unsigned char type) -{ - return ((d->b1 & 7) == type); -} - -struct vpd83_data { - unsigned char b0; /* xxx..... = peripheral_qualifier */ - /* ...xxxxx = peripheral_device_type */ - unsigned char page_code; /* 0x83 */ - unsigned char length[2]; /* size-4 */ - struct vpd83_dscr data[0]; -} __attribute__((packed)); - -/*----------------------------------------------------------------------------- - * This macro should be used to walk through all identification descriptors - * defined in the code page 0x83. - * The argument p is a pointer to the code page 0x83 data and d is used to - * point to the current descriptor. - *----------------------------------------------------------------------------- - */ -#define FOR_EACH_VPD83_DSCR(p, d) \ - for( \ - d = p->data; \ - (((char *) d) - ((char *) p)) < \ - get_uint16(p->length); \ - d = (struct vpd83_dscr *) \ - ((char *) d + d->length + 4) \ - ) - -/*============================================================================= - * The following stuctures and macros are used to call the report target port - * groups command defined in SPC-3. - * This command is used to get information about the target port groups (which - * states are supported, which ports belong to this group, and so on) and the - * current state of each target port group. - *============================================================================= - */ -#define OPERATION_CODE_RTPG 0xa3 -#define SERVICE_ACTION_RTPG 0x0a - -struct rtpg_command { - unsigned char op; /* 0xa3 */ - unsigned char b1; /* xxx..... = reserved */ - /* ...xxxxx = service action (0x0a) */ - unsigned char reserved2[4]; - unsigned char length[4]; - unsigned char reserved3; - unsigned char control; -} __attribute__((packed)); - -static inline void -rtpg_command_set_service_action(struct rtpg_command *cmd) -{ - cmd->b1 = (cmd->b1 & 0xe0) | SERVICE_ACTION_RTPG; -} - -struct rtpg_tp_dscr { - unsigned char obsolete1[2]; - /* The Relative Target Port Identifier of a target port. */ - unsigned char rtpi[2]; -} __attribute__((packed)); - -#define AAS_OPTIMIZED 0x0 -#define AAS_NON_OPTIMIZED 0x1 -#define AAS_STANDBY 0x2 -#define AAS_UNAVAILABLE 0x3 -#define AAS_TRANSITIONING 0xf - -#define TPG_STATUS_NONE 0x0 -#define TPG_STATUS_SET 0x1 -#define TPG_STATUS_IMPLICIT_CHANGE 0x2 - -struct rtpg_tpg_dscr { - unsigned char b0; /* x....... = pref(ered) port */ - /* .xxx.... = reserved */ - /* ....xxxx = asymetric access state */ - unsigned char b1; /* xxxx.... = reserved */ - /* ....x... = unavailable support */ - /* .....x.. = standby support */ - /* ......x. = non-optimized support */ - /* .......x = optimized support */ - unsigned char tpg[2]; - unsigned char reserved3; - unsigned char status; - unsigned char vendor_unique; - unsigned char port_count; - struct rtpg_tp_dscr data[0]; -} __attribute__((packed)); - -static inline int -rtpg_tpg_dscr_get_aas(struct rtpg_tpg_dscr *d) -{ - return (d->b0 & 0x0f); -} - -struct rtpg_data { - unsigned char length[4]; /* size-4 */ - struct rtpg_tpg_dscr data[0]; -} __attribute__((packed)); - -#define RTPG_FOR_EACH_PORT_GROUP(p, g) \ - for( \ - g = &(p->data[0]); \ - (((char *) g) - ((char *) p)) < get_uint32(p->length); \ - g = (struct rtpg_tpg_dscr *) ( \ - ((char *) g) + \ - sizeof(struct rtpg_tpg_dscr) + \ - g->port_count * sizeof(struct rtpg_tp_dscr) \ - ) \ - ) - -#endif /* __SPC3_H__ */ - diff --git a/path_priority/pp_balance_units/Makefile b/path_priority/pp_balance_units/Makefile deleted file mode 100644 index cb1e6c6..0000000 --- a/path_priority/pp_balance_units/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr> -# -BUILD = glibc -DEBUG = 0 - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -ifeq ($(strip $(BUILD)),klibc) - CFLAGS += -I/usr/include -DDEBUG=$(DEBUG) - OBJS = pp_balance_units.o $(MULTIPATHLIB)-$(BUILD).a -else - CFLAGS += -I$(multipathdir) -DDEBUG=$(DEBUG) - LDFLAGS = -ldevmapper - OBJS = pp_balance_units.o $(MULTIPATHLIB)-$(BUILD).a -endif - -EXEC = mpath_prio_balance_units - -all: $(BUILD) - -prepare: - rm -f core *.o *.gz - -glibc: prepare $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: prepare $(OBJS) - $(CC) -static -o $(EXEC) $(CRT0) $(OBJS) $(KLIBC) $(LIBGCC) - -$(MULTIPATHLIB)-$(BUILD).a: - make -C $(multipathdir) BUILD=$(BUILD) $(BUILD) - -install: - install -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) - -clean: - rm -f core *.o $(EXEC) *.gz diff --git a/path_priority/pp_balance_units/pp_balance_units.c b/path_priority/pp_balance_units/pp_balance_units.c deleted file mode 100644 index ea70f13..0000000 --- a/path_priority/pp_balance_units/pp_balance_units.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Christophe Varoqui (2004) - * This code is GPLv2, see license file - * - * This path prioritizer aims to balance logical units over all - * controllers available. The logic is : - * - * - list all paths in all primary path groups - * - for each path, get the controller's serial - * - compute the number of active paths attached to each controller - * - compute the max number of paths attached to the same controller - * - if sums are already balanced or if the path passed as parameter is - * attached to controller with less active paths, then return - * (max_path_attached_to_one_controller - number_of_paths_on_this_controller) - * - else, or if anything goes wrong, return 1 as a default prio - * - */ -#define __user - -#include <stdio.h> -#include <stdlib.h> -#include <libdevmapper.h> -#include <vector.h> -#include <memory.h> - -#include <string.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <scsi/sg.h> - -#define SERIAL_SIZE 255 -#define WORD_SIZE 255 -#define PARAMS_SIZE 255 -#define FILE_NAME_SIZE 255 -#define INQUIRY_CMDLEN 6 -#define INQUIRY_CMD 0x12 -#define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 300000 -#define RECOVERED_ERROR 0x01 -#define MX_ALLOC_LEN 255 -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -#if DEBUG -#define debug(format, arg...) fprintf(stderr, format "\n", ##arg) -#else -#define debug(format, arg...) do {} while(0) -#endif - -#define safe_sprintf(var, format, args...) \ - snprintf(var, sizeof(var), format, ##args) >= sizeof(var) -#define safe_snprintf(var, size, format, args...) \ - snprintf(var, size, format, ##args) >= size - -struct path { - char dev_t[WORD_SIZE]; - char serial[SERIAL_SIZE]; -}; - -struct controller { - char serial[SERIAL_SIZE]; - int path_count; -}; - -static int -exit_tool (int ret) -{ - printf("1\n"); - exit(ret); -} - -static int -opennode (char * devt, int mode) -{ - char devpath[FILE_NAME_SIZE]; - unsigned int major; - unsigned int minor; - int fd; - - sscanf(devt, "%u:%u", &major, &minor); - memset(devpath, 0, FILE_NAME_SIZE); - - if (safe_sprintf(devpath, "/tmp/.pp_balance.%u.%u.devnode", - major, minor)) { - fprintf(stderr, "devpath too small\n"); - return -1; - } - unlink (devpath); - mknod(devpath, S_IFBLK|S_IRUSR|S_IWUSR, makedev(major, minor)); - fd = open(devpath, mode); - - if (fd < 0) - unlink(devpath); - - return fd; - -} - -static void -closenode (char * devt, int fd) -{ - char devpath[FILE_NAME_SIZE]; - unsigned int major; - unsigned int minor; - - if (fd >= 0) - close(fd); - - sscanf(devt, "%u:%u", &major, &minor); - if (safe_sprintf(devpath, "/tmp/.pp_balance.%u.%u.devnode", - major, minor)) { - fprintf(stderr, "devpath too small\n"); - return; - } - unlink(devpath); -} - -static int -do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy) -{ - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = - { INQUIRY_CMD, 0, 0, 0, 0, 0 }; - unsigned char sense_b[SENSE_BUFF_LEN]; - struct sg_io_hdr io_hdr; - - if (cmddt) - inqCmdBlk[1] |= 2; - if (evpd) - inqCmdBlk[1] |= 1; - inqCmdBlk[2] = (unsigned char) pg_op; - inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff); - inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff); - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_b); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = mx_resp_len; - io_hdr.dxferp = resp; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_b; - io_hdr.timeout = DEF_TIMEOUT; - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) - return -1; - - /* treat SG_ERR here to get rid of sg_err.[ch] */ - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) - return 0; - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - if(RECOVERED_ERROR == sense_key) - return 0; - } - } - return -1; -} - -static int -get_serial (char * str, int maxlen, char * devt) -{ - int fd; - int len; - char buff[MX_ALLOC_LEN + 1]; - - fd = opennode(devt, O_RDONLY); - - if (fd < 0) - return 1; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len >= maxlen) - return 1; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - close(fd); - return 0; - } - - closenode(devt, fd); - return 1; -} - -static void * -get_params (void) -{ - struct dm_task *dmt, *dmt1; - struct dm_names *names = NULL; - unsigned next = 0; - void *nexttgt; - uint64_t start, length; - char *target_type = NULL; - char *params; - char *pp; - vector paramsvec = NULL; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return NULL; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - debug("no devmap found"); - goto out; - } - do { - /* - * keep only multipath maps - */ - names = (void *) names + next; - nexttgt = NULL; - debug("devmap %s :", names->name); - - if (!(dmt1 = dm_task_create(DM_DEVICE_TABLE))) - goto out; - - if (!dm_task_set_name(dmt1, names->name)) - goto out1; - - if (!dm_task_run(dmt1)) - goto out1; - - do { - nexttgt = dm_get_next_target(dmt1, nexttgt, - &start, - &length, - &target_type, - ¶ms); - debug("\\_ %lu %lu %s", (unsigned long) start, - (unsigned long) length, - target_type); - - if (!target_type) { - debug("unknown target type"); - goto out1; - } - - if (!strncmp(target_type, "multipath", 9)) { - if (!paramsvec) - paramsvec = vector_alloc(); - - pp = malloc(PARAMS_SIZE); - strncpy(pp, params, PARAMS_SIZE); - vector_alloc_slot(paramsvec); - vector_set_slot(paramsvec, pp); - } else - debug("skip non multipath target"); - } while (nexttgt); -out1: - dm_task_destroy(dmt1); - next = names->next; - } while (next); -out: - dm_task_destroy(dmt); - return paramsvec; -} - -static int -get_word (char *sentence, char *word) -{ - char *p; - int skip = 0; - - while (*sentence == ' ') { - sentence++; - skip++; - } - p = sentence; - - while (*p != ' ' && *p != '\0') - p++; - - skip += (p - sentence); - - if (p - sentence > WORD_SIZE) { - fprintf(stderr, "word too small\n"); - exit_tool(1); - } - strncpy(word, sentence, WORD_SIZE); - word += p - sentence; - *word = '\0'; - - if (*p == '\0') - return 0; - - return skip; -} - -static int -is_path (char * word) -{ - char *p; - - if (!word) - return 0; - - p = word; - - while (*p != '\0') { - if (*p == ':') - return 1; - p++; - } - return 0; -} - -static int -get_paths (vector pathvec) -{ - vector paramsvec = NULL; - char * str; - struct path * pp; - int i; - enum where {BEFOREPG, INPG, AFTERPG}; - int pos = BEFOREPG; - - if (!pathvec) - return 1; - - if (!(paramsvec = get_params())) - exit_tool(0); - - vector_foreach_slot (paramsvec, str, i) { - debug("params %s", str); - while (pos != AFTERPG) { - pp = zalloc(sizeof(struct path)); - str += get_word(str, pp->dev_t); - - if (!is_path(pp->dev_t)) { - debug("skip \"%s\"", pp->dev_t); - free(pp); - - if (pos == INPG) - pos = AFTERPG; - - continue; - } - if (pos == BEFOREPG) - pos = INPG; - - get_serial(pp->serial, SERIAL_SIZE, pp->dev_t); - vector_alloc_slot(pathvec); - vector_set_slot(pathvec, pp); - debug("store %s [%s]", - pp->dev_t, pp->serial); - } - pos = BEFOREPG; - } - return 0; -} - -static void * -find_controller (vector controllers, char * serial) -{ - int i; - struct controller * cp; - - if (!controllers) - return NULL; - - vector_foreach_slot (controllers, cp, i) - if (!strncmp(cp->serial, serial, SERIAL_SIZE)) - return cp; - return NULL; -} - -static void -get_controllers (vector controllers, vector pathvec) -{ - int i; - struct path * pp; - struct controller * cp; - - if (!controllers) - return; - - vector_foreach_slot (pathvec, pp, i) { - if (!pp || !strlen(pp->serial)) - continue; - - cp = find_controller(controllers, pp->serial); - - if (!cp) { - cp = zalloc(sizeof(struct controller)); - vector_alloc_slot(controllers); - vector_set_slot(controllers, cp); - strncpy(cp->serial, pp->serial, SERIAL_SIZE); - } - cp->path_count++; - } -} - -static int -get_max_path_count (vector controllers) -{ - int i; - int max = 0; - struct controller * cp; - - if (!controllers) - return 0; - - vector_foreach_slot (controllers, cp, i) { - debug("controller %s : %i paths", cp->serial, cp->path_count); - if(cp->path_count > max) - max = cp->path_count; - } - debug("max_path_count = %i", max); - return max; -} - -int -main (int argc, char **argv) -{ - vector pathvec = NULL; - vector controllers = NULL; - struct path * ref_path = NULL; - struct controller * cp = NULL; - int max_path_count = 0; - - ref_path = zalloc(sizeof(struct path)); - - if (!ref_path) - exit_tool(1); - - if (argc != 2) - exit_tool(1); - - if (optind<argc) - strncpy(ref_path->dev_t, argv[optind], WORD_SIZE); - - get_serial(ref_path->serial, SERIAL_SIZE, ref_path->dev_t); - - if (!ref_path->serial || !strlen(ref_path->serial)) - exit_tool(0); - - pathvec = vector_alloc(); - controllers = vector_alloc(); - - get_paths(pathvec); - get_controllers(controllers, pathvec); - max_path_count = get_max_path_count(controllers); - cp = find_controller(controllers, ref_path->serial); - - if (!cp) { - debug("no other active path on serial %s\n", - ref_path->serial); - exit_tool(0); - } - - printf("%i\n", max_path_count - cp->path_count + 1); - - return(0); -} diff --git a/path_priority/pp_emc/Makefile b/path_priority/pp_emc/Makefile deleted file mode 100644 index 93e6075..0000000 --- a/path_priority/pp_emc/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -EXEC = mpath_prio_emc -BUILD = glibc -OBJS = pp_emc.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< diff --git a/path_priority/pp_emc/pp_emc.c b/path_priority/pp_emc/pp_emc.c deleted file mode 100644 index 4031720..0000000 --- a/path_priority/pp_emc/pp_emc.c +++ /dev/null @@ -1,101 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "../../libmultipath/sg_include.h" - -#define INQUIRY_CMD 0x12 -#define INQUIRY_CMDLEN 6 - -int emc_clariion_prio(const char *dev) -{ - unsigned char sense_buffer[256]; - unsigned char sb[128]; - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0, - sizeof(sb), 0}; - struct sg_io_hdr io_hdr; - int ret = 0; - int fd; - - fd = open(dev, O_RDWR|O_NONBLOCK); - - if (fd <= 0) { - fprintf(stderr, "Opening the device failed.\n"); - goto out; - } - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sb); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = sizeof (sense_buffer); - io_hdr.dxferp = sense_buffer; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sb; - io_hdr.timeout = 60000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - fprintf(stderr, "sending query command failed\n"); - goto out; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - fprintf(stderr, "query command indicates error"); - goto out; - } - - close(fd); - - if (/* Verify the code page - right page & revision */ - sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) { - fprintf(stderr, "Path unit report page in unknown format"); - goto out; - } - - if ( /* Effective initiator type */ - sense_buffer[27] != 0x03 - /* - * Failover mode should be set to 1 (PNR failover mode) - * or 4 (ALUA failover mode). - */ - || (((sense_buffer[28] & 0x07) != 0x04) && - ((sense_buffer[28] & 0x07) != 0x06)) - /* Arraycommpath should be set to 1 */ - || (sense_buffer[30] & 0x04) != 0x04) { - fprintf(stderr, "Path not correctly configured for failover"); - } - - if ( /* LUN operations should indicate normal operations */ - sense_buffer[48] != 0x00) { - fprintf(stderr, "Path not available for normal operations"); - } - - /* Is the default owner equal to this path? */ - /* Note this will switch to the default priority group, even if - * it is not the currently active one. */ - ret = (sense_buffer[5] == sense_buffer[8]) ? 1 : 0; - -out: - return(ret); -} - -int -main (int argc, char **argv) -{ - int prio; - if (argc != 2) { - fprintf(stderr, "Arguments wrong!\n"); - prio = 0; - } else - prio = emc_clariion_prio(argv[1]); - - printf("%d\n", prio); - exit(0); -} - diff --git a/path_priority/pp_hds_modular/Makefile b/path_priority/pp_hds_modular/Makefile deleted file mode 100644 index ca00ca7..0000000 --- a/path_priority/pp_hds_modular/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXEC = mpath_prio_hds_modular -BUILD = glibc -OBJS = pp_hds_modular.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) diff --git a/path_priority/pp_hds_modular/pp_hds_modular.c b/path_priority/pp_hds_modular/pp_hds_modular.c deleted file mode 100644 index 7411508..0000000 --- a/path_priority/pp_hds_modular/pp_hds_modular.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * (C) Copyright HDS GmbH 2006. All Rights Reserved. - * - * pp_hds_modular.c - * Version 2.00 - * - * Prioritizer for Device Mapper Multipath and HDS Storage - * - * Hitachis Modular Storage contains two controllers for redundancy. The - * Storage internal LUN (LDEV) will normally allocated via two pathes to the - * server (one path per controller). For performance reasons should the server - * access to a LDEV only via one controller. The other path to the other - * controller is stand-by. It is also possible to allocate more as one path - * for a LDEV per controller. Here is active/active access allowed. The other - * pathes via the other controller are stand-by. - * - * This prioritizer checks with inquiry command the represented LDEV and - * Controller number and gives back a priority followed by this scheme: - * - * CONTROLLER ODD and LDEV ODD: PRIORITY 1 - * CONTROLLER ODD and LDEV EVEN: PRIORITY 0 - * CONTROLLER EVEN and LDEV ODD: PRIORITY 0 - * CONTROLLER EVEN and LDEV EVEN: PRIORITY 1 - * - * In the storage you can define for each LDEV a owner controller. If the - * server makes IOs via the other controller the storage will switch the - * ownership automatically. In this case you can see in the storage that the - * current controller is different from the default controller, but this is - * absolutely no problem. - * - * With this prioritizer it is possible to establish a static load balancing. - * Half of the LUNs are accessed via one HBA/storage controller and the other - * half via the other HBA/storage controller. - * - * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have - * access to the LDEVs via the same controller. - * - * You can run the prioritizer manually in verbose mode: - * # pp_hds_modular -v 8:224 - * VENDOR: HITACHI - * PRODUCT: DF600F-CM - * SERIAL: 0x0105 - * LDEV: 0x00C6 - * CTRL: 1 - * PORT: B - * CTRL ODD, LDEV EVEN, PRIO 0 - * - * To compile this source please execute # cc pp_hds_modular.c -o /sbin/mpath_prio_hds_modular - * - * Changes 2006-07-16: - * - Changed to forward declaration of functions - * - The switch-statement was changed to a logical expression - * - unlinking of the devpath now also occurs at the end of - * hds_modular_prio to avoid old /tmp/.pp_balance.%u.%u.devnode - * entries in /tmp-Directory - * - The for-statements for passing variables where changed to - * snprintf-commands in verbose mode - * Changes 2006-08-10: - * - Back to the old switch statements because the regular expression does - * not work under RHEL4 U3 i386 - * Changes 2007-06-27: - * - switched from major:minor argument to device node argument - * - * This file is released under the GPL. - * - */ - -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <stdlib.h> -#include <libdevmapper.h> -#include <memory.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <scsi/sg.h> - -#define INQ_REPLY_LEN 255 -#define INQ_CMD_CODE 0x12 -#define INQ_CMD_LEN 6 -#define FILE_NAME_SIZE 255 - -int verbose=0; - -void print_help (void); -int hds_modular_prio (const char *); - -int main (int argc, char **argv) -{ - int prio; - if (argc == 2) - { - if (strcmp (argv[1], "-h") == 0) - { - print_help (); - exit (0); - } - else - { - verbose = 0; - prio = hds_modular_prio (argv[1]); - printf ("%d\n", prio); - exit (0); - } - } - if ((argc == 3) && (strcmp (argv[1], "-v")) == 0) - { - verbose = 1; - prio = hds_modular_prio (argv[2]); - printf ("%d\n", prio); - exit (0); - } - print_help (); - exit (1); -} - -int hds_modular_prio (const char *dev) -{ - int sg_fd, k; - char vendor[8]; - char product[32]; - char serial[32]; - char ldev[32]; - char ctrl[32]; - char port[32]; - unsigned char inqCmdBlk[INQ_CMD_LEN] = { INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0 }; - unsigned char inqBuff[INQ_REPLY_LEN]; - unsigned char *inqBuffp = inqBuff; - unsigned char sense_buffer[32]; - sg_io_hdr_t io_hdr; - - if ((sg_fd = open (dev, O_RDONLY)) < 0) exit (1); - if ((ioctl (sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) exit (1); - - memset (&io_hdr, 0, sizeof (sg_io_hdr_t)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = INQ_REPLY_LEN; - io_hdr.dxferp = inqBuff; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 2000; /* TimeOut = 2 seconds */ - - if (ioctl (sg_fd, SG_IO, &io_hdr) < 0) exit (1); - if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) exit (1); - - snprintf (vendor, 9, "%.8s\n", inqBuffp + 8); - snprintf (product, 17, "%.16s", inqBuffp + 16); - snprintf (serial, 5, "%.4s", inqBuffp + 40); - snprintf (ldev, 5, "%.4s", inqBuffp + 44); - snprintf (ctrl, 2, "%.1s", inqBuffp + 49); - snprintf (port, 2, "%.1s", inqBuffp + 50); - - close (sg_fd); - - if (verbose) - { - printf ("VENDOR: %s\n", vendor); - printf ("PRODUCT: %s\n", product); - printf ("SERIAL: 0x%s\n", serial); - printf ("LDEV: 0x%s\n", ldev); - printf ("CTRL: %s\n", ctrl); - printf ("PORT: %s\n", port); - } - - switch (ctrl[0]) { - case '0': case '2': case '4': case '6': case '8': - switch (ldev[3]) { - case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': - if (1 == verbose) printf("CTRL EVEN, LDEV EVEN, PRIO 1\n"); - return 1; - break; - case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': - if (1 == verbose) printf("CTRL EVEN, LDEV ODD, PRIO 0\n"); - return 0; - break; - } - case '1': case '3': case '5': case '7': case '9': - switch (ldev[3]) { - case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': - if (1 == verbose) printf("CTRL ODD, LDEV EVEN, PRIO 0\n"); - return 0; - break; - case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': - if (1 == verbose) printf("CTRL ODD, LDEV ODD, PRIO 1\n"); - return 1; - break; - } - } - return 0; -} - -void print_help (void) -{ - printf ("\n"); - printf ("Usage: pp_hds_modular [-v] <device>\n"); - printf ("Option: -v verbose mode\n"); - printf ("Description: Prioritizer for Device Mapper Multipath and HDS Storage\n"); - printf ("Version: 2.00\n"); - printf ("Author: Matthias Rudolph <matthias.rudolph@hds.com>\n"); - printf ("Remarks: Prioritizer CTRL#1 corresponds to hardware CTRL#0\n"); - printf (" Prioritizer CTRL#2 corresponds to hardware CTRL#1\n"); - printf ("\n"); - return; -} - diff --git a/path_priority/pp_hp_sw/Makefile b/path_priority/pp_hp_sw/Makefile deleted file mode 100644 index e7debf5..0000000 --- a/path_priority/pp_hp_sw/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -EXEC = mpath_prio_hp_sw -BUILD = glibc -OBJS = pp_hp_sw.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - install -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< diff --git a/path_priority/pp_hp_sw/pp_hp_sw.c b/path_priority/pp_hp_sw/pp_hp_sw.c deleted file mode 100644 index e4a18b1..0000000 --- a/path_priority/pp_hp_sw/pp_hp_sw.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Path priority checker for HP active/standby controller - * - * Check the path state and sort them into groups. - * There is actually a preferred path in the controller; - * we should ask HP on how to retrieve that information. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> - -#define TUR_CMD_LEN 6 -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define UNIT_ATTENTION 0x06 - -#define HP_PATH_ACTIVE 0x04 -#define HP_PATH_STANDBY 0x02 -#define HP_PATH_FAILED 0x00 - -#include "../../libmultipath/sg_include.h" - -int hp_sw_prio(const char *dev) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - unsigned char sb[128]; - struct sg_io_hdr io_hdr; - int ret = HP_PATH_FAILED; - int fd; - - fd = open(dev, O_RDWR|O_NONBLOCK); - - if (fd <= 0) { - fprintf(stderr, "Opening the device failed.\n"); - goto out; - } - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sb); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sb; - io_hdr.timeout = 60000; - io_hdr.pack_id = 0; - retry: - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - fprintf(stderr, "sending tur command failed\n"); - goto out; - } - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) { - /* Command completed normally, path is active */ - ret = HP_PATH_ACTIVE; - } - - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key, asc, asq; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) { - sense_key = sense_buffer[1] & 0xf; - asc = sense_buffer[2]; - asq = sense_buffer[3]; - } else { - sense_key = sense_buffer[2] & 0xf; - asc = sense_buffer[12]; - asq = sense_buffer[13]; - } - if(RECOVERED_ERROR == sense_key) - ret = HP_PATH_ACTIVE; - if(NOT_READY == sense_key) { - if (asc == 0x04 && asq == 0x02) { - /* This is a standby path */ - ret = HP_PATH_STANDBY; - } - } - if(UNIT_ATTENTION == sense_key) { - if (asc == 0x29) { - /* Retry for device reset */ - goto retry; - } - } - } - } - - close(fd); - -out: - return(ret); -} - -int -main (int argc, char **argv) -{ - int prio; - if (argc != 2) { - fprintf(stderr, "Arguments wrong!\n"); - prio = 0; - } else - prio = hp_sw_prio(argv[1]); - - printf("%d\n", prio); - exit(0); -} - diff --git a/path_priority/pp_netapp/Makefile b/path_priority/pp_netapp/Makefile deleted file mode 100644 index b29d002..0000000 --- a/path_priority/pp_netapp/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXEC = mpath_prio_netapp -BUILD = glibc -OBJS = pp_netapp.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) diff --git a/path_priority/pp_netapp/pp_netapp.c b/path_priority/pp_netapp/pp_netapp.c deleted file mode 100644 index 8562a95..0000000 --- a/path_priority/pp_netapp/pp_netapp.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2005 Network Appliance, Inc., All Rights Reserved - * Author: David Wysochanski available at davidw@netapp.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License v2 for more details. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <assert.h> - -#include "../../libmultipath/sg_include.h" - -#define INQUIRY_CMD 0x12 -#define INQUIRY_CMDLEN 6 -#define DEFAULT_PRIO 10 -#define RESULTS_MAX 256 -#define SG_TIMEOUT 30000 - - -static void dump_cdb(unsigned char *cdb, int size) -{ - int i; - - fprintf(stderr, "- SCSI CDB: "); - for (i=0; i<size; i++) { - fprintf(stderr, "0x%02x ", cdb[i]); - } - fprintf(stderr, "\n"); -} - -static void process_sg_error(struct sg_io_hdr *io_hdr) -{ - int i; - - fprintf(stderr, "- masked_status=0x%02x, host_status=0x%02x, " - "driver_status=0x%02x\n", io_hdr->masked_status, - io_hdr->host_status, io_hdr->driver_status); - if (io_hdr->sb_len_wr > 0) { - fprintf(stderr, "- SCSI sense data: "); - for (i=0; i<io_hdr->sb_len_wr; i++) { - fprintf(stderr, "0x%02x ", io_hdr->sbp[i]); - } - fprintf(stderr, "\n"); - } -} - -/* - * Returns: - * -1: error, errno set - * 0: success - */ -static int send_gva(const char *dev, unsigned char pg, - unsigned char *results, int *results_size) -{ - unsigned char sb[128]; - unsigned char cdb[10] = {0xc0, 0, 0x1, 0xa, 0x98, 0xa, - pg, sizeof(sb), 0, 0}; - struct sg_io_hdr io_hdr; - int ret = -1; - int fd; - - fd = open(dev, O_RDWR|O_NONBLOCK); - - if (fd <= 0) { - fprintf(stderr, "Opening %s failed, errno=%d.\n", dev, errno); - goto out_no_close; - } - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (cdb); - io_hdr.mx_sb_len = sizeof (sb); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = *results_size; - io_hdr.dxferp = results; - io_hdr.cmdp = cdb; - io_hdr.sbp = sb; - io_hdr.timeout = SG_TIMEOUT; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - fprintf(stderr, "SG_IO ioctl failed, errno=%d\n", errno); - dump_cdb(cdb, sizeof(cdb)); - goto out; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - fprintf(stderr, "SCSI error\n"); - dump_cdb(cdb, sizeof(cdb)); - process_sg_error(&io_hdr); - goto out; - } - - if (results[4] != 0x0a || results[5] != 0x98 || - results[6] != 0x0a ||results[7] != 0x01) { - dump_cdb(cdb, sizeof(cdb)); - fprintf(stderr, "GVA return wrong format "); - fprintf(stderr, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x\n", - results[4], results[5], results[6], results[7]); - goto out; - } - ret = 0; - out: - close(fd); - out_no_close: - return(ret); -} - -/* - * Retuns: - * -1: Unable to obtain proxy info - * 0: Device _not_ proxy path - * 1: Device _is_ proxy path - */ -static int get_proxy(const char *dev) -{ - unsigned char results[256]; - unsigned char sb[128]; - unsigned char cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xc1, 0, - sizeof(sb), 0}; - struct sg_io_hdr io_hdr; - int ret = -1; - int fd; - - fd = open(dev, O_RDWR|O_NONBLOCK); - - if (fd <= 0) { - fprintf(stderr, "Opening %s failed, errno=%d.\n", dev, errno); - goto out_no_close; - } - - memset(&results, 0, sizeof (results)); - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (cdb); - io_hdr.mx_sb_len = sizeof (sb); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = sizeof (results); - io_hdr.dxferp = results; - io_hdr.cmdp = cdb; - io_hdr.sbp = sb; - io_hdr.timeout = SG_TIMEOUT; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - fprintf(stderr, "ioctl sending inquiry command failed, " - "errno=%d\n", errno); - dump_cdb(cdb, sizeof(cdb)); - goto out; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - fprintf(stderr, "SCSI error\n"); - dump_cdb(cdb, sizeof(cdb)); - process_sg_error(&io_hdr); - goto out; - } - - if (results[1] != 0xc1 || results[8] != 0x0a || - results[9] != 0x98 || results[10] != 0x0a || - results[11] != 0x0 || results[12] != 0xc1 || - results[13] != 0x0) { - fprintf(stderr,"Proxy info page in unknown format - "); - fprintf(stderr,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x " - "0x%02x 0x%02x\n", - results[8], results[9], results[10], - results[11], results[12], results[13]); - dump_cdb(cdb, sizeof(cdb)); - goto out; - } - ret = (results[19] & 0x02) >> 1; - - out: - close(fd); - out_no_close: - return(ret); -} - -/* - * Returns priority of device based on device info. - * - * 4: FCP non-proxy, FCP proxy unknown, or unable to determine protocol - * 3: iSCSI HBA - * 2: iSCSI software - * 1: FCP proxy - */ -static int netapp_prio(const char *dev) -{ - unsigned char results[RESULTS_MAX]; - int results_size=RESULTS_MAX; - int rc; - int is_proxy; - int is_iscsi_software; - int is_iscsi_hardware; - int tot_len; - - is_iscsi_software = is_iscsi_hardware = is_proxy = 0; - - memset(&results, 0, sizeof (results)); - rc = send_gva(dev, 0x41, results, &results_size); - if (rc == 0) { - tot_len = results[0] << 24 | results[1] << 16 | - results[2] << 8 | results[3]; - if (tot_len <= 8) { - goto try_fcp_proxy; - } - if (results[8] != 0x41) { - fprintf(stderr, "GVA page 0x41 error - " - "results[8] = 0x%x\n", results[8]); - goto try_fcp_proxy; - } - if ((strncmp((char *)&results[12], "ism_sw", 6) == 0) || - (strncmp((char *)&results[12], "iswt", 4) == 0)) { - is_iscsi_software = 1; - goto prio_select; - } - else if (strncmp((char *)&results[12], "ism_sn", 6) == 0) { - is_iscsi_hardware = 1; - goto prio_select; - } - } - - try_fcp_proxy: - rc = get_proxy(dev); - if (rc >= 0) { - is_proxy = rc; - } - - prio_select: - if (is_iscsi_hardware) { - return 3; - } else if (is_iscsi_software) { - return 2; - } else { - if (is_proxy) { - return 1; - } else { - /* Either non-proxy, or couldn't get proxy info */ - return 4; - } - } -} - -int -main (int argc, char **argv) -{ - int prio; - if (argc != 2) { - fprintf(stderr, "Arguments wrong!\n"); - prio = 0; - } else - prio = netapp_prio(argv[1]); - - printf("%d\n", prio); - exit(0); -} - diff --git a/path_priority/pp_random/Makefile b/path_priority/pp_random/Makefile deleted file mode 100644 index 85d7c2f..0000000 --- a/path_priority/pp_random/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXEC = mpath_prio_random -BUILD = glibc -OBJS = pp_random.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) diff --git a/path_priority/pp_random/pp_random.c b/path_priority/pp_random/pp_random.c deleted file mode 100644 index 05c4b8d..0000000 --- a/path_priority/pp_random/pp_random.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <sys/time.h> -#include <time.h> - -int main(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - srand((unsigned int)tv.tv_usec); - printf("%i\n", 1+(int) (10.0*rand()/(RAND_MAX+1.0))); - return 0; -} diff --git a/path_priority/pp_rdac/Makefile b/path_priority/pp_rdac/Makefile deleted file mode 100644 index 64ed4c3..0000000 --- a/path_priority/pp_rdac/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXEC = mpath_prio_rdac -BUILD = glibc -OBJS = pp_rdac.o - -TOPDIR = ../.. -include $(TOPDIR)/Makefile.inc - -all: $(BUILD) - -glibc: $(OBJS) - $(CC) -o $(EXEC) $(OBJS) $(LDFLAGS) - -klibc: $(OBJS) - $(CC) -static -o $(EXEC) $(OBJS) - -install: $(EXEC) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/$(EXEC) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) -clean: - rm -f *.o $(EXEC) diff --git a/path_priority/pp_rdac/pp_rdac.c b/path_priority/pp_rdac/pp_rdac.c deleted file mode 100644 index 49a13cf..0000000 --- a/path_priority/pp_rdac/pp_rdac.c +++ /dev/null @@ -1,112 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "../../libmultipath/sg_include.h" - -#define INQUIRY_CMD 0x12 -#define INQUIRY_CMDLEN 6 - -int rdac_prio(const char *dev) -{ - unsigned char sense_buffer[256]; - unsigned char sb[128]; - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC9, 0, - sizeof(sb), 0}; - struct sg_io_hdr io_hdr; - int ret = 0; - int fd; - - fd = open(dev, O_RDWR|O_NONBLOCK); - - if (fd <= 0) { - fprintf(stderr, "opening of the device failed.\n"); - goto out; - } - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sb); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = sizeof (sense_buffer); - io_hdr.dxferp = sense_buffer; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sb; - io_hdr.timeout = 60000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - fprintf(stderr, "sending inquiry command failed\n"); - goto out; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - fprintf(stderr, "inquiry command indicates error"); - goto out; - } - - close(fd); - - if (/* Verify the code page - right page & page identifier */ - sense_buffer[1] != 0xc9 || - sense_buffer[3] != 0x2c || - sense_buffer[4] != 'v' || - sense_buffer[5] != 'a' || - sense_buffer[6] != 'c' ) { - fprintf(stderr, "Volume access control page in unknown format"); - goto out; - } - - if ( /* Current Volume Path Bit */ - ( sense_buffer[8] & 0x01) == 0x01 ) { - /* - * This volume was owned by the controller receiving - * the inquiry command. - */ - ret |= 0x01; - } - - /* Volume Preferred Path Priority */ - switch ( sense_buffer[9] & 0x0F ) { - case 0x01: - /* - * Access to this volume is most preferred through - * this path and other paths with this value. - */ - ret |= 0x02; - break; - case 0x02: - /* - * Access to this volume through this path is to be used - * as a secondary path. Typically this path would be used - * for fail-over situations. - */ - /* Fallthrough */ - default: - /* Reserved values */ - break; - } - -out: - return(ret); -} - -int -main (int argc, char **argv) -{ - int prio; - if (argc != 2) { - fprintf(stderr, "Wrong number of arguments.\n"); - fprintf(stderr, "Usage: %s device\n", argv[0]); - prio = 0; - } else - prio = rdac_prio(argv[1]); - - printf("%d\n", prio); - exit(0); -} |