[lib] merge libprio in libmultipath
authorChristophe Varoqui <christophe.varoqui@free.fr>
Tue, 8 Apr 2008 21:21:48 +0000 (23:21 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Tue, 8 Apr 2008 21:21:48 +0000 (23:21 +0200)
There is actually just the prio plugins api files linked into libmultipath.so
Prioritizers proper go under libmultipath/prioritizers

59 files changed:
Makefile
Makefile.inc
libmultipath/Makefile
libmultipath/config.c
libmultipath/configure.c
libmultipath/dict.c
libmultipath/discovery.c
libmultipath/hwtable.c
libmultipath/prio.c [new file with mode: 0644]
libmultipath/prio.h [new file with mode: 0644]
libmultipath/prioritizers/Makefile [new file with mode: 0644]
libmultipath/prioritizers/alua.c [new file with mode: 0644]
libmultipath/prioritizers/alua.h [new file with mode: 0644]
libmultipath/prioritizers/alua_rtpg.c [new file with mode: 0644]
libmultipath/prioritizers/alua_rtpg.h [new file with mode: 0644]
libmultipath/prioritizers/alua_spc3.h [new file with mode: 0644]
libmultipath/prioritizers/const.c [new file with mode: 0644]
libmultipath/prioritizers/const.h [new file with mode: 0644]
libmultipath/prioritizers/emc.c [new file with mode: 0644]
libmultipath/prioritizers/emc.h [new file with mode: 0644]
libmultipath/prioritizers/hds.c [new file with mode: 0644]
libmultipath/prioritizers/hds.h [new file with mode: 0644]
libmultipath/prioritizers/hp_sw.c [new file with mode: 0644]
libmultipath/prioritizers/hp_sw.h [new file with mode: 0644]
libmultipath/prioritizers/netapp.c [new file with mode: 0644]
libmultipath/prioritizers/netapp.h [new file with mode: 0644]
libmultipath/prioritizers/random.c [new file with mode: 0644]
libmultipath/prioritizers/random.h [new file with mode: 0644]
libmultipath/prioritizers/rdac.c [new file with mode: 0644]
libmultipath/prioritizers/rdac.h [new file with mode: 0644]
libmultipath/propsel.c
libmultipath/structs.c
libmultipath/structs_vec.c
libprio/Makefile [deleted file]
libprio/alua.c [deleted file]
libprio/alua.h [deleted file]
libprio/alua_rtpg.c [deleted file]
libprio/alua_rtpg.h [deleted file]
libprio/alua_spc3.h [deleted file]
libprio/const.c [deleted file]
libprio/const.h [deleted file]
libprio/emc.c [deleted file]
libprio/emc.h [deleted file]
libprio/hds.c [deleted file]
libprio/hds.h [deleted file]
libprio/hp_sw.c [deleted file]
libprio/hp_sw.h [deleted file]
libprio/libprio.c [deleted file]
libprio/libprio.h [deleted file]
libprio/netapp.c [deleted file]
libprio/netapp.h [deleted file]
libprio/random.c [deleted file]
libprio/random.h [deleted file]
libprio/rdac.c [deleted file]
libprio/rdac.h [deleted file]
multipath/Makefile
multipath/main.c
multipathd/Makefile
multipathd/main.c

index 4e68ae1..8b9bb31 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -21,8 +21,8 @@ export KRNLOBJ
 
 BUILDDIRS = \
        libmultipath \
+       libmultipath/prioritizers \
        libcheckers \
-       libprio \
        multipath \
        multipathd \
        devmap_name \
index 46a08dd..8947c8c 100644 (file)
@@ -18,7 +18,6 @@ exec_prefix = $(prefix)
 bindir      = $(exec_prefix)/sbin
 libudevdir  = ${prefix}/lib/udev
 checkersdir = $(TOPDIR)/libcheckers
-libpriodir  = $(TOPDIR)/libprio
 multipathdir = $(TOPDIR)/libmultipath
 mandir      = $(prefix)/usr/share/man/man8
 man5dir     = $(prefix)/usr/share/man/man5
index b9833c3..3865df3 100644 (file)
@@ -5,14 +5,14 @@
 include ../Makefile.inc
 
 LIBS = libmultipath.so
-CFLAGS += -I$(checkersdir) -I$(libpriodir)
+CFLAGS += -I$(checkersdir)
 
 OBJS = memory.o parser.o vector.o devmapper.o callout.o \
        hwtable.o blacklist.o util.o dmparser.o config.o \
        structs.o discovery.o propsel.o dict.o \
        pgpolicies.o debug.o regex.o defaults.o uevent.o \
        switchgroup.o uxsock.o print.o alias.o log_pthread.o \
-       log.o configure.o structs_vec.o sysfs.o
+       log.o configure.o structs_vec.o sysfs.o prio.o
 
 #ifeq ($(strip $(DAEMON)),1)
        OBJS += lock.o waiter.o
index b6d4fb9..7abe6fa 100644 (file)
@@ -7,7 +7,6 @@
 #include <string.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "memory.h"
 #include "util.h"
@@ -20,6 +19,7 @@
 #include "config.h"
 #include "blacklist.h"
 #include "defaults.h"
+#include "prio.h"
 
 static struct hwentry *
 find_hwe_strmatch (vector hwtable, char * vendor, char * product, char * revision)
index 72148c9..988c41b 100644 (file)
@@ -15,7 +15,6 @@
 #include <libdevmapper.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "vector.h"
 #include "memory.h"
@@ -35,6 +34,7 @@
 #include "pgpolicies.h"
 #include "dict.h"
 #include "alias.h"
+#include "prio.h"
 
 extern int
 setup_map (struct multipath * mpp)
index fa37ee8..e24ad7f 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (c) 2005 Kiyoshi Ueda, NEC
  */
 #include <checkers.h>
-#include <libprio.h>
 
 #include "vector.h"
 #include "hwtable.h"
@@ -17,6 +16,7 @@
 #include "pgpolicies.h"
 #include "blacklist.h"
 #include "defaults.h"
+#include "prio.h"
 
 /*
  * default block handlers
index 30c36e5..a1079ac 100644 (file)
@@ -12,7 +12,6 @@
 #include <errno.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "vector.h"
 #include "memory.h"
@@ -26,6 +25,7 @@
 #include "sg_include.h"
 #include "sysfs.h"
 #include "discovery.h"
+#include "prio.h"
 
 struct path *
 store_pathinfo (vector pathvec, vector hwtable, char * devname, int flag)
index 0b644ed..814a290 100644 (file)
@@ -1,13 +1,13 @@
 #include <stdio.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "vector.h"
 #include "defaults.h"
 #include "structs.h"
 #include "config.h"
 #include "pgpolicies.h"
+#include "prio.h"
 
 /*
  * Tuning suggestions on these parameters should go to
diff --git a/libmultipath/prio.c b/libmultipath/prio.c
new file mode 100644 (file)
index 0000000..617fc19
--- /dev/null
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <dlfcn.h>
+
+#include "debug.h"
+#include "prio.h"
+
+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;
+
+       list_for_each_entry(p, &prioritizers, node) {
+               if (!strncmp(name, p->name, PRIO_NAME_LEN))
+                       return 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(3, "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);
+}
+
+char * prio_name (struct prio * p)
+{
+       return p->name;
+}
+
+struct prio * prio_default (void)
+{
+       return prio_lookup(DEFAULT_PRIO);
+}
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
new file mode 100644 (file)
index 0000000..751c874
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _PRIO_H
+#define _PRIO_H
+
+/*
+ * knowing about path struct gives flexibility to prioritizers
+ */
+#include "../libcheckers/checkers.h"
+#include "vector.h"
+#include "structs.h"
+#include "list.h"
+#include "memory.h"
+
+#define DEFAULT_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
+ */
+#define PRIO_UNDEF -1
+
+/*
+ * strings lengths
+ */
+#define LIB_PRIO_NAMELEN 255
+#define PRIO_NAME_LEN 16
+
+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 *);
+struct prio * prio_default (void);
+
+#endif /* _PRIO_H */
diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile
new file mode 100644 (file)
index 0000000..c05d457
--- /dev/null
@@ -0,0 +1,34 @@
+# Makefile
+#
+# Copyright (C) 2007 Christophe Varoqui, <christophe.varoqui@free.fr>
+#
+include ../../Makefile.inc
+
+LIBS = \
+       libpriorandom.so \
+       libprioconst.so \
+       libpriohp_sw.so \
+       libprioemc.so \
+       libpriordac.so \
+       libprioalua.so \
+       libprionetapp.so \
+       libpriohds.so
+
+CFLAGS += -I..
+
+all: $(LIBS)
+
+libprioalua.so: alua.o alua_rtpg.o
+       $(CC) $(SHARED_FLAGS) -o $@ $^
+
+libprio%.so: %.o
+       $(CC) $(SHARED_FLAGS) -o $@ $^
+
+install: $(LIBS)
+       install -m 755 libprio*.so $(libdir)
+
+uninstall:
+       rm -f $(libdir)/libprio*.so
+
+clean:
+       rm -f core *.a *.o *.gz *.so
diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c
new file mode 100644 (file)
index 0000000..67e4adb
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * (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 <stdio.h>
+
+#include <debug.h>
+#include <prio.h>
+
+#include "alua.h"
+
+#define ALUA_PRIO_NOT_SUPPORTED                        1
+#define ALUA_PRIO_RTPG_FAILED                  2
+#define ALUA_PRIO_GETAAS_FAILED                        3
+
+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 (rc == TPGS_NONE)
+               return -ALUA_PRIO_NOT_SUPPORTED;
+
+       tpg = get_target_port_group(fd);
+       if (tpg < 0)
+               return -ALUA_PRIO_RTPG_FAILED;
+
+       condlog(3, "reported target port group is %i", tpg);
+       rc = get_asymmetric_access_state(fd, tpg);
+       if (rc < 0)
+               return -ALUA_PRIO_GETAAS_FAILED;
+
+       condlog(3, "aas = [%s]",
+               (aas_string[rc]) ? aas_string[rc] : "invalid/reserved");
+       return rc;
+}
+
+int getprio (struct path * pp)
+{
+       int rc = get_alua_info(pp->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;
+               }
+       } else {
+               switch(-rc) {
+                       case ALUA_PRIO_NOT_SUPPORTED:
+                               condlog(0, "%s: alua not supported", pp->dev);
+                               break;
+                       case ALUA_PRIO_RTPG_FAILED:
+                               condlog(0, "%s: couldn't get target port group", pp->dev);
+                               break;
+                       case ALUA_PRIO_GETAAS_FAILED:
+                               condlog(0, "%s: couln't get asymmetric access state", pp->dev);
+                               break;
+               }
+       }
+       return rc;
+}
diff --git a/libmultipath/prioritizers/alua.h b/libmultipath/prioritizers/alua.h
new file mode 100644 (file)
index 0000000..78a3d15
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _ALUA_H
+#define _ALUA_H
+
+#include "alua_rtpg.h"
+
+#define PRIO_ALUA "alua"
+int prio_alua(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c
new file mode 100644 (file)
index 0000000..c5528c5
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * (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 <sys/ioctl.h>
+#include <inttypes.h>
+
+#define __user
+#include <scsi/sg.h>
+
+#include "alua_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/libmultipath/prioritizers/alua_rtpg.h b/libmultipath/prioritizers/alua_rtpg.h
new file mode 100644 (file)
index 0000000..c43e0a9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * (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 "alua_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/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h
new file mode 100644 (file)
index 0000000..bddbbdd
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * (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/libmultipath/prioritizers/const.c b/libmultipath/prioritizers/const.c
new file mode 100644 (file)
index 0000000..529cf82
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+#include <prio.h>
+
+int getprio (struct path * pp)
+{
+       return 1;
+}
diff --git a/libmultipath/prioritizers/const.h b/libmultipath/prioritizers/const.h
new file mode 100644 (file)
index 0000000..220db54
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _CONST_H
+#define _CONST_H
+
+#define PRIO_CONST "const"
+int prio_const(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/emc.c b/libmultipath/prioritizers/emc.c
new file mode 100644 (file)
index 0000000..61d7a77
--- /dev/null
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.h>
+
+#define INQUIRY_CMD     0x12
+#define INQUIRY_CMDLEN  6
+
+#define pp_emc_log(prio, msg) condlog(prio, "%s: emc prio: " msg, dev)
+
+int emc_clariion_prio(const char *dev, int fd)
+{
+       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;
+
+       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) {
+               pp_emc_log(0, "sending query command failed");
+               goto out;
+       }
+       if (io_hdr.info & SG_INFO_OK_MASK) {
+               pp_emc_log(0, "query command indicates error");
+               goto out;
+       }
+
+       if (/* Verify the code page - right page & revision */
+           sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) {
+               pp_emc_log(0, "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) {
+               pp_emc_log(0, "path not correctly configured for failover");
+       }
+
+       if ( /* LUN operations should indicate normal operations */
+               sense_buffer[48] != 0x00) {
+               pp_emc_log(0, "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 getprio (struct path * pp)
+{
+       return emc_clariion_prio(pp->dev, pp->fd);
+}
diff --git a/libmultipath/prioritizers/emc.h b/libmultipath/prioritizers/emc.h
new file mode 100644 (file)
index 0000000..0ab0bc5
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _EMC_H
+#define _EMC_H
+
+#define PRIO_EMC "emc"
+int prio_emc(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c
new file mode 100644 (file)
index 0000000..6ebe4d8
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * (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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.h>
+
+#define INQ_REPLY_LEN 255
+#define INQ_CMD_CODE 0x12
+#define INQ_CMD_LEN 6
+
+#define pp_hds_log(prio, fmt, args...) \
+        condlog(prio, "%s: hds prio: " fmt, dev, ##args)
+
+int hds_modular_prio (const char *dev, int fd)
+{
+       int 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 ((ioctl (fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
+               pp_hds_log(0, "can't use SG ioctl interface");
+               return -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 (fd, SG_IO, &io_hdr) < 0) {
+               pp_hds_log(0, "SG_IO error");
+               return -1;
+       }
+       if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
+               pp_hds_log(0, "SCSI error");
+               return -1;
+       }
+
+       snprintf (vendor, 9, "%.8s", 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);
+
+       pp_hds_log(4, "VENDOR:  %s", vendor);
+       pp_hds_log(4, "PRODUCT: %s", product);
+       pp_hds_log(4, "SERIAL:  0x%s", serial);
+       pp_hds_log(4, "LDEV:    0x%s", ldev);
+       pp_hds_log(4, "CTRL:    %s", ctrl);
+       pp_hds_log(4, "PORT:    %s", 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':
+                       pp_hds_log(4, "CTRL EVEN, LDEV EVEN, PRIO 1");
+                       return 1;
+                       break;
+               case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F':
+                       pp_hds_log(4, "CTRL EVEN, LDEV ODD, PRIO 0");
+                       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':
+                       pp_hds_log(4, "CTRL ODD, LDEV EVEN, PRIO 0");
+                       return 0;
+                       break;
+               case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F':
+                       pp_hds_log(4, "CTRL ODD, LDEV ODD, PRIO 1");
+                       return 1;
+                       break;
+               }
+       }
+       return -1;
+}
+
+int getprio (struct path * pp)
+{
+       return hds_modular_prio(pp->dev, pp->fd);
+}
diff --git a/libmultipath/prioritizers/hds.h b/libmultipath/prioritizers/hds.h
new file mode 100644 (file)
index 0000000..084d77c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _HDS_H
+#define _HDS_H
+
+#define PRIO_HDS "hds"
+int prio_hds(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/hp_sw.c b/libmultipath/prioritizers/hp_sw.c
new file mode 100644 (file)
index 0000000..ae0975f
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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 <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.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
+
+#define pp_hp_sw_log(prio, fmt, args...) \
+        condlog(prio, "%s: hp_sw prio: " fmt, dev, ##args)
+
+int hp_sw_prio(const char *dev, int fd)
+{
+        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;
+
+       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) {
+               pp_hp_sw_log(0, "sending tur command failed");
+               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;
+                               }
+                       }
+                }
+        }
+out:
+       return(ret);
+}
+
+int getprio (struct path * pp)
+{
+       return hp_sw_prio(pp->dev, pp->fd);
+}
diff --git a/libmultipath/prioritizers/hp_sw.h b/libmultipath/prioritizers/hp_sw.h
new file mode 100644 (file)
index 0000000..2fea486
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _HP_SW_H
+#define _HP_SW_H
+
+#define PRIO_HP_SW "hp_sw"
+int prio_hp_sw(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/netapp.c b/libmultipath/prioritizers/netapp.c
new file mode 100644 (file)
index 0000000..812ecf6
--- /dev/null
@@ -0,0 +1,243 @@
+/* 
+ * 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/ioctl.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.h>
+
+#define INQUIRY_CMD    0x12
+#define INQUIRY_CMDLEN 6
+#define DEFAULT_PRIOVAL        10
+#define RESULTS_MAX    256
+#define SG_TIMEOUT     30000
+
+#define pp_netapp_log(prio, fmt, args...) \
+        condlog(prio, "%s: netapp prio: " fmt, dev, ##args)
+
+static void dump_cdb(unsigned char *cdb, int size)
+{
+       int i;
+       char buf[10*5+1];
+       char * p = &buf[0];
+       
+       condlog(0, "- SCSI CDB: ");
+       for (i=0; i<size; i++) {
+               p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
+       }
+       condlog(0, "%s", buf);
+}
+
+static void process_sg_error(struct sg_io_hdr *io_hdr)
+{
+       int i;
+       char buf[128*5+1];
+       char * p = &buf[0];
+       
+       condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
+               "driver_status=0x%02x", io_hdr->masked_status,
+               io_hdr->host_status, io_hdr->driver_status);
+       if (io_hdr->sb_len_wr > 0) {
+               condlog(0, "- SCSI sense data: ");
+               for (i=0; i<io_hdr->sb_len_wr; i++) {
+                       p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
+                                     io_hdr->sbp[i]);
+               }
+               condlog(0, "%s", buf);
+       }
+}
+
+/*
+ * Returns:
+ * -1: error, errno set
+ *  0: success
+ */
+static int send_gva(const char *dev, int fd, 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;
+
+       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) {
+               pp_netapp_log(0, "SG_IO ioctl failed, errno=%d", errno);
+               dump_cdb(cdb, sizeof(cdb));
+               goto out;
+       }
+       if (io_hdr.info & SG_INFO_OK_MASK) {
+               pp_netapp_log(0, "SCSI error");
+               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));
+               pp_netapp_log(0, "GVA return wrong format ");
+               pp_netapp_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
+                       results[4], results[5], results[6], results[7]);
+               goto out;
+       }
+       ret = 0;
+ out:
+       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, int fd)
+{
+       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;
+
+       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) {
+               pp_netapp_log(0, "ioctl sending inquiry command failed, "
+                       "errno=%d", errno);
+               dump_cdb(cdb, sizeof(cdb));
+               goto out;
+       }
+       if (io_hdr.info & SG_INFO_OK_MASK) {
+               pp_netapp_log(0, "SCSI error");
+               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) {
+               pp_netapp_log(0,"proxy info page in unknown format - ");
+               pp_netapp_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
+                       "0x%02x 0x%02x",
+                       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:
+       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, int fd)
+{
+       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, fd, 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) {
+                       pp_netapp_log(0, "GVA page 0x41 error - "
+                               "results[8] = 0x%x", 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, fd);
+       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 getprio (struct path * pp)
+{
+       return netapp_prio(pp->dev, pp->fd);
+}
diff --git a/libmultipath/prioritizers/netapp.h b/libmultipath/prioritizers/netapp.h
new file mode 100644 (file)
index 0000000..ec38821
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _NETAPP_H
+#define _NETAPP_H
+
+#define PRIO_NETAPP "netapp"
+int prio_netapp(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/random.c b/libmultipath/prioritizers/random.c
new file mode 100644 (file)
index 0000000..e3852a7
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <prio.h>
+
+int getprio (struct path * pp)
+{
+       struct timeval tv;
+       
+       gettimeofday(&tv, NULL);
+       srand((unsigned int)tv.tv_usec);
+       return 1+(int) (10.0*rand()/(RAND_MAX+1.0));
+}
diff --git a/libmultipath/prioritizers/random.h b/libmultipath/prioritizers/random.h
new file mode 100644 (file)
index 0000000..b9dae69
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _RANDOM_H
+#define _RANDOM_H
+
+#define PRIO_RANDOM "random"
+int prio_random(struct path * pp);
+
+#endif
diff --git a/libmultipath/prioritizers/rdac.c b/libmultipath/prioritizers/rdac.c
new file mode 100644 (file)
index 0000000..4dd8f44
--- /dev/null
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.h>
+
+#define INQUIRY_CMD     0x12
+#define INQUIRY_CMDLEN  6
+
+#define pp_rdac_log(prio, msg) condlog(prio, "%s: rdac prio: " msg, dev)
+
+int rdac_prio(const char *dev, int fd)
+{
+       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;
+
+       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) {
+               pp_rdac_log(0, "sending inquiry command failed");
+               goto out;
+       }
+       if (io_hdr.info & SG_INFO_OK_MASK) {
+               pp_rdac_log(0, "inquiry command indicates error");
+               goto out;
+       }
+       
+       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' ) {
+               pp_rdac_log(0, "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 getprio (struct path * pp)
+{
+       return rdac_prio(pp->dev, pp->fd);
+}
diff --git a/libmultipath/prioritizers/rdac.h b/libmultipath/prioritizers/rdac.h
new file mode 100644 (file)
index 0000000..a5b7f8e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _RDAC_H
+#define _RDAC_H
+
+#define PRIO_RDAC "rdac"
+int prio_rdac(struct path * pp);
+
+#endif
index bb2b2b7..3d12ec0 100644 (file)
@@ -6,7 +6,6 @@
 #include <stdio.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "memory.h"
 #include "vector.h"
@@ -17,6 +16,7 @@
 #include "alias.h"
 #include "defaults.h"
 #include "devmapper.h"
+#include "prio.h"
 
 pgpolicyfn *pgpolicies[] = {
        NULL,
index c9b446b..442a3ee 100644 (file)
@@ -7,7 +7,6 @@
 #include <libdevmapper.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "memory.h"
 #include "vector.h"
@@ -18,6 +17,7 @@
 #include "structs_vec.h"
 #include "blacklist.h"
 #include "waiter.h"
+#include "prio.h"
 
 struct path *
 alloc_path (void)
index 52f1db5..dfb1d33 100644 (file)
@@ -3,20 +3,20 @@
 #include <unistd.h>
 
 #include <checkers.h>
-#include <libprio.h>
 
 #include "vector.h"
 #include "defaults.h"
 #include "debug.h"
-#include "waiter.h"
 #include "structs.h"
 #include "structs_vec.h"
+#include "waiter.h"
 #include "devmapper.h"
 #include "dmparser.h"
 #include "config.h"
 #include "propsel.h"
 #include "sysfs.h"
 #include "discovery.h"
+#include "prio.h"
 
 /*
  * creates or updates mpp->paths reading mpp->pg
diff --git a/libprio/Makefile b/libprio/Makefile
deleted file mode 100644 (file)
index 46fd0ac..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile
-#
-# Copyright (C) 2007 Christophe Varoqui, <christophe.varoqui@free.fr>
-#
-include ../Makefile.inc
-
-LIBS = \
-       libprio.so \
-       libpriorandom.so \
-       libprioconst.so \
-       libpriohp_sw.so \
-       libprioemc.so \
-       libpriordac.so \
-       libprioalua.so \
-       libprionetapp.so \
-       libpriohds.so
-
-CFLAGS += -I$(multipathdir)
-
-all: $(LIBS)
-
-libprioalua.so: alua.o alua_rtpg.o
-       $(CC) $(SHARED_FLAGS) -o $@ $^
-
-%.so: %.o
-       $(CC) $(SHARED_FLAGS) -o $@ $^
-
-libprio%.so: %.o
-       $(CC) $(SHARED_FLAGS) -o $@ $^
-
-install: $(LIBS)
-       install -m 755 libprio*.so $(libdir)
-
-uninstall:
-       rm -f $(libdir)/libprio*.so
-
-clean:
-       rm -f core *.a *.o *.gz *.so
diff --git a/libprio/alua.c b/libprio/alua.c
deleted file mode 100644 (file)
index a19d691..0000000
+++ /dev/null
@@ -1,91 +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 <stdio.h>
-
-#include <debug.h>
-
-#include "libprio.h"
-#include "alua.h"
-
-#define ALUA_PRIO_NOT_SUPPORTED                        1
-#define ALUA_PRIO_RTPG_FAILED                  2
-#define ALUA_PRIO_GETAAS_FAILED                        3
-
-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 (rc == TPGS_NONE)
-               return -ALUA_PRIO_NOT_SUPPORTED;
-
-       tpg = get_target_port_group(fd);
-       if (tpg < 0)
-               return -ALUA_PRIO_RTPG_FAILED;
-
-       condlog(3, "reported target port group is %i", tpg);
-       rc = get_asymmetric_access_state(fd, tpg);
-       if (rc < 0)
-               return -ALUA_PRIO_GETAAS_FAILED;
-
-       condlog(3, "aas = [%s]",
-               (aas_string[rc]) ? aas_string[rc] : "invalid/reserved");
-       return rc;
-}
-
-int getprio (struct path * pp)
-{
-       int rc = get_alua_info(pp->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;
-               }
-       } else {
-               switch(-rc) {
-                       case ALUA_PRIO_NOT_SUPPORTED:
-                               condlog(0, "%s: alua not supported", pp->dev);
-                               break;
-                       case ALUA_PRIO_RTPG_FAILED:
-                               condlog(0, "%s: couldn't get target port group", pp->dev);
-                               break;
-                       case ALUA_PRIO_GETAAS_FAILED:
-                               condlog(0, "%s: couln't get asymmetric access state", pp->dev);
-                               break;
-               }
-       }
-       return rc;
-}
diff --git a/libprio/alua.h b/libprio/alua.h
deleted file mode 100644 (file)
index 78a3d15..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _ALUA_H
-#define _ALUA_H
-
-#include "alua_rtpg.h"
-
-#define PRIO_ALUA "alua"
-int prio_alua(struct path * pp);
-
-#endif
diff --git a/libprio/alua_rtpg.c b/libprio/alua_rtpg.c
deleted file mode 100644 (file)
index c5528c5..0000000
+++ /dev/null
@@ -1,301 +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 <sys/ioctl.h>
-#include <inttypes.h>
-
-#define __user
-#include <scsi/sg.h>
-
-#include "alua_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/libprio/alua_rtpg.h b/libprio/alua_rtpg.h
deleted file mode 100644 (file)
index c43e0a9..0000000
+++ /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 "alua_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/libprio/alua_spc3.h b/libprio/alua_spc3.h
deleted file mode 100644 (file)
index bddbbdd..0000000
+++ /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/libprio/const.c b/libprio/const.c
deleted file mode 100644 (file)
index 9951f55..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-#include "libprio.h"
-
-int getprio (struct path * pp)
-{
-       return 1;
-}
diff --git a/libprio/const.h b/libprio/const.h
deleted file mode 100644 (file)
index 220db54..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _CONST_H
-#define _CONST_H
-
-#define PRIO_CONST "const"
-int prio_const(struct path * pp);
-
-#endif
diff --git a/libprio/emc.c b/libprio/emc.c
deleted file mode 100644 (file)
index f230d52..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include <sg_include.h>
-#include <debug.h>
-
-#include "libprio.h"
-
-#define INQUIRY_CMD     0x12
-#define INQUIRY_CMDLEN  6
-
-#define pp_emc_log(prio, msg) condlog(prio, "%s: emc prio: " msg, dev)
-
-int emc_clariion_prio(const char *dev, int fd)
-{
-       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;
-
-       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) {
-               pp_emc_log(0, "sending query command failed");
-               goto out;
-       }
-       if (io_hdr.info & SG_INFO_OK_MASK) {
-               pp_emc_log(0, "query command indicates error");
-               goto out;
-       }
-
-       if (/* Verify the code page - right page & revision */
-           sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) {
-               pp_emc_log(0, "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) {
-               pp_emc_log(0, "path not correctly configured for failover");
-       }
-
-       if ( /* LUN operations should indicate normal operations */
-               sense_buffer[48] != 0x00) {
-               pp_emc_log(0, "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 getprio (struct path * pp)
-{
-       return emc_clariion_prio(pp->dev, pp->fd);
-}
diff --git a/libprio/emc.h b/libprio/emc.h
deleted file mode 100644 (file)
index 0ab0bc5..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _EMC_H
-#define _EMC_H
-
-#define PRIO_EMC "emc"
-int prio_emc(struct path * pp);
-
-#endif
diff --git a/libprio/hds.c b/libprio/hds.c
deleted file mode 100644 (file)
index bdce175..0000000
+++ /dev/null
@@ -1,171 +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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-
-#include <sg_include.h>
-#include <debug.h>
-
-#include "libprio.h"
-
-#define INQ_REPLY_LEN 255
-#define INQ_CMD_CODE 0x12
-#define INQ_CMD_LEN 6
-
-#define pp_hds_log(prio, fmt, args...) \
-        condlog(prio, "%s: hds prio: " fmt, dev, ##args)
-
-int hds_modular_prio (const char *dev, int fd)
-{
-       int 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 ((ioctl (fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
-               pp_hds_log(0, "can't use SG ioctl interface");
-               return -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 (fd, SG_IO, &io_hdr) < 0) {
-               pp_hds_log(0, "SG_IO error");
-               return -1;
-       }
-       if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
-               pp_hds_log(0, "SCSI error");
-               return -1;
-       }
-
-       snprintf (vendor, 9, "%.8s", 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);
-
-       pp_hds_log(4, "VENDOR:  %s", vendor);
-       pp_hds_log(4, "PRODUCT: %s", product);
-       pp_hds_log(4, "SERIAL:  0x%s", serial);
-       pp_hds_log(4, "LDEV:    0x%s", ldev);
-       pp_hds_log(4, "CTRL:    %s", ctrl);
-       pp_hds_log(4, "PORT:    %s", 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':
-                       pp_hds_log(4, "CTRL EVEN, LDEV EVEN, PRIO 1");
-                       return 1;
-                       break;
-               case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F':
-                       pp_hds_log(4, "CTRL EVEN, LDEV ODD, PRIO 0");
-                       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':
-                       pp_hds_log(4, "CTRL ODD, LDEV EVEN, PRIO 0");
-                       return 0;
-                       break;
-               case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F':
-                       pp_hds_log(4, "CTRL ODD, LDEV ODD, PRIO 1");
-                       return 1;
-                       break;
-               }
-       }
-       return -1;
-}
-
-int getprio (struct path * pp)
-{
-       return hds_modular_prio(pp->dev, pp->fd);
-}
diff --git a/libprio/hds.h b/libprio/hds.h
deleted file mode 100644 (file)
index 084d77c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _HDS_H
-#define _HDS_H
-
-#define PRIO_HDS "hds"
-int prio_hds(struct path * pp);
-
-#endif
diff --git a/libprio/hp_sw.c b/libprio/hp_sw.c
deleted file mode 100644 (file)
index 7230e48..0000000
+++ /dev/null
@@ -1,101 +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 <unistd.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include <sg_include.h>
-#include <debug.h>
-
-#include "libprio.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
-
-#define pp_hp_sw_log(prio, fmt, args...) \
-        condlog(prio, "%s: hp_sw prio: " fmt, dev, ##args)
-
-int hp_sw_prio(const char *dev, int fd)
-{
-        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;
-
-       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) {
-               pp_hp_sw_log(0, "sending tur command failed");
-               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;
-                               }
-                       }
-                }
-        }
-out:
-       return(ret);
-}
-
-int getprio (struct path * pp)
-{
-       return hp_sw_prio(pp->dev, pp->fd);
-}
diff --git a/libprio/hp_sw.h b/libprio/hp_sw.h
deleted file mode 100644 (file)
index 2fea486..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _HP_SW_H
-#define _HP_SW_H
-
-#define PRIO_HP_SW "hp_sw"
-int prio_hp_sw(struct path * pp);
-
-#endif
diff --git a/libprio/libprio.c b/libprio/libprio.c
deleted file mode 100644 (file)
index e5e4f3a..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <dlfcn.h>
-
-#include <debug.h>
-#include "libprio.h"
-
-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;
-
-       list_for_each_entry(p, &prioritizers, node) {
-               if (!strncmp(name, p->name, PRIO_NAME_LEN))
-                       return 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(3, "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);
-}
-
-char * prio_name (struct prio * p)
-{
-       return p->name;
-}
-
-struct prio * prio_default (void)
-{
-       return prio_lookup(DEFAULT_PRIO);
-}
diff --git a/libprio/libprio.h b/libprio/libprio.h
deleted file mode 100644 (file)
index 4a0900d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _LIBPRIO_H
-#define _LIBPRIO_H
-
-/*
- * knowing about path struct gives flexibility to prioritizers
- */
-#include "../libcheckers/checkers.h"
-#include "../libmultipath/vector.h"
-#include "../libmultipath/structs.h"
-#include "../libmultipath/list.h"
-#include "../libmultipath/memory.h"
-
-#define DEFAULT_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
- */
-#define PRIO_UNDEF -1
-
-/*
- * strings lengths
- */
-#define LIB_PRIO_NAMELEN 255
-#define PRIO_NAME_LEN 16
-
-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 *);
-struct prio * prio_default (void);
-
-#endif /* _LIBPRIO_H */
diff --git a/libprio/netapp.c b/libprio/netapp.c
deleted file mode 100644 (file)
index 59718f8..0000000
+++ /dev/null
@@ -1,244 +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/ioctl.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <sg_include.h>
-#include <debug.h>
-
-#include "libprio.h"
-
-#define INQUIRY_CMD    0x12
-#define INQUIRY_CMDLEN 6
-#define DEFAULT_PRIOVAL        10
-#define RESULTS_MAX    256
-#define SG_TIMEOUT     30000
-
-#define pp_netapp_log(prio, fmt, args...) \
-        condlog(prio, "%s: netapp prio: " fmt, dev, ##args)
-
-static void dump_cdb(unsigned char *cdb, int size)
-{
-       int i;
-       char buf[10*5+1];
-       char * p = &buf[0];
-       
-       condlog(0, "- SCSI CDB: ");
-       for (i=0; i<size; i++) {
-               p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
-       }
-       condlog(0, "%s", buf);
-}
-
-static void process_sg_error(struct sg_io_hdr *io_hdr)
-{
-       int i;
-       char buf[128*5+1];
-       char * p = &buf[0];
-       
-       condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
-               "driver_status=0x%02x", io_hdr->masked_status,
-               io_hdr->host_status, io_hdr->driver_status);
-       if (io_hdr->sb_len_wr > 0) {
-               condlog(0, "- SCSI sense data: ");
-               for (i=0; i<io_hdr->sb_len_wr; i++) {
-                       p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
-                                     io_hdr->sbp[i]);
-               }
-               condlog(0, "%s", buf);
-       }
-}
-
-/*
- * Returns:
- * -1: error, errno set
- *  0: success
- */
-static int send_gva(const char *dev, int fd, 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;
-
-       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) {
-               pp_netapp_log(0, "SG_IO ioctl failed, errno=%d", errno);
-               dump_cdb(cdb, sizeof(cdb));
-               goto out;
-       }
-       if (io_hdr.info & SG_INFO_OK_MASK) {
-               pp_netapp_log(0, "SCSI error");
-               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));
-               pp_netapp_log(0, "GVA return wrong format ");
-               pp_netapp_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
-                       results[4], results[5], results[6], results[7]);
-               goto out;
-       }
-       ret = 0;
- out:
-       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, int fd)
-{
-       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;
-
-       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) {
-               pp_netapp_log(0, "ioctl sending inquiry command failed, "
-                       "errno=%d", errno);
-               dump_cdb(cdb, sizeof(cdb));
-               goto out;
-       }
-       if (io_hdr.info & SG_INFO_OK_MASK) {
-               pp_netapp_log(0, "SCSI error");
-               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) {
-               pp_netapp_log(0,"proxy info page in unknown format - ");
-               pp_netapp_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
-                       "0x%02x 0x%02x",
-                       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:
-       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, int fd)
-{
-       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, fd, 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) {
-                       pp_netapp_log(0, "GVA page 0x41 error - "
-                               "results[8] = 0x%x", 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, fd);
-       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 getprio (struct path * pp)
-{
-       return netapp_prio(pp->dev, pp->fd);
-}
diff --git a/libprio/netapp.h b/libprio/netapp.h
deleted file mode 100644 (file)
index ec38821..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _NETAPP_H
-#define _NETAPP_H
-
-#define PRIO_NETAPP "netapp"
-int prio_netapp(struct path * pp);
-
-#endif
diff --git a/libprio/random.c b/libprio/random.c
deleted file mode 100644 (file)
index 4ee2995..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "libprio.h"
-
-int getprio (struct path * pp)
-{
-       struct timeval tv;
-       
-       gettimeofday(&tv, NULL);
-       srand((unsigned int)tv.tv_usec);
-       return 1+(int) (10.0*rand()/(RAND_MAX+1.0));
-}
diff --git a/libprio/random.h b/libprio/random.h
deleted file mode 100644 (file)
index b9dae69..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _RANDOM_H
-#define _RANDOM_H
-
-#define PRIO_RANDOM "random"
-int prio_random(struct path * pp);
-
-#endif
diff --git a/libprio/rdac.c b/libprio/rdac.c
deleted file mode 100644 (file)
index 71efae2..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include <sg_include.h>
-#include <debug.h>
-
-#include "libprio.h"
-
-#define INQUIRY_CMD     0x12
-#define INQUIRY_CMDLEN  6
-
-#define pp_rdac_log(prio, msg) condlog(prio, "%s: rdac prio: " msg, dev)
-
-int rdac_prio(const char *dev, int fd)
-{
-       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;
-
-       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) {
-               pp_rdac_log(0, "sending inquiry command failed");
-               goto out;
-       }
-       if (io_hdr.info & SG_INFO_OK_MASK) {
-               pp_rdac_log(0, "inquiry command indicates error");
-               goto out;
-       }
-       
-       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' ) {
-               pp_rdac_log(0, "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 getprio (struct path * pp)
-{
-       return rdac_prio(pp->dev, pp->fd);
-}
diff --git a/libprio/rdac.h b/libprio/rdac.h
deleted file mode 100644 (file)
index a5b7f8e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _RDAC_H
-#define _RDAC_H
-
-#define PRIO_RDAC "rdac"
-int prio_rdac(struct path * pp);
-
-#endif
index b01cca8..b9d0ec4 100644 (file)
@@ -6,11 +6,10 @@ include ../Makefile.inc
 
 OBJS = main.o
 
-CFLAGS += -I$(multipathdir) -I$(checkersdir) -I$(libpriodir)
+CFLAGS += -I$(multipathdir) -I$(checkersdir)
 LDFLAGS += -laio -ldevmapper -lpthread \
           -lmultipath -L$(multipathdir) \
           -lcheckers -L$(checkersdir) \
-          -lprio -L$(libpriodir) \
 
 EXEC = multipath
 
index f196ee7..ce36265 100644 (file)
@@ -27,7 +27,7 @@
 #include <ctype.h>
 
 #include <checkers.h>
-#include <libprio.h>
+#include <prio.h>
 #include <vector.h>
 #include <memory.h>
 #include <libdevmapper.h>
index d5525aa..fc3733b 100644 (file)
@@ -5,11 +5,10 @@ include ../Makefile.inc
 #
 # basic flags setting
 #
-CFLAGS += -DDAEMON -I$(multipathdir) -I$(checkersdir) -I$(libpriodir)
+CFLAGS += -DDAEMON -I$(multipathdir) -I$(checkersdir)
 LDFLAGS += -lpthread -ldevmapper -lreadline -lncurses -laio \
           -lmultipath -L$(multipathdir) \
-          -lcheckers -L$(checkersdir) \
-          -lprio -L$(libpriodir)
+          -lcheckers -L$(checkersdir)
 
 #
 # debuging stuff
index 8947ba4..2fc00f7 100644 (file)
@@ -19,7 +19,6 @@
  * libcheckers
  */
 #include <checkers.h>
-#include <libprio.h>
 
 /*
  * libmultipath
@@ -46,6 +45,7 @@
 #include <switchgroup.h>
 #include <print.h>
 #include <configure.h>
+#include <prio.h>
 
 #include "main.h"
 #include "pidfile.h"