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