[checkers] checkers are now dlopen'ed plugins
authorChristophe Varoqui <christophe.varoqui@free.fr>
Sat, 12 Apr 2008 21:57:57 +0000 (23:57 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Sat, 12 Apr 2008 21:57:57 +0000 (23:57 +0200)
just like prioritizers.
A lot of files shuffling too.

57 files changed:
Makefile
Makefile.inc
libcheckers/Makefile [deleted file]
libcheckers/checkers.c [deleted file]
libcheckers/checkers.h [deleted file]
libcheckers/directio.c [deleted file]
libcheckers/directio.h [deleted file]
libcheckers/emc_clariion.c [deleted file]
libcheckers/emc_clariion.h [deleted file]
libcheckers/hp_sw.c [deleted file]
libcheckers/hp_sw.h [deleted file]
libcheckers/libsg.c [deleted file]
libcheckers/libsg.h [deleted file]
libcheckers/rdac.c [deleted file]
libcheckers/rdac.h [deleted file]
libcheckers/readsector0.c [deleted file]
libcheckers/readsector0.h [deleted file]
libcheckers/tur.c [deleted file]
libcheckers/tur.h [deleted file]
libmultipath/Makefile
libmultipath/blacklist.c
libmultipath/callout.c
libmultipath/checkers.c [new file with mode: 0644]
libmultipath/checkers.h [new file with mode: 0644]
libmultipath/checkers/Makefile [new file with mode: 0644]
libmultipath/checkers/directio.c [new file with mode: 0644]
libmultipath/checkers/directio.h [new file with mode: 0644]
libmultipath/checkers/emc_clariion.c [new file with mode: 0644]
libmultipath/checkers/emc_clariion.h [new file with mode: 0644]
libmultipath/checkers/hp_sw.c [new file with mode: 0644]
libmultipath/checkers/hp_sw.h [new file with mode: 0644]
libmultipath/checkers/libsg.c [new file with mode: 0644]
libmultipath/checkers/libsg.h [new file with mode: 0644]
libmultipath/checkers/rdac.c [new file with mode: 0644]
libmultipath/checkers/rdac.h [new file with mode: 0644]
libmultipath/checkers/readsector0.c [new file with mode: 0644]
libmultipath/checkers/readsector0.h [new file with mode: 0644]
libmultipath/checkers/tur.c [new file with mode: 0644]
libmultipath/checkers/tur.h [new file with mode: 0644]
libmultipath/config.c
libmultipath/configure.c
libmultipath/devmapper.c
libmultipath/dict.c
libmultipath/discovery.c
libmultipath/dmparser.c
libmultipath/hwtable.c
libmultipath/pgpolicies.c
libmultipath/print.c
libmultipath/prio.h
libmultipath/propsel.c
libmultipath/structs.c
libmultipath/structs_vec.c
libmultipath/switchgroup.c
multipath/Makefile
multipath/main.c
multipathd/Makefile
multipathd/main.c

index 8b9bb31..a099daf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ export KRNLOBJ
 BUILDDIRS = \
        libmultipath \
        libmultipath/prioritizers \
-       libcheckers \
+       libmultipath/checkers \
        multipath \
        multipathd \
        devmap_name \
index 8947c8c..622f557 100644 (file)
@@ -17,7 +17,6 @@ prefix      =
 exec_prefix = $(prefix)
 bindir      = $(exec_prefix)/sbin
 libudevdir  = ${prefix}/lib/udev
-checkersdir = $(TOPDIR)/libcheckers
 multipathdir = $(TOPDIR)/libmultipath
 mandir      = $(prefix)/usr/share/man/man8
 man5dir     = $(prefix)/usr/share/man/man5
diff --git a/libcheckers/Makefile b/libcheckers/Makefile
deleted file mode 100644 (file)
index 5c2c7e9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile
-#
-# Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr>
-#
-include ../Makefile.inc
-
-LIBS = libcheckers.so
-OBJS = libsg.o checkers.o readsector0.o tur.o directio.o emc_clariion.o hp_sw.o rdac.o
-
-all: $(LIBS)
-
-$(LIBS): $(OBJS)
-       $(CC) $(SHARED_FLAGS) -o $@ $^
-
-install:
-       $(INSTALL_PROGRAM) -o root -g root -m 755 $(LIBS) $(libdir)
-
-uninstall:
-       rm -f $(libdir)/$(LIBS)
-
-clean:
-       rm -f core *.a *.o *.gz *.so
diff --git a/libcheckers/checkers.c b/libcheckers/checkers.c
deleted file mode 100644 (file)
index f07d537..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "checkers.h"
-
-#include "directio.h"
-#include "tur.h"
-#include "hp_sw.h"
-#include "emc_clariion.h"
-#include "rdac.h"
-#include "readsector0.h"
-
-static struct checker checkers[] = {
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = DIRECTIO,
-               .message    = "",
-               .context    = NULL,
-               .check      = directio,
-               .init       = directio_init,
-               .free       = directio_free
-       },
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = TUR,
-               .message    = "",
-               .context    = NULL,
-               .check      = tur,
-               .init       = tur_init,
-               .free       = tur_free
-       },
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = HP_SW,
-               .message    = "",
-               .context    = NULL,
-               .check      = hp_sw,
-               .init       = hp_sw_init,
-               .free       = hp_sw_free
-       },
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = EMC_CLARIION,
-               .message    = "",
-               .context    = NULL,
-               .check      = emc_clariion,
-               .init       = emc_clariion_init,
-               .free       = emc_clariion_free
-       },
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = RDAC,
-               .message    = "",
-               .context    = NULL,
-               .check      = rdac,
-               .init       = rdac_init,
-               .free       = rdac_free
-       },
-       {
-               .fd         = 0,
-               .sync       = 1,
-               .name       = READSECTOR0,
-               .message    = "",
-               .context    = NULL,
-               .check      = readsector0,
-               .init       = readsector0_init,
-               .free       = readsector0_free
-       },
-       {0, 1, 0, "", "", NULL, NULL, NULL, NULL},
-};
-
-void checker_set_fd (struct checker * c, int fd)
-{
-       c->fd = fd;
-}
-
-void checker_set_sync (struct checker * c)
-{
-       c->sync = 1;
-}
-
-void checker_set_async (struct checker * c)
-{
-       c->sync = 0;
-}
-
-void checker_enable (struct checker * c)
-{
-       c->disable = 0;
-}
-
-void checker_disable (struct checker * c)
-{
-       c->disable = 1;
-}
-
-struct checker * checker_lookup (char * name)
-{
-       struct checker * c = &checkers[0];
-       
-       while (c->check) {
-               if (!strncmp(name, c->name, CHECKER_NAME_LEN))
-                       return c;
-               c++;
-       }
-       return NULL;
-}
-
-int checker_init (struct checker * c, void ** mpctxt_addr)
-{
-       c->mpcontext = mpctxt_addr;
-       return c->init(c);
-}
-
-void checker_put (struct checker * c)
-{
-       if (c->free)
-               c->free(c);
-       memset(c, 0x0, sizeof(struct checker));
-}
-
-int checker_check (struct checker * c)
-{
-       int r;
-
-       if (c->disable)
-               return PATH_UNCHECKED;
-       if (c->fd <= 0) {
-               MSG(c, "no usable fd");
-               return PATH_WILD;
-       }
-       r = c->check(c);
-
-       return r;
-}
-
-int checker_selected (struct checker * c)
-{
-       return (c->check) ? 1 : 0;
-}
-
-char * checker_name (struct checker * c)
-{
-       return c->name;
-}
-
-char * checker_message (struct checker * c)
-{
-       return c->message;
-}
-
-struct checker * checker_default (void)
-{
-       return checker_lookup(DEFAULT_CHECKER);
-}
-
-void checker_get (struct checker * dst, struct checker * src)
-{
-       dst->fd = src->fd;
-       dst->sync = src->sync;
-       strncpy(dst->name, src->name, CHECKER_NAME_LEN);
-       strncpy(dst->message, src->message, CHECKER_MSG_LEN);
-       dst->check = src->check;
-       dst->init = src->init;
-       dst->free = src->free;
-}
diff --git a/libcheckers/checkers.h b/libcheckers/checkers.h
deleted file mode 100644 (file)
index 3ce643b..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef _CHECKERS_H
-#define _CHECKERS_H
-
-/*
- *
- * Userspace (multipath/multipathd) path states
- *
- * PATH_WILD:
- * - Use: None of the checkers (returned if we don't have an fd)
- * - Description: Corner case where "fd <= 0" for path fd (see checker_check())
- *
- * PATH_UNCHECKED:
- * - Use: Only in directio checker
- * - Description: set when fcntl(F_GETFL) fails to return flags or O_DIRECT
- *   not include in flags, or O_DIRECT read fails
- * - Notes:
- *   - multipathd: uses it to skip over paths in sync_map_state()
- *   - multipath: used in update_paths(); if state==PATH_UNCHECKED, call
- *     pathinfo()
- *
- * PATH_DOWN:
- * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
- * - Description: Either a) SG_IO ioctl failed, or b) check condition on some
- *   SG_IO ioctls that succeed (tur, readsector0 checkers); path is down and
- *   you shouldn't try to send commands to it
- *
- * PATH_UP:
- * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
- * - Description: Path is up and I/O can be sent to it
- *
- * PATH_SHAKY:
- * - Use: Only emc_clariion
- * - Description: Indicates path not available for "normal" operations
- *
- * PATH_GHOST:
- * - Use: Only hp_sw
- * - Description: Indicates a "passive/standby" path on active/passive HP
- *   arrays.  These paths will return valid answers to certain SCSI commands
- *   (tur, read_capacity, inquiry, start_stop), but will fail I/O commands.
- *   The path needs an initialization command to be sent to it in order for
- *   I/Os to succeed.
- *
- * PATH_PENDING:
- * - Use: All async checkers
- * - Description: Indicates a check IO is in flight.
- */
-#define PATH_WILD      -1
-#define PATH_UNCHECKED 0
-#define PATH_DOWN      1
-#define PATH_UP                2
-#define PATH_SHAKY     3
-#define PATH_GHOST     4
-#define PATH_PENDING   5
-
-#define DIRECTIO     "directio"
-#define TUR          "tur"
-#define HP_SW        "hp_sw"
-#define RDAC         "rdac"
-#define EMC_CLARIION "emc_clariion"
-#define READSECTOR0  "readsector0"
-
-#define DEFAULT_CHECKER DIRECTIO
-
-/*
- * Overloaded storage response time can be very long.
- * SG_IO timouts after DEF_TIMEOUT milliseconds, and checkers interprets this
- * as a path failure. multipathd then proactively evicts the path from the DM
- * multipath table in this case.
- *
- * This generaly snow balls and ends up in full eviction and IO errors for end
- * users. Bad. This may also cause SCSI bus resets, causing disruption for all
- * local and external storage hardware users.
- * 
- * Provision a long timeout. Longer than any real-world application would cope
- * with.
- */
-#define DEF_TIMEOUT            300000
-#define ASYNC_TIMEOUT_SEC      30
-
-/*
- * strings lengths
- */
-#define CHECKER_NAME_LEN 16
-#define CHECKER_MSG_LEN 256
-#define CHECKER_DEV_LEN 256
-
-struct checker {
-       int fd;
-       int sync;
-       int disable;
-       char name[CHECKER_NAME_LEN];
-       char message[CHECKER_MSG_LEN];       /* comm with callers */
-       void * context;                      /* store for persistent data */
-       void ** mpcontext;                   /* store for persistent data
-                                               shared multipath-wide */
-       int (*check)(struct checker *);
-       int (*init)(struct checker *);       /* to allocate the context */
-       void (*free)(struct checker *);      /* to free the context */
-};
-
-#define MSG(c, fmt, args...) snprintf((c)->message, CHECKER_MSG_LEN, fmt, ##args);
-
-int checker_init (struct checker *, void **);
-void checker_put (struct checker *);
-void checker_reset (struct checker *);
-void checker_set_sync (struct checker *);
-void checker_set_async (struct checker *);
-void checker_set_fd (struct checker *, int);
-void checker_enable (struct checker *);
-void checker_disable (struct checker *);
-struct checker * checker_lookup (char *);
-int checker_check (struct checker *);
-int checker_selected (struct checker *);
-char * checker_name (struct checker *);
-char * checker_message (struct checker *);
-struct checker * checker_default (void);
-void checker_get (struct checker *, struct checker *);
-
-#endif /* _CHECKERS_H */
diff --git a/libcheckers/directio.c b/libcheckers/directio.c
deleted file mode 100644 (file)
index ee09af7..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2005 Hannes Reinecke, Suse
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <errno.h>
-#include <linux/kdev_t.h>
-#include <asm/unistd.h>
-#include <libaio.h>
-
-#include "checkers.h"
-#include "../libmultipath/debug.h"
-
-#define MSG_DIRECTIO_UNKNOWN   "directio checker is not available"
-#define MSG_DIRECTIO_UP                "directio checker reports path is up"
-#define MSG_DIRECTIO_DOWN      "directio checker reports path is down"
-#define MSG_DIRECTIO_PENDING   "directio checker is waiting on aio"
-
-#define LOG(prio, fmt, args...) condlog(prio, "directio: " fmt, ##args)
-
-struct directio_context {
-       int             running;
-       int             reset_flags;
-       int             blksize;
-       unsigned char * buf;
-       unsigned char * ptr;
-       io_context_t    ioctx;
-       struct iocb     io;
-};
-
-
-int directio_init (struct checker * c)
-{
-       unsigned long pgsize = getpagesize();
-       struct directio_context * ct;
-       long flags;
-
-       ct = malloc(sizeof(struct directio_context));
-       if (!ct)
-               return 1;
-       memset(ct, 0, sizeof(struct directio_context));
-
-       if (io_setup(1, &ct->ioctx) != 0) {
-               condlog(1, "io_setup failed");
-               free(ct);
-               return 1;
-       }
-
-       if (ioctl(c->fd, BLKBSZGET, &ct->blksize) < 0) {
-               MSG(c, "cannot get blocksize, set default");
-               ct->blksize = 512;
-       }
-       if (ct->blksize > 4096) {
-               /*
-                * Sanity check for DASD; BSZGET is broken
-                */
-               ct->blksize = 4096;
-       }
-       if (!ct->blksize)
-               goto out;
-       ct->buf = (unsigned char *)malloc(ct->blksize + pgsize);
-       if (!ct->buf)
-               goto out;
-
-       flags = fcntl(c->fd, F_GETFL);
-       if (flags < 0)
-               goto out;
-       if (!(flags & O_DIRECT)) {
-               flags |= O_DIRECT;
-               if (fcntl(c->fd, F_SETFL, flags) < 0)
-                       goto out;
-               ct->reset_flags = 1;
-       }
-
-       ct->ptr = (unsigned char *) (((unsigned long)ct->buf + pgsize - 1) &
-                 (~(pgsize - 1)));
-
-       /* Sucessfully initialized, return the context. */
-       c->context = (void *) ct;
-       return 0;
-
-out:
-       if (ct->buf)
-               free(ct->buf);
-       io_destroy(ct->ioctx);
-       free(ct);
-       return 1;
-}
-
-void directio_free (struct checker * c)
-{
-       struct directio_context * ct = (struct directio_context *)c->context;
-       long flags;
-
-       if (!ct)
-               return;
-
-       if (ct->reset_flags) {
-               if ((flags = fcntl(c->fd, F_GETFL)) >= 0) {
-                       flags &= ~O_DIRECT;
-                       /* No point in checking for errors */
-                       fcntl(c->fd, F_SETFL, flags);
-               }
-       }
-
-       if (ct->buf)
-               free(ct->buf);
-       io_destroy(ct->ioctx);
-       free(ct);
-}
-
-static int
-check_state(int fd, struct directio_context *ct, int sync)
-{
-       struct timespec timeout = { .tv_nsec = 5 };
-       struct io_event event;
-       struct stat     sb;
-       int             rc = PATH_UNCHECKED;
-       long            r;
-
-       if (fstat(fd, &sb) == 0) {
-               LOG(4, "called for %x", (unsigned) sb.st_rdev);
-       }
-       if (sync) {
-               LOG(4, "called in synchronous mode");
-               timeout.tv_sec  = ASYNC_TIMEOUT_SEC;
-               timeout.tv_nsec = 0;
-       }
-
-       if (!ct->running) {
-               struct iocb *ios[1] = { &ct->io };
-
-               LOG(3, "starting new request");
-               memset(&ct->io, 0, sizeof(struct iocb));
-               io_prep_pread(&ct->io, fd, ct->ptr, ct->blksize, 0);
-               if (io_submit(ct->ioctx, 1, ios) != 1) {
-                       LOG(3, "io_submit error %i", errno);
-                       return PATH_UNCHECKED;
-               }
-       }
-       ct->running++;
-
-       r = io_getevents(ct->ioctx, 1L, 1L, &event, &timeout);
-       LOG(3, "async io getevents returns %li (errno=%s)", r, strerror(errno));
-
-       if (r < 1L) {
-               if (ct->running > ASYNC_TIMEOUT_SEC || sync) {
-                       LOG(3, "abort check on timeout");
-                       rc = PATH_DOWN;
-               } else
-                       rc = PATH_PENDING;
-       } else {
-               LOG(3, "io finished %lu/%lu", event.res, event.res2);
-               ct->running = 0;
-               rc = (event.res == ct->blksize) ? PATH_UP : PATH_DOWN;
-       }
-
-       return rc;
-}
-
-int directio (struct checker * c)
-{
-       int ret;
-       struct directio_context * ct = (struct directio_context *)c->context;
-
-       if (!ct)
-               return PATH_UNCHECKED;
-
-       ret = check_state(c->fd, ct, c->sync);
-
-       switch (ret)
-       {
-       case PATH_UNCHECKED:
-               MSG(c, MSG_DIRECTIO_UNKNOWN);
-               break;
-       case PATH_DOWN:
-               MSG(c, MSG_DIRECTIO_DOWN);
-               break;
-       case PATH_UP:
-               MSG(c, MSG_DIRECTIO_UP);
-               break;
-       case PATH_PENDING:
-               MSG(c, MSG_DIRECTIO_PENDING);
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
diff --git a/libcheckers/directio.h b/libcheckers/directio.h
deleted file mode 100644 (file)
index 1865b1f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _DIRECTIO_H
-#define _DIRECTIO_H
-
-int directio (struct checker *);
-int directio_init (struct checker *);
-void directio_free (struct checker *);
-
-#endif /* _DIRECTIO_H */
diff --git a/libcheckers/emc_clariion.c b/libcheckers/emc_clariion.c
deleted file mode 100644 (file)
index 6c7167e..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Lars Marowsky-Bree
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "../libmultipath/sg_include.h"
-#include "libsg.h"
-#include "checkers.h"
-
-#define INQUIRY_CMD     0x12
-#define INQUIRY_CMDLEN  6
-#define HEAVY_CHECK_COUNT       10
-
-/*
- * Mechanism to track CLARiiON inactive snapshot LUs.
- * This is done so that we can fail passive paths
- * to an inactive snapshot LU even though since a
- * simple read test would return 02/04/03 instead
- * of 05/25/01 sensekey/ASC/ASCQ data.
- */
-#define        IS_INACTIVE_SNAP(c)   (c->mpcontext ?                              \
-                              ((struct emc_clariion_checker_LU_context *) \
-                                       (*c->mpcontext))->inactive_snap    \
-                                           : 0)
-
-#define        SET_INACTIVE_SNAP(c)  if (c->mpcontext)                            \
-                               ((struct emc_clariion_checker_LU_context *)\
-                                       (*c->mpcontext))->inactive_snap = 1
-
-#define        CLR_INACTIVE_SNAP(c)  if (c->mpcontext)                            \
-                               ((struct emc_clariion_checker_LU_context *)\
-                                       (*c->mpcontext))->inactive_snap = 0
-
-struct emc_clariion_checker_path_context {
-       char wwn[16];
-       unsigned wwn_set;
-};
-
-struct emc_clariion_checker_LU_context {
-       int inactive_snap;
-};
-
-extern void
-hexadecimal_to_ascii(char * wwn, char *wwnstr)
-{
-       int i,j, nbl;
-
-       for (i=0,j=0;i<16;i++) {
-               wwnstr[j++] = ((nbl = ((wwn[i]&0xf0) >> 4)) <= 9) ?
-                                       '0' + nbl : 'a' + (nbl - 10);
-               wwnstr[j++] = ((nbl = (wwn[i]&0x0f)) <= 9) ?
-                                       '0' + nbl : 'a' + (nbl - 10);
-       }
-       wwnstr[32]=0;
-}
-
-int emc_clariion_init (struct checker * c)
-{
-       /*
-        * Allocate and initialize the path specific context.
-        */
-       c->context = malloc(sizeof(struct emc_clariion_checker_path_context));
-       if (!c->context)
-               return 1;
-       ((struct emc_clariion_checker_path_context *)c->context)->wwn_set = 0;
-
-       /*
-        * Allocate and initialize the multi-path global context.
-        */
-       if (c->mpcontext) {
-               void * mpctxt = malloc(sizeof(int));
-               *c->mpcontext = mpctxt;
-               CLR_INACTIVE_SNAP(c);
-       }
-
-       return 0;
-}
-
-void emc_clariion_free (struct checker * c)
-{
-       free(c->context);
-}
-
-int emc_clariion(struct checker * c)
-{
-       unsigned char sense_buffer[128] = { 0, };
-       unsigned char sb[SENSE_BUFF_LEN] = { 0, }, *sbb;
-       unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
-                                               sizeof(sense_buffer), 0};
-       struct sg_io_hdr io_hdr;
-       struct emc_clariion_checker_path_context * ct =
-               (struct emc_clariion_checker_path_context *)c->context;
-       char wwnstr[33];
-       int ret;
-
-       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 = DEF_TIMEOUT;
-       io_hdr.pack_id = 0;
-       if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
-               MSG(c, "emc_clariion_checker: sending query command failed");
-               return PATH_DOWN;
-       }
-       if (io_hdr.info & SG_INFO_OK_MASK) {
-               MSG(c, "emc_clariion_checker: query command indicates error");
-               return PATH_DOWN;
-       }
-       if (/* Verify the code page - right page & revision */
-           sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) {
-               MSG(c, "emc_clariion_checker: Path unit report page in "
-                   "unknown format");
-               return PATH_DOWN;
-       }
-
-       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) {
-               MSG(c, "emc_clariion_checker: Path not correctly configured "
-                   "for failover");
-               return PATH_DOWN;
-       }
-
-       if ( /* LUN operations should indicate normal operations */
-               sense_buffer[48] != 0x00) {
-               MSG(c, "emc_clariion_checker: Path not available for normal "
-                   "operations");
-               return PATH_SHAKY;
-       }
-
-       if ( /* LUN should at least be bound somewhere and not be LUNZ */
-               sense_buffer[4] == 0x00) {
-               MSG(c, "emc_clariion_checker: Logical Unit is unbound "
-                   "or LUNZ");
-               return PATH_DOWN;
-       }
-       
-       /*
-        * store the LUN WWN there and compare that it indeed did not
-        * change in between, to protect against the path suddenly
-        * pointing somewhere else.
-        */
-       if (ct->wwn_set) {
-               if (memcmp(ct->wwn, &sense_buffer[10], 16) != 0) {
-                       MSG(c, "emc_clariion_checker: Logical Unit WWN "
-                           "has changed!");
-                       return PATH_DOWN;
-               }
-       } else {
-               memcpy(ct->wwn, &sense_buffer[10], 16);
-               ct->wwn_set = 1;
-       }
-       
-       /*
-        * Issue read on active path to determine if inactive snapshot.
-        */
-       if (sense_buffer[4] == 2) {/* if active path */
-               unsigned char buf[4096];
-
-               ret = sg_read(c->fd, &buf[0], sbb = &sb[0]);
-               if (ret == PATH_DOWN) {
-                       hexadecimal_to_ascii(ct->wwn, wwnstr);
-
-                       /*
-                        * Check for inactive snapshot LU this way.  Must
-                        * fail these.
-                        */
-                       if (((sbb[2]&0xf) == 5) && (sbb[12] == 0x25) &&
-                           (sbb[13]==1)) {
-                               /*
-                                * Do this so that we can fail even the
-                                * passive paths which will return
-                                * 02/04/03 not 05/25/01 on read.
-                                */
-                               SET_INACTIVE_SNAP(c);
-                               MSG(c, "emc_clariion_checker: Active "
-                                       "path to inactive snapshot WWN %s.",
-                                       wwnstr);
-                       } else
-                               MSG(c, "emc_clariion_checker: Read "
-                                       "error for WWN %s.  Sense data are "
-                                       "0x%x/0x%x/0x%x.", wwnstr,
-                                       sbb[2]&0xf, sbb[12], sbb[13]);
-               } else {
-                       MSG(c, "emc_clariion_checker: Active path is "
-                           "healthy.");
-                       /*
-                        * Remove the path from the set of paths to inactive
-                        * snapshot LUs if it was in this list since the
-                        * snapshot is no longer inactive.
-                        */
-                       CLR_INACTIVE_SNAP(c);
-               }
-       } else {
-               if (IS_INACTIVE_SNAP(c)) {
-                       hexadecimal_to_ascii(ct->wwn, wwnstr);
-                       MSG(c, "emc_clariion_checker: Passive "
-                               "path to inactive snapshot WWN %s.",
-                               wwnstr);
-                       ret = PATH_DOWN;
-               } else {
-                       MSG(c,
-                           "emc_clariion_checker: Passive path is healthy.");
-                       ret = PATH_UP;  /* not ghost */
-               }
-       }
-
-       return ret;
-}
diff --git a/libcheckers/emc_clariion.h b/libcheckers/emc_clariion.h
deleted file mode 100644 (file)
index a1018a6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _EMC_CLARIION_H
-#define _EMC_CLARIION_H
-
-int emc_clariion (struct checker *);
-int emc_clariion_init (struct checker *);
-void emc_clariion_free (struct checker *);
-
-#endif /* _EMC_CLARIION_H */
diff --git a/libcheckers/hp_sw.c b/libcheckers/hp_sw.c
deleted file mode 100644 (file)
index b9731ff..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2005 Christophe Varoqui
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "checkers.h"
-
-#include "../libmultipath/sg_include.h"
-
-#define TUR_CMD_LEN            6
-#define INQUIRY_CMDLEN         6
-#define INQUIRY_CMD            0x12
-#define SENSE_BUFF_LEN         32
-#define SCSI_CHECK_CONDITION   0x2
-#define SCSI_COMMAND_TERMINATED        0x22
-#define SG_ERR_DRIVER_SENSE    0x08
-#define RECOVERED_ERROR                0x01
-#define MX_ALLOC_LEN           255
-#define HEAVY_CHECK_COUNT       10
-
-#define MSG_HP_SW_UP   "hp_sw checker reports path is up"
-#define MSG_HP_SW_DOWN "hp_sw checker reports path is down"
-#define MSG_HP_SW_GHOST        "hp_sw checker reports path is ghost"
-
-struct sw_checker_context {
-       void * dummy;
-};
-
-int hp_sw_init (struct checker * c)
-{
-       return 0;
-}
-
-void hp_sw_free (struct checker * c)
-{
-       return;
-}
-
-static int
-do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
-       void *resp, int mx_resp_len, int noisy)
-{
-        unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
-            { INQUIRY_CMD, 0, 0, 0, 0, 0 };
-        unsigned char sense_b[SENSE_BUFF_LEN];
-        struct sg_io_hdr io_hdr;
-                                                                                                                 
-        if (cmddt)
-                inqCmdBlk[1] |= 2;
-        if (evpd)
-                inqCmdBlk[1] |= 1;
-        inqCmdBlk[2] = (unsigned char) pg_op;
-       inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
-       inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
-        memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
-        io_hdr.interface_id = 'S';
-        io_hdr.cmd_len = sizeof (inqCmdBlk);
-        io_hdr.mx_sb_len = sizeof (sense_b);
-        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-        io_hdr.dxfer_len = mx_resp_len;
-        io_hdr.dxferp = resp;
-        io_hdr.cmdp = inqCmdBlk;
-        io_hdr.sbp = sense_b;
-        io_hdr.timeout = DEF_TIMEOUT;
-        if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
-                return 1;
-        /* treat SG_ERR here to get rid of sg_err.[ch] */
-        io_hdr.status &= 0x7e;
-        if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
-            (0 == io_hdr.driver_status))
-                return 0;
-        if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
-            (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
-            (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
-                if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
-                        int sense_key;
-                        unsigned char * sense_buffer = io_hdr.sbp;
-                        if (sense_buffer[0] & 0x2)
-                                sense_key = sense_buffer[1] & 0xf;
-                        else
-                                sense_key = sense_buffer[2] & 0xf;
-                        if(RECOVERED_ERROR == sense_key)
-                                return 0;
-                }
-        }
-        return 1;
-}
-
-static int
-do_tur (int fd)
-{
-        unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
-        struct sg_io_hdr io_hdr;
-        unsigned char sense_buffer[32];
-
-        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 (sense_buffer);
-        io_hdr.dxfer_direction = SG_DXFER_NONE;
-        io_hdr.cmdp = turCmdBlk;
-        io_hdr.sbp = sense_buffer;
-        io_hdr.timeout = DEF_TIMEOUT;
-        io_hdr.pack_id = 0;
-
-        if (ioctl(fd, SG_IO, &io_hdr) < 0)
-               return 1;
-
-        if (io_hdr.info & SG_INFO_OK_MASK)
-               return 1;
-
-       return 0;
-}
-
-extern int
-hp_sw (struct checker * c)
-{
-       char buff[MX_ALLOC_LEN];
-
-       if (0 != do_inq(c->fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
-               MSG(c, MSG_HP_SW_DOWN);
-               return PATH_DOWN;
-       }
-
-       if (do_tur(c->fd)) {
-               MSG(c, MSG_HP_SW_GHOST);
-                return PATH_GHOST;
-        }
-       MSG(c, MSG_HP_SW_UP);
-       return PATH_UP;
-}
diff --git a/libcheckers/hp_sw.h b/libcheckers/hp_sw.h
deleted file mode 100644 (file)
index 3be0d8e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _HP_SW_H
-#define _HP_SW_H
-
-int hp_sw (struct checker *);
-int hp_sw_init (struct checker *);
-void hp_sw_free (struct checker *);
-
-#endif /* _HP_SW_H */
diff --git a/libcheckers/libsg.c b/libcheckers/libsg.c
deleted file mode 100644 (file)
index 9171b10..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Christophe Varoqui
- */
-#include <string.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "checkers.h"
-#include "libsg.h"
-#include "../libmultipath/sg_include.h"
-
-int
-sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff)
-{
-       /* defaults */
-       int blocks = 1;
-       long long start_block = 0;
-       int bs = 512;
-       int cdbsz = 10;
-       int * diop = NULL;
-
-       unsigned char rdCmd[cdbsz];
-       unsigned char *sbb = senseBuff;
-       struct sg_io_hdr io_hdr;
-       int res;
-       int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
-       int sz_ind;
-       struct stat filestatus;
-       int retry_count = 3;
-
-       if (fstat(sg_fd, &filestatus) != 0)
-               return PATH_DOWN;
-       bs = (filestatus.st_blksize > 4096)? 4096: filestatus.st_blksize;
-       memset(rdCmd, 0, cdbsz);
-       sz_ind = 1;
-       rdCmd[0] = rd_opcode[sz_ind];
-       rdCmd[2] = (unsigned char)((start_block >> 24) & 0xff);
-       rdCmd[3] = (unsigned char)((start_block >> 16) & 0xff);
-       rdCmd[4] = (unsigned char)((start_block >> 8) & 0xff);
-       rdCmd[5] = (unsigned char)(start_block & 0xff);
-       rdCmd[7] = (unsigned char)((blocks >> 8) & 0xff);
-       rdCmd[8] = (unsigned char)(blocks & 0xff);
-
-       memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-       io_hdr.interface_id = 'S';
-       io_hdr.cmd_len = cdbsz;
-       io_hdr.cmdp = rdCmd;
-       io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-       io_hdr.dxfer_len = bs * blocks;
-       io_hdr.dxferp = buff;
-       io_hdr.mx_sb_len = SENSE_BUFF_LEN;
-       io_hdr.sbp = senseBuff;
-       io_hdr.timeout = DEF_TIMEOUT;
-       io_hdr.pack_id = (int)start_block;
-       if (diop && *diop)
-       io_hdr.flags |= SG_FLAG_DIRECT_IO;
-
-retry: 
-       memset(senseBuff, 0, SENSE_BUFF_LEN);
-       while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) && (EINTR == errno));
-
-       if (res < 0) {
-               if (ENOMEM == errno) {
-                       return PATH_UP;
-               }
-               return PATH_DOWN;
-       }
-
-       if ((0 == io_hdr.status) &&
-           (0 == io_hdr.host_status) &&
-           (0 == io_hdr.driver_status)) {
-               return PATH_UP;
-       } else {
-               /*
-                * Retry if UNIT_ATTENTION check condition.
-                */
-               if ((sbb[2]&0xf) == 6) {
-                       if (--retry_count)
-                               goto retry;
-               }
-               return PATH_DOWN;
-       }
-}
diff --git a/libcheckers/libsg.h b/libcheckers/libsg.h
deleted file mode 100644 (file)
index 97c4491..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _LIBSG_H
-#define _LIBSG_H
-
-#define SENSE_BUFF_LEN 32
-
-int sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff);
-
-#endif /* _LIBSG_H */
diff --git a/libcheckers/rdac.c b/libcheckers/rdac.c
deleted file mode 100644 (file)
index f430488..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2005 Christophe Varoqui
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "checkers.h"
-
-#include "../libmultipath/sg_include.h"
-
-#define INQUIRY_CMDLEN         6
-#define INQUIRY_CMD            0x12
-#define SENSE_BUFF_LEN         32
-#define RDAC_DEF_TIMEOUT       60000
-#define SCSI_CHECK_CONDITION   0x2
-#define SCSI_COMMAND_TERMINATED        0x22
-#define SG_ERR_DRIVER_SENSE    0x08
-#define RECOVERED_ERROR                0x01
-
-#define MSG_RDAC_UP    "rdac checker reports path is up"
-#define MSG_RDAC_DOWN  "rdac checker reports path is down"
-#define MSG_RDAC_GHOST "rdac checker reports path is ghost"
-
-struct rdac_checker_context {
-       void * dummy;
-};
-
-int rdac_init (struct checker * c)
-{
-       return 0;
-}
-
-void rdac_free (struct checker * c)
-{
-       return;
-}
-
-static int
-do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len)
-{
-       unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 1, 0, 0, 0, 0 };
-       unsigned char sense_b[SENSE_BUFF_LEN];
-       struct sg_io_hdr io_hdr;
-
-       inqCmdBlk[2] = (unsigned char) pg_op;
-       inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
-       memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
-
-       io_hdr.interface_id = 'S';
-       io_hdr.cmd_len = sizeof (inqCmdBlk);
-       io_hdr.mx_sb_len = sizeof (sense_b);
-       io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-       io_hdr.dxfer_len = mx_resp_len;
-       io_hdr.dxferp = resp;
-       io_hdr.cmdp = inqCmdBlk;
-       io_hdr.sbp = sense_b;
-       io_hdr.timeout = RDAC_DEF_TIMEOUT;
-
-       if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
-               return 1;
-
-       /* treat SG_ERR here to get rid of sg_err.[ch] */
-       io_hdr.status &= 0x7e;
-       if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
-           (0 == io_hdr.driver_status))
-               return 0;
-       if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
-           (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
-           (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
-               if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
-                       int sense_key;
-                       unsigned char * sense_buffer = io_hdr.sbp;
-                       if (sense_buffer[0] & 0x2)
-                               sense_key = sense_buffer[1] & 0xf;
-                       else
-                               sense_key = sense_buffer[2] & 0xf;
-                       if (RECOVERED_ERROR == sense_key)
-                               return 0;
-               }
-       }
-       return 1;
-}
-
-struct volume_access_inq
-{
-       char dontcare0[8];
-       char avtcvp;
-       char dontcare1[39];
-};
-
-extern int
-rdac(struct checker * c)
-{
-       struct volume_access_inq inq;
-
-       if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq))) {
-               MSG(c, MSG_RDAC_DOWN);
-               return PATH_DOWN;
-       }
-
-       return ((inq.avtcvp & 0x1) ? PATH_UP : PATH_GHOST);
-}
diff --git a/libcheckers/rdac.h b/libcheckers/rdac.h
deleted file mode 100644 (file)
index d7bf812..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _RDAC_H
-#define _RDAC_H
-
-int rdac(struct checker *);
-int rdac_init(struct checker *);
-void rdac_free(struct checker *);
-
-#endif /* _RDAC_H */
diff --git a/libcheckers/readsector0.c b/libcheckers/readsector0.c
deleted file mode 100644 (file)
index bef0eb6..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Christophe Varoqui
- */
-#include <stdio.h>
-
-#include "checkers.h"
-#include "libsg.h"
-
-#define MSG_READSECTOR0_UP     "readsector0 checker reports path is up"
-#define MSG_READSECTOR0_DOWN   "readsector0 checker reports path is down"
-
-struct readsector0_checker_context {
-       void * dummy;
-};
-
-int readsector0_init (struct checker * c)
-{
-       return 0;
-}
-
-void readsector0_free (struct checker * c)
-{
-       return;
-}
-
-extern int
-readsector0 (struct checker * c)
-{
-       unsigned char buf[4096];
-       unsigned char sbuf[SENSE_BUFF_LEN];
-       int ret;
-
-       ret = sg_read(c->fd, &buf[0], &sbuf[0]);
-
-       switch (ret)
-       {
-       case PATH_DOWN:
-               MSG(c, MSG_READSECTOR0_DOWN);
-               break;
-       case PATH_UP:
-               MSG(c, MSG_READSECTOR0_UP);
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
diff --git a/libcheckers/readsector0.h b/libcheckers/readsector0.h
deleted file mode 100644 (file)
index 0f5d654..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _READSECTOR0_H
-#define _READSECTOR0_H
-
-int readsector0 (struct checker *);
-int readsector0_init (struct checker *);
-void readsector0_free (struct checker *);
-
-#endif /* _READSECTOR0_H */
diff --git a/libcheckers/tur.c b/libcheckers/tur.c
deleted file mode 100644 (file)
index e79bc0a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Some code borrowed from sg-utils.
- *
- * Copyright (c) 2004 Christophe Varoqui
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "checkers.h"
-
-#include "../libmultipath/sg_include.h"
-
-#define TUR_CMD_LEN 6
-#define HEAVY_CHECK_COUNT       10
-
-#define MSG_TUR_UP     "tur checker reports path is up"
-#define MSG_TUR_DOWN   "tur checker reports path is down"
-
-struct tur_checker_context {
-       void * dummy;
-};
-
-int tur_init (struct checker * c)
-{
-       return 0;
-}
-
-void tur_free (struct checker * c)
-{
-       return;
-}
-
-extern int
-tur (struct checker * c)
-{
-       struct sg_io_hdr io_hdr;
-        unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
-        unsigned char sense_buffer[32];
-
-        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 (sense_buffer);
-        io_hdr.dxfer_direction = SG_DXFER_NONE;
-        io_hdr.cmdp = turCmdBlk;
-        io_hdr.sbp = sense_buffer;
-        io_hdr.timeout = DEF_TIMEOUT;
-        io_hdr.pack_id = 0;
-        if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
-               MSG(c, MSG_TUR_DOWN);
-                return PATH_DOWN;
-        }
-        if (io_hdr.info & SG_INFO_OK_MASK) {
-               MSG(c, MSG_TUR_DOWN);
-                return PATH_DOWN;
-        }
-       MSG(c, MSG_TUR_UP);
-        return PATH_UP;
-}
diff --git a/libcheckers/tur.h b/libcheckers/tur.h
deleted file mode 100644 (file)
index a2e8c88..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _TUR_H
-#define _TUR_H
-
-int tur (struct checker *);
-int tur_init (struct checker *);
-void tur_free (struct checker *);
-
-#endif /* _TUR_H */
index 3865df3..16bd978 100644 (file)
@@ -5,14 +5,13 @@
 include ../Makefile.inc
 
 LIBS = libmultipath.so
-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 prio.o
+       log.o configure.o structs_vec.o sysfs.o prio.o checkers.o
 
 #ifeq ($(strip $(DAEMON)),1)
        OBJS += lock.o waiter.o
index 6297516..d85b385 100644 (file)
@@ -2,8 +2,8 @@
  * Copyright (c) 2004, 2005 Christophe Varoqui
  */
 #include <stdio.h>
-#include <checkers.h>
 
+#include "checkers.h"
 #include "memory.h"
 #include "vector.h"
 #include "util.h"
index 46b89e6..d54f3ca 100644 (file)
@@ -13,8 +13,7 @@
 #include <sys/wait.h>
 #include <errno.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "structs.h"
 #include "debug.h"
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
new file mode 100644 (file)
index 0000000..ff606d0
--- /dev/null
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <dlfcn.h>
+
+#include "debug.h"
+#include "checkers.h"
+
+static LIST_HEAD(checkers);
+
+int init_checkers (void)
+{
+       INIT_LIST_HEAD(&checkers);
+       if (!add_checker(DEFAULT_CHECKER))
+               return 1;
+       return 0;
+}
+
+struct checker * alloc_checker (void)
+{
+       return zalloc(sizeof(struct checker));
+}
+
+void free_checker (struct checker * c)
+{
+       free(c);
+}
+
+void cleanup_checkers (void)
+{
+       struct checker * checker_loop;
+       struct checker * checker_temp;
+
+       list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
+               list_del(&checker_loop->node);
+               free(checker_loop);
+       }
+}
+
+struct checker * checker_lookup (char * name)
+{
+       struct checker * c;
+
+       list_for_each_entry(c, &checkers, node) {
+               if (!strncmp(name, c->name, CHECKER_NAME_LEN))
+                       return c;
+       }
+       c = add_checker(name);
+       if (c)
+               return c;
+       return checker_default();
+}
+
+struct checker * add_checker (char * name)
+{
+       char libname[LIB_CHECKER_NAMELEN];
+       void * handle;
+       struct checker * c;
+       char *errstr;
+
+       c = alloc_checker();
+       if (!c)
+               return NULL;
+       snprintf(libname, LIB_CHECKER_NAMELEN, "libcheck%s.so", name);
+       condlog(3, "loading %s checker", libname);
+       handle = dlopen(libname, RTLD_NOW);
+       errstr = dlerror();
+       if (errstr != NULL)
+       condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!handle)
+               goto out;
+
+       c->check = (int (*)(struct checker *)) dlsym(handle, "libcheck_check");
+       errstr = dlerror();
+       if (errstr != NULL)
+       condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!c->check)
+               goto out;
+
+       c->init = (int (*)(struct checker *)) dlsym(handle, "libcheck_init");
+       errstr = dlerror();
+       if (errstr != NULL)
+       condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!c->init)
+               goto out;
+
+       c->free = (void (*)(struct checker *)) dlsym(handle, "libcheck_free");
+       errstr = dlerror();
+       if (errstr != NULL)
+       condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!c->free)
+               goto out;
+
+       snprintf(c->name, CHECKER_NAME_LEN, "%s", name);
+       c->fd = 0;
+       c->sync = 1;
+       list_add(&c->node, &checkers);
+       return c;
+out:
+       free_checker(c);
+       return NULL;
+}
+
+void checker_set_fd (struct checker * c, int fd)
+{
+       c->fd = fd;
+}
+
+void checker_set_sync (struct checker * c)
+{
+       c->sync = 1;
+}
+
+void checker_set_async (struct checker * c)
+{
+       c->sync = 0;
+}
+
+void checker_enable (struct checker * c)
+{
+       c->disable = 0;
+}
+
+void checker_disable (struct checker * c)
+{
+       c->disable = 1;
+}
+
+int checker_init (struct checker * c, void ** mpctxt_addr)
+{
+       c->mpcontext = mpctxt_addr;
+       return c->init(c);
+}
+
+void checker_put (struct checker * c)
+{
+       if (c->free)
+               c->free(c);
+       memset(c, 0x0, sizeof(struct checker));
+}
+
+int checker_check (struct checker * c)
+{
+       int r;
+
+       if (c->disable)
+               return PATH_UNCHECKED;
+       if (c->fd <= 0) {
+               MSG(c, "no usable fd");
+               return PATH_WILD;
+       }
+       r = c->check(c);
+
+       return r;
+}
+
+int checker_selected (struct checker * c)
+{
+       return (c->check) ? 1 : 0;
+}
+
+char * checker_name (struct checker * c)
+{
+       return c->name;
+}
+
+char * checker_message (struct checker * c)
+{
+       return c->message;
+}
+
+struct checker * checker_default (void)
+{
+       return checker_lookup(DEFAULT_CHECKER);
+}
+
+void checker_get (struct checker * dst, struct checker * src)
+{
+       dst->fd = src->fd;
+       dst->sync = src->sync;
+       strncpy(dst->name, src->name, CHECKER_NAME_LEN);
+       strncpy(dst->message, src->message, CHECKER_MSG_LEN);
+       dst->check = src->check;
+       dst->init = src->init;
+       dst->free = src->free;
+}
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
new file mode 100644 (file)
index 0000000..93337f1
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef _CHECKERS_H
+#define _CHECKERS_H
+
+#include "list.h"
+#include "memory.h"
+
+/*
+ *
+ * Userspace (multipath/multipathd) path states
+ *
+ * PATH_WILD:
+ * - Use: None of the checkers (returned if we don't have an fd)
+ * - Description: Corner case where "fd <= 0" for path fd (see checker_check())
+ *
+ * PATH_UNCHECKED:
+ * - Use: Only in directio checker
+ * - Description: set when fcntl(F_GETFL) fails to return flags or O_DIRECT
+ *   not include in flags, or O_DIRECT read fails
+ * - Notes:
+ *   - multipathd: uses it to skip over paths in sync_map_state()
+ *   - multipath: used in update_paths(); if state==PATH_UNCHECKED, call
+ *     pathinfo()
+ *
+ * PATH_DOWN:
+ * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
+ * - Description: Either a) SG_IO ioctl failed, or b) check condition on some
+ *   SG_IO ioctls that succeed (tur, readsector0 checkers); path is down and
+ *   you shouldn't try to send commands to it
+ *
+ * PATH_UP:
+ * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
+ * - Description: Path is up and I/O can be sent to it
+ *
+ * PATH_SHAKY:
+ * - Use: Only emc_clariion
+ * - Description: Indicates path not available for "normal" operations
+ *
+ * PATH_GHOST:
+ * - Use: Only hp_sw
+ * - Description: Indicates a "passive/standby" path on active/passive HP
+ *   arrays.  These paths will return valid answers to certain SCSI commands
+ *   (tur, read_capacity, inquiry, start_stop), but will fail I/O commands.
+ *   The path needs an initialization command to be sent to it in order for
+ *   I/Os to succeed.
+ *
+ * PATH_PENDING:
+ * - Use: All async checkers
+ * - Description: Indicates a check IO is in flight.
+ */
+#define PATH_WILD      -1
+#define PATH_UNCHECKED 0
+#define PATH_DOWN      1
+#define PATH_UP                2
+#define PATH_SHAKY     3
+#define PATH_GHOST     4
+#define PATH_PENDING   5
+
+#define DIRECTIO     "directio"
+#define TUR          "tur"
+#define HP_SW        "hp_sw"
+#define RDAC         "rdac"
+#define EMC_CLARIION "emc_clariion"
+#define READSECTOR0  "readsector0"
+
+#define DEFAULT_CHECKER DIRECTIO
+
+/*
+ * Overloaded storage response time can be very long.
+ * SG_IO timouts after DEF_TIMEOUT milliseconds, and checkers interprets this
+ * as a path failure. multipathd then proactively evicts the path from the DM
+ * multipath table in this case.
+ *
+ * This generaly snow balls and ends up in full eviction and IO errors for end
+ * users. Bad. This may also cause SCSI bus resets, causing disruption for all
+ * local and external storage hardware users.
+ * 
+ * Provision a long timeout. Longer than any real-world application would cope
+ * with.
+ */
+#define DEF_TIMEOUT            300000
+#define ASYNC_TIMEOUT_SEC      30
+
+/*
+ * strings lengths
+ */
+#define CHECKER_NAME_LEN 16
+#define CHECKER_MSG_LEN 256
+#define CHECKER_DEV_LEN 256
+#define LIB_CHECKER_NAMELEN 256
+
+struct checker {
+       struct list_head node;
+       int fd;
+       int sync;
+       int disable;
+       char name[CHECKER_NAME_LEN];
+       char message[CHECKER_MSG_LEN];       /* comm with callers */
+       void * context;                      /* store for persistent data */
+       void ** mpcontext;                   /* store for persistent data
+                                               shared multipath-wide */
+       int (*check)(struct checker *);
+       int (*init)(struct checker *);       /* to allocate the context */
+       void (*free)(struct checker *);      /* to free the context */
+};
+
+#define MSG(c, fmt, args...) snprintf((c)->message, CHECKER_MSG_LEN, fmt, ##args);
+
+int init_checkers (void);
+struct checker * add_checker (char *);
+struct checker * checker_lookup (char *);
+int checker_init (struct checker *, void **);
+void checker_put (struct checker *);
+void checker_reset (struct checker *);
+void checker_set_sync (struct checker *);
+void checker_set_async (struct checker *);
+void checker_set_fd (struct checker *, int);
+void checker_enable (struct checker *);
+void checker_disable (struct checker *);
+struct checker * checker_lookup (char *);
+int checker_check (struct checker *);
+int checker_selected (struct checker *);
+char * checker_name (struct checker *);
+char * checker_message (struct checker *);
+struct checker * checker_default (void);
+void checker_get (struct checker *, struct checker *);
+
+#endif /* _CHECKERS_H */
diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile
new file mode 100644 (file)
index 0000000..f37a0f9
--- /dev/null
@@ -0,0 +1,29 @@
+# Makefile
+#
+# Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@free.fr>
+#
+include ../../Makefile.inc
+
+LIBS= \
+       libcheckreadsector0.so \
+       libchecktur.so \
+       libcheckdirectio.so \
+       libcheckemc_clariion.so \
+       libcheckhp_sw.so \
+       libcheckrdac.so
+
+CFLAGS += -I..
+
+all: $(LIBS)
+
+libcheck%.so: libsg.o %.o
+       $(CC) $(SHARED_FLAGS) -o $@ $^
+
+install:
+       $(INSTALL_PROGRAM) -o root -g root -m 755 $(LIBS) $(libdir)
+
+uninstall:
+       rm -f $(libdir)/$(LIBS)
+
+clean:
+       rm -f core *.a *.o *.gz *.so
diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
new file mode 100644 (file)
index 0000000..5c92dac
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2005 Hannes Reinecke, Suse
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <errno.h>
+#include <linux/kdev_t.h>
+#include <asm/unistd.h>
+#include <libaio.h>
+
+#include "checkers.h"
+#include "../libmultipath/debug.h"
+
+#define MSG_DIRECTIO_UNKNOWN   "directio checker is not available"
+#define MSG_DIRECTIO_UP                "directio checker reports path is up"
+#define MSG_DIRECTIO_DOWN      "directio checker reports path is down"
+#define MSG_DIRECTIO_PENDING   "directio checker is waiting on aio"
+
+#define LOG(prio, fmt, args...) condlog(prio, "directio: " fmt, ##args)
+
+struct directio_context {
+       int             running;
+       int             reset_flags;
+       int             blksize;
+       unsigned char * buf;
+       unsigned char * ptr;
+       io_context_t    ioctx;
+       struct iocb     io;
+};
+
+
+int libcheck_init (struct checker * c)
+{
+       unsigned long pgsize = getpagesize();
+       struct directio_context * ct;
+       long flags;
+
+       ct = malloc(sizeof(struct directio_context));
+       if (!ct)
+               return 1;
+       memset(ct, 0, sizeof(struct directio_context));
+
+       if (io_setup(1, &ct->ioctx) != 0) {
+               condlog(1, "io_setup failed");
+               free(ct);
+               return 1;
+       }
+
+       if (ioctl(c->fd, BLKBSZGET, &ct->blksize) < 0) {
+               MSG(c, "cannot get blocksize, set default");
+               ct->blksize = 512;
+       }
+       if (ct->blksize > 4096) {
+               /*
+                * Sanity check for DASD; BSZGET is broken
+                */
+               ct->blksize = 4096;
+       }
+       if (!ct->blksize)
+               goto out;
+       ct->buf = (unsigned char *)malloc(ct->blksize + pgsize);
+       if (!ct->buf)
+               goto out;
+
+       flags = fcntl(c->fd, F_GETFL);
+       if (flags < 0)
+               goto out;
+       if (!(flags & O_DIRECT)) {
+               flags |= O_DIRECT;
+               if (fcntl(c->fd, F_SETFL, flags) < 0)
+                       goto out;
+               ct->reset_flags = 1;
+       }
+
+       ct->ptr = (unsigned char *) (((unsigned long)ct->buf + pgsize - 1) &
+                 (~(pgsize - 1)));
+
+       /* Sucessfully initialized, return the context. */
+       c->context = (void *) ct;
+       return 0;
+
+out:
+       if (ct->buf)
+               free(ct->buf);
+       io_destroy(ct->ioctx);
+       free(ct);
+       return 1;
+}
+
+void libcheck_free (struct checker * c)
+{
+       struct directio_context * ct = (struct directio_context *)c->context;
+       long flags;
+
+       if (!ct)
+               return;
+
+       if (ct->reset_flags) {
+               if ((flags = fcntl(c->fd, F_GETFL)) >= 0) {
+                       flags &= ~O_DIRECT;
+                       /* No point in checking for errors */
+                       fcntl(c->fd, F_SETFL, flags);
+               }
+       }
+
+       if (ct->buf)
+               free(ct->buf);
+       io_destroy(ct->ioctx);
+       free(ct);
+}
+
+static int
+check_state(int fd, struct directio_context *ct, int sync)
+{
+       struct timespec timeout = { .tv_nsec = 5 };
+       struct io_event event;
+       struct stat     sb;
+       int             rc = PATH_UNCHECKED;
+       long            r;
+
+       if (fstat(fd, &sb) == 0) {
+               LOG(4, "called for %x", (unsigned) sb.st_rdev);
+       }
+       if (sync) {
+               LOG(4, "called in synchronous mode");
+               timeout.tv_sec  = ASYNC_TIMEOUT_SEC;
+               timeout.tv_nsec = 0;
+       }
+
+       if (!ct->running) {
+               struct iocb *ios[1] = { &ct->io };
+
+               LOG(3, "starting new request");
+               memset(&ct->io, 0, sizeof(struct iocb));
+               io_prep_pread(&ct->io, fd, ct->ptr, ct->blksize, 0);
+               if (io_submit(ct->ioctx, 1, ios) != 1) {
+                       LOG(3, "io_submit error %i", errno);
+                       return PATH_UNCHECKED;
+               }
+       }
+       ct->running++;
+
+       r = io_getevents(ct->ioctx, 1L, 1L, &event, &timeout);
+       LOG(3, "async io getevents returns %li (errno=%s)", r, strerror(errno));
+
+       if (r < 1L) {
+               if (ct->running > ASYNC_TIMEOUT_SEC || sync) {
+                       LOG(3, "abort check on timeout");
+                       rc = PATH_DOWN;
+               } else
+                       rc = PATH_PENDING;
+       } else {
+               LOG(3, "io finished %lu/%lu", event.res, event.res2);
+               ct->running = 0;
+               rc = (event.res == ct->blksize) ? PATH_UP : PATH_DOWN;
+       }
+
+       return rc;
+}
+
+int libcheck_check (struct checker * c)
+{
+       int ret;
+       struct directio_context * ct = (struct directio_context *)c->context;
+
+       if (!ct)
+               return PATH_UNCHECKED;
+
+       ret = check_state(c->fd, ct, c->sync);
+
+       switch (ret)
+       {
+       case PATH_UNCHECKED:
+               MSG(c, MSG_DIRECTIO_UNKNOWN);
+               break;
+       case PATH_DOWN:
+               MSG(c, MSG_DIRECTIO_DOWN);
+               break;
+       case PATH_UP:
+               MSG(c, MSG_DIRECTIO_UP);
+               break;
+       case PATH_PENDING:
+               MSG(c, MSG_DIRECTIO_PENDING);
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
diff --git a/libmultipath/checkers/directio.h b/libmultipath/checkers/directio.h
new file mode 100644 (file)
index 0000000..1865b1f
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _DIRECTIO_H
+#define _DIRECTIO_H
+
+int directio (struct checker *);
+int directio_init (struct checker *);
+void directio_free (struct checker *);
+
+#endif /* _DIRECTIO_H */
diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c
new file mode 100644 (file)
index 0000000..9eac31d
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2004, 2005 Lars Marowsky-Bree
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "../libmultipath/sg_include.h"
+#include "libsg.h"
+#include "checkers.h"
+
+#define INQUIRY_CMD     0x12
+#define INQUIRY_CMDLEN  6
+#define HEAVY_CHECK_COUNT       10
+
+/*
+ * Mechanism to track CLARiiON inactive snapshot LUs.
+ * This is done so that we can fail passive paths
+ * to an inactive snapshot LU even though since a
+ * simple read test would return 02/04/03 instead
+ * of 05/25/01 sensekey/ASC/ASCQ data.
+ */
+#define        IS_INACTIVE_SNAP(c)   (c->mpcontext ?                              \
+                              ((struct emc_clariion_checker_LU_context *) \
+                                       (*c->mpcontext))->inactive_snap    \
+                                           : 0)
+
+#define        SET_INACTIVE_SNAP(c)  if (c->mpcontext)                            \
+                               ((struct emc_clariion_checker_LU_context *)\
+                                       (*c->mpcontext))->inactive_snap = 1
+
+#define        CLR_INACTIVE_SNAP(c)  if (c->mpcontext)                            \
+                               ((struct emc_clariion_checker_LU_context *)\
+                                       (*c->mpcontext))->inactive_snap = 0
+
+struct emc_clariion_checker_path_context {
+       char wwn[16];
+       unsigned wwn_set;
+};
+
+struct emc_clariion_checker_LU_context {
+       int inactive_snap;
+};
+
+extern void
+hexadecimal_to_ascii(char * wwn, char *wwnstr)
+{
+       int i,j, nbl;
+
+       for (i=0,j=0;i<16;i++) {
+               wwnstr[j++] = ((nbl = ((wwn[i]&0xf0) >> 4)) <= 9) ?
+                                       '0' + nbl : 'a' + (nbl - 10);
+               wwnstr[j++] = ((nbl = (wwn[i]&0x0f)) <= 9) ?
+                                       '0' + nbl : 'a' + (nbl - 10);
+       }
+       wwnstr[32]=0;
+}
+
+int libcheck_init (struct checker * c)
+{
+       /*
+        * Allocate and initialize the path specific context.
+        */
+       c->context = malloc(sizeof(struct emc_clariion_checker_path_context));
+       if (!c->context)
+               return 1;
+       ((struct emc_clariion_checker_path_context *)c->context)->wwn_set = 0;
+
+       /*
+        * Allocate and initialize the multi-path global context.
+        */
+       if (c->mpcontext) {
+               void * mpctxt = malloc(sizeof(int));
+               *c->mpcontext = mpctxt;
+               CLR_INACTIVE_SNAP(c);
+       }
+
+       return 0;
+}
+
+void libcheck_free (struct checker * c)
+{
+       free(c->context);
+}
+
+int libcheck_check (struct checker * c)
+{
+       unsigned char sense_buffer[128] = { 0, };
+       unsigned char sb[SENSE_BUFF_LEN] = { 0, }, *sbb;
+       unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
+                                               sizeof(sense_buffer), 0};
+       struct sg_io_hdr io_hdr;
+       struct emc_clariion_checker_path_context * ct =
+               (struct emc_clariion_checker_path_context *)c->context;
+       char wwnstr[33];
+       int ret;
+
+       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 = DEF_TIMEOUT;
+       io_hdr.pack_id = 0;
+       if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
+               MSG(c, "emc_clariion_checker: sending query command failed");
+               return PATH_DOWN;
+       }
+       if (io_hdr.info & SG_INFO_OK_MASK) {
+               MSG(c, "emc_clariion_checker: query command indicates error");
+               return PATH_DOWN;
+       }
+       if (/* Verify the code page - right page & revision */
+           sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) {
+               MSG(c, "emc_clariion_checker: Path unit report page in "
+                   "unknown format");
+               return PATH_DOWN;
+       }
+
+       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) {
+               MSG(c, "emc_clariion_checker: Path not correctly configured "
+                   "for failover");
+               return PATH_DOWN;
+       }
+
+       if ( /* LUN operations should indicate normal operations */
+               sense_buffer[48] != 0x00) {
+               MSG(c, "emc_clariion_checker: Path not available for normal "
+                   "operations");
+               return PATH_SHAKY;
+       }
+
+       if ( /* LUN should at least be bound somewhere and not be LUNZ */
+               sense_buffer[4] == 0x00) {
+               MSG(c, "emc_clariion_checker: Logical Unit is unbound "
+                   "or LUNZ");
+               return PATH_DOWN;
+       }
+       
+       /*
+        * store the LUN WWN there and compare that it indeed did not
+        * change in between, to protect against the path suddenly
+        * pointing somewhere else.
+        */
+       if (ct->wwn_set) {
+               if (memcmp(ct->wwn, &sense_buffer[10], 16) != 0) {
+                       MSG(c, "emc_clariion_checker: Logical Unit WWN "
+                           "has changed!");
+                       return PATH_DOWN;
+               }
+       } else {
+               memcpy(ct->wwn, &sense_buffer[10], 16);
+               ct->wwn_set = 1;
+       }
+       
+       /*
+        * Issue read on active path to determine if inactive snapshot.
+        */
+       if (sense_buffer[4] == 2) {/* if active path */
+               unsigned char buf[4096];
+
+               ret = sg_read(c->fd, &buf[0], sbb = &sb[0]);
+               if (ret == PATH_DOWN) {
+                       hexadecimal_to_ascii(ct->wwn, wwnstr);
+
+                       /*
+                        * Check for inactive snapshot LU this way.  Must
+                        * fail these.
+                        */
+                       if (((sbb[2]&0xf) == 5) && (sbb[12] == 0x25) &&
+                           (sbb[13]==1)) {
+                               /*
+                                * Do this so that we can fail even the
+                                * passive paths which will return
+                                * 02/04/03 not 05/25/01 on read.
+                                */
+                               SET_INACTIVE_SNAP(c);
+                               MSG(c, "emc_clariion_checker: Active "
+                                       "path to inactive snapshot WWN %s.",
+                                       wwnstr);
+                       } else
+                               MSG(c, "emc_clariion_checker: Read "
+                                       "error for WWN %s.  Sense data are "
+                                       "0x%x/0x%x/0x%x.", wwnstr,
+                                       sbb[2]&0xf, sbb[12], sbb[13]);
+               } else {
+                       MSG(c, "emc_clariion_checker: Active path is "
+                           "healthy.");
+                       /*
+                        * Remove the path from the set of paths to inactive
+                        * snapshot LUs if it was in this list since the
+                        * snapshot is no longer inactive.
+                        */
+                       CLR_INACTIVE_SNAP(c);
+               }
+       } else {
+               if (IS_INACTIVE_SNAP(c)) {
+                       hexadecimal_to_ascii(ct->wwn, wwnstr);
+                       MSG(c, "emc_clariion_checker: Passive "
+                               "path to inactive snapshot WWN %s.",
+                               wwnstr);
+                       ret = PATH_DOWN;
+               } else {
+                       MSG(c,
+                           "emc_clariion_checker: Passive path is healthy.");
+                       ret = PATH_UP;  /* not ghost */
+               }
+       }
+
+       return ret;
+}
diff --git a/libmultipath/checkers/emc_clariion.h b/libmultipath/checkers/emc_clariion.h
new file mode 100644 (file)
index 0000000..a1018a6
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _EMC_CLARIION_H
+#define _EMC_CLARIION_H
+
+int emc_clariion (struct checker *);
+int emc_clariion_init (struct checker *);
+void emc_clariion_free (struct checker *);
+
+#endif /* _EMC_CLARIION_H */
diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c
new file mode 100644 (file)
index 0000000..7509307
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2005 Christophe Varoqui
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "checkers.h"
+
+#include "../libmultipath/sg_include.h"
+
+#define TUR_CMD_LEN            6
+#define INQUIRY_CMDLEN         6
+#define INQUIRY_CMD            0x12
+#define SENSE_BUFF_LEN         32
+#define SCSI_CHECK_CONDITION   0x2
+#define SCSI_COMMAND_TERMINATED        0x22
+#define SG_ERR_DRIVER_SENSE    0x08
+#define RECOVERED_ERROR                0x01
+#define MX_ALLOC_LEN           255
+#define HEAVY_CHECK_COUNT       10
+
+#define MSG_HP_SW_UP   "hp_sw checker reports path is up"
+#define MSG_HP_SW_DOWN "hp_sw checker reports path is down"
+#define MSG_HP_SW_GHOST        "hp_sw checker reports path is ghost"
+
+struct sw_checker_context {
+       void * dummy;
+};
+
+int libcheck_init (struct checker * c)
+{
+       return 0;
+}
+
+void libcheck_free (struct checker * c)
+{
+       return;
+}
+
+static int
+do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
+       void *resp, int mx_resp_len, int noisy)
+{
+        unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
+            { INQUIRY_CMD, 0, 0, 0, 0, 0 };
+        unsigned char sense_b[SENSE_BUFF_LEN];
+        struct sg_io_hdr io_hdr;
+                                                                                                                 
+        if (cmddt)
+                inqCmdBlk[1] |= 2;
+        if (evpd)
+                inqCmdBlk[1] |= 1;
+        inqCmdBlk[2] = (unsigned char) pg_op;
+       inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
+       inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
+        memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
+        io_hdr.interface_id = 'S';
+        io_hdr.cmd_len = sizeof (inqCmdBlk);
+        io_hdr.mx_sb_len = sizeof (sense_b);
+        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+        io_hdr.dxfer_len = mx_resp_len;
+        io_hdr.dxferp = resp;
+        io_hdr.cmdp = inqCmdBlk;
+        io_hdr.sbp = sense_b;
+        io_hdr.timeout = DEF_TIMEOUT;
+        if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
+                return 1;
+        /* treat SG_ERR here to get rid of sg_err.[ch] */
+        io_hdr.status &= 0x7e;
+        if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
+            (0 == io_hdr.driver_status))
+                return 0;
+        if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
+            (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
+            (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
+                if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
+                        int sense_key;
+                        unsigned char * sense_buffer = io_hdr.sbp;
+                        if (sense_buffer[0] & 0x2)
+                                sense_key = sense_buffer[1] & 0xf;
+                        else
+                                sense_key = sense_buffer[2] & 0xf;
+                        if(RECOVERED_ERROR == sense_key)
+                                return 0;
+                }
+        }
+        return 1;
+}
+
+static int
+do_tur (int fd)
+{
+        unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
+        struct sg_io_hdr io_hdr;
+        unsigned char sense_buffer[32];
+
+        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 (sense_buffer);
+        io_hdr.dxfer_direction = SG_DXFER_NONE;
+        io_hdr.cmdp = turCmdBlk;
+        io_hdr.sbp = sense_buffer;
+        io_hdr.timeout = DEF_TIMEOUT;
+        io_hdr.pack_id = 0;
+
+        if (ioctl(fd, SG_IO, &io_hdr) < 0)
+               return 1;
+
+        if (io_hdr.info & SG_INFO_OK_MASK)
+               return 1;
+
+       return 0;
+}
+
+extern int
+libcheck_check (struct checker * c)
+{
+       char buff[MX_ALLOC_LEN];
+
+       if (0 != do_inq(c->fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
+               MSG(c, MSG_HP_SW_DOWN);
+               return PATH_DOWN;
+       }
+
+       if (do_tur(c->fd)) {
+               MSG(c, MSG_HP_SW_GHOST);
+                return PATH_GHOST;
+        }
+       MSG(c, MSG_HP_SW_UP);
+       return PATH_UP;
+}
diff --git a/libmultipath/checkers/hp_sw.h b/libmultipath/checkers/hp_sw.h
new file mode 100644 (file)
index 0000000..3be0d8e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _HP_SW_H
+#define _HP_SW_H
+
+int hp_sw (struct checker *);
+int hp_sw_init (struct checker *);
+void hp_sw_free (struct checker *);
+
+#endif /* _HP_SW_H */
diff --git a/libmultipath/checkers/libsg.c b/libmultipath/checkers/libsg.c
new file mode 100644 (file)
index 0000000..9171b10
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2004, 2005 Christophe Varoqui
+ */
+#include <string.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "checkers.h"
+#include "libsg.h"
+#include "../libmultipath/sg_include.h"
+
+int
+sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff)
+{
+       /* defaults */
+       int blocks = 1;
+       long long start_block = 0;
+       int bs = 512;
+       int cdbsz = 10;
+       int * diop = NULL;
+
+       unsigned char rdCmd[cdbsz];
+       unsigned char *sbb = senseBuff;
+       struct sg_io_hdr io_hdr;
+       int res;
+       int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
+       int sz_ind;
+       struct stat filestatus;
+       int retry_count = 3;
+
+       if (fstat(sg_fd, &filestatus) != 0)
+               return PATH_DOWN;
+       bs = (filestatus.st_blksize > 4096)? 4096: filestatus.st_blksize;
+       memset(rdCmd, 0, cdbsz);
+       sz_ind = 1;
+       rdCmd[0] = rd_opcode[sz_ind];
+       rdCmd[2] = (unsigned char)((start_block >> 24) & 0xff);
+       rdCmd[3] = (unsigned char)((start_block >> 16) & 0xff);
+       rdCmd[4] = (unsigned char)((start_block >> 8) & 0xff);
+       rdCmd[5] = (unsigned char)(start_block & 0xff);
+       rdCmd[7] = (unsigned char)((blocks >> 8) & 0xff);
+       rdCmd[8] = (unsigned char)(blocks & 0xff);
+
+       memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+       io_hdr.interface_id = 'S';
+       io_hdr.cmd_len = cdbsz;
+       io_hdr.cmdp = rdCmd;
+       io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+       io_hdr.dxfer_len = bs * blocks;
+       io_hdr.dxferp = buff;
+       io_hdr.mx_sb_len = SENSE_BUFF_LEN;
+       io_hdr.sbp = senseBuff;
+       io_hdr.timeout = DEF_TIMEOUT;
+       io_hdr.pack_id = (int)start_block;
+       if (diop && *diop)
+       io_hdr.flags |= SG_FLAG_DIRECT_IO;
+
+retry: 
+       memset(senseBuff, 0, SENSE_BUFF_LEN);
+       while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) && (EINTR == errno));
+
+       if (res < 0) {
+               if (ENOMEM == errno) {
+                       return PATH_UP;
+               }
+               return PATH_DOWN;
+       }
+
+       if ((0 == io_hdr.status) &&
+           (0 == io_hdr.host_status) &&
+           (0 == io_hdr.driver_status)) {
+               return PATH_UP;
+       } else {
+               /*
+                * Retry if UNIT_ATTENTION check condition.
+                */
+               if ((sbb[2]&0xf) == 6) {
+                       if (--retry_count)
+                               goto retry;
+               }
+               return PATH_DOWN;
+       }
+}
diff --git a/libmultipath/checkers/libsg.h b/libmultipath/checkers/libsg.h
new file mode 100644 (file)
index 0000000..97c4491
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LIBSG_H
+#define _LIBSG_H
+
+#define SENSE_BUFF_LEN 32
+
+int sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff);
+
+#endif /* _LIBSG_H */
diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
new file mode 100644 (file)
index 0000000..0086125
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2005 Christophe Varoqui
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "checkers.h"
+
+#include "../libmultipath/sg_include.h"
+
+#define INQUIRY_CMDLEN         6
+#define INQUIRY_CMD            0x12
+#define SENSE_BUFF_LEN         32
+#define RDAC_DEF_TIMEOUT       60000
+#define SCSI_CHECK_CONDITION   0x2
+#define SCSI_COMMAND_TERMINATED        0x22
+#define SG_ERR_DRIVER_SENSE    0x08
+#define RECOVERED_ERROR                0x01
+
+#define MSG_RDAC_UP    "rdac checker reports path is up"
+#define MSG_RDAC_DOWN  "rdac checker reports path is down"
+#define MSG_RDAC_GHOST "rdac checker reports path is ghost"
+
+struct rdac_checker_context {
+       void * dummy;
+};
+
+int libcheck_init (struct checker * c)
+{
+       return 0;
+}
+
+void libcheck_free (struct checker * c)
+{
+       return;
+}
+
+static int
+do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len)
+{
+       unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 1, 0, 0, 0, 0 };
+       unsigned char sense_b[SENSE_BUFF_LEN];
+       struct sg_io_hdr io_hdr;
+
+       inqCmdBlk[2] = (unsigned char) pg_op;
+       inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
+       memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
+
+       io_hdr.interface_id = 'S';
+       io_hdr.cmd_len = sizeof (inqCmdBlk);
+       io_hdr.mx_sb_len = sizeof (sense_b);
+       io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+       io_hdr.dxfer_len = mx_resp_len;
+       io_hdr.dxferp = resp;
+       io_hdr.cmdp = inqCmdBlk;
+       io_hdr.sbp = sense_b;
+       io_hdr.timeout = RDAC_DEF_TIMEOUT;
+
+       if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
+               return 1;
+
+       /* treat SG_ERR here to get rid of sg_err.[ch] */
+       io_hdr.status &= 0x7e;
+       if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
+           (0 == io_hdr.driver_status))
+               return 0;
+       if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
+           (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
+           (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
+               if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
+                       int sense_key;
+                       unsigned char * sense_buffer = io_hdr.sbp;
+                       if (sense_buffer[0] & 0x2)
+                               sense_key = sense_buffer[1] & 0xf;
+                       else
+                               sense_key = sense_buffer[2] & 0xf;
+                       if (RECOVERED_ERROR == sense_key)
+                               return 0;
+               }
+       }
+       return 1;
+}
+
+struct volume_access_inq
+{
+       char dontcare0[8];
+       char avtcvp;
+       char dontcare1[39];
+};
+
+extern int
+libcheck_check (struct checker * c)
+{
+       struct volume_access_inq inq;
+
+       if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq))) {
+               MSG(c, MSG_RDAC_DOWN);
+               return PATH_DOWN;
+       }
+
+       return ((inq.avtcvp & 0x1) ? PATH_UP : PATH_GHOST);
+}
diff --git a/libmultipath/checkers/rdac.h b/libmultipath/checkers/rdac.h
new file mode 100644 (file)
index 0000000..d7bf812
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _RDAC_H
+#define _RDAC_H
+
+int rdac(struct checker *);
+int rdac_init(struct checker *);
+void rdac_free(struct checker *);
+
+#endif /* _RDAC_H */
diff --git a/libmultipath/checkers/readsector0.c b/libmultipath/checkers/readsector0.c
new file mode 100644 (file)
index 0000000..24182e6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2004, 2005 Christophe Varoqui
+ */
+#include <stdio.h>
+
+#include "checkers.h"
+#include "libsg.h"
+
+#define MSG_READSECTOR0_UP     "readsector0 checker reports path is up"
+#define MSG_READSECTOR0_DOWN   "readsector0 checker reports path is down"
+
+struct readsector0_checker_context {
+       void * dummy;
+};
+
+int libcheck_init (struct checker * c)
+{
+       return 0;
+}
+
+void libcheck_free (struct checker * c)
+{
+       return;
+}
+
+int libcheck_check (struct checker * c)
+{
+       unsigned char buf[4096];
+       unsigned char sbuf[SENSE_BUFF_LEN];
+       int ret;
+
+       ret = sg_read(c->fd, &buf[0], &sbuf[0]);
+
+       switch (ret)
+       {
+       case PATH_DOWN:
+               MSG(c, MSG_READSECTOR0_DOWN);
+               break;
+       case PATH_UP:
+               MSG(c, MSG_READSECTOR0_UP);
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
diff --git a/libmultipath/checkers/readsector0.h b/libmultipath/checkers/readsector0.h
new file mode 100644 (file)
index 0000000..0f5d654
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _READSECTOR0_H
+#define _READSECTOR0_H
+
+int readsector0 (struct checker *);
+int readsector0_init (struct checker *);
+void readsector0_free (struct checker *);
+
+#endif /* _READSECTOR0_H */
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
new file mode 100644 (file)
index 0000000..e84435e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Some code borrowed from sg-utils.
+ *
+ * Copyright (c) 2004 Christophe Varoqui
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "checkers.h"
+
+#include "../libmultipath/sg_include.h"
+
+#define TUR_CMD_LEN 6
+#define HEAVY_CHECK_COUNT       10
+
+#define MSG_TUR_UP     "tur checker reports path is up"
+#define MSG_TUR_DOWN   "tur checker reports path is down"
+
+struct tur_checker_context {
+       void * dummy;
+};
+
+int libcheck_init (struct checker * c)
+{
+       return 0;
+}
+
+void libcheck_free (struct checker * c)
+{
+       return;
+}
+
+extern int
+libcheck_check (struct checker * c)
+{
+       struct sg_io_hdr io_hdr;
+        unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
+        unsigned char sense_buffer[32];
+
+        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 (sense_buffer);
+        io_hdr.dxfer_direction = SG_DXFER_NONE;
+        io_hdr.cmdp = turCmdBlk;
+        io_hdr.sbp = sense_buffer;
+        io_hdr.timeout = DEF_TIMEOUT;
+        io_hdr.pack_id = 0;
+        if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
+               MSG(c, MSG_TUR_DOWN);
+                return PATH_DOWN;
+        }
+        if (io_hdr.info & SG_INFO_OK_MASK) {
+               MSG(c, MSG_TUR_DOWN);
+                return PATH_DOWN;
+        }
+       MSG(c, MSG_TUR_UP);
+        return PATH_UP;
+}
diff --git a/libmultipath/checkers/tur.h b/libmultipath/checkers/tur.h
new file mode 100644 (file)
index 0000000..a2e8c88
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _TUR_H
+#define _TUR_H
+
+int tur (struct checker *);
+int tur_init (struct checker *);
+void tur_free (struct checker *);
+
+#endif /* _TUR_H */
index 7abe6fa..af862b7 100644 (file)
@@ -6,8 +6,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "memory.h"
 #include "util.h"
 #include "debug.h"
index 988c41b..df31cdd 100644 (file)
@@ -14,8 +14,7 @@
 #include <errno.h>
 #include <libdevmapper.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "memory.h"
 #include "devmapper.h"
index d6991ba..f21d3ab 100644 (file)
@@ -14,8 +14,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "structs.h"
 #include "debug.h"
index e24ad7f..2dfe4ae 100644 (file)
@@ -4,8 +4,7 @@
  * Copyright (c) 2005 Benjamin Marzinski, Redhat
  * Copyright (c) 2005 Kiyoshi Ueda, NEC
  */
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "hwtable.h"
 #include "structs.h"
index a1079ac..83e1865 100644 (file)
@@ -11,8 +11,7 @@
 #include <dirent.h>
 #include <errno.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "memory.h"
 #include "util.h"
index 631933d..fe7d986 100644 (file)
@@ -7,8 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "memory.h"
 #include "structs.h"
index 814a290..d938379 100644 (file)
@@ -1,7 +1,6 @@
 #include <stdio.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "defaults.h"
 #include "structs.h"
index 0ac7448..1a355af 100644 (file)
@@ -5,8 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "util.h"
 #include "memory.h"
 #include "vector.h"
index 3c3f0fe..641ade6 100644 (file)
@@ -8,8 +8,7 @@
 #include <sys/stat.h>
 #include <dirent.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "structs.h"
 #include "structs_vec.h"
index 751c874..6bf6d4b 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * knowing about path struct gives flexibility to prioritizers
  */
-#include "../libcheckers/checkers.h"
+#include "checkers.h"
 #include "vector.h"
 #include "structs.h"
 #include "list.h"
index 3d12ec0..0c7fb99 100644 (file)
@@ -5,8 +5,7 @@
  */
 #include <stdio.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "memory.h"
 #include "vector.h"
 #include "structs.h"
index 442a3ee..11f3061 100644 (file)
@@ -6,8 +6,7 @@
 #include <unistd.h>
 #include <libdevmapper.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "memory.h"
 #include "vector.h"
 #include "util.h"
index dfb1d33..f4d69bb 100644 (file)
@@ -2,8 +2,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "defaults.h"
 #include "debug.h"
index e99a297..58b08f6 100644 (file)
@@ -2,8 +2,7 @@
  * Copyright (c) 2005 Christophe Varoqui
  * Copyright (c) 2005 Edward Goggin, EMC
  */
-#include <checkers.h>
-
+#include "checkers.h"
 #include "vector.h"
 #include "structs.h"
 #include "switchgroup.h"
index b9d0ec4..71df431 100644 (file)
@@ -6,17 +6,16 @@ include ../Makefile.inc
 
 OBJS = main.o
 
-CFLAGS += -I$(multipathdir) -I$(checkersdir)
+CFLAGS += -I$(multipathdir) -Wl,-rpath,$(libdir)
 LDFLAGS += -laio -ldevmapper -lpthread \
-          -lmultipath -L$(multipathdir) \
-          -lcheckers -L$(checkersdir) \
+          -lmultipath -L$(multipathdir)
 
 EXEC = multipath
 
 all: $(EXEC)
 
 $(EXEC): $(OBJS)
-       $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS)
+       $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
        $(GZIP) $(EXEC).8 > $(EXEC).8.gz
        $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
 
