]>
Commit | Line | Data |
---|---|---|
ddd82ff6 | 1 | /* lib/systemd Code |
896014f4 DL |
2 | * Copyright (C) 2016 Cumulus Networks, Inc. |
3 | * Donald Sharp | |
4 | * | |
5 | * This file is part of Quagga. | |
6 | * | |
7 | * Quagga is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * Quagga is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along | |
18 | * with this program; see the file COPYING; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | */ | |
ddd82ff6 DS |
21 | |
22 | #include <zebra.h> | |
23 | ||
24 | #include "thread.h" | |
25 | #include "systemd.h" | |
26 | ||
27 | #if defined HAVE_SYSTEMD | |
28 | #include <systemd/sd-daemon.h> | |
29 | #endif | |
30 | ||
31 | /* | |
32 | * Wrapper this silliness if we | |
33 | * don't have systemd | |
34 | */ | |
d62a17ae | 35 | void systemd_send_information(const char *info) |
ddd82ff6 DS |
36 | { |
37 | #if defined HAVE_SYSTEMD | |
d62a17ae | 38 | sd_notify(0, info); |
ddd82ff6 | 39 | #else |
d62a17ae | 40 | return; |
ddd82ff6 DS |
41 | #endif |
42 | } | |
43 | ||
44 | /* | |
45 | * A return of 0 means that we are not watchdoged | |
46 | */ | |
d62a17ae | 47 | static int systemd_get_watchdog_time(int the_process) |
ddd82ff6 DS |
48 | { |
49 | #if defined HAVE_SYSTEMD | |
d62a17ae | 50 | uint64_t usec; |
51 | char *watchdog = NULL; | |
52 | int ret; | |
53 | ||
54 | ret = sd_watchdog_enabled(0, &usec); | |
55 | ||
56 | /* | |
57 | * If return is 0 -> we don't want watchdog | |
58 | * if return is < 0, some sort of failure occurred | |
59 | */ | |
60 | if (ret < 0) | |
61 | return 0; | |
62 | ||
63 | /* | |
64 | * systemd can return that this process | |
65 | * is not the expected sender of the watchdog timer | |
66 | * If we set the_process = 0 then we expect to | |
67 | * be able to send the watchdog to systemd | |
68 | * irrelevant of the pid of this process. | |
69 | */ | |
70 | if (ret == 0 && the_process) | |
71 | return 0; | |
72 | ||
73 | if (ret == 0 && !the_process) { | |
74 | watchdog = getenv("WATCHDOG_USEC"); | |
75 | if (!watchdog) | |
76 | return 0; | |
77 | ||
78 | usec = atol(watchdog); | |
79 | } | |
80 | ||
81 | return (usec / 1000000) / 3; | |
ddd82ff6 | 82 | #else |
d62a17ae | 83 | return 0; |
ddd82ff6 DS |
84 | #endif |
85 | } | |
86 | ||
d62a17ae | 87 | void systemd_send_stopping(void) |
ddd82ff6 | 88 | { |
b3ee8bcc | 89 | systemd_send_information("STATUS="); |
d62a17ae | 90 | systemd_send_information("STOPPING=1"); |
ddd82ff6 DS |
91 | } |
92 | ||
93 | /* | |
94 | * How many seconds should we wait between watchdog sends | |
95 | */ | |
96 | int wsecs = 0; | |
97 | struct thread_master *systemd_master = NULL; | |
98 | ||
d62a17ae | 99 | static int systemd_send_watchdog(struct thread *t) |
ddd82ff6 | 100 | { |
d62a17ae | 101 | systemd_send_information("WATCHDOG=1"); |
ddd82ff6 | 102 | |
d62a17ae | 103 | thread_add_timer(systemd_master, systemd_send_watchdog, NULL, wsecs, |
104 | NULL); | |
ddd82ff6 | 105 | |
d62a17ae | 106 | return 1; |
ddd82ff6 DS |
107 | } |
108 | ||
d62a17ae | 109 | void systemd_send_started(struct thread_master *m, int the_process) |
ddd82ff6 | 110 | { |
d62a17ae | 111 | assert(m != NULL); |
ddd82ff6 | 112 | |
d62a17ae | 113 | wsecs = systemd_get_watchdog_time(the_process); |
114 | systemd_master = m; | |
ddd82ff6 | 115 | |
d62a17ae | 116 | systemd_send_information("READY=1"); |
117 | if (wsecs != 0) | |
118 | thread_add_timer(m, systemd_send_watchdog, m, wsecs, NULL); | |
ddd82ff6 | 119 | } |
b3ee8bcc DS |
120 | |
121 | void systemd_send_status(const char *status) | |
122 | { | |
123 | char buffer[1024]; | |
124 | ||
125 | snprintf(buffer, sizeof(buffer), "STATUS=%s", status); | |
126 | systemd_send_information(buffer); | |
127 | } |