Imported Upstream version 0.7.0
[platform/upstream/multipath-tools.git] / libmultipath / checkers.c
index 01dafdd..05e024f 100644 (file)
@@ -7,16 +7,18 @@
 #include "debug.h"
 #include "checkers.h"
 #include "vector.h"
-#include "config.h"
 
 char *checker_state_names[] = {
-      "wild",
-      "unchecked",
-      "down",
-      "up",
-      "shaky",
-      "ghost",
-      "pending"
+       "wild",
+       "unchecked",
+       "down",
+       "up",
+       "shaky",
+       "ghost",
+       "pending",
+       "timeout",
+       "removed",
+       "delayed",
 };
 
 static LIST_HEAD(checkers);
@@ -26,9 +28,9 @@ char * checker_state_name (int i)
        return checker_state_names[i];
 }
 
-int init_checkers (void)
+int init_checkers (char *multipath_dir)
 {
-       if (!add_checker(DEFAULT_CHECKER))
+       if (!add_checker(multipath_dir, DEFAULT_CHECKER))
                return 1;
        return 0;
 }
@@ -86,10 +88,10 @@ struct checker * checker_lookup (char * name)
                if (!strncmp(name, c->name, CHECKER_NAME_LEN))
                        return c;
        }
-       return add_checker(name);
+       return NULL;
 }
 
-struct checker * add_checker (char * name)
+struct checker * add_checker (char *multipath_dir, char * name)
 {
        char libname[LIB_CHECKER_NAMELEN];
        struct stat stbuf;
@@ -101,10 +103,10 @@ struct checker * add_checker (char * name)
                return NULL;
        snprintf(c->name, CHECKER_NAME_LEN, "%s", name);
        snprintf(libname, LIB_CHECKER_NAMELEN, "%s/libcheck%s.so",
-                conf->multipath_dir, name);
+                multipath_dir, name);
        if (stat(libname,&stbuf) < 0) {
                condlog(0,"Checker '%s' not found in %s",
-                       name, conf->multipath_dir);
+                       name, multipath_dir);
                goto out;
        }
        condlog(3, "loading %s checker", libname);
@@ -136,6 +138,14 @@ struct checker * add_checker (char * name)
        if (!c->free)
                goto out;
 
+       c->repair = (void (*)(struct checker *)) dlsym(c->handle,
+                                                      "libcheck_repair");
+       errstr = dlerror();
+       if (errstr != NULL)
+               condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+       if (!c->repair)
+               goto out;
+
        c->fd = 0;
        c->sync = 1;
        list_add(&c->node, &checkers);
@@ -192,7 +202,7 @@ void checker_put (struct checker * dst)
 {
        struct checker * src;
 
-       if (!dst)
+       if (!dst || !dst->check)
                return;
        src = checker_lookup(dst->name);
        if (dst->free)
@@ -201,6 +211,20 @@ void checker_put (struct checker * dst)
        free_checker(src);
 }
 
+void checker_repair (struct checker * c)
+{
+       if (!checker_selected(c))
+               return;
+
+       c->message[0] = '\0';
+       if (c->disable) {
+               MSG(c, "checker disabled");
+               return;
+       }
+
+       c->repair(c);
+}
+
 int checker_check (struct checker * c)
 {
        int r;
@@ -250,13 +274,18 @@ void checker_clear_message (struct checker *c)
        c->message[0] = '\0';
 }
 
-void checker_get (struct checker * dst, char * name)
+void checker_get (char *multipath_dir, struct checker * dst, char * name)
 {
-       struct checker * src = checker_lookup(name);
+       struct checker * src = NULL;
 
        if (!dst)
                return;
 
+       if (name && strlen(name)) {
+               src = checker_lookup(name);
+               if (!src)
+                       src = add_checker(multipath_dir, name);
+       }
        if (!src) {
                dst->check = NULL;
                return;
@@ -265,6 +294,7 @@ void checker_get (struct checker * dst, char * name)
        dst->sync = src->sync;
        strncpy(dst->name, src->name, CHECKER_NAME_LEN);
        strncpy(dst->message, src->message, CHECKER_MSG_LEN);
+       dst->repair = src->repair;
        dst->check = src->check;
        dst->init = src->init;
        dst->free = src->free;