]> git.proxmox.com Git - mirror_frr.git/blob - watchquagga/watchquagga.c
Merge branch 'cmaster-next' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into...
[mirror_frr.git] / watchquagga / watchquagga.c
1 /*
2 Monitor status of quagga daemons and restart if necessary.
3
4 Copyright (C) 2004 Andrew J. Schorr
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <zebra.h>
22 #include <thread.h>
23 #include <log.h>
24 #include <network.h>
25 #include <sigevent.h>
26 #include <lib/version.h>
27 #include <getopt.h>
28 #include <sys/un.h>
29 #include <sys/wait.h>
30 #include <memory.h>
31 #include <systemd.h>
32
33 #ifndef MIN
34 #define MIN(X,Y) (((X) <= (Y)) ? (X) : (Y))
35 #endif
36
37 /* Macros to help randomize timers. */
38 #define JITTER(X) ((random() % ((X)+1))-((X)/2))
39 #define FUZZY(X) ((X)+JITTER((X)/20))
40
41 #define DEFAULT_PERIOD 5
42 #define DEFAULT_TIMEOUT 10
43 #define DEFAULT_RESTART_TIMEOUT 20
44 #define DEFAULT_LOGLEVEL LOG_INFO
45 #define DEFAULT_MIN_RESTART 60
46 #define DEFAULT_MAX_RESTART 600
47 #ifdef PATH_WATCHQUAGGA_PID
48 #define DEFAULT_PIDFILE PATH_WATCHQUAGGA_PID
49 #else
50 #define DEFAULT_PIDFILE STATEDIR "/watchquagga.pid"
51 #endif
52 #ifdef DAEMON_VTY_DIR
53 #define VTYDIR DAEMON_VTY_DIR
54 #else
55 #define VTYDIR STATEDIR
56 #endif
57
58 #define PING_TOKEN "PING"
59
60 /* Needs to be global, referenced somewhere inside libzebra. */
61 struct thread_master *master;
62
63 typedef enum
64 {
65 MODE_MONITOR = 0,
66 MODE_GLOBAL_RESTART,
67 MODE_SEPARATE_RESTART,
68 MODE_PHASED_ZEBRA_RESTART,
69 MODE_PHASED_ALL_RESTART
70 } watch_mode_t;
71
72 static const char *mode_str[] =
73 {
74 "monitor",
75 "global restart",
76 "individual daemon restart",
77 "phased zebra restart",
78 "phased global restart for any failure",
79 };
80
81 typedef enum
82 {
83 PHASE_NONE = 0,
84 PHASE_STOPS_PENDING,
85 PHASE_WAITING_DOWN,
86 PHASE_ZEBRA_RESTART_PENDING,
87 PHASE_WAITING_ZEBRA_UP
88 } restart_phase_t;
89
90 static const char *phase_str[] =
91 {
92 "None",
93 "Stop jobs running",
94 "Waiting for other daemons to come down",
95 "Zebra restart job running",
96 "Waiting for zebra to come up",
97 "Start jobs running",
98 };
99
100 #define PHASE_TIMEOUT (3*gs.restart_timeout)
101
102 struct restart_info
103 {
104 const char *name;
105 const char *what;
106 pid_t pid;
107 struct timeval time;
108 long interval;
109 struct thread *t_kill;
110 int kills;
111 };
112
113 static struct global_state
114 {
115 watch_mode_t mode;
116 restart_phase_t phase;
117 struct thread *t_phase_hanging;
118 const char *vtydir;
119 long period;
120 long timeout;
121 long restart_timeout;
122 long min_restart_interval;
123 long max_restart_interval;
124 int do_ping;
125 struct daemon *daemons;
126 const char *restart_command;
127 const char *start_command;
128 const char *stop_command;
129 struct restart_info restart;
130 int unresponsive_restart;
131 int loglevel;
132 struct daemon *special; /* points to zebra when doing phased restart */
133 int numdaemons;
134 int numpids;
135 int numdown; /* # of daemons that are not UP or UNRESPONSIVE */
136 } gs = {
137 .mode = MODE_MONITOR,
138 .phase = PHASE_NONE,
139 .vtydir = VTYDIR,
140 .period = 1000*DEFAULT_PERIOD,
141 .timeout = DEFAULT_TIMEOUT,
142 .restart_timeout = DEFAULT_RESTART_TIMEOUT,
143 .loglevel = DEFAULT_LOGLEVEL,
144 .min_restart_interval = DEFAULT_MIN_RESTART,
145 .max_restart_interval = DEFAULT_MAX_RESTART,
146 .do_ping = 1,
147 };
148
149 typedef enum
150 {
151 DAEMON_INIT,
152 DAEMON_DOWN,
153 DAEMON_CONNECTING,
154 DAEMON_UP,
155 DAEMON_UNRESPONSIVE
156 } daemon_state_t;
157
158 #define IS_UP(DMN) \
159 (((DMN)->state == DAEMON_UP) || ((DMN)->state == DAEMON_UNRESPONSIVE))
160
161 static const char *state_str[] =
162 {
163 "Init",
164 "Down",
165 "Connecting",
166 "Up",
167 "Unresponsive",
168 };
169
170 struct daemon {
171 const char *name;
172 daemon_state_t state;
173 int fd;
174 struct timeval echo_sent;
175 u_int connect_tries;
176 struct thread *t_wakeup;
177 struct thread *t_read;
178 struct thread *t_write;
179 struct daemon *next;
180 struct restart_info restart;
181 };
182
183 static const struct option longopts[] =
184 {
185 { "daemon", no_argument, NULL, 'd'},
186 { "statedir", required_argument, NULL, 'S'},
187 { "no-echo", no_argument, NULL, 'e'},
188 { "loglevel", required_argument, NULL, 'l'},
189 { "interval", required_argument, NULL, 'i'},
190 { "timeout", required_argument, NULL, 't'},
191 { "restart-timeout", required_argument, NULL, 'T'},
192 { "restart", required_argument, NULL, 'r'},
193 { "start-command", required_argument, NULL, 's'},
194 { "kill-command", required_argument, NULL, 'k'},
195 { "restart-all", required_argument, NULL, 'R'},
196 { "all-restart", no_argument, NULL, 'a'},
197 { "always-all-restart", no_argument, NULL, 'A'},
198 { "unresponsive-restart", no_argument, NULL, 'z'},
199 { "min-restart-interval", required_argument, NULL, 'm'},
200 { "max-restart-interval", required_argument, NULL, 'M'},
201 { "pid-file", required_argument, NULL, 'p'},
202 { "blank-string", required_argument, NULL, 'b'},
203 { "help", no_argument, NULL, 'h'},
204 { "version", no_argument, NULL, 'v'},
205 { NULL, 0, NULL, 0 }
206 };
207
208 static int try_connect(struct daemon *dmn);
209 static int wakeup_send_echo(struct thread *t_wakeup);
210 static void try_restart(struct daemon *dmn);
211 static void phase_check(void);
212
213 static int
214 usage(const char *progname, int status)
215 {
216 if (status != 0)
217 fprintf(stderr, "Try `%s --help' for more information.\n", progname);
218 else
219 {
220 printf("Usage : %s [OPTION...] <daemon name> ...\n\n\
221 Watchdog program to monitor status of quagga daemons and try to restart\n\
222 them if they are down or unresponsive. It determines whether a daemon is\n\
223 up based on whether it can connect to the daemon's vty unix stream socket.\n\
224 It then repeatedly sends echo commands over that socket to determine whether\n\
225 the daemon is responsive. If the daemon crashes, we will receive an EOF\n\
226 on the socket connection and know immediately that the daemon is down.\n\n\
227 The daemons to be monitored should be listed on the command line.\n\n\
228 This program can run in one of 5 modes:\n\n\
229 0. Mode: %s.\n\
230 Just monitor and report on status changes. Example:\n\
231 %s -d zebra ospfd bgpd\n\n\
232 1. Mode: %s.\n\
233 Whenever any daemon hangs or crashes, use the given command to restart\n\
234 them all. Example:\n\
235 %s -dz \\\n\
236 -R '/sbin/service zebra restart; /sbin/service ospfd restart' \\\n\
237 zebra ospfd\n\n\
238 2. Mode: %s.\n\
239 When any single daemon hangs or crashes, restart only the daemon that's\n\
240 in trouble using the supplied restart command. Example:\n\
241 %s -dz -r '/sbin/service %%s restart' zebra ospfd bgpd\n\n\
242 3. Mode: %s.\n\
243 The same as the previous mode, except that there is special treatment when\n\
244 the zebra daemon is in trouble. In that case, a phased restart approach\n\
245 is used: 1. stop all other daemons; 2. restart zebra; 3. start the other\n\
246 daemons. Example:\n\
247 %s -adz -r '/sbin/service %%s restart' \\\n\
248 -s '/sbin/service %%s start' \\\n\
249 -k '/sbin/service %%s stop' zebra ospfd bgpd\n\n\
250 4. Mode: %s.\n\
251 This is the same as the previous mode, except that the phased restart\n\
252 procedure is used whenever any of the daemons hangs or crashes. Example:\n\
253 %s -Adz -r '/sbin/service %%s restart' \\\n\
254 -s '/sbin/service %%s start' \\\n\
255 -k '/sbin/service %%s stop' zebra ospfd bgpd\n\n\
256 As of this writing, it is believed that mode 2 [%s]\n\
257 is not safe, and mode 3 [%s] may not be safe with some of the\n\
258 routing daemons.\n\n\
259 In order to avoid attempting to restart the daemons in a fast loop,\n\
260 the -m and -M options allow you to control the minimum delay between\n\
261 restart commands. The minimum restart delay is recalculated each time\n\
262 a restart is attempted: if the time since the last restart attempt exceeds\n\
263 twice the -M value, then the restart delay is set to the -m value.\n\
264 Otherwise, the interval is doubled (but capped at the -M value).\n\n",
265 progname,mode_str[0],progname,mode_str[1],progname,mode_str[2],
266 progname,mode_str[3],progname,mode_str[4],progname,mode_str[2],
267 mode_str[3]);
268
269 printf("Options:\n\
270 -d, --daemon Run in daemon mode. In this mode, error messages are sent\n\
271 to syslog instead of stdout.\n\
272 -S, --statedir Set the vty socket directory (default is %s)\n\
273 -e, --no-echo Do not ping the daemons to test responsiveness (this\n\
274 option is necessary if the daemons do not support the\n\
275 echo command)\n\
276 -l, --loglevel Set the logging level (default is %d).\n\
277 The value should range from %d (LOG_EMERG) to %d (LOG_DEBUG),\n\
278 but it can be set higher than %d if extra-verbose debugging\n\
279 messages are desired.\n\
280 -m, --min-restart-interval\n\
281 Set the minimum seconds to wait between invocations of daemon\n\
282 restart commands (default is %d).\n\
283 -M, --max-restart-interval\n\
284 Set the maximum seconds to wait between invocations of daemon\n\
285 restart commands (default is %d).\n\
286 -i, --interval Set the status polling interval in seconds (default is %d)\n\
287 -t, --timeout Set the unresponsiveness timeout in seconds (default is %d)\n\
288 -T, --restart-timeout\n\
289 Set the restart (kill) timeout in seconds (default is %d).\n\
290 If any background jobs are still running after this much\n\
291 time has elapsed, they will be killed.\n\
292 -r, --restart Supply a Bourne shell command to use to restart a single\n\
293 daemon. The command string should include '%%s' where the\n\
294 name of the daemon should be substituted.\n\
295 Note that -r and -R are incompatible.\n\
296 -s, --start-command\n\
297 Supply a Bourne shell to command to use to start a single\n\
298 daemon. The command string should include '%%s' where the\n\
299 name of the daemon should be substituted.\n\
300 -k, --kill-command\n\
301 Supply a Bourne shell to command to use to stop a single\n\
302 daemon. The command string should include '%%s' where the\n\
303 name of the daemon should be substituted.\n\
304 -R, --restart-all\n\
305 When one or more daemons is down, try to restart everything\n\
306 using the Bourne shell command supplied as the argument.\n\
307 Note that -r and -R are incompatible.\n\
308 -z, --unresponsive-restart\n\
309 When a daemon is unresponsive, treat it as being down for\n\
310 restart purposes.\n\
311 -a, --all-restart\n\
312 When zebra hangs or crashes, restart all daemons using\n\
313 this phased approach: 1. stop all other daemons; 2. restart\n\
314 zebra; 3. start other daemons. Requires -r, -s, and -k.\n\
315 -A, --always-all-restart\n\
316 When any daemon (not just zebra) hangs or crashes, use the\n\
317 same phased restart mechanism described above for -a.\n\
318 Requires -r, -s, and -k.\n\
319 -p, --pid-file Set process identifier file name\n\
320 (default is %s).\n\
321 -b, --blank-string\n\
322 When the supplied argument string is found in any of the\n\
323 various shell command arguments (-r, -s, -k, or -R), replace\n\
324 it with a space. This is an ugly hack to circumvent problems\n\
325 passing command-line arguments with embedded spaces.\n\
326 -v, --version Print program version\n\
327 -h, --help Display this help and exit\n",
328 VTYDIR,DEFAULT_LOGLEVEL,LOG_EMERG,LOG_DEBUG,LOG_DEBUG,
329 DEFAULT_MIN_RESTART,DEFAULT_MAX_RESTART,
330 DEFAULT_PERIOD,DEFAULT_TIMEOUT,DEFAULT_RESTART_TIMEOUT,
331 DEFAULT_PIDFILE);
332 }
333
334 return status;
335 }
336
337 static pid_t
338 run_background(char *shell_cmd)
339 {
340 pid_t child;
341
342 switch (child = fork())
343 {
344 case -1:
345 zlog_err("fork failed, cannot run command [%s]: %s",
346 shell_cmd,safe_strerror(errno));
347 return -1;
348 case 0:
349 /* Child process. */
350 /* Use separate process group so child processes can be killed easily. */
351 if (setpgid(0,0) < 0)
352 zlog_warn("warning: setpgid(0,0) failed: %s",safe_strerror(errno));
353 {
354 char shell[] = "sh";
355 char dashc[] = "-c";
356 char * const argv[4] = { shell, dashc, shell_cmd, NULL};
357 execv("/bin/sh", argv);
358 zlog_err("execv(/bin/sh -c '%s') failed: %s",
359 shell_cmd,safe_strerror(errno));
360 _exit(127);
361 }
362 default:
363 /* Parent process: we will reap the child later. */
364 zlog_err("Forked background command [pid %d]: %s",(int)child,shell_cmd);
365 return child;
366 }
367 }
368
369 static struct timeval *
370 time_elapsed(struct timeval *result, const struct timeval *start_time)
371 {
372 gettimeofday(result,NULL);
373 result->tv_sec -= start_time->tv_sec;
374 result->tv_usec -= start_time->tv_usec;
375 while (result->tv_usec < 0)
376 {
377 result->tv_usec += 1000000L;
378 result->tv_sec--;
379 }
380 return result;
381 }
382
383 static int
384 restart_kill(struct thread *t_kill)
385 {
386 struct restart_info *restart = THREAD_ARG(t_kill);
387 struct timeval delay;
388
389 time_elapsed(&delay,&restart->time);
390 zlog_warn("Warning: %s %s child process %d still running after "
391 "%ld seconds, sending signal %d",
392 restart->what,restart->name,(int)restart->pid, (long)delay.tv_sec,
393 (restart->kills ? SIGKILL : SIGTERM));
394 kill(-restart->pid,(restart->kills ? SIGKILL : SIGTERM));
395 restart->kills++;
396 restart->t_kill = thread_add_timer(master,restart_kill,restart,
397 gs.restart_timeout);
398 return 0;
399 }
400
401 static struct restart_info *
402 find_child(pid_t child)
403 {
404 if (gs.mode == MODE_GLOBAL_RESTART)
405 {
406 if (gs.restart.pid == child)
407 return &gs.restart;
408 }
409 else
410 {
411 struct daemon *dmn;
412 for (dmn = gs.daemons; dmn; dmn = dmn->next)
413 {
414 if (dmn->restart.pid == child)
415 return &dmn->restart;
416 }
417 }
418 return NULL;
419 }
420
421 static void
422 sigchild(void)
423 {
424 pid_t child;
425 int status;
426 const char *name;
427 const char *what;
428 struct restart_info *restart;
429
430 switch (child = waitpid(-1,&status,WNOHANG))
431 {
432 case -1:
433 zlog_err("waitpid failed: %s",safe_strerror(errno));
434 return;
435 case 0:
436 zlog_warn("SIGCHLD received, but waitpid did not reap a child");
437 return;
438 }
439
440 if ((restart = find_child(child)) != NULL)
441 {
442 name = restart->name;
443 what = restart->what;
444 restart->pid = 0;
445 gs.numpids--;
446 thread_cancel(restart->t_kill);
447 restart->t_kill = NULL;
448 /* Update restart time to reflect the time the command completed. */
449 gettimeofday(&restart->time,NULL);
450 }
451 else
452 {
453 zlog_err("waitpid returned status for an unknown child process %d",
454 (int)child);
455 name = "(unknown)";
456 what = "background";
457 }
458 if (WIFSTOPPED(status))
459 zlog_warn("warning: %s %s process %d is stopped",
460 what,name,(int)child);
461 else if (WIFSIGNALED(status))
462 zlog_warn("%s %s process %d terminated due to signal %d",
463 what,name,(int)child,WTERMSIG(status));
464 else if (WIFEXITED(status))
465 {
466 if (WEXITSTATUS(status) != 0)
467 zlog_warn("%s %s process %d exited with non-zero status %d",
468 what,name,(int)child,WEXITSTATUS(status));
469 else
470 zlog_debug("%s %s process %d exited normally",what,name,(int)child);
471 }
472 else
473 zlog_err("cannot interpret %s %s process %d wait status 0x%x",
474 what,name,(int)child,status);
475 phase_check();
476 }
477
478 static int
479 run_job(struct restart_info *restart, const char *cmdtype, const char *command,
480 int force, int update_interval)
481 {
482 struct timeval delay;
483
484 if (gs.loglevel > LOG_DEBUG+1)
485 zlog_debug("attempting to %s %s",cmdtype,restart->name);
486
487 if (restart->pid)
488 {
489 if (gs.loglevel > LOG_DEBUG+1)
490 zlog_debug("cannot %s %s, previous pid %d still running",
491 cmdtype,restart->name,(int)restart->pid);
492 return -1;
493 }
494
495 /* Note: time_elapsed test must come before the force test, since we need
496 to make sure that delay is initialized for use below in updating the
497 restart interval. */
498 if ((time_elapsed(&delay,&restart->time)->tv_sec < restart->interval) &&
499 !force)
500 {
501 if (gs.loglevel > LOG_DEBUG+1)
502 zlog_debug("postponing %s %s: "
503 "elapsed time %ld < retry interval %ld",
504 cmdtype,restart->name,(long)delay.tv_sec,restart->interval);
505 return -1;
506 }
507
508 gettimeofday(&restart->time,NULL);
509 restart->kills = 0;
510 {
511 char cmd[strlen(command)+strlen(restart->name)+1];
512 snprintf(cmd,sizeof(cmd),command,restart->name);
513 if ((restart->pid = run_background(cmd)) > 0)
514 {
515 restart->t_kill = thread_add_timer(master,restart_kill,restart,
516 gs.restart_timeout);
517 restart->what = cmdtype;
518 gs.numpids++;
519 }
520 else
521 restart->pid = 0;
522 }
523
524 /* Calculate the new restart interval. */
525 if (update_interval)
526 {
527 if (delay.tv_sec > 2*gs.max_restart_interval)
528 restart->interval = gs.min_restart_interval;
529 else if ((restart->interval *= 2) > gs.max_restart_interval)
530 restart->interval = gs.max_restart_interval;
531 if (gs.loglevel > LOG_DEBUG+1)
532 zlog_debug("restart %s interval is now %ld",
533 restart->name,restart->interval);
534 }
535 return restart->pid;
536 }
537
538 #define SET_READ_HANDLER(DMN) \
539 (DMN)->t_read = thread_add_read(master,handle_read,(DMN),(DMN)->fd)
540
541 #define SET_WAKEUP_DOWN(DMN) \
542 (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_down,(DMN), \
543 FUZZY(gs.period))
544
545 #define SET_WAKEUP_UNRESPONSIVE(DMN) \
546 (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_unresponsive,(DMN), \
547 FUZZY(gs.period))
548
549 #define SET_WAKEUP_ECHO(DMN) \
550 (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_send_echo,(DMN), \
551 FUZZY(gs.period))
552
553 static int
554 wakeup_down(struct thread *t_wakeup)
555 {
556 struct daemon *dmn = THREAD_ARG(t_wakeup);
557
558 dmn->t_wakeup = NULL;
559 if (try_connect(dmn) < 0)
560 SET_WAKEUP_DOWN(dmn);
561 if ((dmn->connect_tries > 1) && (dmn->state != DAEMON_UP))
562 try_restart(dmn);
563 return 0;
564 }
565
566 static int
567 wakeup_init(struct thread *t_wakeup)
568 {
569 struct daemon *dmn = THREAD_ARG(t_wakeup);
570
571 dmn->t_wakeup = NULL;
572 if (try_connect(dmn) < 0)
573 {
574 SET_WAKEUP_DOWN(dmn);
575 zlog_err("%s state -> down : initial connection attempt failed",
576 dmn->name);
577 dmn->state = DAEMON_DOWN;
578 }
579 return 0;
580 }
581
582 static void
583 daemon_down(struct daemon *dmn, const char *why)
584 {
585 if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
586 zlog_err("%s state -> down : %s",dmn->name,why);
587 else if (gs.loglevel > LOG_DEBUG)
588 zlog_debug("%s still down : %s",dmn->name,why);
589 if (IS_UP(dmn))
590 gs.numdown++;
591 dmn->state = DAEMON_DOWN;
592 if (dmn->fd >= 0)
593 {
594 close(dmn->fd);
595 dmn->fd = -1;
596 }
597 THREAD_OFF(dmn->t_read);
598 THREAD_OFF(dmn->t_write);
599 THREAD_OFF(dmn->t_wakeup);
600 if (try_connect(dmn) < 0)
601 SET_WAKEUP_DOWN(dmn);
602 phase_check();
603 }
604
605 static int
606 handle_read(struct thread *t_read)
607 {
608 struct daemon *dmn = THREAD_ARG(t_read);
609 static const char resp[sizeof(PING_TOKEN)+4] = PING_TOKEN "\n";
610 char buf[sizeof(resp)+100];
611 ssize_t rc;
612 struct timeval delay;
613
614 dmn->t_read = NULL;
615 if ((rc = read(dmn->fd,buf,sizeof(buf))) < 0)
616 {
617 char why[100];
618
619 if (ERRNO_IO_RETRY(errno))
620 {
621 /* Pretend it never happened. */
622 SET_READ_HANDLER(dmn);
623 return 0;
624 }
625 snprintf(why,sizeof(why),"unexpected read error: %s",
626 safe_strerror(errno));
627 daemon_down(dmn,why);
628 return 0;
629 }
630 if (rc == 0)
631 {
632 daemon_down(dmn,"read returned EOF");
633 return 0;
634 }
635 if (!dmn->echo_sent.tv_sec)
636 {
637 char why[sizeof(buf)+100];
638 snprintf(why,sizeof(why),"unexpected read returns %d bytes: %.*s",
639 (int)rc,(int)rc,buf);
640 daemon_down(dmn,why);
641 return 0;
642 }
643
644 /* We are expecting an echo response: is there any chance that the
645 response would not be returned entirely in the first read? That
646 seems inconceivable... */
647 if ((rc != sizeof(resp)) || memcmp(buf,resp,sizeof(resp)))
648 {
649 char why[100+sizeof(buf)];
650 snprintf(why,sizeof(why),"read returned bad echo response of %d bytes "
651 "(expecting %u): %.*s",
652 (int)rc,(u_int)sizeof(resp),(int)rc,buf);
653 daemon_down(dmn,why);
654 return 0;
655 }
656
657 time_elapsed(&delay,&dmn->echo_sent);
658 dmn->echo_sent.tv_sec = 0;
659 if (dmn->state == DAEMON_UNRESPONSIVE)
660 {
661 if (delay.tv_sec < gs.timeout)
662 {
663 dmn->state = DAEMON_UP;
664 zlog_warn("%s state -> up : echo response received after %ld.%06ld "
665 "seconds", dmn->name,
666 (long)delay.tv_sec, (long)delay.tv_usec);
667 }
668 else
669 zlog_warn("%s: slow echo response finally received after %ld.%06ld "
670 "seconds", dmn->name,
671 (long)delay.tv_sec, (long)delay.tv_usec);
672 }
673 else if (gs.loglevel > LOG_DEBUG+1)
674 zlog_debug("%s: echo response received after %ld.%06ld seconds",
675 dmn->name, (long)delay.tv_sec, (long)delay.tv_usec);
676
677 SET_READ_HANDLER(dmn);
678 if (dmn->t_wakeup)
679 thread_cancel(dmn->t_wakeup);
680 SET_WAKEUP_ECHO(dmn);
681
682 return 0;
683 }
684
685 static void
686 daemon_up(struct daemon *dmn, const char *why)
687 {
688 dmn->state = DAEMON_UP;
689 gs.numdown--;
690 dmn->connect_tries = 0;
691 zlog_notice("%s state -> up : %s",dmn->name,why);
692 if (gs.do_ping)
693 SET_WAKEUP_ECHO(dmn);
694 phase_check();
695 }
696
697 static int
698 check_connect(struct thread *t_write)
699 {
700 struct daemon *dmn = THREAD_ARG(t_write);
701 int sockerr;
702 socklen_t reslen = sizeof(sockerr);
703
704 dmn->t_write = NULL;
705 if (getsockopt(dmn->fd,SOL_SOCKET,SO_ERROR,(char *)&sockerr,&reslen) < 0)
706 {
707 zlog_warn("%s: check_connect: getsockopt failed: %s",
708 dmn->name,safe_strerror(errno));
709 daemon_down(dmn,"getsockopt failed checking connection success");
710 return 0;
711 }
712 if ((reslen == sizeof(sockerr)) && sockerr)
713 {
714 char why[100];
715 snprintf(why,sizeof(why),
716 "getsockopt reports that connection attempt failed: %s",
717 safe_strerror(sockerr));
718 daemon_down(dmn,why);
719 return 0;
720 }
721
722 daemon_up(dmn,"delayed connect succeeded");
723 return 0;
724 }
725
726 static int
727 wakeup_connect_hanging(struct thread *t_wakeup)
728 {
729 struct daemon *dmn = THREAD_ARG(t_wakeup);
730 char why[100];
731
732 dmn->t_wakeup = NULL;
733 snprintf(why,sizeof(why),"connection attempt timed out after %ld seconds",
734 gs.timeout);
735 daemon_down(dmn,why);
736 return 0;
737 }
738
739 /* Making connection to protocol daemon. */
740 static int
741 try_connect(struct daemon *dmn)
742 {
743 int sock;
744 struct sockaddr_un addr;
745 socklen_t len;
746
747 if (gs.loglevel > LOG_DEBUG+1)
748 zlog_debug("%s: attempting to connect",dmn->name);
749 dmn->connect_tries++;
750
751 memset (&addr, 0, sizeof (struct sockaddr_un));
752 addr.sun_family = AF_UNIX;
753 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s.vty",
754 gs.vtydir,dmn->name);
755 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
756 len = addr.sun_len = SUN_LEN(&addr);
757 #else
758 len = sizeof (addr.sun_family) + strlen (addr.sun_path);
759 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
760
761 /* Quick check to see if we might succeed before we go to the trouble
762 of creating a socket. */
763 if (access(addr.sun_path, W_OK) < 0)
764 {
765 if (errno != ENOENT)
766 zlog_err("%s: access to socket %s denied: %s",
767 dmn->name,addr.sun_path,safe_strerror(errno));
768 return -1;
769 }
770
771 if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
772 {
773 zlog_err("%s(%s): cannot make socket: %s",
774 __func__,addr.sun_path, safe_strerror(errno));
775 return -1;
776 }
777
778 if (set_nonblocking(sock) < 0)
779 {
780 zlog_err("%s(%s): set_nonblocking(%d) failed",
781 __func__, addr.sun_path, sock);
782 close(sock);
783 return -1;
784 }
785
786 if (connect (sock, (struct sockaddr *) &addr, len) < 0)
787 {
788 if ((errno != EINPROGRESS) && (errno != EWOULDBLOCK))
789 {
790 if (gs.loglevel > LOG_DEBUG)
791 zlog_debug("%s(%s): connect failed: %s",
792 __func__,addr.sun_path, safe_strerror(errno));
793 close (sock);
794 return -1;
795 }
796 if (gs.loglevel > LOG_DEBUG)
797 zlog_debug("%s: connection in progress",dmn->name);
798 dmn->state = DAEMON_CONNECTING;
799 dmn->fd = sock;
800 dmn->t_write = thread_add_write(master,check_connect,dmn,dmn->fd);
801 dmn->t_wakeup = thread_add_timer(master,wakeup_connect_hanging,dmn,
802 gs.timeout);
803 SET_READ_HANDLER(dmn);
804 return 0;
805 }
806
807 dmn->fd = sock;
808 SET_READ_HANDLER(dmn);
809 daemon_up(dmn,"connect succeeded");
810 return 1;
811 }
812
813 static int
814 phase_hanging(struct thread *t_hanging)
815 {
816 gs.t_phase_hanging = NULL;
817 zlog_err("Phase [%s] hanging for %ld seconds, aborting phased restart",
818 phase_str[gs.phase],PHASE_TIMEOUT);
819 gs.phase = PHASE_NONE;
820 return 0;
821 }
822
823 static void
824 set_phase(restart_phase_t new_phase)
825 {
826 gs.phase = new_phase;
827 if (gs.t_phase_hanging)
828 thread_cancel(gs.t_phase_hanging);
829 gs.t_phase_hanging = thread_add_timer(master,phase_hanging,NULL,
830 PHASE_TIMEOUT);
831 }
832
833 static void
834 phase_check(void)
835 {
836 switch (gs.phase)
837 {
838 case PHASE_NONE:
839 break;
840 case PHASE_STOPS_PENDING:
841 if (gs.numpids)
842 break;
843 zlog_info("Phased restart: all routing daemon stop jobs have completed.");
844 set_phase(PHASE_WAITING_DOWN);
845 /*FALLTHRU*/
846 case PHASE_WAITING_DOWN:
847 if (gs.numdown+IS_UP(gs.special) < gs.numdaemons)
848 break;
849 zlog_info("Phased restart: all routing daemons now down.");
850 run_job(&gs.special->restart,"restart",gs.restart_command,1,1);
851 set_phase(PHASE_ZEBRA_RESTART_PENDING);
852 /*FALLTHRU*/
853 case PHASE_ZEBRA_RESTART_PENDING:
854 if (gs.special->restart.pid)
855 break;
856 zlog_info("Phased restart: %s restart job completed.",gs.special->name);
857 set_phase(PHASE_WAITING_ZEBRA_UP);
858 /*FALLTHRU*/
859 case PHASE_WAITING_ZEBRA_UP:
860 if (!IS_UP(gs.special))
861 break;
862 zlog_info("Phased restart: %s is now up.",gs.special->name);
863 {
864 struct daemon *dmn;
865 for (dmn = gs.daemons; dmn; dmn = dmn->next)
866 {
867 if (dmn != gs.special)
868 run_job(&dmn->restart,"start",gs.start_command,1,0);
869 }
870 }
871 gs.phase = PHASE_NONE;
872 THREAD_OFF(gs.t_phase_hanging);
873 zlog_notice("Phased global restart has completed.");
874 break;
875 }
876 }
877
878 static void
879 try_restart(struct daemon *dmn)
880 {
881 switch (gs.mode)
882 {
883 case MODE_MONITOR:
884 return;
885 case MODE_GLOBAL_RESTART:
886 run_job(&gs.restart,"restart",gs.restart_command,0,1);
887 break;
888 case MODE_SEPARATE_RESTART:
889 run_job(&dmn->restart,"restart",gs.restart_command,0,1);
890 break;
891 case MODE_PHASED_ZEBRA_RESTART:
892 if (dmn != gs.special)
893 {
894 if ((gs.special->state == DAEMON_UP) && (gs.phase == PHASE_NONE))
895 run_job(&dmn->restart,"restart",gs.restart_command,0,1);
896 else
897 zlog_debug("%s: postponing restart attempt because master %s daemon "
898 "not up [%s], or phased restart in progress",
899 dmn->name,gs.special->name,state_str[gs.special->state]);
900 break;
901 }
902 /*FALLTHRU*/
903 case MODE_PHASED_ALL_RESTART:
904 if ((gs.phase != PHASE_NONE) || gs.numpids)
905 {
906 if (gs.loglevel > LOG_DEBUG+1)
907 zlog_debug("postponing phased global restart: restart already in "
908 "progress [%s], or outstanding child processes [%d]",
909 phase_str[gs.phase],gs.numpids);
910 break;
911 }
912 /* Is it too soon for a restart? */
913 {
914 struct timeval delay;
915 if (time_elapsed(&delay,&gs.special->restart.time)->tv_sec <
916 gs.special->restart.interval)
917 {
918 if (gs.loglevel > LOG_DEBUG+1)
919 zlog_debug("postponing phased global restart: "
920 "elapsed time %ld < retry interval %ld",
921 (long)delay.tv_sec,gs.special->restart.interval);
922 break;
923 }
924 }
925 run_job(&gs.restart,"restart",gs.restart_command,0,1);
926 break;
927 default:
928 zlog_err("error: unknown restart mode %d",gs.mode);
929 break;
930 }
931 }
932
933 static int
934 wakeup_unresponsive(struct thread *t_wakeup)
935 {
936 struct daemon *dmn = THREAD_ARG(t_wakeup);
937
938 dmn->t_wakeup = NULL;
939 if (dmn->state != DAEMON_UNRESPONSIVE)
940 zlog_err("%s: no longer unresponsive (now %s), "
941 "wakeup should have been cancelled!",
942 dmn->name,state_str[dmn->state]);
943 else
944 {
945 SET_WAKEUP_UNRESPONSIVE(dmn);
946 try_restart(dmn);
947 }
948 return 0;
949 }
950
951 static int
952 wakeup_no_answer(struct thread *t_wakeup)
953 {
954 struct daemon *dmn = THREAD_ARG(t_wakeup);
955
956 dmn->t_wakeup = NULL;
957 dmn->state = DAEMON_UNRESPONSIVE;
958 zlog_err("%s state -> unresponsive : no response yet to ping "
959 "sent %ld seconds ago",dmn->name,gs.timeout);
960 if (gs.unresponsive_restart)
961 {
962 SET_WAKEUP_UNRESPONSIVE(dmn);
963 try_restart(dmn);
964 }
965 return 0;
966 }
967
968 static int
969 wakeup_send_echo(struct thread *t_wakeup)
970 {
971 static const char echocmd[] = "echo " PING_TOKEN;
972 ssize_t rc;
973 struct daemon *dmn = THREAD_ARG(t_wakeup);
974
975 dmn->t_wakeup = NULL;
976 if (((rc = write(dmn->fd,echocmd,sizeof(echocmd))) < 0) ||
977 ((size_t)rc != sizeof(echocmd)))
978 {
979 char why[100+sizeof(echocmd)];
980 snprintf(why,sizeof(why),"write '%s' returned %d instead of %u",
981 echocmd,(int)rc,(u_int)sizeof(echocmd));
982 daemon_down(dmn,why);
983 }
984 else
985 {
986 gettimeofday(&dmn->echo_sent,NULL);
987 dmn->t_wakeup = thread_add_timer(master,wakeup_no_answer,dmn,gs.timeout);
988 }
989 return 0;
990 }
991
992 static void
993 sigint(void)
994 {
995 zlog_notice("Terminating on signal");
996 systemd_send_stopping ();
997 exit(0);
998 }
999
1000 static int
1001 valid_command(const char *cmd)
1002 {
1003 char *p;
1004
1005 return ((p = strchr(cmd,'%')) != NULL) && (*(p+1) == 's') && !strchr(p+1,'%');
1006 }
1007
1008 /* This is an ugly hack to circumvent problems with passing command-line
1009 arguments that contain spaces. The fix is to use a configuration file. */
1010 static char *
1011 translate_blanks(const char *cmd, const char *blankstr)
1012 {
1013 char *res;
1014 char *p;
1015 size_t bslen = strlen(blankstr);
1016
1017 if (!(res = strdup(cmd)))
1018 {
1019 perror("strdup");
1020 exit(1);
1021 }
1022 while ((p = strstr(res,blankstr)) != NULL)
1023 {
1024 *p = ' ';
1025 if (bslen != 1)
1026 memmove(p+1,p+bslen,strlen(p+bslen)+1);
1027 }
1028 return res;
1029 }
1030
1031 int
1032 main(int argc, char **argv)
1033 {
1034 const char *progname;
1035 int opt;
1036 int daemon_mode = 0;
1037 const char *pidfile = DEFAULT_PIDFILE;
1038 const char *special = "zebra";
1039 const char *blankstr = NULL;
1040 static struct quagga_signal_t my_signals[] =
1041 {
1042 {
1043 .signal = SIGINT,
1044 .handler = sigint,
1045 },
1046 {
1047 .signal = SIGTERM,
1048 .handler = sigint,
1049 },
1050 {
1051 .signal = SIGCHLD,
1052 .handler = sigchild,
1053 },
1054 };
1055
1056 if ((progname = strrchr (argv[0], '/')) != NULL)
1057 progname++;
1058 else
1059 progname = argv[0];
1060
1061 gs.restart.name = "all";
1062 while ((opt = getopt_long(argc, argv, "aAb:dek:l:m:M:i:p:r:R:S:s:t:T:zvh",
1063 longopts, 0)) != EOF)
1064 {
1065 switch (opt)
1066 {
1067 case 0:
1068 break;
1069 case 'a':
1070 if ((gs.mode != MODE_MONITOR) && (gs.mode != MODE_SEPARATE_RESTART))
1071 {
1072 fputs("Ambiguous operating mode selected.\n",stderr);
1073 return usage(progname,1);
1074 }
1075 gs.mode = MODE_PHASED_ZEBRA_RESTART;
1076 break;
1077 case 'A':
1078 if ((gs.mode != MODE_MONITOR) && (gs.mode != MODE_SEPARATE_RESTART))
1079 {
1080 fputs("Ambiguous operating mode selected.\n",stderr);
1081 return usage(progname,1);
1082 }
1083 gs.mode = MODE_PHASED_ALL_RESTART;
1084 break;
1085 case 'b':
1086 blankstr = optarg;
1087 break;
1088 case 'd':
1089 daemon_mode = 1;
1090 break;
1091 case 'e':
1092 gs.do_ping = 0;
1093 break;
1094 case 'k':
1095 if (!valid_command(optarg))
1096 {
1097 fprintf(stderr,"Invalid kill command, must contain '%%s': %s\n",
1098 optarg);
1099 return usage(progname,1);
1100 }
1101 gs.stop_command = optarg;
1102 break;
1103 case 'l':
1104 {
1105 char garbage[3];
1106 if ((sscanf(optarg,"%d%1s",&gs.loglevel,garbage) != 1) ||
1107 (gs.loglevel < LOG_EMERG))
1108 {
1109 fprintf(stderr,"Invalid loglevel argument: %s\n",optarg);
1110 return usage(progname,1);
1111 }
1112 }
1113 break;
1114 case 'm':
1115 {
1116 char garbage[3];
1117 if ((sscanf(optarg,"%ld%1s",
1118 &gs.min_restart_interval,garbage) != 1) ||
1119 (gs.min_restart_interval < 0))
1120 {
1121 fprintf(stderr,"Invalid min_restart_interval argument: %s\n",
1122 optarg);
1123 return usage(progname,1);
1124 }
1125 }
1126 break;
1127 case 'M':
1128 {
1129 char garbage[3];
1130 if ((sscanf(optarg,"%ld%1s",
1131 &gs.max_restart_interval,garbage) != 1) ||
1132 (gs.max_restart_interval < 0))
1133 {
1134 fprintf(stderr,"Invalid max_restart_interval argument: %s\n",
1135 optarg);
1136 return usage(progname,1);
1137 }
1138 }
1139 break;
1140 case 'i':
1141 {
1142 char garbage[3];
1143 int period;
1144 if ((sscanf(optarg,"%d%1s",&period,garbage) != 1) ||
1145 (gs.period < 1))
1146 {
1147 fprintf(stderr,"Invalid interval argument: %s\n",optarg);
1148 return usage(progname,1);
1149 }
1150 gs.period = 1000*period;
1151 }
1152 break;
1153 case 'p':
1154 pidfile = optarg;
1155 break;
1156 case 'r':
1157 if ((gs.mode == MODE_GLOBAL_RESTART) ||
1158 (gs.mode == MODE_SEPARATE_RESTART))
1159 {
1160 fputs("Ambiguous operating mode selected.\n",stderr);
1161 return usage(progname,1);
1162 }
1163 if (!valid_command(optarg))
1164 {
1165 fprintf(stderr,
1166 "Invalid restart command, must contain '%%s': %s\n",
1167 optarg);
1168 return usage(progname,1);
1169 }
1170 gs.restart_command = optarg;
1171 if (gs.mode == MODE_MONITOR)
1172 gs.mode = MODE_SEPARATE_RESTART;
1173 break;
1174 case 'R':
1175 if (gs.mode != MODE_MONITOR)
1176 {
1177 fputs("Ambiguous operating mode selected.\n",stderr);
1178 return usage(progname,1);
1179 }
1180 if (strchr(optarg,'%'))
1181 {
1182 fprintf(stderr,
1183 "Invalid restart-all arg, must not contain '%%s': %s\n",
1184 optarg);
1185 return usage(progname,1);
1186 }
1187 gs.restart_command = optarg;
1188 gs.mode = MODE_GLOBAL_RESTART;
1189 break;
1190 case 's':
1191 if (!valid_command(optarg))
1192 {
1193 fprintf(stderr,"Invalid start command, must contain '%%s': %s\n",
1194 optarg);
1195 return usage(progname,1);
1196 }
1197 gs.start_command = optarg;
1198 break;
1199 case 'S':
1200 gs.vtydir = optarg;
1201 break;
1202 case 't':
1203 {
1204 char garbage[3];
1205 if ((sscanf(optarg,"%ld%1s",&gs.timeout,garbage) != 1) ||
1206 (gs.timeout < 1))
1207 {
1208 fprintf(stderr,"Invalid timeout argument: %s\n",optarg);
1209 return usage(progname,1);
1210 }
1211 }
1212 break;
1213 case 'T':
1214 {
1215 char garbage[3];
1216 if ((sscanf(optarg,"%ld%1s",&gs.restart_timeout,garbage) != 1) ||
1217 (gs.restart_timeout < 1))
1218 {
1219 fprintf(stderr,"Invalid restart timeout argument: %s\n",optarg);
1220 return usage(progname,1);
1221 }
1222 }
1223 break;
1224 case 'z':
1225 gs.unresponsive_restart = 1;
1226 break;
1227 case 'v':
1228 printf ("%s version %s\n", progname, QUAGGA_VERSION);
1229 puts("Copyright 2004 Andrew J. Schorr");
1230 return 0;
1231 case 'h':
1232 return usage(progname,0);
1233 default:
1234 fputs("Invalid option.\n",stderr);
1235 return usage(progname,1);
1236 }
1237 }
1238
1239 if (gs.unresponsive_restart && (gs.mode == MODE_MONITOR))
1240 {
1241 fputs("Option -z requires a -r or -R restart option.\n",stderr);
1242 return usage(progname,1);
1243 }
1244 switch (gs.mode)
1245 {
1246 case MODE_MONITOR:
1247 if (gs.restart_command || gs.start_command || gs.stop_command)
1248 {
1249 fprintf(stderr,"No kill/(re)start commands needed for %s mode.\n",
1250 mode_str[gs.mode]);
1251 return usage(progname,1);
1252 }
1253 break;
1254 case MODE_GLOBAL_RESTART:
1255 case MODE_SEPARATE_RESTART:
1256 if (!gs.restart_command || gs.start_command || gs.stop_command)
1257 {
1258 fprintf(stderr,"No start/kill commands needed in [%s] mode.\n",
1259 mode_str[gs.mode]);
1260 return usage(progname,1);
1261 }
1262 break;
1263 case MODE_PHASED_ZEBRA_RESTART:
1264 case MODE_PHASED_ALL_RESTART:
1265 if (!gs.restart_command || !gs.start_command || !gs.stop_command)
1266 {
1267 fprintf(stderr,
1268 "Need start, kill, and restart commands in [%s] mode.\n",
1269 mode_str[gs.mode]);
1270 return usage(progname,1);
1271 }
1272 break;
1273 }
1274
1275 if (blankstr)
1276 {
1277 if (gs.restart_command)
1278 gs.restart_command = translate_blanks(gs.restart_command,blankstr);
1279 if (gs.start_command)
1280 gs.start_command = translate_blanks(gs.start_command,blankstr);
1281 if (gs.stop_command)
1282 gs.stop_command = translate_blanks(gs.stop_command,blankstr);
1283 }
1284
1285 gs.restart.interval = gs.min_restart_interval;
1286 master = thread_master_create();
1287 systemd_send_started (master, 0);
1288 signal_init (master, array_size(my_signals), my_signals);
1289 srandom(time(NULL));
1290
1291 {
1292 int i;
1293 struct daemon *tail = NULL;
1294
1295 for (i = optind; i < argc; i++)
1296 {
1297 struct daemon *dmn;
1298
1299 if (!(dmn = (struct daemon *)calloc(1,sizeof(*dmn))))
1300 {
1301 fprintf(stderr,"calloc(1,%u) failed: %s\n",
1302 (u_int)sizeof(*dmn), safe_strerror(errno));
1303 return 1;
1304 }
1305 dmn->name = dmn->restart.name = argv[i];
1306 dmn->state = DAEMON_INIT;
1307 gs.numdaemons++;
1308 gs.numdown++;
1309 dmn->fd = -1;
1310 dmn->t_wakeup = thread_add_timer_msec(master,wakeup_init,dmn,
1311 100+(random() % 900));
1312 dmn->restart.interval = gs.min_restart_interval;
1313 if (tail)
1314 tail->next = dmn;
1315 else
1316 gs.daemons = dmn;
1317 tail = dmn;
1318
1319 if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
1320 (gs.mode == MODE_PHASED_ALL_RESTART)) &&
1321 !strcmp(dmn->name,special))
1322 gs.special = dmn;
1323 }
1324 }
1325 if (!gs.daemons)
1326 {
1327 fputs("Must specify one or more daemons to monitor.\n",stderr);
1328 return usage(progname,1);
1329 }
1330 if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
1331 (gs.mode == MODE_PHASED_ALL_RESTART)) && !gs.special)
1332 {
1333 fprintf(stderr,"In mode [%s], but cannot find master daemon %s\n",
1334 mode_str[gs.mode],special);
1335 return usage(progname,1);
1336 }
1337
1338 zlog_default = openzlog(progname, ZLOG_NONE, 0,
1339 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
1340 zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
1341 if (daemon_mode)
1342 {
1343 zlog_set_level(NULL, ZLOG_DEST_SYSLOG, MIN(gs.loglevel,LOG_DEBUG));
1344 if (daemon (0, 0) < 0)
1345 {
1346 fprintf(stderr, "Watchquagga daemon failed: %s", strerror(errno));
1347 exit (1);
1348 }
1349 }
1350 else
1351 zlog_set_level(NULL, ZLOG_DEST_STDOUT, MIN(gs.loglevel,LOG_DEBUG));
1352
1353 /* Make sure we're not already running. */
1354 pid_output (pidfile);
1355
1356 /* Announce which daemons are being monitored. */
1357 {
1358 struct daemon *dmn;
1359 size_t len = 0;
1360
1361 for (dmn = gs.daemons; dmn; dmn = dmn->next)
1362 len += strlen(dmn->name)+1;
1363
1364 {
1365 char buf[len+1];
1366 char *p = buf;
1367
1368 for (dmn = gs.daemons; dmn; dmn = dmn->next)
1369 {
1370 if (p != buf)
1371 *p++ = ' ';
1372 strcpy(p,dmn->name);
1373 p += strlen(p);
1374 }
1375 zlog_notice("%s %s watching [%s], mode [%s]",
1376 progname, QUAGGA_VERSION, buf, mode_str[gs.mode]);
1377 }
1378 }
1379
1380 {
1381 struct thread thread;
1382
1383 while (thread_fetch (master, &thread))
1384 thread_call (&thread);
1385 }
1386
1387 systemd_send_stopping ();
1388 /* Not reached. */
1389 return 0;
1390 }