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