The context handling and the layering were poor, so rewrite.
The users now need to :
- alloc a "struct checker"
- select a checker by name : checker_lookup()
- init own checker instance : checker_get()
- set the path file descriptor to check : checker_set_fd()
- use : checker_check()
- release : checker_put()
Checkers now are asked to provide 3 functions :
- foo_init : alloc and initialize the checker context
- foo_free : free the context
- foo : the checking function proper
These 3 are registered in a static checkers array, along with the checker
name. Lookups are based on checker name.
The users are all updated :
- checker_get is folded into path (re)discovery
- checker_put is folded into path free/orphan
Additional gains :
- directio is updated to use a context to avoid computations upon each
check
- checkers code is leaner
Please test and report.
include ../Makefile.inc
-OBJS = readsector0.o tur.o selector.o directio.o emc_clariion.o hp_sw.o
+OBJS = checkers.o readsector0.o tur.o directio.o emc_clariion.o hp_sw.o
all: $(BUILD)
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+#include "checkers.h"
+
+#include "directio.h"
+#include "tur.h"
+#include "hp_sw.h"
+#include "emc_clariion.h"
+#include "readsector0.h"
+
+static struct checker checkers[] = {
+ {
+ .fd = 0,
+ .name = DIRECTIO,
+ .message = "",
+ .context = NULL,
+ .check = directio,
+ .init = directio_init,
+ .free = directio_free
+ },
+ {
+ .fd = 0,
+ .name = TUR,
+ .message = "",
+ .context = NULL,
+ .check = tur,
+ .init = tur_init,
+ .free = tur_free
+ },
+ {
+ .fd = 0,
+ .name = HP_SW,
+ .message = "",
+ .context = NULL,
+ .check = hp_sw,
+ .init = hp_sw_init,
+ .free = hp_sw_free
+ },
+ {
+ .fd = 0,
+ .name = EMC_CLARIION,
+ .message = "",
+ .context = NULL,
+ .check = emc_clariion,
+ .init = emc_clariion_init,
+ .free = emc_clariion_free
+ },
+ {
+ .fd = 0,
+ .name = READSECTOR0,
+ .message = "",
+ .context = NULL,
+ .check = readsector0,
+ .init = readsector0_init,
+ .free = readsector0_free
+ },
+ {0, "", "", NULL, NULL, NULL, NULL},
+};
+
+void checker_set_fd (struct checker * c, int fd)
+{
+ c->fd = fd;
+}
+
+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 += sizeof(struct checker);
+ }
+ return NULL;
+}
+
+int checker_init (struct checker * c)
+{
+ return c->init(c);
+}
+
+void checker_put (struct checker * c)
+{
+ c->free(c);
+ memset(c, 0x0, sizeof(struct checker));
+}
+
+int checker_check (struct checker * c)
+{
+ int r;
+
+ 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;
+ 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;
+}
#ifndef _CHECKERS_H
#define _CHECKERS_H
-#define CHECKER_NAME_SIZE 16
-#define DEVNODE_SIZE 256
-#define MAX_CHECKER_MSG_SIZE 256
-
-enum checkers {
- CHECKER_UNDEF,
- TUR,
- READSECTOR0,
- DIRECTIO,
- EMC_CLARIION,
- HP_SW
-};
+/*
+ * path states
+ */
+#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 DIRECTIO "directio"
+#define TUR "tur"
+#define HP_SW "hp_sw"
+#define EMC_CLARIION "emc_clariion"
+#define READSECTOR0 "readsector0"
-#define DEFAULT_CHECKER_ID READSECTOR0
+#define DEFAULT_CHECKER READSECTOR0
-#define MSG(a) if (msg != NULL) \
- snprintf(msg, MAX_CHECKER_MSG_SIZE, "%s", a);
+/*
+ * strings lengths
+ */
+#define CHECKER_NAME_LEN 16
+#define CHECKER_MSG_LEN 256
+#define CHECKER_DEV_LEN 256
+
+struct checker {
+ int fd;
+ char name[CHECKER_NAME_LEN];
+ char message[CHECKER_MSG_LEN]; /* comm with callers */
+ void * context; /* store for persistent data */
+ int (*check)(struct checker *);
+ int (*init)(struct checker *); /* to allocate the context */
+ void (*free)(struct checker *); /* to free the context */
+};
-int get_checker_id (char *);
-void *get_checker_addr (int);
-int get_checker_name (char *, int, int);
+#define MSG(c, a) snprintf((c)->message, CHECKER_MSG_LEN, a);
-int emc_clariion (int fd, char * msg, void ** ctxt);
-int directio (int fd, char * msg, void ** ctxt);
-int readsector0 (int fd, char * msg, void ** ctxt);
-int tur (int fd, char * msg, void ** ctxt);
-int hp_sw (int fd, char * msg, void ** ctxt);
+int checker_init (struct checker *);
+void checker_put (struct checker *);
+void checker_reset (struct checker * c);
+void checker_set_fd (struct checker *, int);
+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 */
#include <linux/fs.h>
#include <errno.h>
-#include "path_state.h"
#include "checkers.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"
-struct readsector0_checker_context {
- void * dummy;
+struct directio_context {
+ int blksize;
+ unsigned char *buf;
+ unsigned char *ptr;
};
+int directio_init (struct checker * c)
+{
+ unsigned long pgsize = getpagesize();
+ struct directio_context * ct;
+
+ ct = malloc(sizeof(struct directio_context));
+ if (!ct)
+ return 1;
+ c->context = (void *)ct;
+
+ 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;
+ ct->ptr = (unsigned char *)(((unsigned long)ct->buf + pgsize - 1) &
+ (~(pgsize - 1)));
+
+ return 0;
+out:
+ free(ct);
+ return 1;
+}
+
+void directio_free (struct checker * c)
+{
+ struct directio_context * ct = (struct directio_context *)c->context;
+
+ if (!ct)
+ return;
+ if (ct->buf)
+ free(ct->buf);
+ free(ct);
+}
+
static int
direct_read (int fd, unsigned char * buff, int size)
{
return retval;
}
-extern int
-directio (int fd, char *msg, void **context)
+int directio (struct checker * c)
{
- unsigned char *buf, *ptr;
- struct readsector0_checker_context * ctxt = NULL;
- unsigned long pgsize, numsect;
- int ret, blksize;
+ int ret;
+ struct directio_context * ct = (struct directio_context *)c->context;
- pgsize = getpagesize();
-
- /*
- * caller passed in a context : use its address
- */
- if (context)
- ctxt = (struct readsector0_checker_context *) (*context);
-
- /*
- * passed in context is uninitialized or volatile context :
- * initialize it
- */
- if (!ctxt) {
- ctxt = malloc(sizeof(struct readsector0_checker_context));
- memset(ctxt, 0, sizeof(struct readsector0_checker_context));
-
- if (!ctxt) {
- MSG("cannot allocate context");
- return -1;
- }
- if (context)
- *context = ctxt;
- }
- if (fd <= 0) {
- MSG("no usable fd");
- ret = -1;
- goto out;
- }
-
- if (ioctl(fd, BLKGETSIZE, &numsect) < 0) {
- MSG("cannot get number of sectors, set default");
- numsect = 0;
- }
-
- if (ioctl(fd, BLKBSZGET, &blksize) < 0) {
- MSG("cannot get blocksize, set default");
- blksize = 512;
- }
-
- if (blksize > 4096) {
- /*
- * Sanity check for DASD; BSZGET is broken
- */
- blksize = 4096;
- }
-
- if (!blksize) {
- /*
- * Blocksize is 0, assume we can't write
- * to this device.
- */
- MSG(MSG_DIRECTIO_DOWN);
- ret = PATH_DOWN;
- goto out;
- }
-
- buf = (unsigned char *)malloc(blksize + pgsize);
- if (!buf){
- goto out;
- }
- ptr = (unsigned char *)(((unsigned long)buf + pgsize - 1) &
- (~(pgsize - 1)));
- ret = direct_read(fd, ptr, blksize);
+ ret = direct_read(c->fd, ct->ptr, ct->blksize);
switch (ret)
{
case PATH_UNCHECKED:
- MSG(MSG_DIRECTIO_UNKNOWN);
+ MSG(c, MSG_DIRECTIO_UNKNOWN);
break;
case PATH_DOWN:
- MSG(MSG_DIRECTIO_DOWN);
+ MSG(c, MSG_DIRECTIO_DOWN);
break;
case PATH_UP:
- MSG(MSG_DIRECTIO_UP);
+ MSG(c, MSG_DIRECTIO_UP);
break;
default:
break;
}
- free(buf);
-
-out:
- /*
- * caller told us he doesn't want to keep the context :
- * free it
- */
- if (!context)
- free(ctxt);
-
return ret;
}
--- /dev/null
+#ifndef _DIRECTIO_H
+#define _DIRECTIO_H
+
+int directio (struct checker *);
+int directio_init (struct checker *);
+void directio_free (struct checker *);
+
+#endif /* _DIRECTIO_H */
#include <sys/ioctl.h>
#include <errno.h>
-#include "path_state.h"
#include "checkers.h"
#include "../libmultipath/sg_include.h"
#define HEAVY_CHECK_COUNT 10
struct emc_clariion_checker_context {
- int run_count;
char wwn[16];
unsigned wwn_set;
};
-int emc_clariion(int fd, char *msg, void **context)
+int emc_clariion_init (struct checker * c)
+{
+ c->context = malloc(sizeof(struct emc_clariion_checker_context));
+ if (!c->context)
+ return 1;
+ return 0;
+}
+
+void emc_clariion_free (struct checker * c)
+{
+ free(c->context);
+}
+
+int emc_clariion(struct checker * c)
{
unsigned char sense_buffer[256] = { 0, };
unsigned char sb[128] = { 0, };
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
sizeof(sb), 0};
struct sg_io_hdr io_hdr;
- struct emc_clariion_checker_context * ctxt = NULL;
- int ret;
+ struct emc_clariion_checker_context * ct =
+ (struct emc_clariion_checker_context *)c->context;
- /*
- * caller passed in a context : use its address
- */
- if (context)
- ctxt = (struct emc_clariion_checker_context *) (*context);
-
- /*
- * passed in context is uninitialized or volatile context :
- * initialize it
- */
- if (!ctxt) {
- ctxt = malloc(sizeof(struct emc_clariion_checker_context));
- memset(ctxt, 0, sizeof(struct emc_clariion_checker_context));
-
- if (!ctxt) {
- MSG("cannot allocate context");
- return -1;
- }
- if (context)
- *context = ctxt;
- }
- ctxt->run_count++;
-
- if ((ctxt->run_count % HEAVY_CHECK_COUNT) == 0) {
- ctxt->run_count = 0;
- /* do stuff */
- }
-
- if (fd <= 0) {
- MSG("no usable fd");
- ret = -1;
- goto out;
- }
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof (inqCmdBlk);
io_hdr.sbp = sb;
io_hdr.timeout = 60000;
io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- MSG("emc_clariion_checker: sending query command failed");
- ret = PATH_DOWN;
- goto out;
+ 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("emc_clariion_checker: query command indicates error");
- ret = PATH_DOWN;
- goto out;
+ 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("emc_clariion_checker: Path unit report page in unknown format");
- ret = PATH_DOWN;
- goto out;
+ MSG(c, "emc_clariion_checker: Path unit report page in unknown format");
+ return PATH_DOWN;
}
if ( /* Effective initiator type */
|| (sense_buffer[28] & 0x07) != 0x04
/* Arraycommpath should be set to 1 */
|| (sense_buffer[30] & 0x04) != 0x04) {
- MSG("emc_clariion_checker: Path not correctly configured for failover");
- ret = PATH_DOWN;
- goto out;
+ 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("emc_clariion_checker: Path not available for normal operations");
- ret = PATH_SHAKY;
- goto out;
+ MSG(c, "emc_clariion_checker: Path not available for normal operations");
+ return PATH_SHAKY;
}
#if 0
* _would_ bind the path */
if ( /* LUN should at least be bound somewhere */
sense_buffer[4] != 0x00) {
- ret = PATH_UP;
- goto out;
+ return PATH_UP;
}
#endif
* change in between, to protect against the path suddenly
* pointing somewhere else.
*/
- if (context && ctxt->wwn_set) {
- if (memcmp(ctxt->wwn, &sense_buffer[10], 16) != 0) {
- MSG("emc_clariion_checker: Logical Unit WWN has changed!");
- ret = PATH_DOWN;
- goto out;
+ 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(ctxt->wwn, &sense_buffer[10], 16);
- ctxt->wwn_set = 1;
+ memcpy(ct->wwn, &sense_buffer[10], 16);
+ ct->wwn_set = 1;
}
- MSG("emc_clariion_checker: Path healthy");
- ret = PATH_UP;
-out:
- /*
- * caller told us he doesn't want to keep the context :
- * free it
- */
- if (!context)
- free(ctxt);
-
- return(ret);
+ MSG(c, "emc_clariion_checker: Path healthy");
+ return PATH_UP;
}
--- /dev/null
+#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 */
#include <sys/ioctl.h>
#include <errno.h>
-#include "path_state.h"
#include "checkers.h"
#include "../libmultipath/sg_include.h"
#define MSG_HP_SW_GHOST "hp_sw checker reports path is ghost"
struct sw_checker_context {
- int run_count;
+ 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)
}
extern int
-hp_sw (int fd, char *msg, void **context)
+hp_sw (struct checker * c)
{
char buff[MX_ALLOC_LEN];
- struct sw_checker_context * ctxt = NULL;
- int ret;
-
- /*
- * caller passed in a context : use its address
- */
- if (context)
- ctxt = (struct sw_checker_context *) (*context);
-
- /*
- * passed in context is uninitialized or volatile context :
- * initialize it
- */
- if (!ctxt) {
- ctxt = malloc(sizeof(struct sw_checker_context));
- memset(ctxt, 0, sizeof(struct sw_checker_context));
-
- if (!ctxt) {
- MSG("cannot allocate context");
- return -1;
- }
- if (context)
- *context = ctxt;
- }
- ctxt->run_count++;
- if ((ctxt->run_count % HEAVY_CHECK_COUNT) == 0) {
- ctxt->run_count = 0;
- /* do stuff */
- }
- if (fd <= 0) {
- MSG("no usable fd");
- ret = -1;
- goto out;
- }
-
- if (0 != do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
- MSG(MSG_HP_SW_DOWN);
- ret = PATH_DOWN;
- goto out;
+ 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(fd)) {
- MSG(MSG_HP_SW_GHOST);
- ret = PATH_GHOST;
- } else {
- MSG(MSG_HP_SW_UP);
- ret = PATH_UP;
- }
-
-out:
- /*
- * caller told us he doesn't want to keep the context :
- * free it
- */
- if (!context)
- free(ctxt);
-
- return(ret);
+ if (do_tur(c->fd)) {
+ MSG(c, MSG_HP_SW_GHOST);
+ return PATH_GHOST;
+ }
+ MSG(c, MSG_HP_SW_UP);
+ return PATH_UP;
}
--- /dev/null
+#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 */
+++ /dev/null
-#define PATH_WILD -1
-#define PATH_UNCHECKED 0
-#define PATH_DOWN 1
-#define PATH_UP 2
-#define PATH_SHAKY 3
-#define PATH_GHOST 4
#include <sys/ioctl.h>
#include <errno.h>
-#include "path_state.h"
#include "checkers.h"
#include "../libmultipath/sg_include.h"
void * dummy;
};
+int readsector0_init (struct checker * c)
+{
+ return 0;
+}
+
+void readsector0_free (struct checker * c)
+{
+ return;
+}
+
static int
sg_read (int sg_fd, unsigned char * buff)
{
}
extern int
-readsector0 (int fd, char *msg, void **context)
+readsector0 (struct checker * c)
{
unsigned char buf[512];
- struct readsector0_checker_context * ctxt = NULL;
int ret;
- /*
- * caller passed in a context : use its address
- */
- if (context)
- ctxt = (struct readsector0_checker_context *) (*context);
-
- /*
- * passed in context is uninitialized or volatile context :
- * initialize it
- */
- if (!ctxt) {
- ctxt = malloc(sizeof(struct readsector0_checker_context));
- memset(ctxt, 0, sizeof(struct readsector0_checker_context));
-
- if (!ctxt) {
- MSG("cannot allocate context");
- return -1;
- }
- if (context)
- *context = ctxt;
- }
- if (fd <= 0) {
- MSG("no usable fd");
- ret = -1;
- goto out;
- }
- ret = sg_read(fd, &buf[0]);
+ ret = sg_read(c->fd, &buf[0]);
switch (ret)
{
case PATH_DOWN:
- MSG(MSG_READSECTOR0_DOWN);
+ MSG(c, MSG_READSECTOR0_DOWN);
break;
case PATH_UP:
- MSG(MSG_READSECTOR0_UP);
+ MSG(c, MSG_READSECTOR0_UP);
break;
default:
break;
}
-out:
- /*
- * caller told us he doesn't want to keep the context :
- * free it
- */
- if (!context)
- free(ctxt);
-
return ret;
}
--- /dev/null
+#ifndef _READSECTOR0_H
+#define _READSECTOR0_H
+
+int readsector0 (struct checker *);
+int readsector0_init (struct checker *);
+void readsector0_free (struct checker *);
+
+#endif /* _READSECTOR0_H */
+++ /dev/null
-/*
- * Copyright (c) 2004, 2005 Christophe Varoqui
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "checkers.h"
-
-extern int
-get_checker_id (char * str)
-{
- if (0 == strncmp(str, "tur", 3))
- return TUR;
- if (0 == strncmp(str, "readsector0", 11))
- return READSECTOR0;
- if (0 == strncmp(str, "directio", 8))
- return DIRECTIO;
- if (0 == strncmp(str, "emc_clariion", 12))
- return EMC_CLARIION;
- if (0 == strncmp(str, "hp_sw", 5))
- return HP_SW;
- return -1;
-}
-
-extern void *
-get_checker_addr (int id)
-{
- int (*checker) (int, char *, void **);
-
- switch (id) {
- case TUR:
- checker = &tur;
- break;
- case READSECTOR0:
- checker = &readsector0;
- break;
- case DIRECTIO:
- checker = &directio;
- break;
- case EMC_CLARIION:
- checker = &emc_clariion;
- break;
- case HP_SW:
- checker = &hp_sw;
- break;
- default:
- checker = NULL;
- break;
- }
- return checker;
-}
-
-extern int
-get_checker_name (char * str, int len, int id)
-{
- char * s;
-
- switch (id) {
- case TUR:
- s = "tur";
- break;
- case READSECTOR0:
- s = "readsector0";
- break;
- case DIRECTIO:
- s = "directio";
- break;
- case EMC_CLARIION:
- s = "emc_clariion";
- break;
- case HP_SW:
- s = "hp_sw";
- break;
- default:
- s = "undefined";
- break;
- }
- return snprintf(str, len, "%s", s);
-}
#include <sys/ioctl.h>
#include <errno.h>
-#include "path_state.h"
#include "checkers.h"
#include "../libmultipath/sg_include.h"
#define MSG_TUR_DOWN "tur checker reports path is down"
struct tur_checker_context {
- int run_count;
+ void * dummy;
};
+int tur_init (struct checker * c)
+{
+ return 0;
+}
+
+void tur_free (struct checker * c)
+{
+ return;
+}
extern int
-tur (int fd, char *msg, void **context)
+tur (struct checker * c)
{
+ struct sg_io_hdr io_hdr;
unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
- struct sg_io_hdr io_hdr;
unsigned char sense_buffer[32];
- struct tur_checker_context * ctxt = NULL;
- int ret;
- /*
- * caller passed in a context : use its address
- */
- if (context)
- ctxt = (struct tur_checker_context *) (*context);
-
- /*
- * passed in context is uninitialized or volatile context :
- * initialize it
- */
- if (!ctxt) {
- ctxt = malloc(sizeof(struct tur_checker_context));
- memset(ctxt, 0, sizeof(struct tur_checker_context));
-
- if (!ctxt) {
- MSG("cannot allocate context");
- return -1;
- }
- if (context)
- *context = ctxt;
- }
- ctxt->run_count++;
-
- if ((ctxt->run_count % HEAVY_CHECK_COUNT) == 0) {
- ctxt->run_count = 0;
- /* do stuff */
- }
- if (fd <= 0) {
- MSG("no usable fd");
- ret = -1;
- goto out;
- }
-
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof (turCmdBlk);
io_hdr.sbp = sense_buffer;
io_hdr.timeout = 20000;
io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- MSG(MSG_TUR_DOWN);
- ret = PATH_DOWN;
- goto out;
+ 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(MSG_TUR_DOWN);
- ret = PATH_DOWN;
- goto out;
+ MSG(c, MSG_TUR_DOWN);
+ return PATH_DOWN;
}
- MSG(MSG_TUR_UP);
- ret = PATH_UP;
-
-out:
- /*
- * caller told us he doesn't want to keep the context :
- * free it
- */
- if (!context)
- free(ctxt);
-
- return(ret);
+ MSG(c, MSG_TUR_UP);
+ return PATH_UP;
}
--- /dev/null
+#ifndef _TUR_H
+#define _TUR_H
+
+int tur (struct checker *);
+int tur_init (struct checker *);
+void tur_free (struct checker *);
+
+#endif /* _TUR_H */
include ../Makefile.inc
+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 \
*/
#include <stdio.h>
+#include <checkers.h>
+
#include "memory.h"
#include "vector.h"
#include "util.h"
#include <sys/wait.h>
#include <errno.h>
+#include <checkers.h>
+
#include "vector.h"
#include "structs.h"
#include "debug.h"
#include <stdio.h>
#include <string.h>
+#include <checkers.h>
+
#include "memory.h"
#include "util.h"
#include "debug.h"
#include "blacklist.h"
#include "defaults.h"
-#include "../libcheckers/checkers.h"
-
struct hwentry *
find_hwe (vector hwtable, char * vendor, char * product)
{
hwe->rr_weight = dhwe->rr_weight;
hwe->no_path_retry = dhwe->no_path_retry;
hwe->minio = dhwe->minio;
- hwe->checker_index = dhwe->checker_index;
+ hwe->checker = dhwe->checker;
if (!vector_alloc_slot(hwtable))
!conf->hwhandler)
goto out;
- if (!conf->checker_index)
- conf->checker_index = READSECTOR0;
+ if (!conf->checker)
+ conf->checker = checker_lookup(DEFAULT_CHECKER);
return 0;
out:
char * features;
char * hwhandler;
char * selector;
+ char * checker_name;
int pgpolicy;
int pgfailback;
int rr_weight;
int no_path_retry;
int minio;
- int checker_index;
+ struct checker * checker;
};
struct mpentry {
int pgpolicy_flag;
int with_sysfs;
int pgpolicy;
- int checker_index;
+ struct checker * checker;
int dev_type;
int minio;
int checkint;
#include <errno.h>
#include <libdevmapper.h>
-#include "../libcheckers/path_state.h"
+#include <checkers.h>
+
#include "vector.h"
#include "memory.h"
#include "devmapper.h"
#include <linux/kdev_t.h>
#include <unistd.h>
+#include <checkers.h>
+
#include "vector.h"
#include "structs.h"
#include "debug.h"
* Copyright (c) 2005 Benjamin Marzinski, Redhat
* Copyright (c) 2005 Kiyoshi Ueda, NEC
*/
+#include <checkers.h>
+
#include "vector.h"
#include "hwtable.h"
#include "structs.h"
#include "blacklist.h"
#include "defaults.h"
-#include "../libcheckers/checkers.h"
-
/*
* default block handlers
*/
if (!buff)
return 1;
- conf->checker_index = get_checker_id(buff);
+ conf->checker = checker_lookup(buff);
FREE(buff);
return 0;
if (!buff)
return 1;
- hwe->checker_index = get_checker_id(buff);
+ hwe->checker = checker_lookup(buff);
FREE(buff);
return 0;
static int
snprint_hw_path_checker (char * buff, int len, void * data)
{
- char str[CHECKER_NAME_SIZE];
struct hwentry * hwe = (struct hwentry *)data;
- if (!hwe->checker_index)
+ if (!checker_selected(hwe->checker))
return 0;
- if (hwe->checker_index == conf->checker_index)
+ if (hwe->checker == conf->checker)
return 0;
- get_checker_name(str, CHECKER_NAME_SIZE, hwe->checker_index);
- return snprintf(buff, len, "%s", str);
+ return snprintf(buff, len, "%s", checker_name(hwe->checker));
}
static int
static int
snprint_def_path_checker (char * buff, int len, void * data)
{
- char str[CHECKER_NAME_SIZE];
-
- if (!conf->checker_index)
+ if (!conf->checker)
return 0;
- if (conf->checker_index == DEFAULT_CHECKER_ID)
+ if (conf->checker == checker_default())
return 0;
- get_checker_name(str, CHECKER_NAME_SIZE, conf->checker_index);
- return snprintf(buff, len, "%s", str);
+ return snprintf(buff, len, "%s", checker_name(conf->checker));
}
static int
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>
-
#include <sysfs/dlist.h>
#include <sysfs/libsysfs.h>
+#include <checkers.h>
+
#include "vector.h"
#include "memory.h"
#include "util.h"
#include "sg_include.h"
#include "discovery.h"
-#include "../libcheckers/path_state.h"
-
struct path *
store_pathinfo (vector pathvec, vector hwtable, char * devname, int flag)
{
static int
get_state (struct path * pp)
{
- if (!pp->checkfn)
- select_checkfn(pp);
- if (!pp->checkfn)
- return 1;
- pp->state = pp->checkfn(pp->fd, NULL, NULL);
+ struct checker * c = &pp->checker;
+
+ if (!checker_selected(c)) {
+ select_checker(pp);
+ if (!checker_selected(c))
+ return 1;
+ checker_set_fd(c, pp->fd);
+ if (checker_init(c))
+ return 1;
+ }
+ pp->state = checker_check(c);
condlog(3, "%s: state = %i", pp->dev, pp->state);
return 0;
}
#include <stdlib.h>
#include <string.h>
+#include <checkers.h>
+
#include "vector.h"
#include "memory.h"
#include "structs.h"
#include <stdio.h>
+#include <checkers.h>
+
#include "vector.h"
#include "defaults.h"
#include "structs.h"
#include "config.h"
#include "pgpolicies.h"
-#include "../libcheckers/checkers.h"
-
/*
* Tuning suggestions on these parameters should go to
* dm-devel@redhat.com
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = DEFAULT_CHECKER_ID,
+ .checker_name = DEFAULT_CHECKER,
},
{
.vendor = "DEC",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = HP_SW,
+ .checker_name = HP_SW,
},
{
.vendor = "{COMPAQ,HP}",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = HP_SW,
+ .checker_name = HP_SW,
},
{
.vendor = "HP",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
{
.vendor = "HP",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* DDN controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* EMC / Clariion controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
{
.vendor = "DGC",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = EMC_CLARIION,
+ .checker_name = EMC_CLARIION,
},
/*
* Fujitsu controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* Hitachi controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* IBM controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
{
/* IBM DS4100 / FAStT100 */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
{
/* IBM DS4200 / FAStT200 */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
{
/* IBM ESS F20 aka Shark */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
{
/* IBM DS6000 / SAN Volume Controller */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
{
/* IBM DS8000 */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
{
/* IBM S/390 ECKD DASD */
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = DIRECTIO,
+ .checker_name = DIRECTIO,
},
/*
* NETAPP controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* Pillar Data controler family
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
/*
* SGI arrays
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
{
.vendor = "SGI",
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
/*
* STK arrays
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = TUR,
+ .checker_name = TUR,
},
/*
* SUN arrays
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = DEFAULT_MINIO,
- .checker_index = READSECTOR0,
+ .checker_name = READSECTOR0,
},
/*
* EOL
.rr_weight = 0,
.no_path_retry = 0,
.minio = 0,
- .checker_index = 0,
+ .checker_name = NULL,
},
};
struct hwentry * hwe = default_hw;
while (hwe->vendor) {
+ hwe->checker = checker_lookup(hwe->checker_name);
r += store_hwe(hw, hwe);
hwe++;
}
#include <stdlib.h>
#include <string.h>
+#include <checkers.h>
+
#include "util.h"
#include "memory.h"
#include "vector.h"
#include "structs.h"
#include "pgpolicies.h"
-#include "../libcheckers/path_state.h"
-
extern int
get_pgpolicy_id (char * str)
{
#include <libdevmapper.h>
#include <stdarg.h>
+#include <checkers.h>
+
#include "vector.h"
#include "structs.h"
#include "structs_vec.h"
#include "defaults.h"
#include "parser.h"
-#include "../libcheckers/path_state.h"
-#include "../libcheckers/checkers.h"
-
#define MAX(x,y) (x > y) ? x : y
#define TAIL (line + len - 1 - c)
#define NOPAD s = c
*/
#include <stdio.h>
+#include <checkers.h>
+
#include "memory.h"
#include "vector.h"
#include "structs.h"
#include "alias.h"
#include "defaults.h"
-#include "../libcheckers/checkers.h"
-
pgpolicyfn *pgpolicies[] = {
NULL,
one_path_per_group,
}
extern int
-select_checkfn(struct path *pp)
+select_checker(struct path *pp)
{
- char checker_name[CHECKER_NAME_SIZE];
+ struct checker * c = &pp->checker;
- if (pp->hwe && pp->hwe->checker_index > 0) {
- get_checker_name(checker_name, CHECKER_NAME_SIZE,
- pp->hwe->checker_index);
+ if (pp->hwe && pp->hwe->checker) {
+ checker_get(c, pp->hwe->checker);
condlog(3, "%s: path checker = %s (controler setting)",
- pp->dev, checker_name);
- pp->checkfn = get_checker_addr(pp->hwe->checker_index);
+ pp->dev, checker_name(c));
return 0;
}
- if (conf->checker_index > 0) {
- pp->checkfn = get_checker_addr(conf->checker_index);
- get_checker_name(checker_name, CHECKER_NAME_SIZE,
- conf->checker_index);
+ if (conf->checker) {
+ checker_get(c, conf->checker);
condlog(3, "%s: path checker = %s (config file default)",
- pp->dev, checker_name);
+ pp->dev, checker_name(c));
return 0;
}
- pp->checkfn = get_checker_addr(DEFAULT_CHECKER_ID);
- get_checker_name(checker_name, CHECKER_NAME_SIZE, DEFAULT_CHECKER_ID);
+ checker_get(c, checker_default());
condlog(3, "%s: path checker = %s (internal default)",
- pp->dev, checker_name);
+ pp->dev, checker_name(c));
return 0;
}
int select_alias (struct multipath * mp);
int select_features (struct multipath * mp);
int select_hwhandler (struct multipath * mp);
-int select_checkfn(struct path *pp);
+int select_checker(struct path *pp);
int select_getuid (struct path * pp);
int select_getprio (struct path * pp);
int select_no_path_retry(struct multipath *mp);
#include <unistd.h>
#include <libdevmapper.h>
+#include <checkers.h>
+
#include "memory.h"
#include "vector.h"
#include "util.h"
if (!pp)
return;
- if (pp->checker_context)
- free(pp->checker_context);
+ if (checker_selected(&pp->checker))
+ checker_put(&pp->checker);
if (pp->fd >= 0)
close(pp->fd);
char * getuid;
char * getprio;
int getprio_selected;
- int (*checkfn) (int, char *, void **);
- void * checker_context;
+ struct checker checker;
struct multipath * mpp;
int fd;
#include <string.h>
#include <unistd.h>
+#include <checkers.h>
+
#include "vector.h"
#include "defaults.h"
#include "debug.h"
#include "config.h"
#include "propsel.h"
#include "discovery.h"
-#include "../libcheckers/path_state.h"
/*
orphan_path (struct path * pp)
{
pp->mpp = NULL;
- pp->checkfn = NULL;
pp->dmstate = PSTATE_UNDEF;
- pp->checker_context = NULL;
pp->getuid = NULL;
pp->getprio = NULL;
pp->getprio_selected = 0;
-
+ checker_put(&pp->checker);
if (pp->fd >= 0)
close(pp->fd);
-
pp->fd = -1;
}
* Copyright (c) 2005 Christophe Varoqui
* Copyright (c) 2005 Edward Goggin, EMC
*/
+#include <checkers.h>
+
#include "vector.h"
#include "structs.h"
#include "switchgroup.h"
-#include "../libcheckers/path_state.h"
extern int
select_path_group (struct multipath * mpp)
#include <ctype.h>
#include <sysfs/libsysfs.h>
+#include <checkers.h>
#include <vector.h>
#include <memory.h>
#include <libdevmapper.h>
#include <devmapper.h>
-#include <path_state.h>
#include <util.h>
#include <defaults.h>
#include <structs.h>
/*
* Copyright (c) 2005 Christophe Varoqui
*/
+#include <checkers.h>
#include <memory.h>
#include <vector.h>
#include <structs.h>
* libcheckers
*/
#include <checkers.h>
-#include <path_state.h>
/*
* libmultipath
#include <propsel.h>
#include <uevent.h>
#include <switchgroup.h>
-#include <path_state.h>
#include <print.h>
#include <configure.h>
#define CMDSIZE 160
#define LOG_MSG(a,b) \
- if (strlen(b)) { \
- condlog(a, "%s: %s", pp->dev_t, b); \
- memset(b, 0, MAX_CHECKER_MSG_SIZE); \
- }
+ if (strlen(b)) condlog(a, "%s: %s", pp->dev_t, b);
#ifdef LCKDBG
#define lock(a) \
struct path *pp;
int i, count = 0;
int newstate;
- char checker_msg[MAX_CHECKER_MSG_SIZE];
mlockall(MCL_CURRENT | MCL_FUTURE);
-
- memset(checker_msg, 0, MAX_CHECKER_MSG_SIZE);
vecs = (struct vectors *)ap;
-
condlog(2, "path checkers start up");
/*
*/
pp->tick = conf->checkint;
- if (!pp->checkfn) {
+ if (!checker_selected(&pp->checker)) {
pathinfo(pp, conf->hwtable, DI_SYSFS);
- select_checkfn(pp);
+ select_checker(pp);
}
- if (!pp->checkfn) {
- condlog(0, "%s: checkfn is void", pp->dev);
+ if (!checker_selected(&pp->checker)) {
+ condlog(0, "%s: checker is not set", pp->dev);
continue;
}
- newstate = pp->checkfn(pp->fd, checker_msg,
- &pp->checker_context);
+ newstate = checker_check(&pp->checker);
if (newstate < 0) {
condlog(2, "%s: unusable path", pp->dev);
if (newstate != pp->state) {
pp->state = newstate;
- LOG_MSG(1, checker_msg);
+ LOG_MSG(1, checker_message(&pp->checker));
/*
* upon state change, reset the checkint
enable_group(pp);
}
else if (newstate == PATH_UP || newstate == PATH_GHOST) {
- LOG_MSG(4, checker_msg);
+ LOG_MSG(4, checker_message(&pp->checker));
/*
* double the next check delay.
* max at conf->max_checkint
#include <sys/un.h>
#include <sys/poll.h>
+#include <checkers.h>
+
#include <memory.h>
#include <debug.h>
#include <vector.h>