2 * Copyright (c) 2004, 2005 Christophe Varoqui
3 * Copyright (c) 2005 Kiyoshi Ueda, NEC
4 * Copyright (c) 2005 Benjamin Marzinski, Redhat
5 * Copyright (c) 2005 Edward Goggin, EMC
9 #include <libdevmapper.h>
12 #include <sys/types.h>
19 #include <sysfs/libsysfs.h>
20 #include <sysfs/dlist.h>
26 #include <path_state.h>
37 #include <blacklist.h>
42 #include <devmapper.h>
44 #include <discovery.h>
48 #include <switchgroup.h>
49 #include <path_state.h>
57 #include "cli_handlers.h"
59 #define FILE_NAME_SIZE 256
62 #define LOG_MSG(a,b) \
64 condlog(a, "%s: %s", pp->dev_t, b); \
65 memset(b, 0, MAX_CHECKER_MSG_SIZE); \
70 fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
73 fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
74 pthread_mutex_unlock(a)
75 #define lock_cleanup_pop(a) \
76 fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
77 pthread_cleanup_pop(1);
79 #define lock(a) pthread_mutex_lock(a)
80 #define unlock(a) pthread_mutex_unlock(a)
81 #define lock_cleanup_pop(a) pthread_cleanup_pop(1);
84 pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
85 pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
87 typedef void (stop_waiter_thread_func) (struct multipath *, struct vectors *);
88 typedef int (start_waiter_thread_func) (struct multipath *, struct vectors *);
93 struct vectors * gvecs; /* global copy of vecs for use in sig handlers */
99 char mapname[WWID_SIZE];
100 struct vectors *vecs;
103 static struct event_thread *
107 struct event_thread * wp;
109 wp = (struct event_thread *)MALLOC(sizeof(struct event_thread));
115 free_waiter (void * data)
117 struct event_thread * wp = (struct event_thread *)data;
120 dm_task_destroy(wp->dmt);
125 stop_waiter_thread (struct multipath * mpp, struct vectors * vecs)
127 struct event_thread * wp = (struct event_thread *)mpp->waiter;
130 condlog(3, "%s: no waiter thread", mpp->alias);
133 condlog(2, "%s: stop event checker thread", wp->mapname);
134 pthread_kill((pthread_t)wp->thread, SIGUSR1);
138 cleanup_lock (void * data)
140 pthread_mutex_unlock((pthread_mutex_t *)data);
144 * creates or updates mpp->paths reading mpp->pg
147 update_mpp_paths(struct multipath * mpp)
149 struct pathgroup * pgp;
157 !(mpp->paths = vector_alloc()))
160 vector_foreach_slot (mpp->pg, pgp, i) {
161 vector_foreach_slot (pgp->paths, pp, j) {
162 if (!find_path_by_devt(mpp->paths, pp->dev_t) &&
163 store_path(mpp->paths, pp))
171 adopt_paths (vector pathvec, struct multipath * mpp)
179 if (update_mpp_paths(mpp))
182 vector_foreach_slot (pathvec, pp, i) {
183 if (!strncmp(mpp->wwid, pp->wwid, WWID_SIZE)) {
184 condlog(3, "%s ownership set for %s", pp->dev_t, mpp->alias);
187 if (!find_path_by_dev(mpp->paths, pp->dev) &&
188 store_path(mpp->paths, pp))
196 orphan_path (struct path * pp)
200 pp->dmstate = PSTATE_UNDEF;
201 pp->checker_context = NULL;
204 pp->getprio_selected = 0;
213 orphan_paths (struct vectors * vecs, struct multipath * mpp)
218 vector_foreach_slot (vecs->pathvec, pp, i) {
219 if (pp->mpp == mpp) {
220 condlog(4, "%s is orphaned", pp->dev_t);
227 update_multipath_table (struct multipath *mpp, vector pathvec)
232 if (dm_get_map(mpp->alias, &mpp->size, mpp->params))
235 if (disassemble_map(pathvec, mpp->params, mpp))
242 update_multipath_status (struct multipath *mpp)
247 if(dm_get_status(mpp->alias, mpp->status))
250 if (disassemble_status(mpp->status, mpp))
257 update_multipath_strings (struct multipath *mpp, vector pathvec)
259 free_multipath_attributes(mpp);
260 free_pgvec(mpp->pg, KEEP_PATHS);
263 if (update_multipath_table(mpp, pathvec))
266 if (update_multipath_status(mpp))
273 set_multipath_wwid (struct multipath * mpp)
278 dm_get_uuid(mpp->alias, mpp->wwid);
282 * mpp->no_path_retry:
283 * -2 (QUEUE) : queue_if_no_path enabled, never turned off
284 * -1 (FAIL) : fail_if_no_path
285 * 0 (UNDEF) : nothing
286 * >0 : queue_if_no_path enabled, turned off after polling n times
289 update_queue_mode_del_path(struct multipath *mpp)
291 if (--mpp->nr_active == 0 && mpp->no_path_retry > 0) {
294 * meaning of +1: retry_tick may be decremented in
295 * checkerloop before starting retry.
297 mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1;
298 condlog(1, "%s: Entering recovery mode: max_retries=%d",
299 mpp->alias, mpp->no_path_retry);
301 condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
305 update_queue_mode_add_path(struct multipath *mpp)
307 if (mpp->nr_active++ == 0 && mpp->no_path_retry > 0) {
308 /* come back to normal mode from retry mode */
310 dm_queue_if_no_path(mpp->alias, 1);
311 condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
312 condlog(1, "%s: Recovered to normal mode", mpp->alias);
314 condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
318 set_no_path_retry(struct multipath *mpp)
321 mpp->nr_active = pathcount(mpp, PATH_UP);
322 select_no_path_retry(mpp);
324 switch (mpp->no_path_retry) {
325 case NO_PATH_RETRY_UNDEF:
327 case NO_PATH_RETRY_FAIL:
328 dm_queue_if_no_path(mpp->alias, 0);
330 case NO_PATH_RETRY_QUEUE:
331 dm_queue_if_no_path(mpp->alias, 1);
334 dm_queue_if_no_path(mpp->alias, 1);
335 if (mpp->nr_active == 0) {
336 /* Enter retry mode */
337 mpp->retry_tick = mpp->no_path_retry * conf->checkint;
338 condlog(1, "%s: Entering recovery mode: max_retries=%d",
339 mpp->alias, mpp->no_path_retry);
345 static struct hwentry *
346 extract_hwe_from_path(struct multipath * mpp)
349 struct pathgroup * pgp;
351 pgp = VECTOR_SLOT(mpp->pg, 0);
352 pp = VECTOR_SLOT(pgp->paths, 0);
358 remove_map (struct multipath * mpp, struct vectors * vecs,
359 stop_waiter_thread_func *stop_waiter, int purge_vec)
364 * stop the DM event waiter thread
367 stop_waiter(mpp, vecs);
370 * clear references to this map
372 orphan_paths(vecs, mpp);
375 (i = find_slot(vecs->mpvec, (void *)mpp)) != -1)
376 vector_del_slot(vecs->mpvec, i);
381 free_multipath(mpp, KEEP_PATHS);
385 remove_maps (struct vectors * vecs,
386 stop_waiter_thread_func *stop_waiter)
389 struct multipath * mpp;
391 vector_foreach_slot (vecs->mpvec, mpp, i) {
392 remove_map(mpp, vecs, stop_waiter, 1);
396 vector_free(vecs->mpvec);
401 setup_multipath (struct vectors * vecs, struct multipath * mpp)
403 if (dm_get_info(mpp->alias, &mpp->dmi))
406 set_multipath_wwid(mpp);
407 mpp->mpe = find_mpe(mpp->wwid);
408 condlog(4, "discovered map %s", mpp->alias);
410 if (update_multipath_strings(mpp, vecs->pathvec))
413 adopt_paths(vecs->pathvec, mpp);
414 mpp->hwe = extract_hwe_from_path(mpp);
415 select_rr_weight(mpp);
416 select_pgfailback(mpp);
417 set_no_path_retry(mpp);
421 condlog(0, "%s: failed to setup multipath", mpp->alias);
422 remove_map(mpp, vecs, NULL, 1);
427 need_switch_pathgroup (struct multipath * mpp, int refresh)
429 struct pathgroup * pgp;
433 if (!mpp || mpp->pgfailback == -FAILBACK_MANUAL)
437 * Refresh path priority values
440 vector_foreach_slot (mpp->pg, pgp, i)
441 vector_foreach_slot (pgp->paths, pp, j)
442 pathinfo(pp, conf->hwtable, DI_PRIO);
444 mpp->bestpg = select_path_group(mpp);
446 if (mpp->bestpg != mpp->nextpg)
453 switch_pathgroup (struct multipath * mpp)
455 dm_switchgroup(mpp->alias, mpp->bestpg);
456 condlog(2, "%s: switch to path group #%i",
457 mpp->alias, mpp->bestpg);
461 update_multipath (struct vectors *vecs, char *mapname)
463 struct multipath *mpp;
464 struct pathgroup *pgp;
469 mpp = find_mp_by_alias(vecs->mpvec, mapname);
474 free_pgvec(mpp->pg, KEEP_PATHS);
477 if (setup_multipath(vecs, mpp))
478 goto out; /* mpp freed in setup_multipath */
481 * compare checkers states with DM states
483 vector_foreach_slot (mpp->pg, pgp, i) {
484 vector_foreach_slot (pgp->paths, pp, j) {
485 if (pp->dmstate != PSTATE_FAILED)
488 if (pp->state != PATH_DOWN) {
489 condlog(2, "%s: mark as failed", pp->dev_t);
490 pp->state = PATH_DOWN;
491 update_queue_mode_del_path(mpp);
495 * schedule the next check earlier
497 if (pp->tick > conf->checkint)
498 pp->tick = conf->checkint;
505 condlog(0, "failed to update multipath");
510 static sigset_t unblock_signals(void)
515 sigaddset(&set, SIGHUP);
516 sigaddset(&set, SIGUSR1);
517 pthread_sigmask(SIG_UNBLOCK, &set, &old);
522 * returns the reschedule delay
523 * negative means *stop*
526 waiteventloop (struct event_thread * waiter)
532 if (!waiter->event_nr)
533 waiter->event_nr = dm_geteventnr(waiter->mapname);
535 if (!(waiter->dmt = dm_task_create(DM_DEVICE_WAITEVENT))) {
536 condlog(0, "%s: devmap event #%i dm_task_create error",
537 waiter->mapname, waiter->event_nr);
541 if (!dm_task_set_name(waiter->dmt, waiter->mapname)) {
542 condlog(0, "%s: devmap event #%i dm_task_set_name error",
543 waiter->mapname, waiter->event_nr);
544 dm_task_destroy(waiter->dmt);
548 if (waiter->event_nr && !dm_task_set_event_nr(waiter->dmt,
550 condlog(0, "%s: devmap event #%i dm_task_set_event_nr error",
551 waiter->mapname, waiter->event_nr);
552 dm_task_destroy(waiter->dmt);
556 dm_task_no_open_count(waiter->dmt);
558 /* accept wait interruption */
559 set = unblock_signals();
561 /* interruption spits messages */
565 r = dm_task_run(waiter->dmt);
567 /* wait is over : event or interrupt */
568 pthread_sigmask(SIG_SETMASK, &set, NULL);
571 if (!r) /* wait interrupted by signal */
574 dm_task_destroy(waiter->dmt);
582 condlog(3, "%s: devmap event #%i",
583 waiter->mapname, waiter->event_nr);
588 * 1) a table reload, which means our mpp structure is
589 * obsolete : refresh it through update_multipath()
590 * 2) a path failed by DM : mark as such through
592 * 3) map has gone away : stop the thread.
593 * 4) a path reinstate : nothing to do
594 * 5) a switch group : nothing to do
596 pthread_cleanup_push(cleanup_lock, waiter->vecs->lock);
597 lock(waiter->vecs->lock);
598 r = update_multipath(waiter->vecs, waiter->mapname);
599 lock_cleanup_pop(waiter->vecs->lock);
602 return -1; /* stop the thread */
604 event_nr = dm_geteventnr(waiter->mapname);
606 if (waiter->event_nr == event_nr)
607 return 1; /* upon problem reschedule 1s later */
609 waiter->event_nr = event_nr;
611 return -1; /* never reach there */
615 waitevent (void * et)
618 struct event_thread *waiter;
620 mlockall(MCL_CURRENT | MCL_FUTURE);
622 waiter = (struct event_thread *)et;
623 pthread_cleanup_push(free_waiter, et);
626 r = waiteventloop(waiter);
634 pthread_cleanup_pop(1);
639 start_waiter_thread (struct multipath * mpp, struct vectors * vecs)
642 struct event_thread * wp;
647 if (pthread_attr_init(&attr))
650 pthread_attr_setstacksize(&attr, 32 * 1024);
651 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
658 mpp->waiter = (void *)wp;
659 strncpy(wp->mapname, mpp->alias, WWID_SIZE);
662 if (pthread_create(&wp->thread, &attr, waitevent, wp)) {
663 condlog(0, "%s: cannot create event checker", wp->mapname);
666 condlog(2, "%s: event checker started", wp->mapname);
673 condlog(0, "failed to start waiter thread");
677 extern struct multipath *
678 add_map_without_path (struct vectors * vecs,
679 int minor, char * alias,
680 start_waiter_thread_func *start_waiter)
682 struct multipath * mpp = alloc_multipath();
689 if (setup_multipath(vecs, mpp))
690 return NULL; /* mpp freed in setup_multipath */
692 if (adopt_paths(vecs->pathvec, mpp))
695 if (!vector_alloc_slot(vecs->mpvec))
698 vector_set_slot(vecs->mpvec, mpp);
700 if (start_waiter(mpp, vecs))
705 remove_map(mpp, vecs, NULL, 1);
710 uev_add_map (char * devname, struct vectors * vecs)
713 char dev_t[BLK_DEV_SIZE];
715 struct multipath * mpp;
717 if (sscanf(devname, "dm-%d", &minor) == 1 &&
718 !sysfs_get_dev(sysfs_path, devname, dev_t, BLK_DEV_SIZE) &&
719 sscanf(dev_t, "%d:%d", &major, &minor) == 2)
720 alias = dm_mapname(major, minor);
722 alias = STRDUP(devname);
727 if (!dm_type(alias, DEFAULT_TARGET)) {
728 condlog(4, "%s: not a multipath map", alias);
733 mpp = find_mp_by_alias(vecs->mpvec, alias);
737 * Not really an error -- we generate our own uevent
738 * if we create a multipath mapped device as a result
741 condlog(0, "%s: supurious uevent, devmap already registered",
748 * now we can register the map
750 if ((mpp = add_map_without_path(vecs, minor, alias,
751 start_waiter_thread))) {
752 condlog(3, "%s devmap %s added", devname, alias);
756 condlog(0, "%s: uev_add_map failed", alias);
761 uev_remove_map (char * devname, struct vectors * vecs)
764 struct multipath * mpp;
766 if (sscanf(devname, "dm-%d", &minor) == 1)
767 mpp = find_mp_by_minor(vecs->mpvec, minor);
769 mpp = find_mp_by_alias(vecs->mpvec, devname);
772 condlog(3, "%s: devmap not registered, can't remove",
777 condlog(2, "remove %s devmap", mpp->alias);
778 remove_map(mpp, vecs, stop_waiter_thread, 1);
784 uev_add_path (char * devname, struct vectors * vecs)
788 pp = find_path_by_dev(vecs->pathvec, devname);
791 condlog(3, "%s: already in pathvec", devname);
794 pp = store_pathinfo(vecs->pathvec, conf->hwtable,
795 devname, DI_SYSFS | DI_WWID);
798 condlog(0, "%s: failed to store path info", devname);
802 condlog(2, "%s: path checker registered", devname);
803 pp->mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
806 condlog(4, "%s: ownership set to %s",
807 pp->dev_t, pp->mpp->alias);
809 condlog(4, "%s: orphaned", pp->dev_t);
817 uev_remove_path (char * devname, struct vectors * vecs)
822 pp = find_path_by_dev(vecs->pathvec, devname);
825 condlog(3, "%s: not in pathvec", devname);
829 if (pp->mpp && pp->state == PATH_UP)
830 update_queue_mode_del_path(pp->mpp);
832 condlog(2, "remove %s path checker", devname);
833 i = find_slot(vecs->pathvec, (void *)pp);
834 vector_del_slot(vecs->pathvec, i);
841 show_paths (char ** r, int * len, struct vectors * vecs)
847 int maxlen = INITIAL_REPLY_LEN;
850 get_path_layout(vecs->pathvec);
851 reply = MALLOC(maxlen);
859 if (VECTOR_SIZE(vecs->pathvec) > 0)
860 c += snprint_path_header(c, reply + maxlen - c,
863 vector_foreach_slot(vecs->pathvec, pp, i)
864 c += snprint_path(c, reply + maxlen - c,
865 PRINT_PATH_CHECKER, pp);
867 again = ((c - reply) == (maxlen - 1));
870 reply = REALLOC(reply, maxlen *= 2);
874 *len = (int)(c - reply + 1);
879 show_maps (char ** r, int *len, struct vectors * vecs)
882 struct multipath * mpp;
885 int maxlen = INITIAL_REPLY_LEN;
888 get_map_layout(vecs->mpvec);
889 reply = MALLOC(maxlen);
896 if (VECTOR_SIZE(vecs->mpvec) > 0)
897 c += snprint_map_header(c, reply + maxlen - c,
900 vector_foreach_slot(vecs->mpvec, mpp, i)
901 c += snprint_map(c, reply + maxlen - c,
902 PRINT_MAP_FAILBACK, mpp);
904 again = ((c - reply) == (maxlen - 1));
907 reply = REALLOC(reply, maxlen *= 2);
910 *len = (int)(c - reply + 1);
915 dump_pathvec (char ** r, int * len, struct vectors * vecs)
922 *len = VECTOR_SIZE(vecs->pathvec) * sizeof(struct path);
923 reply = (char *)MALLOC(*len);
931 vector_foreach_slot (vecs->pathvec, pp, i) {
932 memcpy((void *)p, pp, sizeof(struct path));
933 p += sizeof(struct path);
936 /* return negative to hint caller not to add "ok" to the dump */
941 map_discovery (struct vectors * vecs)
944 struct multipath * mpp;
946 if (dm_get_maps(vecs->mpvec, "multipath"))
949 vector_foreach_slot (vecs->mpvec, mpp, i) {
950 if (setup_multipath(vecs, mpp))
952 if (start_waiter_thread(mpp, vecs))
960 reconfigure (struct vectors * vecs)
962 struct config * old = conf;
963 struct multipath * mpp;
969 if (load_config(DEFAULT_CONFIGFILE)) {
971 condlog(2, "reconfigure failed, continue with old config");
974 conf->verbosity = old->verbosity;
977 vector_foreach_slot (vecs->mpvec, mpp, i) {
978 mpp->mpe = find_mpe(mpp->wwid);
979 mpp->hwe = extract_hwe_from_path(mpp);
980 adopt_paths(vecs->pathvec, mpp);
981 set_no_path_retry(mpp);
983 vector_foreach_slot (vecs->pathvec, pp, i) {
988 condlog(2, "reconfigured");
993 uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
995 struct vectors * vecs;
1000 vecs = (struct vectors *)trigger_data;
1002 pthread_cleanup_push(cleanup_lock, vecs->lock);
1005 r = parse_cmd(str, reply, len, vecs);
1008 *reply = STRDUP("fail\n");
1009 *len = strlen(*reply) + 1;
1012 else if (!r && *len == 0) {
1013 *reply = STRDUP("ok\n");
1014 *len = strlen(*reply) + 1;
1017 /* else if (r < 0) leave *reply alone */
1019 lock_cleanup_pop(vecs->lock);
1024 uev_discard(char * devpath)
1029 * keep only block devices, discard partitions
1031 if (sscanf(devpath, "/block/%10s", a) != 1 ||
1032 sscanf(devpath, "/block/%10[^/]/%10s", a, b) == 2) {
1033 condlog(4, "discard event on %s", devpath);
1040 uev_trigger (struct uevent * uev, void * trigger_data)
1044 struct vectors * vecs;
1046 vecs = (struct vectors *)trigger_data;
1048 if (uev_discard(uev->devpath))
1051 basename(uev->devpath, devname);
1055 * device map add/remove event
1057 if (!strncmp(devname, "dm-", 3)) {
1058 if (!strncmp(uev->action, "add", 3)) {
1059 r = uev_add_map(devname, vecs);
1063 if (!strncmp(uev->action, "remove", 6)) {
1064 r = uev_remove_map(devname, vecs);
1072 * path add/remove event
1074 if (blacklist(conf->blist, devname))
1077 if (!strncmp(uev->action, "add", 3)) {
1078 r = uev_add_path(devname, vecs);
1081 if (!strncmp(uev->action, "remove", 6)) {
1082 r = uev_remove_path(devname, vecs);
1092 ueventloop (void * ap)
1094 if (uevent_listen(&uev_trigger, ap))
1095 fprintf(stderr, "error starting uevent listener");
1101 uxlsnrloop (void * ap)
1106 if (alloc_handlers())
1109 add_handler(LIST+PATHS, cli_list_paths);
1110 add_handler(LIST+MAPS, cli_list_maps);
1111 add_handler(ADD+PATH, cli_add_path);
1112 add_handler(DEL+PATH, cli_del_path);
1113 add_handler(ADD+MAP, cli_add_map);
1114 add_handler(DEL+MAP, cli_del_map);
1115 add_handler(SWITCH+MAP+GROUP, cli_switch_group);
1116 add_handler(DUMP+PATHVEC, cli_dump_pathvec);
1117 add_handler(RECONFIGURE, cli_reconfigure);
1118 add_handler(SUSPEND+MAP, cli_suspend);
1119 add_handler(RESUME+MAP, cli_resume);
1120 add_handler(REINSTATE+PATH, cli_reinstate);
1121 add_handler(FAIL+PATH, cli_fail);
1123 uxsock_listen(&uxsock_trigger, ap);
1129 exit_daemon (int status)
1132 fprintf(stderr, "bad exit status. see daemon.log\n");
1134 condlog(3, "unlink pidfile");
1135 unlink(DEFAULT_PIDFILE);
1138 pthread_cond_signal(&exit_cond);
1139 unlock(&exit_mutex);
1145 fail_path (struct path * pp)
1150 condlog(2, "checker failed path %s in map %s",
1151 pp->dev_t, pp->mpp->alias);
1153 dm_fail_path(pp->mpp->alias, pp->dev_t);
1154 update_queue_mode_del_path(pp->mpp);
1158 * caller must have locked the path list before calling that function
1161 reinstate_path (struct path * pp)
1166 if (dm_reinstate_path(pp->mpp->alias, pp->dev_t))
1167 condlog(0, "%s: reinstate failed", pp->dev_t);
1169 condlog(2, "%s: reinstated", pp->dev_t);
1170 update_queue_mode_add_path(pp->mpp);
1175 enable_group(struct path * pp)
1177 struct pathgroup * pgp;
1180 * if path is added through uev_add_path, pgindex can be unset.
1181 * next update_strings() will set it, upon map reload event.
1183 * we can safely return here, because upon map reload, all
1184 * PG will be enabled.
1186 if (!pp->mpp->pg || !pp->pgindex)
1189 pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
1191 if (pgp->status == PGSTATE_DISABLED) {
1192 condlog(2, "%s: enable group #%i", pp->mpp->alias, pp->pgindex);
1193 dm_enablegroup(pp->mpp->alias, pp->pgindex);
1198 mpvec_garbage_collector (struct vectors * vecs)
1200 struct multipath * mpp;
1203 vector_foreach_slot (vecs->mpvec, mpp, i) {
1204 if (mpp && mpp->alias && !dm_map_present(mpp->alias)) {
1205 condlog(2, "%s: remove dead map", mpp->alias);
1206 remove_map(mpp, vecs, stop_waiter_thread, 1);
1213 defered_failback_tick (vector mpvec)
1215 struct multipath * mpp;
1218 vector_foreach_slot (mpvec, mpp, i) {
1220 * defered failback getting sooner
1222 if (mpp->pgfailback > 0 && mpp->failback_tick > 0) {
1223 mpp->failback_tick--;
1225 if (!mpp->failback_tick && need_switch_pathgroup(mpp, 1))
1226 switch_pathgroup(mpp);
1232 retry_count_tick(vector mpvec)
1234 struct multipath *mpp;
1237 vector_foreach_slot (mpvec, mpp, i) {
1238 if (mpp->retry_tick) {
1239 condlog(4, "%s: Retrying.. No active path", mpp->alias);
1240 if(--mpp->retry_tick == 0) {
1241 dm_queue_if_no_path(mpp->alias, 0);
1242 condlog(2, "%s: Disable queueing", mpp->alias);
1249 checkerloop (void *ap)
1251 struct vectors *vecs;
1255 char checker_msg[MAX_CHECKER_MSG_SIZE];
1257 mlockall(MCL_CURRENT | MCL_FUTURE);
1259 memset(checker_msg, 0, MAX_CHECKER_MSG_SIZE);
1260 vecs = (struct vectors *)ap;
1262 condlog(2, "path checkers start up");
1265 * init the path check interval
1267 vector_foreach_slot (vecs->pathvec, pp, i) {
1268 pp->checkint = conf->checkint;
1272 pthread_cleanup_push(cleanup_lock, vecs->lock);
1276 vector_foreach_slot (vecs->pathvec, pp, i) {
1280 if (pp->tick && --pp->tick)
1281 continue; /* don't check this path yet */
1284 * provision a next check soonest,
1285 * in case we exit abnormaly from here
1287 pp->tick = conf->checkint;
1290 pathinfo(pp, conf->hwtable, DI_SYSFS);
1295 condlog(0, "%s: checkfn is void", pp->dev);
1298 newstate = pp->checkfn(pp->fd, checker_msg,
1299 &pp->checker_context);
1302 condlog(2, "%s: unusable path", pp->dev);
1303 pathinfo(pp, conf->hwtable, 0);
1307 if (newstate != pp->state) {
1308 pp->state = newstate;
1309 LOG_MSG(1, checker_msg);
1312 * upon state change, reset the checkint
1313 * to the shortest delay
1315 pp->checkint = conf->checkint;
1317 if (newstate == PATH_DOWN ||
1318 newstate == PATH_SHAKY ||
1319 update_multipath_strings(pp->mpp,
1322 * proactively fail path in the DM
1327 * cancel scheduled failback
1329 pp->mpp->failback_tick = 0;
1335 * reinstate this path
1340 * schedule [defered] failback
1342 if (pp->mpp->pgfailback > 0)
1343 pp->mpp->failback_tick =
1344 pp->mpp->pgfailback + 1;
1345 else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE &&
1346 need_switch_pathgroup(pp->mpp, 1))
1347 switch_pathgroup(pp->mpp);
1350 * if at least one path is up in a group, and
1351 * the group is disabled, re-enable it
1353 if (newstate == PATH_UP)
1356 else if (newstate == PATH_UP || newstate == PATH_GHOST) {
1357 LOG_MSG(4, checker_msg);
1359 * double the next check delay.
1360 * max at conf->max_checkint
1362 if (pp->checkint < (conf->max_checkint / 2))
1363 pp->checkint = 2 * pp->checkint;
1365 pp->checkint = conf->max_checkint;
1367 pp->tick = pp->checkint;
1368 condlog(4, "%s: delay next check %is",
1369 pp->dev_t, pp->tick);
1372 pp->state = newstate;
1375 * path prio refreshing
1377 condlog(4, "path prio refresh");
1378 pathinfo(pp, conf->hwtable, DI_PRIO);
1380 if (need_switch_pathgroup(pp->mpp, 0)) {
1381 if (pp->mpp->pgfailback > 0)
1382 pp->mpp->failback_tick =
1383 pp->mpp->pgfailback + 1;
1384 else if (pp->mpp->pgfailback ==
1385 -FAILBACK_IMMEDIATE)
1386 switch_pathgroup(pp->mpp);
1389 defered_failback_tick(vecs->mpvec);
1390 retry_count_tick(vecs->mpvec);
1395 condlog(4, "map garbage collection");
1396 mpvec_garbage_collector(vecs);
1400 lock_cleanup_pop(vecs->lock);
1406 static struct vectors *
1409 struct vectors * vecs;
1411 vecs = (struct vectors *)MALLOC(sizeof(struct vectors));
1417 (pthread_mutex_t *)MALLOC(sizeof(pthread_mutex_t));
1422 vecs->pathvec = vector_alloc();
1427 vecs->mpvec = vector_alloc();
1432 pthread_mutex_init(vecs->lock, NULL);
1437 vector_free(vecs->pathvec);
1442 condlog(0, "failed to init paths");
1447 signal_set(int signo, void (*func) (int))
1450 struct sigaction sig;
1451 struct sigaction osig;
1453 sig.sa_handler = func;
1454 sigemptyset(&sig.sa_mask);
1457 r = sigaction(signo, &sig, &osig);
1462 return (osig.sa_handler);
1468 condlog(3, "SIGHUP received");
1472 unlock(gvecs->lock);
1475 dbg_free_final(NULL);
1488 condlog(3, "SIGUSR1 received");
1494 signal_set(SIGHUP, sighup);
1495 signal_set(SIGUSR1, sigusr1);
1496 signal_set(SIGINT, sigend);
1497 signal_set(SIGTERM, sigend);
1498 signal_set(SIGKILL, sigend);
1505 static struct sched_param sched_param = {
1509 res = sched_setscheduler (0, SCHED_RR, &sched_param);
1512 condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99");
1517 set_oom_adj (int val)
1521 fp = fopen("/proc/self/oom_adj", "w");
1526 fprintf(fp, "%i", val);
1531 child (void * param)
1533 pthread_t check_thr, uevent_thr, uxlsnr_thr;
1534 pthread_attr_t attr;
1535 struct vectors * vecs;
1537 mlockall(MCL_CURRENT | MCL_FUTURE);
1542 condlog(2, "--------start up--------");
1543 condlog(2, "read " DEFAULT_CONFIGFILE);
1545 if (load_config(DEFAULT_CONFIGFILE))
1548 setlogmask(LOG_UPTO(conf->verbosity + 3));
1551 * fill the voids left in the config file
1553 if (!conf->checkint) {
1554 conf->checkint = CHECKINT;
1555 conf->max_checkint = MAX_CHECKINT;
1558 if (pidfile_create(DEFAULT_PIDFILE, getpid())) {
1567 vecs = gvecs = init_vecs();
1572 if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) {
1573 condlog(0, "can not find sysfs mount point");
1578 * fetch paths and multipaths lists
1579 * no paths and/or no multipaths are valid scenarii
1580 * vectors maintenance will be driven by events
1582 path_discovery(vecs->pathvec, conf, DI_SYSFS | DI_WWID | DI_CHECKER);
1583 map_discovery(vecs);
1588 pthread_attr_init(&attr);
1589 pthread_attr_setstacksize(&attr, 64 * 1024);
1590 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1592 pthread_create(&check_thr, &attr, checkerloop, vecs);
1593 pthread_create(&uevent_thr, &attr, ueventloop, vecs);
1594 pthread_create(&uxlsnr_thr, &attr, uxlsnrloop, vecs);
1596 pthread_cond_wait(&exit_cond, &exit_mutex);
1602 remove_maps(vecs, stop_waiter_thread);
1603 free_pathvec(vecs->pathvec, FREE_PATHS);
1605 pthread_cancel(check_thr);
1606 pthread_cancel(uevent_thr);
1607 pthread_cancel(uxlsnr_thr);
1611 free_handlers(handlers);
1616 pthread_mutex_destroy(vecs->lock);
1624 condlog(2, "--------shut down-------");
1633 dbg_free_final(NULL);
1645 if( (pid = fork()) < 0){
1646 fprintf(stderr, "Failed first fork : %s\n", strerror(errno));
1654 if ( (pid = fork()) < 0)
1655 fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
1659 in_fd = open("/dev/null", O_RDONLY);
1661 fprintf(stderr, "cannot open /dev/null for input : %s\n",
1665 out_fd = open("/dev/console", O_WRONLY);
1667 fprintf(stderr, "cannot open /dev/console for output : %s\n",
1672 close(STDIN_FILENO);
1674 close(STDOUT_FILENO);
1676 close(STDERR_FILENO);
1687 main (int argc, char *argv[])
1689 extern char *optarg;
1696 if (getuid() != 0) {
1697 fprintf(stderr, "need to be root\n");
1701 /* make sure we don't lock any path */
1703 umask(umask(077) | 022);
1705 conf = alloc_config();
1710 while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) {
1714 //debug=1; /* ### comment me out ### */
1717 if (sizeof(optarg) > sizeof(char *) ||
1718 !isdigit(optarg[0]))
1721 conf->verbosity = atoi(optarg);
1744 return (child(NULL));