summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--Makefile.inc16
-rw-r--r--devmap_name/Makefile31
-rw-r--r--kpartx/Makefile43
-rw-r--r--libcheckers/Makefile19
-rw-r--r--libmultipath/Makefile31
-rw-r--r--libmultipath/configure.c10
-rw-r--r--libmultipath/hwtable.c1
-rw-r--r--libmultipath/structs_vec.c56
-rw-r--r--libmultipath/structs_vec.h14
-rw-r--r--libprio/Makefile34
-rw-r--r--libprio/alua.c3
-rw-r--r--libprio/const.c2
-rw-r--r--libprio/emc.c2
-rw-r--r--libprio/hds.c2
-rw-r--r--libprio/hp_sw.c2
-rw-r--r--libprio/libprio.c113
-rw-r--r--libprio/libprio.h28
-rw-r--r--libprio/netapp.c2
-rw-r--r--libprio/random.c2
-rw-r--r--libprio/rdac.c2
-rw-r--r--multipath/Makefile52
-rw-r--r--multipath/main.c4
-rw-r--r--multipathd/Makefile41
-rw-r--r--multipathd/main.c22
-rw-r--r--path_priority/pp_alua/LICENSE483
-rw-r--r--path_priority/pp_alua/Makefile54
-rw-r--r--path_priority/pp_alua/main.c279
-rw-r--r--path_priority/pp_alua/mpath_prio_alua.8162
-rw-r--r--path_priority/pp_alua/rtpg.c306
-rw-r--r--path_priority/pp_alua/rtpg.h30
-rw-r--r--path_priority/pp_alua/spc3.h322
-rw-r--r--path_priority/pp_balance_units/Makefile44
-rw-r--r--path_priority/pp_balance_units/pp_balance_units.c476
-rw-r--r--path_priority/pp_emc/Makefile25
-rw-r--r--path_priority/pp_emc/pp_emc.c101
-rw-r--r--path_priority/pp_hds_modular/Makefile22
-rw-r--r--path_priority/pp_hds_modular/pp_hds_modular.c211
-rw-r--r--path_priority/pp_hp_sw/Makefile25
-rw-r--r--path_priority/pp_hp_sw/pp_hp_sw.c119
-rw-r--r--path_priority/pp_netapp/Makefile22
-rw-r--r--path_priority/pp_netapp/pp_netapp.c268
-rw-r--r--path_priority/pp_random/Makefile22
-rw-r--r--path_priority/pp_random/pp_random.c14
-rw-r--r--path_priority/pp_rdac/Makefile22
-rw-r--r--path_priority/pp_rdac/pp_rdac.c112
46 files changed, 271 insertions, 3392 deletions
diff --git a/Makefile b/Makefile
index ee554e7..4e68ae1 100644
--- a/Makefile
+++ b/Makefile
@@ -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,
- &params);
- 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);
-}