[multipathd] ev_add_map should return ok for spurious events
[platform/upstream/multipath-tools.git] / multipathd / main.c
1 /*
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
6  */
7 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <libdevmapper.h>
10 #include <wait.h>
11 #include <sys/mman.h>
12 #include <sys/types.h>
13 #include <fcntl.h>
14 #include <errno.h>
15
16 /*
17  * libsysfs
18  */
19 #include <sysfs/libsysfs.h>
20 #include <sysfs/dlist.h>
21
22 /*
23  * libcheckers
24  */
25 #include <checkers.h>
26
27 /*
28  * libmultipath
29  */
30 #include <parser.h>
31 #include <vector.h>
32 #include <memory.h>
33 #include <config.h>
34 #include <util.h>
35 #include <hwtable.h>
36 #include <defaults.h>
37 #include <structs.h>
38 #include <callout.h>
39 #include <blacklist.h>
40 #include <structs_vec.h>
41 #include <dmparser.h>
42 #include <devmapper.h>
43 #include <dict.h>
44 #include <discovery.h>
45 #include <debug.h>
46 #include <propsel.h>
47 #include <uevent.h>
48 #include <switchgroup.h>
49 #include <print.h>
50 #include <configure.h>
51
52 #include "main.h"
53 #include "pidfile.h"
54 #include "uxlsnr.h"
55 #include "uxclnt.h"
56 #include "cli.h"
57 #include "cli_handlers.h"
58
59 #define FILE_NAME_SIZE 256
60 #define CMDSIZE 160
61
62 #define LOG_MSG(a,b) \
63         if (strlen(b)) condlog(a, "%s: %s", pp->dev_t, b);
64
65 #ifdef LCKDBG
66 #define lock(a) \
67         fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
68         pthread_mutex_lock(a)
69 #define unlock(a) \
70         fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
71         pthread_mutex_unlock(a)
72 #define lock_cleanup_pop(a) \
73         fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
74         pthread_cleanup_pop(1);
75 #else
76 #define lock(a) pthread_mutex_lock(a)
77 #define unlock(a) pthread_mutex_unlock(a)
78 #define lock_cleanup_pop(a) pthread_cleanup_pop(1);
79 #endif
80
81 pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
82 pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
83
84 /*
85  * structs
86  */
87 struct vectors * gvecs; /* global copy of vecs for use in sig handlers */
88
89 static struct event_thread *
90 alloc_waiter (void)
91 {
92
93         struct event_thread * wp;
94
95         wp = (struct event_thread *)MALLOC(sizeof(struct event_thread));
96
97         return wp;
98 }
99
100 static void
101 free_waiter (void * data)
102 {
103         struct event_thread * wp = (struct event_thread *)data;
104
105         /*
106          * indicate in mpp that the wp is already freed storage
107          */
108         lock(wp->vecs->lock);
109
110         if (wp->mpp)
111                 /*
112                  * be careful, mpp may already be freed -- null if so
113                  */
114                 wp->mpp->waiter = NULL;
115         else
116                 condlog(3, "free_waiter, mpp freed before wp=%p,", wp);
117
118         unlock(wp->vecs->lock);
119
120         if (wp->dmt)
121                 dm_task_destroy(wp->dmt);
122
123         FREE(wp);
124 }
125
126 static void
127 stop_waiter_thread (struct multipath * mpp, struct vectors * vecs)
128 {
129         struct event_thread * wp = (struct event_thread *)mpp->waiter;
130         
131         if (!wp) {
132                 condlog(3, "%s: no waiter thread", mpp->alias);
133                 return;
134         }
135         condlog(2, "%s: stop event checker thread", wp->mapname);
136         pthread_kill((pthread_t)wp->thread, SIGUSR1);
137 }
138
139 static void
140 cleanup_lock (void * data)
141 {
142         unlock((pthread_mutex_t *)data);
143 }
144
145 /*
146  * mpp->no_path_retry:
147  *   -2 (QUEUE) : queue_if_no_path enabled, never turned off
148  *   -1 (FAIL)  : fail_if_no_path
149  *    0 (UNDEF) : nothing
150  *   >0         : queue_if_no_path enabled, turned off after polling n times
151  */
152 static void
153 update_queue_mode_del_path(struct multipath *mpp)
154 {
155         if (--mpp->nr_active == 0 && mpp->no_path_retry > 0) {
156                 /*
157                  * Enter retry mode.
158                  * meaning of +1: retry_tick may be decremented in
159                  *                checkerloop before starting retry.
160                  */
161                 mpp->stat_queueing_timeouts++;
162                 mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1;
163                 condlog(1, "%s: Entering recovery mode: max_retries=%d",
164                         mpp->alias, mpp->no_path_retry);
165         }
166         condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
167 }
168
169 static void
170 update_queue_mode_add_path(struct multipath *mpp)
171 {
172         if (mpp->nr_active++ == 0 && mpp->no_path_retry > 0) {
173                 /* come back to normal mode from retry mode */
174                 mpp->retry_tick = 0;
175                 dm_queue_if_no_path(mpp->alias, 1);
176                 condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
177                 condlog(1, "%s: Recovered to normal mode", mpp->alias);
178         }
179         condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
180 }
181
182 static int
183 need_switch_pathgroup (struct multipath * mpp, int refresh)
184 {
185         struct pathgroup * pgp;
186         struct path * pp;
187         int i, j;
188
189         if (!mpp || mpp->pgfailback == -FAILBACK_MANUAL)
190                 return 0;
191
192         /*
193          * Refresh path priority values
194          */
195         if (refresh)
196                 vector_foreach_slot (mpp->pg, pgp, i)
197                         vector_foreach_slot (pgp->paths, pp, j)
198                                 pathinfo(pp, conf->hwtable, DI_PRIO);
199
200         mpp->bestpg = select_path_group(mpp);
201
202         if (mpp->bestpg != mpp->nextpg)
203                 return 1;
204
205         return 0;
206 }
207
208 static void
209 switch_pathgroup (struct multipath * mpp)
210 {
211         mpp->stat_switchgroup++;
212         dm_switchgroup(mpp->alias, mpp->bestpg);
213         condlog(2, "%s: switch to path group #%i",
214                  mpp->alias, mpp->bestpg);
215 }
216
217 static int
218 coalesce_maps(struct vectors *vecs, vector nmpv)
219 {
220         struct multipath * ompp;
221         vector ompv = vecs->mpvec;
222         int i, j;
223
224         vector_foreach_slot (ompv, ompp, i) {
225                 if (!find_mp_by_wwid(nmpv, ompp->wwid)) {
226                         /*
227                          * remove all current maps not allowed by the
228                          * current configuration
229                          */
230                         if (dm_flush_map(ompp->alias, DEFAULT_TARGET)) {
231                                 condlog(0, "%s: unable to flush devmap",
232                                         ompp->alias);
233                                 /*
234                                  * may be just because the device is open
235                                  */
236                                 if (!vector_alloc_slot(nmpv))
237                                         return 1;
238
239                                 vector_set_slot(nmpv, ompp);
240                                 setup_multipath(vecs, ompp);
241
242                                 if ((j = find_slot(ompv, (void *)ompp)) != -1)
243                                         vector_del_slot(ompv, j);
244
245                                 continue;
246                         }
247                         else {
248                                 dm_lib_release();
249                                 condlog(3, "%s devmap removed", ompp->alias);
250                         }
251                 }
252         }
253         return 0;
254 }
255
256 static int
257 update_multipath (struct vectors *vecs, char *mapname)
258 {
259         struct multipath *mpp;
260         struct pathgroup  *pgp;
261         struct path *pp;
262         int i, j;
263         int r = 1;
264
265         mpp = find_mp_by_alias(vecs->mpvec, mapname);
266
267         if (!mpp)
268                 goto out;
269
270         free_pgvec(mpp->pg, KEEP_PATHS);
271         mpp->pg = NULL;
272
273         if (setup_multipath(vecs, mpp))
274                 goto out; /* mpp freed in setup_multipath */
275
276         /*
277          * compare checkers states with DM states
278          */
279         vector_foreach_slot (mpp->pg, pgp, i) {
280                 vector_foreach_slot (pgp->paths, pp, j) {
281                         if (pp->dmstate != PSTATE_FAILED)
282                                 continue;
283
284                         if (pp->state != PATH_DOWN) {
285                                 int oldstate = pp->state;
286                                 condlog(2, "%s: mark as failed", pp->dev_t);
287                                 mpp->stat_path_failures++;
288                                 pp->state = PATH_DOWN;
289                                 if (oldstate == PATH_UP ||
290                                     oldstate == PATH_GHOST)
291                                         update_queue_mode_del_path(mpp);
292
293                                 /*
294                                  * if opportune,
295                                  * schedule the next check earlier
296                                  */
297                                 if (pp->tick > conf->checkint)
298                                         pp->tick = conf->checkint;
299                         }
300                 }
301         }
302         r = 0;
303 out:
304         if (r)
305                 condlog(0, "failed to update multipath");
306
307         return r;
308 }
309
310 static sigset_t unblock_signals(void)
311 {
312         sigset_t set, old;
313
314         sigemptyset(&set);
315         sigaddset(&set, SIGHUP);
316         sigaddset(&set, SIGUSR1);
317         pthread_sigmask(SIG_UNBLOCK, &set, &old);
318         return old;
319 }
320
321 /*
322  * returns the reschedule delay
323  * negative means *stop*
324  */
325 static int
326 waiteventloop (struct event_thread * waiter)
327 {
328         sigset_t set;
329         int event_nr;
330         int r;
331
332         if (!waiter->event_nr)
333                 waiter->event_nr = dm_geteventnr(waiter->mapname);
334
335         if (!(waiter->dmt = dm_task_create(DM_DEVICE_WAITEVENT))) {
336                 condlog(0, "%s: devmap event #%i dm_task_create error",
337                                 waiter->mapname, waiter->event_nr);
338                 return 1;
339         }
340
341         if (!dm_task_set_name(waiter->dmt, waiter->mapname)) {
342                 condlog(0, "%s: devmap event #%i dm_task_set_name error",
343                                 waiter->mapname, waiter->event_nr);
344                 dm_task_destroy(waiter->dmt);
345                 return 1;
346         }
347
348         if (waiter->event_nr && !dm_task_set_event_nr(waiter->dmt,
349                                                       waiter->event_nr)) {
350                 condlog(0, "%s: devmap event #%i dm_task_set_event_nr error",
351                                 waiter->mapname, waiter->event_nr);
352                 dm_task_destroy(waiter->dmt);
353                 return 1;
354         }
355
356         dm_task_no_open_count(waiter->dmt);
357         
358         /* accept wait interruption */
359         set = unblock_signals();
360
361         /* interruption spits messages */
362         dm_shut_log();
363
364         /* wait */
365         r = dm_task_run(waiter->dmt);
366
367         /* wait is over : event or interrupt */
368         pthread_sigmask(SIG_SETMASK, &set, NULL);
369         //dm_restore_log();
370
371         if (!r) /* wait interrupted by signal */
372                 return -1;
373
374         dm_task_destroy(waiter->dmt);
375         waiter->dmt = NULL;
376         waiter->event_nr++;
377
378         /*
379          * upon event ...
380          */
381         while (1) {
382                 condlog(3, "%s: devmap event #%i",
383                                 waiter->mapname, waiter->event_nr);
384
385                 /*
386                  * event might be :
387                  *
388                  * 1) a table reload, which means our mpp structure is
389                  *    obsolete : refresh it through update_multipath()
390                  * 2) a path failed by DM : mark as such through
391                  *    update_multipath()
392                  * 3) map has gone away : stop the thread.
393                  * 4) a path reinstate : nothing to do
394                  * 5) a switch group : nothing to do
395                  */
396                 pthread_cleanup_push(cleanup_lock, waiter->vecs->lock);
397                 lock(waiter->vecs->lock);
398                 r = update_multipath(waiter->vecs, waiter->mapname);
399                 lock_cleanup_pop(waiter->vecs->lock);
400
401                 if (r)
402                         return -1; /* stop the thread */
403
404                 event_nr = dm_geteventnr(waiter->mapname);
405
406                 if (waiter->event_nr == event_nr)
407                         return 1; /* upon problem reschedule 1s later */
408
409                 waiter->event_nr = event_nr;
410         }
411         return -1; /* never reach there */
412 }
413
414 static void *
415 waitevent (void * et)
416 {
417         int r;
418         struct event_thread *waiter;
419
420         mlockall(MCL_CURRENT | MCL_FUTURE);
421
422         waiter = (struct event_thread *)et;
423         pthread_cleanup_push(free_waiter, et);
424
425         while (1) {
426                 r = waiteventloop(waiter);
427
428                 if (r < 0)
429                         break;
430
431                 sleep(r);
432         }
433
434         pthread_cleanup_pop(1);
435         return NULL;
436 }
437
438 static int
439 start_waiter_thread (struct multipath * mpp, struct vectors * vecs)
440 {
441         pthread_attr_t attr;
442         struct event_thread * wp;
443
444         if (!mpp)
445                 return 0;
446
447         if (pthread_attr_init(&attr))
448                 goto out;
449
450         pthread_attr_setstacksize(&attr, 32 * 1024);
451         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
452
453         wp = alloc_waiter();
454
455         if (!wp)
456                 goto out;
457
458         mpp->waiter = (void *)wp;
459         strncpy(wp->mapname, mpp->alias, WWID_SIZE);
460         wp->vecs = vecs;
461         wp->mpp = mpp;
462
463         if (pthread_create(&wp->thread, &attr, waitevent, wp)) {
464                 condlog(0, "%s: cannot create event checker", wp->mapname);
465                 goto out1;
466         }
467         condlog(2, "%s: event checker started", wp->mapname);
468
469         return 0;
470 out1:
471         free_waiter(wp);
472         mpp->waiter = NULL;
473 out:
474         condlog(0, "failed to start waiter thread");
475         return 1;
476 }
477
478 static void
479 sync_map_state(struct multipath *mpp)
480 {
481         int i, j;
482         struct pathgroup *pgp;
483         struct path *pp;
484
485         vector_foreach_slot (mpp->pg, pgp, i){
486                 vector_foreach_slot (pgp->paths, pp, j){
487                         if (pp->state <= PATH_UNCHECKED)
488                                 continue;
489                         if ((pp->dmstate == PSTATE_FAILED ||
490                              pp->dmstate == PSTATE_UNDEF) &&
491                             (pp->state == PATH_UP || pp->state == PATH_GHOST))
492                                 dm_reinstate_path(mpp->alias, pp->dev_t);
493                         else if ((pp->dmstate == PSTATE_ACTIVE ||
494                                   pp->dmstate == PSTATE_UNDEF) &&
495                                  (pp->state == PATH_DOWN ||
496                                   pp->state == PATH_SHAKY))
497                                 dm_fail_path(mpp->alias, pp->dev_t);
498                 }
499         }
500 }
501
502 static void
503 sync_maps_state(vector mpvec)
504 {
505         int i;
506         struct multipath *mpp;
507
508         vector_foreach_slot (mpvec, mpp, i) 
509                 sync_map_state(mpp);
510 }
511
512 static int
513 flush_map(struct multipath * mpp, struct vectors * vecs)
514 {
515         /*
516          * clear references to this map before flushing so we can ignore
517          * the spurious uevent we may generate with the dm_flush_map call below
518          */
519         if (dm_flush_map(mpp->alias, DEFAULT_TARGET)) {
520                 /*
521                  * May not really be an error -- if the map was already flushed
522                  * from the device mapper by dmsetup(8) for instance.
523                  */
524                 condlog(0, "%s: can't flush", mpp->alias);
525                 return 1;
526         }
527         else {
528                 dm_lib_release();
529                 condlog(3, "%s: devmap removed", mpp->alias);
530         }
531
532         orphan_paths(vecs->pathvec, mpp);
533         remove_map(mpp, vecs, stop_waiter_thread, 1);
534
535         return 0;
536 }
537
538 static int
539 uev_add_map (char * devname, struct vectors * vecs)
540 {
541         condlog(2, "%s: add map (uevent)", devname);
542         return ev_add_map(devname, vecs);
543 }
544
545 int
546 ev_add_map (char * devname, struct vectors * vecs)
547 {
548         int major, minor;
549         char dev_t[BLK_DEV_SIZE];
550         char * alias;
551         char * refwwid;
552         struct multipath * mpp;
553         int map_present;
554         int r = 1;
555
556         if (sscanf(devname, "dm-%d", &minor) == 1 &&
557             !sysfs_get_dev(sysfs_path, devname, dev_t, BLK_DEV_SIZE) &&
558             sscanf(dev_t, "%d:%d", &major, &minor) == 2)
559                 alias = dm_mapname(major, minor);
560         else
561                 alias = STRDUP(devname);
562                 
563         if (!alias)
564                 return 1;
565         
566         map_present = dm_map_present(alias);
567
568         if (map_present && dm_type(alias, DEFAULT_TARGET) <= 0) {
569                 condlog(4, "%s: not a multipath map", alias);
570                 FREE(alias);
571                 return 0;
572         }
573
574         mpp = find_mp_by_alias(vecs->mpvec, alias);
575
576         if (mpp) {
577                 /*
578                  * Not really an error -- we generate our own uevent
579                  * if we create a multipath mapped device as a result
580                  * of uev_add_path
581                  */
582                 condlog(0, "%s: devmap already registered",
583                         devname);
584                 FREE(alias);
585                 return 0;
586         }
587
588         /*
589          * now we can register the map
590          */
591         if (map_present && (mpp = add_map_without_path(vecs, minor, alias,
592                                         start_waiter_thread))) {
593                 sync_map_state(mpp);
594                 condlog(3, "%s: devmap %s added", alias, devname);
595                 return 0;
596         }
597         refwwid = get_refwwid(devname, DEV_DEVMAP, vecs->pathvec);
598
599         if (refwwid) {
600                 r = coalesce_paths(vecs, NULL, refwwid);
601                 dm_lib_release();
602         }
603         
604         if (!r)
605                 condlog(3, "%s: devmap %s added", alias, devname);
606         else
607                 condlog(0, "%s: uev_add_map %s failed", alias, devname);
608
609         FREE(refwwid);
610         FREE(alias);
611         return r;
612 }
613
614 static int
615 uev_remove_map (char * devname, struct vectors * vecs)
616 {
617         condlog(2, "%s: remove map (uevent)", devname);
618         return ev_remove_map(devname, vecs);
619 }
620
621 int
622 ev_remove_map (char * devname, struct vectors * vecs)
623 {
624         struct multipath * mpp;
625
626         mpp = find_mp_by_str(vecs->mpvec, devname);
627
628         if (!mpp) {
629                 condlog(3, "%s: devmap not registered, can't remove",
630                         devname);
631                 return 0;
632         }
633         flush_map(mpp, vecs);
634
635         return 0;
636 }
637
638 static int
639 uev_umount_map (char * devname, struct vectors * vecs)
640 {
641         struct multipath * mpp;
642
643         condlog(2, "%s: umount map (uevent)", devname);
644
645         mpp = find_mp_by_str(vecs->mpvec, devname);
646
647         if (!mpp)
648                 return 0;
649
650         update_mpp_paths(mpp, vecs->pathvec);
651         verify_paths(mpp, vecs, NULL);
652
653         if (!VECTOR_SIZE(mpp->paths))
654                 flush_map(mpp, vecs);
655
656         return 0;
657 }
658         
659 static int
660 uev_add_path (char * devname, struct vectors * vecs)
661 {
662         condlog(2, "%s: add path (uevent)", devname);
663         return (ev_add_path(devname, vecs) != 1)? 0 : 1;
664 }
665
666
667 /*
668  * returns:
669  * 0: added
670  * 1: error
671  * 2: blacklisted
672  */
673 int
674 ev_add_path (char * devname, struct vectors * vecs)
675 {
676         struct multipath * mpp;
677         struct path * pp;
678         char empty_buff[WWID_SIZE] = {0};
679
680         pp = find_path_by_dev(vecs->pathvec, devname);
681
682         if (pp) {
683                 condlog(0, "%s: spurious uevent, path already in pathvec",
684                         devname);
685                 if (pp->mpp)
686                         return 0;
687         }
688         else {
689                 /*
690                  * get path vital state
691                  */
692                 if (!(pp = store_pathinfo(vecs->pathvec, conf->hwtable,
693                       devname, DI_ALL))) {
694                         condlog(0, "%s: failed to store path info", devname);
695                         return 1;
696                 }
697                 pp->checkint = conf->checkint;
698         }
699
700         /*
701          * need path UID to go any further
702          */
703         if (memcmp(empty_buff, pp->wwid, WWID_SIZE) == 0) {
704                 condlog(0, "%s: failed to get path uid", devname);
705                 return 1; /* leave path added to pathvec */
706         }
707         if (blacklist_path(conf, pp)){
708                 int i = find_slot(vecs->pathvec, (void *)pp);
709                 if (i != -1)
710                         vector_del_slot(vecs->pathvec, i);
711                 free_path(pp);
712                 return 2;
713         }       
714         mpp = pp->mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
715 rescan:
716         if (mpp) {
717                 if (adopt_paths(vecs->pathvec, mpp))
718                         return 1; /* leave path added to pathvec */
719
720                 verify_paths(mpp, vecs, NULL);
721                 mpp->action = ACT_RELOAD;
722         }
723         else {
724                 if ((mpp = add_map_with_path(vecs, pp, 1)))
725                         mpp->action = ACT_CREATE;
726                 else
727                         return 1; /* leave path added to pathvec */
728         }
729
730         /*
731          * push the map to the device-mapper
732          */
733         if (setup_map(mpp)) {
734                 condlog(0, "%s: failed to setup map for addition of new "
735                         "path %s", mpp->alias, devname);
736                 goto out;
737         }
738         /*
739          * reload the map for the multipath mapped device
740          */
741         if (domap(mpp) <= 0) {
742                 condlog(0, "%s: failed in domap for addition of new "
743                         "path %s", mpp->alias, devname);
744                 /*
745                  * deal with asynchronous uevents :((
746                  */
747                 if (mpp->action == ACT_RELOAD) {
748                         condlog(0, "%s: uev_add_path sleep", mpp->alias);
749                         sleep(1);
750                         update_mpp_paths(mpp, vecs->pathvec);
751                         goto rescan;
752                 }
753                 else
754                         goto out;
755         }
756         dm_lib_release();
757
758         /*
759          * update our state from kernel regardless of create or reload
760          */
761         if (setup_multipath(vecs, mpp))
762                 goto out;
763
764         sync_map_state(mpp);
765
766         if (mpp->action == ACT_CREATE &&
767             start_waiter_thread(mpp, vecs))
768                         goto out;
769
770         condlog(3, "%s path added to devmap %s", devname, mpp->alias);
771         return 0;
772
773 out:
774         remove_map(mpp, vecs, NULL, 1);
775         return 1;
776 }
777
778 static int
779 uev_remove_path (char * devname, struct vectors * vecs)
780 {
781         condlog(2, "%s: remove path (uevent)", devname);
782         return ev_remove_path(devname, vecs);
783 }
784
785 int
786 ev_remove_path (char * devname, struct vectors * vecs)
787 {
788         struct multipath * mpp;
789         struct path * pp;
790         int i;
791         int rm_path = 1;
792
793         pp = find_path_by_dev(vecs->pathvec, devname);
794
795         if (!pp) {
796                 condlog(0, "%s: spurious uevent, path not in pathvec", devname);
797                 return 1;
798         }
799
800         /*
801          * avoid referring to the map of an orphanned path
802          */
803         if ((mpp = pp->mpp)) {
804
805                 /*
806                  * remove the map IFF removing the last path
807                  */
808                 if (pathcount(mpp, PATH_WILD) > 1) {
809                         vector rpvec = vector_alloc();
810
811                         /*
812                          * transform the mp->pg vector of vectors of paths
813                          * into a mp->params string to feed the device-mapper
814                          */
815                         update_mpp_paths(mpp, vecs->pathvec);
816                         if ((i = find_slot(mpp->paths, (void *)pp)) != -1)
817                                 vector_del_slot(mpp->paths, i);
818
819                         if (VECTOR_SIZE(mpp->paths) == 0) {
820                                 char alias[WWID_SIZE];
821
822                                 /*
823                                  * flush_map will fail if the device is open
824                                  */
825                                 strncpy(alias, mpp->alias, WWID_SIZE);
826                                 if (flush_map(mpp, vecs))
827                                         rm_path = 0;
828                                 else
829                                         condlog(3, "%s: removed map after removing"
830                                                 " multiple paths", alias);
831                         }
832                         else {
833                                 if (setup_map(mpp)) {
834                                         condlog(0, "%s: failed to setup map for"
835                                                 " removal of path %s", mpp->alias, devname);
836                                         free_pathvec(rpvec, KEEP_PATHS);
837                                         goto out;
838                                 }
839                                 /*
840                                  * reload the map
841                                  */
842                                 mpp->action = ACT_RELOAD;
843                                 if (domap(mpp) <= 0) {
844                                         condlog(0, "%s: failed in domap for "
845                                                 "removal of path %s",
846                                                 mpp->alias, devname);
847                                         /*
848                                          * Delete path from pathvec so that
849                                          * update_mpp_paths wont find it later
850                                          * when/if another path is removed.
851                                          */
852                                         if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
853                                                 vector_del_slot(vecs->pathvec, i);
854                                         free_path(pp);
855                                         return 1;
856                                 }
857                                 /*
858                                  * update our state from kernel
859                                  */
860                                 if (setup_multipath(vecs, mpp)) {
861                                         free_pathvec(rpvec, KEEP_PATHS);
862                                         goto out;
863                                 }
864                                 sync_map_state(mpp);
865
866                                 condlog(3, "%s path removed from devmap %s",
867                                         devname, mpp->alias);
868                         }
869                         free_pathvec(rpvec, KEEP_PATHS);
870                 }
871                 else {
872                         char alias[WWID_SIZE];
873
874                         /*
875                          * flush_map will fail if the device is open
876                          */
877                         strncpy(alias, mpp->alias, WWID_SIZE);
878                         if (flush_map(mpp, vecs))
879                                 rm_path = 0;
880                         else
881                                 condlog(3, "%s: removed map", alias);
882                 }
883         }
884
885         if (rm_path) {
886                 if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
887                         vector_del_slot(vecs->pathvec, i);
888                 free_path(pp);
889         }
890
891         return 0;
892
893 out:
894         remove_map(mpp, vecs, stop_waiter_thread, 1);
895         return 1;
896 }
897
898 static int
899 map_discovery (struct vectors * vecs)
900 {
901         int i;
902         struct multipath * mpp;
903
904         if (dm_get_maps(vecs->mpvec, "multipath"))
905                 return 1;
906
907         vector_foreach_slot (vecs->mpvec, mpp, i)
908                 if (setup_multipath(vecs, mpp))
909                         return 1;
910
911         return 0;
912 }
913
914 int
915 uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
916 {
917         struct vectors * vecs;
918         int r;
919         
920         *reply = NULL;
921         *len = 0;
922         vecs = (struct vectors *)trigger_data;
923
924         pthread_cleanup_push(cleanup_lock, vecs->lock);
925         lock(vecs->lock);
926
927         r = parse_cmd(str, reply, len, vecs);
928
929         if (r > 0) {
930                 *reply = STRDUP("fail\n");
931                 *len = strlen(*reply) + 1;
932                 r = 1;
933         }
934         else if (!r && *len == 0) {
935                 *reply = STRDUP("ok\n");
936                 *len = strlen(*reply) + 1;
937                 r = 0;
938         }
939         /* else if (r < 0) leave *reply alone */
940
941         lock_cleanup_pop(vecs->lock);
942         return r;
943 }
944
945 static int
946 uev_discard(char * devpath)
947 {
948         char a[10], b[10];
949
950         /*
951          * keep only block devices, discard partitions
952          */
953         if (sscanf(devpath, "/block/%10s", a) != 1 ||
954             sscanf(devpath, "/block/%10[^/]/%10s", a, b) == 2) {
955                 condlog(4, "discard event on %s", devpath);
956                 return 1;
957         }
958         return 0;
959 }
960
961 int 
962 uev_trigger (struct uevent * uev, void * trigger_data)
963 {
964         int r = 0;
965         char devname[32];
966         struct vectors * vecs;
967
968         vecs = (struct vectors *)trigger_data;
969
970         if (uev_discard(uev->devpath))
971                 return 0;
972
973         basename(uev->devpath, devname);
974         lock(vecs->lock);
975
976         /*
977          * device map add/remove event
978          */
979         if (!strncmp(devname, "dm-", 3)) {
980                 if (!strncmp(uev->action, "add", 3)) {
981                         r = uev_add_map(devname, vecs);
982                         goto out;
983                 }
984                 if (!strncmp(uev->action, "remove", 6)) {
985                         r = uev_remove_map(devname, vecs);
986                         goto out;
987                 }
988                 if (!strncmp(uev->action, "umount", 6)) {
989                         r = uev_umount_map(devname, vecs);
990                         goto out;
991                 }
992                 goto out;
993         }
994         
995         /*
996          * path add/remove event
997          */
998         if (blacklist(conf->blist_devnode, devname))
999                 goto out;
1000
1001         if (!strncmp(uev->action, "add", 3)) {
1002                 r = uev_add_path(devname, vecs);
1003                 goto out;
1004         }
1005         if (!strncmp(uev->action, "remove", 6)) {
1006                 r = uev_remove_path(devname, vecs);
1007                 goto out;
1008         }
1009
1010 out:
1011         unlock(vecs->lock);
1012         return r;
1013 }
1014
1015 static void *
1016 ueventloop (void * ap)
1017 {
1018         if (uevent_listen(&uev_trigger, ap))
1019                 fprintf(stderr, "error starting uevent listener");
1020                 
1021         return NULL;
1022 }
1023
1024 static void *
1025 uxlsnrloop (void * ap)
1026 {
1027         if (load_keys())
1028                 return NULL;
1029         
1030         if (alloc_handlers())
1031                 return NULL;
1032
1033         add_handler(LIST+PATHS, cli_list_paths);
1034         add_handler(LIST+MAPS, cli_list_maps);
1035         add_handler(LIST+MAPS+STATUS, cli_list_maps_status);
1036         add_handler(LIST+MAPS+STATS, cli_list_maps_stats);
1037         add_handler(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
1038         add_handler(LIST+TOPOLOGY, cli_list_maps_topology);
1039         add_handler(LIST+MAP+TOPOLOGY, cli_list_map_topology);
1040         add_handler(LIST+CONFIG, cli_list_config);
1041         add_handler(ADD+PATH, cli_add_path);
1042         add_handler(DEL+PATH, cli_del_path);
1043         add_handler(ADD+MAP, cli_add_map);
1044         add_handler(DEL+MAP, cli_del_map);
1045         add_handler(SWITCH+MAP+GROUP, cli_switch_group);
1046         add_handler(RECONFIGURE, cli_reconfigure);
1047         add_handler(SUSPEND+MAP, cli_suspend);
1048         add_handler(RESUME+MAP, cli_resume);
1049         add_handler(REINSTATE+PATH, cli_reinstate);
1050         add_handler(FAIL+PATH, cli_fail);
1051
1052         uxsock_listen(&uxsock_trigger, ap);
1053
1054         return NULL;
1055 }
1056
1057 static int
1058 exit_daemon (int status)
1059 {
1060         if (status != 0)
1061                 fprintf(stderr, "bad exit status. see daemon.log\n");
1062
1063         condlog(3, "unlink pidfile");
1064         unlink(DEFAULT_PIDFILE);
1065
1066         lock(&exit_mutex);
1067         pthread_cond_signal(&exit_cond);
1068         unlock(&exit_mutex);
1069
1070         return status;
1071 }
1072
1073 static void
1074 fail_path (struct path * pp, int del_active)
1075 {
1076         if (!pp->mpp)
1077                 return;
1078
1079         condlog(2, "checker failed path %s in map %s",
1080                  pp->dev_t, pp->mpp->alias);
1081
1082         dm_fail_path(pp->mpp->alias, pp->dev_t);
1083         if (del_active)
1084                 update_queue_mode_del_path(pp->mpp);
1085 }
1086
1087 /*
1088  * caller must have locked the path list before calling that function
1089  */
1090 static void
1091 reinstate_path (struct path * pp, int add_active)
1092 {
1093         if (!pp->mpp)
1094                 return;
1095
1096         if (dm_reinstate_path(pp->mpp->alias, pp->dev_t))
1097                 condlog(0, "%s: reinstate failed", pp->dev_t);
1098         else {
1099                 condlog(2, "%s: reinstated", pp->dev_t);
1100                 if (add_active)
1101                         update_queue_mode_add_path(pp->mpp);
1102         }
1103 }
1104
1105 static void
1106 enable_group(struct path * pp)
1107 {
1108         struct pathgroup * pgp;
1109
1110         /*
1111          * if path is added through uev_add_path, pgindex can be unset.
1112          * next update_strings() will set it, upon map reload event.
1113          *
1114          * we can safely return here, because upon map reload, all
1115          * PG will be enabled.
1116          */
1117         if (!pp->mpp->pg || !pp->pgindex)
1118                 return;
1119
1120         pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
1121         
1122         if (pgp->status == PGSTATE_DISABLED) {
1123                 condlog(2, "%s: enable group #%i", pp->mpp->alias, pp->pgindex);
1124                 dm_enablegroup(pp->mpp->alias, pp->pgindex);
1125         }
1126 }
1127
1128 static void
1129 mpvec_garbage_collector (struct vectors * vecs)
1130 {
1131         struct multipath * mpp;
1132         int i;
1133
1134         vector_foreach_slot (vecs->mpvec, mpp, i) {
1135                 if (mpp && mpp->alias && !dm_map_present(mpp->alias)) {
1136                         condlog(2, "%s: remove dead map", mpp->alias);
1137                         remove_map(mpp, vecs, stop_waiter_thread, 1);
1138                         i--;
1139                 }
1140         }
1141 }
1142
1143 static void
1144 defered_failback_tick (vector mpvec)
1145 {
1146         struct multipath * mpp;
1147         int i;
1148
1149         vector_foreach_slot (mpvec, mpp, i) {
1150                 /*
1151                  * defered failback getting sooner
1152                  */
1153                 if (mpp->pgfailback > 0 && mpp->failback_tick > 0) {
1154                         mpp->failback_tick--;
1155
1156                         if (!mpp->failback_tick && need_switch_pathgroup(mpp, 1))
1157                                 switch_pathgroup(mpp);
1158                 }
1159         }
1160 }
1161
1162 static void
1163 retry_count_tick(vector mpvec)
1164 {
1165         struct multipath *mpp;
1166         int i;
1167
1168         vector_foreach_slot (mpvec, mpp, i) {
1169                 if (mpp->retry_tick) {
1170                         mpp->stat_total_queueing_time++;
1171                         condlog(4, "%s: Retrying.. No active path", mpp->alias);
1172                         if(--mpp->retry_tick == 0) {
1173                                 dm_queue_if_no_path(mpp->alias, 0);
1174                                 condlog(2, "%s: Disable queueing", mpp->alias);
1175                         }
1176                 }
1177         }
1178 }
1179
1180 static void *
1181 checkerloop (void *ap)
1182 {
1183         struct vectors *vecs;
1184         struct path *pp;
1185         int i, count = 0;
1186         int newstate;
1187
1188         mlockall(MCL_CURRENT | MCL_FUTURE);
1189         vecs = (struct vectors *)ap;
1190         condlog(2, "path checkers start up");
1191
1192         /*
1193          * init the path check interval
1194          */
1195         vector_foreach_slot (vecs->pathvec, pp, i) {
1196                 pp->checkint = conf->checkint;
1197         }
1198
1199         while (1) {
1200                 pthread_cleanup_push(cleanup_lock, vecs->lock);
1201                 lock(vecs->lock);
1202                 condlog(4, "tick");
1203
1204                 vector_foreach_slot (vecs->pathvec, pp, i) {
1205                         if (!pp->mpp)
1206                                 continue;
1207
1208                         if (pp->tick && --pp->tick)
1209                                 continue; /* don't check this path yet */
1210
1211                         /*
1212                          * provision a next check soonest,
1213                          * in case we exit abnormaly from here
1214                          */
1215                         pp->tick = conf->checkint;
1216                         
1217                         if (!checker_selected(&pp->checker)) {
1218                                 pathinfo(pp, conf->hwtable, DI_SYSFS);
1219                                 select_checker(pp);
1220                         }
1221
1222                         if (!checker_selected(&pp->checker)) {
1223                                 condlog(0, "%s: checker is not set", pp->dev);
1224                                 continue;
1225                         }
1226                         newstate = checker_check(&pp->checker);
1227                         
1228                         if (newstate < 0) {
1229                                 condlog(2, "%s: unusable path", pp->dev);
1230                                 pathinfo(pp, conf->hwtable, 0);
1231                                 continue;
1232                         }
1233
1234                         if (newstate != pp->state) {
1235                                 int oldstate = pp->state;
1236                                 pp->state = newstate;
1237                                 LOG_MSG(1, checker_message(&pp->checker));
1238
1239                                 /*
1240                                  * upon state change, reset the checkint
1241                                  * to the shortest delay
1242                                  */
1243                                 pp->checkint = conf->checkint;
1244
1245                                 if (newstate == PATH_DOWN ||
1246                                     newstate == PATH_SHAKY ||
1247                                     update_multipath_strings(pp->mpp,
1248                                                              vecs->pathvec)) {
1249                                         /*
1250                                          * proactively fail path in the DM
1251                                          */
1252                                         if (oldstate == PATH_UP ||
1253                                             oldstate == PATH_GHOST)
1254                                                 fail_path(pp, 1);
1255                                         else
1256                                                 fail_path(pp, 0);
1257
1258                                         /*
1259                                          * cancel scheduled failback
1260                                          */
1261                                         pp->mpp->failback_tick = 0;
1262
1263                                         pp->mpp->stat_path_failures++;
1264                                         continue;
1265                                 }
1266
1267                                 /*
1268                                  * reinstate this path
1269                                  */
1270                                 if (oldstate != PATH_UP &&
1271                                     oldstate != PATH_GHOST)
1272                                         reinstate_path(pp, 1);
1273                                 else
1274                                         reinstate_path(pp, 0);
1275
1276                                 /*
1277                                  * schedule [defered] failback
1278                                  */
1279                                 if (pp->mpp->pgfailback > 0)
1280                                         pp->mpp->failback_tick =
1281                                                 pp->mpp->pgfailback + 1;
1282                                 else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE &&
1283                                     need_switch_pathgroup(pp->mpp, 1))
1284                                         switch_pathgroup(pp->mpp);
1285
1286                                 /*
1287                                  * if at least one path is up in a group, and
1288                                  * the group is disabled, re-enable it
1289                                  */
1290                                 if (newstate == PATH_UP)
1291                                         enable_group(pp);
1292                         }
1293                         else if (newstate == PATH_UP || newstate == PATH_GHOST) {
1294                                 LOG_MSG(4, checker_message(&pp->checker));
1295                                 /*
1296                                  * double the next check delay.
1297                                  * max at conf->max_checkint
1298                                  */
1299                                 if (pp->checkint < (conf->max_checkint / 2))
1300                                         pp->checkint = 2 * pp->checkint;
1301                                 else
1302                                         pp->checkint = conf->max_checkint;
1303
1304                                 pp->tick = pp->checkint;
1305                                 condlog(4, "%s: delay next check %is",
1306                                                 pp->dev_t, pp->tick);
1307
1308                         }
1309                         pp->state = newstate;
1310
1311                         /*
1312                          * path prio refreshing
1313                          */
1314                         condlog(4, "path prio refresh");
1315                         pathinfo(pp, conf->hwtable, DI_PRIO);
1316
1317                         if (need_switch_pathgroup(pp->mpp, 0)) {
1318                                 if (pp->mpp->pgfailback > 0 &&
1319                                     pp->mpp->failback_tick <= 0)
1320                                         pp->mpp->failback_tick =
1321                                                 pp->mpp->pgfailback + 1;
1322                                 else if (pp->mpp->pgfailback ==
1323                                                 -FAILBACK_IMMEDIATE)
1324                                         switch_pathgroup(pp->mpp);
1325                         }
1326                 }
1327                 defered_failback_tick(vecs->mpvec);
1328                 retry_count_tick(vecs->mpvec);
1329
1330                 if (count)
1331                         count--;
1332                 else {
1333                         condlog(4, "map garbage collection");
1334                         mpvec_garbage_collector(vecs);
1335                         count = MAPGCINT;
1336                 }
1337                 
1338                 lock_cleanup_pop(vecs->lock);
1339                 sleep(1);
1340         }
1341         return NULL;
1342 }
1343
1344 int
1345 configure (struct vectors * vecs, int start_waiters)
1346 {
1347         struct multipath * mpp;
1348         struct path * pp;
1349         vector mpvec;
1350         int i;
1351
1352         if (!(vecs->pathvec = vector_alloc()))
1353                 return 1;
1354         
1355         if (!(vecs->mpvec = vector_alloc()))
1356                 return 1;
1357         
1358         if (!(mpvec = vector_alloc()))
1359                 return 1;
1360
1361         /*
1362          * probe for current path (from sysfs) and map (from dm) sets
1363          */
1364         path_discovery(vecs->pathvec, conf, DI_ALL);
1365
1366         vector_foreach_slot (vecs->pathvec, pp, i){
1367                 if (blacklist_path(conf, pp)){
1368                         vector_del_slot(vecs->pathvec, i);
1369                         free_path(pp);
1370                         i--;
1371                 }       
1372                 else
1373                         pp->checkint = conf->checkint;
1374         }
1375         if (map_discovery(vecs))
1376                 return 1;
1377
1378         /*
1379          * create new set of maps & push changed ones into dm
1380          */
1381         if (coalesce_paths(vecs, mpvec, NULL))
1382                 return 1;
1383
1384         /*
1385          * may need to remove some maps which are no longer relevant
1386          * e.g., due to blacklist changes in conf file
1387          */
1388         if (coalesce_maps(vecs, mpvec))
1389                 return 1;
1390
1391         dm_lib_release();
1392
1393         sync_maps_state(mpvec);
1394
1395         if (conf->verbosity > 2)
1396                 vector_foreach_slot(mpvec, mpp, i)
1397                         print_map(mpp);
1398
1399         /*
1400          * purge dm of old maps
1401          */
1402         remove_maps(vecs, NULL);
1403
1404         /*
1405          * save new set of maps formed by considering current path state
1406          */
1407         vecs->mpvec = mpvec;
1408
1409         /*
1410          * start dm event waiter threads for these new maps
1411          */
1412         vector_foreach_slot(vecs->mpvec, mpp, i) {
1413                 if (setup_multipath(vecs, mpp))
1414                         return 1;
1415                 if (start_waiters)
1416                         if (start_waiter_thread(mpp, vecs))
1417                                 return 1;
1418         }
1419         return 0;
1420 }
1421
1422 int
1423 reconfigure (struct vectors * vecs)
1424 {
1425         struct config * old = conf;
1426
1427         /*
1428          * free old map and path vectors ... they use old conf state
1429          */
1430         if (VECTOR_SIZE(vecs->mpvec))
1431                 remove_maps(vecs, stop_waiter_thread);
1432
1433         if (VECTOR_SIZE(vecs->pathvec))
1434                 free_pathvec(vecs->pathvec, FREE_PATHS);
1435
1436         conf = NULL;
1437
1438         if (load_config(DEFAULT_CONFIGFILE))
1439                 return 1;
1440
1441         conf->verbosity = old->verbosity;
1442
1443         if (!conf->checkint) {
1444                 conf->checkint = DEFAULT_CHECKINT;
1445                 conf->max_checkint = MAX_CHECKINT(conf->checkint);
1446         }
1447         configure(vecs, 1);
1448         free_config(old);
1449         return 0;
1450 }
1451
1452 static struct vectors *
1453 init_vecs (void)
1454 {
1455         struct vectors * vecs;
1456
1457         vecs = (struct vectors *)MALLOC(sizeof(struct vectors));
1458
1459         if (!vecs)
1460                 return NULL;
1461
1462         vecs->lock = 
1463                 (pthread_mutex_t *)MALLOC(sizeof(pthread_mutex_t));
1464
1465         if (!vecs->lock)
1466                 goto out;
1467
1468         vecs->pathvec = vector_alloc();
1469
1470         if (!vecs->pathvec)
1471                 goto out1;
1472                 
1473         vecs->mpvec = vector_alloc();
1474
1475         if (!vecs->mpvec)
1476                 goto out2;
1477         
1478         pthread_mutex_init(vecs->lock, NULL);
1479
1480         return vecs;
1481
1482 out2:
1483         vector_free(vecs->pathvec);
1484 out1:
1485         FREE(vecs->lock);
1486 out:
1487         FREE(vecs);
1488         condlog(0, "failed to init paths");
1489         return NULL;
1490 }
1491
1492 static void *
1493 signal_set(int signo, void (*func) (int))
1494 {
1495         int r;
1496         struct sigaction sig;
1497         struct sigaction osig;
1498
1499         sig.sa_handler = func;
1500         sigemptyset(&sig.sa_mask);
1501         sig.sa_flags = 0;
1502
1503         r = sigaction(signo, &sig, &osig);
1504
1505         if (r < 0)
1506                 return (SIG_ERR);
1507         else
1508                 return (osig.sa_handler);
1509 }
1510
1511 static void
1512 sighup (int sig)
1513 {
1514         condlog(2, "reconfigure (SIGHUP)");
1515
1516         lock(gvecs->lock);
1517         reconfigure(gvecs);
1518         unlock(gvecs->lock);
1519
1520 #ifdef _DEBUG_
1521         dbg_free_final(NULL);
1522 #endif
1523 }
1524
1525 static void
1526 sigend (int sig)
1527 {
1528         exit_daemon(0);
1529 }
1530
1531 static void
1532 sigusr1 (int sig)
1533 {
1534         condlog(3, "SIGUSR1 received");
1535 }
1536
1537 static void
1538 signal_init(void)
1539 {
1540         signal_set(SIGHUP, sighup);
1541         signal_set(SIGUSR1, sigusr1);
1542         signal_set(SIGINT, sigend);
1543         signal_set(SIGTERM, sigend);
1544         signal_set(SIGKILL, sigend);
1545 }
1546
1547 static void
1548 setscheduler (void)
1549 {
1550         int res;
1551         static struct sched_param sched_param = {
1552                 sched_priority: 99
1553         };
1554
1555         res = sched_setscheduler (0, SCHED_RR, &sched_param);
1556
1557         if (res == -1)
1558                 condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99");
1559         return;
1560 }
1561
1562 static void
1563 set_oom_adj (int val)
1564 {
1565         FILE *fp;
1566
1567         fp = fopen("/proc/self/oom_adj", "w");
1568
1569         if (!fp)
1570                 return;
1571
1572         fprintf(fp, "%i", val);
1573         fclose(fp);
1574 }
1575         
1576 static int
1577 child (void * param)
1578 {
1579         pthread_t check_thr, uevent_thr, uxlsnr_thr;
1580         pthread_attr_t attr;
1581         struct vectors * vecs;
1582
1583         mlockall(MCL_CURRENT | MCL_FUTURE);
1584
1585         if (logsink)
1586                 log_thread_start();
1587
1588         condlog(2, "--------start up--------");
1589         condlog(2, "read " DEFAULT_CONFIGFILE);
1590
1591         if (load_config(DEFAULT_CONFIGFILE))
1592                 exit(1);
1593
1594         setlogmask(LOG_UPTO(conf->verbosity + 3));
1595
1596         /*
1597          * fill the voids left in the config file
1598          */
1599         if (!conf->checkint) {
1600                 conf->checkint = DEFAULT_CHECKINT;
1601                 conf->max_checkint = MAX_CHECKINT(conf->checkint);
1602         }
1603
1604         if (pidfile_create(DEFAULT_PIDFILE, getpid())) {
1605                 if (logsink)
1606                         log_thread_stop();
1607
1608                 exit(1);
1609         }
1610         signal_init();
1611         setscheduler();
1612         set_oom_adj(-16);
1613         vecs = gvecs = init_vecs();
1614
1615         if (!vecs)
1616                 exit(1);
1617
1618         if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) {
1619                 condlog(0, "can not find sysfs mount point");
1620                 exit(1);
1621         }
1622
1623         /*
1624          * fetch and configure both paths and multipaths
1625          */
1626         if (configure(vecs, 1)) {
1627                 condlog(0, "failure during configuration");
1628                 exit(1);
1629         }
1630
1631         /*
1632          * start threads
1633          */
1634         pthread_attr_init(&attr);
1635         pthread_attr_setstacksize(&attr, 64 * 1024);
1636         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1637         
1638         pthread_create(&check_thr, &attr, checkerloop, vecs);
1639         pthread_create(&uevent_thr, &attr, ueventloop, vecs);
1640         pthread_create(&uxlsnr_thr, &attr, uxlsnrloop, vecs);
1641
1642         pthread_cond_wait(&exit_cond, &exit_mutex);
1643
1644         /*
1645          * exit path
1646          */
1647         lock(vecs->lock);
1648         remove_maps(vecs, stop_waiter_thread);
1649         free_pathvec(vecs->pathvec, FREE_PATHS);
1650
1651         pthread_cancel(check_thr);
1652         pthread_cancel(uevent_thr);
1653         pthread_cancel(uxlsnr_thr);
1654
1655         free_keys(keys);
1656         keys = NULL;
1657         free_handlers(handlers);
1658         handlers = NULL;
1659         free_polls();
1660
1661         unlock(vecs->lock);
1662         pthread_mutex_destroy(vecs->lock);
1663         FREE(vecs->lock);
1664         vecs->lock = NULL;
1665         FREE(vecs);
1666         vecs = NULL;
1667         free_config(conf);
1668         conf = NULL;
1669
1670         condlog(2, "--------shut down-------");
1671         
1672         if (logsink)
1673                 log_thread_stop();
1674
1675         dm_lib_release();
1676         dm_lib_exit();
1677
1678 #ifdef _DEBUG_
1679         dbg_free_final(NULL);
1680 #endif
1681
1682         exit(0);
1683 }
1684
1685 static int
1686 daemonize(void)
1687 {
1688         int pid;
1689         int in_fd, out_fd;
1690
1691         if( (pid = fork()) < 0){
1692                 fprintf(stderr, "Failed first fork : %s\n", strerror(errno));
1693                 return -1;
1694         }
1695         else if (pid != 0)
1696                 return pid;
1697
1698         setsid();
1699
1700         if ( (pid = fork()) < 0)
1701                 fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
1702         else if (pid != 0)
1703                 _exit(0);
1704
1705         in_fd = open("/dev/null", O_RDONLY);
1706         if (in_fd < 0){
1707                 fprintf(stderr, "cannot open /dev/null for input : %s\n",
1708                         strerror(errno));
1709                 _exit(0);
1710         }
1711         out_fd = open("/dev/console", O_WRONLY);
1712         if (out_fd < 0){
1713                 fprintf(stderr, "cannot open /dev/console for output : %s\n",
1714                         strerror(errno));
1715                 _exit(0);
1716         }
1717
1718         close(STDIN_FILENO);
1719         dup(in_fd);
1720         close(STDOUT_FILENO);
1721         dup(out_fd);
1722         close(STDERR_FILENO);
1723         dup(out_fd);
1724
1725         close(in_fd);
1726         close(out_fd);
1727         chdir("/");
1728         umask(0);
1729         return 0;
1730 }
1731
1732 int
1733 main (int argc, char *argv[])
1734 {
1735         extern char *optarg;
1736         extern int optind;
1737         int arg;
1738         int err;
1739         
1740         logsink = 1;
1741
1742         if (getuid() != 0) {
1743                 fprintf(stderr, "need to be root\n");
1744                 exit(1);
1745         }
1746
1747         /* make sure we don't lock any path */
1748         chdir("/");
1749         umask(umask(077) | 022);
1750
1751         conf = alloc_config();
1752
1753         if (!conf)
1754                 exit(1);
1755
1756         while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) {
1757         switch(arg) {
1758                 case 'd':
1759                         logsink = 0;
1760                         //debug=1; /* ### comment me out ### */
1761                         break;
1762                 case 'v':
1763                         if (sizeof(optarg) > sizeof(char *) ||
1764                             !isdigit(optarg[0]))
1765                                 exit(1);
1766
1767                         conf->verbosity = atoi(optarg);
1768                         break;
1769                 case 'k':
1770                         uxclnt(optarg);
1771                         exit(0);
1772                 default:
1773                         ;
1774                 }
1775         }
1776
1777         if (!logsink)
1778                 err = 0;
1779         else
1780                 err = daemonize();
1781         
1782         if (err < 0)
1783                 /* error */
1784                 exit(1);
1785         else if (err > 0)
1786                 /* parent dies */
1787                 exit(0);
1788         else
1789                 /* child lives */
1790                 return (child(NULL));
1791 }
1792