index ce36265..0f4b2d2 100644 (file)
@@ -324,6 +324,10 @@ main (int argc, char *argv[])
        if (dm_prereq(DEFAULT_TARGET))
                exit(1);
 
+       if (init_checkers()) {
+               condlog(0, "failed to initialize checkers");
+               exit(1);
+       }
        if (init_prio()) {
                condlog(0, "failed to initialize prioritizers");
                exit(1);
index fc3733b..6beb993 100644 (file)
@@ -5,10 +5,9 @@ include ../Makefile.inc
 #
 # basic flags setting
 #
-CFLAGS += -DDAEMON -I$(multipathdir) -I$(checkersdir)
+CFLAGS += -DDAEMON -I$(multipathdir) -Wl,-rpath,$(libdir)
 LDFLAGS += -lpthread -ldevmapper -lreadline -lncurses -laio \
-          -lmultipath -L$(multipathdir) \
-          -lcheckers -L$(checkersdir)
+          -lmultipath -L$(multipathdir)
 
 #
 # debuging stuff
index 2fc00f7..50e7441 100644 (file)
@@ -1272,6 +1272,10 @@ child (void * param)
        condlog(2, "--------start up--------");
        condlog(2, "read " DEFAULT_CONFIGFILE);
 
+       if (init_checkers()) {
+               condlog(0, "failed to initialize checkers");
+               exit(1);
+       }
        if (init_prio()) {
                condlog(0, "failed to initialize prioritizers");
                exit(1);