11 char *checker_state_names[] = {
24 static LIST_HEAD(checkers);
26 char * checker_state_name (int i)
28 return checker_state_names[i];
31 int init_checkers (char *multipath_dir)
33 if (!add_checker(multipath_dir, DEFAULT_CHECKER))
38 struct checker * alloc_checker (void)
42 c = MALLOC(sizeof(struct checker));
44 INIT_LIST_HEAD(&c->node);
50 void free_checker (struct checker * c)
56 condlog(3, "%s checker refcount %d",
57 c->name, c->refcount);
60 condlog(3, "unloading %s checker", c->name);
63 if (dlclose(c->handle) != 0) {
64 condlog(0, "Cannot unload checker %s: %s",
71 void cleanup_checkers (void)
73 struct checker * checker_loop;
74 struct checker * checker_temp;
76 list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
77 free_checker(checker_loop);
81 struct checker * checker_lookup (char * name)
85 if (!name || !strlen(name))
87 list_for_each_entry(c, &checkers, node) {
88 if (!strncmp(name, c->name, CHECKER_NAME_LEN))
94 struct checker * add_checker (char *multipath_dir, char * name)
96 char libname[LIB_CHECKER_NAMELEN];
104 snprintf(c->name, CHECKER_NAME_LEN, "%s", name);
105 snprintf(libname, LIB_CHECKER_NAMELEN, "%s/libcheck%s.so",
106 multipath_dir, name);
107 if (stat(libname,&stbuf) < 0) {
108 condlog(0,"Checker '%s' not found in %s",
109 name, multipath_dir);
112 condlog(3, "loading %s checker", libname);
113 c->handle = dlopen(libname, RTLD_NOW);
115 if ((errstr = dlerror()) != NULL)
116 condlog(0, "A dynamic linking error occurred: (%s)",
120 c->check = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_check");
123 condlog(0, "A dynamic linking error occurred: (%s)", errstr);
127 c->init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_init");
130 condlog(0, "A dynamic linking error occurred: (%s)", errstr);
134 c->free = (void (*)(struct checker *)) dlsym(c->handle, "libcheck_free");
137 condlog(0, "A dynamic linking error occurred: (%s)", errstr);
141 c->repair = (void (*)(struct checker *)) dlsym(c->handle,
145 condlog(0, "A dynamic linking error occurred: (%s)", errstr);
151 list_add(&c->node, &checkers);
158 void checker_set_fd (struct checker * c, int fd)
165 void checker_set_sync (struct checker * c)
172 void checker_set_async (struct checker * c)
179 void checker_enable (struct checker * c)
186 void checker_disable (struct checker * c)
193 int checker_init (struct checker * c, void ** mpctxt_addr)
197 c->mpcontext = mpctxt_addr;
201 void checker_put (struct checker * dst)
203 struct checker * src;
205 if (!dst || !dst->check)
207 src = checker_lookup(dst->name);
210 memset(dst, 0x0, sizeof(struct checker));
214 void checker_repair (struct checker * c)
216 if (!checker_selected(c))
219 c->message[0] = '\0';
221 MSG(c, "checker disabled");
228 int checker_check (struct checker * c)
235 c->message[0] = '\0';
237 MSG(c, "checker disabled");
238 return PATH_UNCHECKED;
241 MSG(c, "no usable fd");
249 int checker_selected (struct checker * c)
253 return (c->check) ? 1 : 0;
256 char * checker_name (struct checker * c)
263 char * checker_message (struct checker * c)
270 void checker_clear_message (struct checker *c)
274 c->message[0] = '\0';
277 void checker_get (char *multipath_dir, struct checker * dst, char * name)
279 struct checker * src = NULL;
284 if (name && strlen(name)) {
285 src = checker_lookup(name);
287 src = add_checker(multipath_dir, name);
294 dst->sync = src->sync;
295 strncpy(dst->name, src->name, CHECKER_NAME_LEN);
296 strncpy(dst->message, src->message, CHECKER_MSG_LEN);
297 dst->repair = src->repair;
298 dst->check = src->check;
299 dst->init = src->init;
300 dst->free = src->free;