diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com_start.c | 10 | ||||
-rw-r--r-- | src/genrc.8 | 58 | ||||
-rw-r--r-- | src/genrc.c | 41 | ||||
-rw-r--r-- | src/genrc.h | 10 | ||||
-rw-r--r-- | src/sentinel.c | 190 |
5 files changed, 291 insertions, 18 deletions
diff --git a/src/com_start.c b/src/com_start.c index 5744e39..3a9dffc 100644 --- a/src/com_start.c +++ b/src/com_start.c | |||
@@ -34,27 +34,31 @@ report_exec_error(int rc, char const *program) | |||
34 | typedef void (*SIGHANDLER)(int); | 34 | typedef void (*SIGHANDLER)(int); |
35 | 35 | ||
36 | void | 36 | void |
37 | sigchld(int sig) | 37 | sigchld(int sig) |
38 | { | 38 | { |
39 | } | 39 | } |
40 | 40 | ||
41 | int | 41 | int |
42 | timedwaitpid(pid_t pid, int *status) | 42 | timedwaitpid(pid_t pid, int *status) |
43 | { | 43 | { |
44 | struct timeval now, stoptime, ttw; | 44 | struct timeval now, stoptime, ttw; |
45 | int rc = -1; | 45 | int rc = -1; |
46 | SIGHANDLER oldsig; | 46 | struct sigaction act, oldact; |
47 | |||
48 | act.sa_handler = sigchld; | ||
49 | act.sa_flags = 0; | ||
50 | sigemptyset(&act.sa_mask); | ||
51 | sigaction(SIGCHLD, &act, &oldact); | ||
47 | 52 | ||
48 | oldsig = signal(SIGCHLD, sigchld); | ||
49 | gettimeofday(&stoptime, NULL); | 53 | gettimeofday(&stoptime, NULL); |
50 | stoptime.tv_sec += genrc_timeout; | 54 | stoptime.tv_sec += genrc_timeout; |
51 | while (1) { | 55 | while (1) { |
52 | pid_t p; | 56 | pid_t p; |
53 | 57 | ||
54 | p = waitpid(pid, status, WNOHANG); | 58 | p = waitpid(pid, status, WNOHANG); |
55 | if (p == pid) { | 59 | if (p == pid) { |
56 | rc = 0; | 60 | rc = 0; |
57 | break; | 61 | break; |
58 | } | 62 | } |
59 | if (p < 0 && errno != EINTR) { | 63 | if (p < 0 && errno != EINTR) { |
60 | system_error(errno, "waitpid"); | 64 | system_error(errno, "waitpid"); |
@@ -64,25 +68,25 @@ timedwaitpid(pid_t pid, int *status) | |||
64 | gettimeofday(&now, NULL); | 68 | gettimeofday(&now, NULL); |
65 | if (timercmp(&now, &stoptime, >=)) | 69 | if (timercmp(&now, &stoptime, >=)) |
66 | break; | 70 | break; |
67 | timersub(&stoptime, &now, &ttw); | 71 | timersub(&stoptime, &now, &ttw); |
68 | if (select(0, NULL, NULL, NULL, &ttw) < 0) { | 72 | if (select(0, NULL, NULL, NULL, &ttw) < 0) { |
69 | if (errno != EINTR) { | 73 | if (errno != EINTR) { |
70 | system_error(errno, "select"); | 74 | system_error(errno, "select"); |
71 | break; | 75 | break; |
72 | } | 76 | } |
73 | } | 77 | } |
74 | 78 | ||
75 | } | 79 | } |
76 | signal(SIGCHLD, oldsig); | 80 | sigaction(SIGCHLD, &oldact, NULL); |
77 | if (rc) { | 81 | if (rc) { |
78 | kill(pid, SIGKILL); | 82 | kill(pid, SIGKILL); |
79 | } | 83 | } |
80 | return rc; | 84 | return rc; |
81 | } | 85 | } |
82 | 86 | ||
83 | int | 87 | int |
84 | com_start(void) | 88 | com_start(void) |
85 | { | 89 | { |
86 | pid_t pid; | 90 | pid_t pid; |
87 | int status; | 91 | int status; |
88 | PIDLIST pids; | 92 | PIDLIST pids; |
diff --git a/src/genrc.8 b/src/genrc.8 index 00522ee..959a00e 100644 --- a/src/genrc.8 +++ b/src/genrc.8 | |||
@@ -4,47 +4,49 @@ | |||
4 | .\" Genrc is free software; you can redistribute it and/or modify | 4 | .\" Genrc is free software; you can redistribute it and/or modify |
5 | .\" it under the terms of the GNU General Public License as published by | 5 | .\" it under the terms of the GNU General Public License as published by |
6 | .\" the Free Software Foundation; either version 3, or (at your option) | 6 | .\" the Free Software Foundation; either version 3, or (at your option) |
7 | .\" any later version. | 7 | .\" any later version. |
8 | .\" | 8 | .\" |
9 | .\" Genrc is distributed in the hope that it will be useful, | 9 | .\" Genrc is distributed in the hope that it will be useful, |
10 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | .\" GNU General Public License for more details. | 12 | .\" GNU General Public License for more details. |
13 | .\" | 13 | .\" |
14 | .\" You should have received a copy of the GNU General Public License | 14 | .\" You should have received a copy of the GNU General Public License |
15 | .\" along with genrc. If not, see <http://www.gnu.org/licenses/>. | 15 | .\" along with genrc. If not, see <http://www.gnu.org/licenses/>. |
16 | .TH GENRC 8 "May 17, 2018" "GENRC" "Genrc User Manual" | 16 | .TH GENRC 8 "May 20, 2018" "GENRC" "Genrc User Manual" |
17 | .SH NAME | 17 | .SH NAME |
18 | genrc \- generic system initialization script helper | 18 | genrc \- generic system initialization script helper |
19 | .SH SYNOPSIS | 19 | .SH SYNOPSIS |
20 | .nh | 20 | .nh |
21 | .na | 21 | .na |
22 | \fBgenrc\fR\ | 22 | \fBgenrc\fR\ |
23 | [\fB\-hv\fR]\ | 23 | [\fB\-hv\fR]\ |
24 | [\fB\-F\fR \fIPIDFILE\fR]\ | 24 | [\fB\-F\fR \fIPIDFILE\fR]\ |
25 | [\fB\-P\fR \fISOURCE\fR]\ | 25 | [\fB\-P\fR \fISOURCE\fR]\ |
26 | [\fB\-c\fR \fICOMMAND\fR]\ | 26 | [\fB\-c\fR \fICOMMAND\fR]\ |
27 | [\fB\-g\fR \fIGROUP\fR[,\fIGROUP\fR...]]\ | 27 | [\fB\-g\fR \fIGROUP\fR[,\fIGROUP\fR...]]\ |
28 | [\fB\-p\fR \fIPROGRAM\fR]\ | 28 | [\fB\-p\fR \fIPROGRAM\fR]\ |
29 | [\fB\-t\fR \fISECONDS\fR]\ | 29 | [\fB\-t\fR \fISECONDS\fR]\ |
30 | [\fB\-u\fR \fIUSER\fR]\ | 30 | [\fB\-u\fR \fIUSER\fR]\ |
31 | [\fB\-\-command=\fICOMMAND\fR]\ | 31 | [\fB\-\-command=\fICOMMAND\fR]\ |
32 | [\fB\-\-create\-pidfile=\fIPIDFILE\fR]\ | 32 | [\fB\-\-create\-pidfile=\fIPIDFILE\fR]\ |
33 | [\fB\-\-group=\fIGROUP\fR[,\fIGROUP\fR...]]\ | 33 | [\fB\-\-group=\fIGROUP\fR[,\fIGROUP\fR...]]\ |
34 | [\fB\-\-help\fR]\ | 34 | [\fB\-\-help\fR]\ |
35 | [\fB\-\-no\-reload\fR]\ | 35 | [\fB\-\-no\-reload\fR]\ |
36 | [\fB\-\-pid\-from=\fISOURCE\fR]\ | 36 | [\fB\-\-pid\-from=\fISOURCE\fR]\ |
37 | [\fB\-\-pidfile=\fIPIDFILE\fR]\ | 37 | [\fB\-\-pidfile=\fIPIDFILE\fR]\ |
38 | [\fB\-\-program=\fIPROGRAM\fR]\ | 38 | [\fB\-\-program=\fIPROGRAM\fR]\ |
39 | [\fB\-\-restart\-on\-exit=\fR[\fB!\fR]\fISTATUS\fR[\fB,\fISTATUS\fR...]]\ | ||
40 | [\fB\-\-restart\-on\-signal=\fR[\fB!\fR]\fISIG\fR[\fB,\fISIG\fR...]]\ | ||
39 | [\fB\-\-sentinel\fR]\ | 41 | [\fB\-\-sentinel\fR]\ |
40 | [\fB\-\-signal\-reload=\fISIG\fR]\ | 42 | [\fB\-\-signal\-reload=\fISIG\fR]\ |
41 | [\fB\-\-signal\-stop=\fISIG\fR]\ | 43 | [\fB\-\-signal\-stop=\fISIG\fR]\ |
42 | [\fB\-\-timeout=\fISECONDS\fR]\ | 44 | [\fB\-\-timeout=\fISECONDS\fR]\ |
43 | [\fB\-\-user=\fIUSER\fR]\ | 45 | [\fB\-\-user=\fIUSER\fR]\ |
44 | [\fB\-\-usage\fR]\ | 46 | [\fB\-\-usage\fR]\ |
45 | [\fB\-\-verbose\fR]\ | 47 | [\fB\-\-verbose\fR]\ |
46 | {\ | 48 | {\ |
47 | \fBstart\fR\ | 49 | \fBstart\fR\ |
48 | |\ | 50 | |\ |
49 | \fBstop\fR\ | 51 | \fBstop\fR\ |
50 | |\ | 52 | |\ |
@@ -92,24 +94,48 @@ is a \fIdaemon\fR, in UNIX sense). If it is not the case, use the | |||
92 | the command and will become daemon itself, controlling the execution | 94 | the command and will become daemon itself, controlling the execution |
93 | of the program. It will exit when the command terminates. So long as | 95 | of the program. It will exit when the command terminates. So long as |
94 | the command runs, \fBgenrc\fR will pipe its standard output and error | 96 | the command runs, \fBgenrc\fR will pipe its standard output and error |
95 | to syslog facility \fBdaemon\fR. The standard output will be logged | 97 | to syslog facility \fBdaemon\fR. The standard output will be logged |
96 | with the priority \fBinfo\fR and the error with the priority | 98 | with the priority \fBinfo\fR and the error with the priority |
97 | \fBerr\fR. | 99 | \fBerr\fR. |
98 | .PP | 100 | .PP |
99 | If the \fB\-\-create\-pidfile=\fIFILENAME\fR option is given together with | 101 | If the \fB\-\-create\-pidfile=\fIFILENAME\fR option is given together with |
100 | \fB\-\-sentinel\fR, the PID of the subsidiary command will be stored | 102 | \fB\-\-sentinel\fR, the PID of the subsidiary command will be stored |
101 | in \fIFILE\fR. The file will be unlinked after the subsidiary command | 103 | in \fIFILE\fR. The file will be unlinked after the subsidiary command |
102 | terminates. Unless the \fB\-\-pid\-from\fR option is given, | 104 | terminates. Unless the \fB\-\-pid\-from\fR option is given, |
103 | \fB\-\-pid\-from=FILE:\fIFILENAME\fR will be assumed. | 105 | \fB\-\-pid\-from=FILE:\fIFILENAME\fR will be assumed. |
106 | .PP | ||
107 | In sentinel mode, it is possible to restart the program if it | ||
108 | terminates with a specific exit code or on a specific signal. This is | ||
109 | controlled by the \fB\-\-restart\-on\-exit\fR and | ||
110 | \fB\-\-restart\-on\-signal\fR options. Use this feature to ensure the | ||
111 | service provided by the program won't get terminated because of | ||
112 | hitting a bug or encountering an unforeseen external condition. For | ||
113 | example, the following two options will ensure that the program will | ||
114 | be terminated only if it exits with status 0 or it is terminated by | ||
115 | SIGTERM or SIGQUIT signal: | ||
116 | .EX | ||
117 | --restart-on-exit='!0' --restart-on-signal='!TERM,QUIT' | ||
118 | .EE | ||
119 | .PP | ||
120 | If restarts are requested, \fBgenrc\fR will control how often it has | ||
121 | to restart the program using the same algorithm as | ||
122 | .B init (8). | ||
123 | Namely, if the program is restarted more than 10 times within two | ||
124 | minutes, \fBgenrc\fR will disable subsequent restarts for the next | ||
125 | 5 minutes. If the \fB\-\-create\-pidfile\fR option was used, the | ||
126 | PID of the controlling \fBgenrc\fR process will be stored in the | ||
127 | file during that interval. If the \fBSIGHUP\fR signal is delivered | ||
128 | during the sleep interval, the sleep will be broken prematurely and | ||
129 | the program restarted again. | ||
104 | .SS status | 130 | .SS status |
105 | In \fBstatus\fR mode \fBgenrc\fR verifies if the \fICOMMAND\fR is | 131 | In \fBstatus\fR mode \fBgenrc\fR verifies if the \fICOMMAND\fR is |
106 | already running and outputs its status on the standard output. To this | 132 | already running and outputs its status on the standard output. To this |
107 | effect, it uses an abstraction called \fIPID source\fR, which allows | 133 | effect, it uses an abstraction called \fIPID source\fR, which allows |
108 | it to determine the PID of the program by its name of command line. | 134 | it to determine the PID of the program by its name of command line. |
109 | .PP | 135 | .PP |
110 | The default PID source is the Linux \fB/proc\fR filesystem (or, if it | 136 | The default PID source is the Linux \fB/proc\fR filesystem (or, if it |
111 | is not available, the output of \fBps -ef\fR), which is scanned for | 137 | is not available, the output of \fBps -ef\fR), which is scanned for |
112 | the name of the program (given by \fB\-\-program\fR or | 138 | the name of the program (given by \fB\-\-program\fR or |
113 | \fB\-\-command\fR options). | 139 | \fB\-\-command\fR options). |
114 | .PP | 140 | .PP |
115 | The source to use can be supplied with the \fB\-\-pid\-from\fR option | 141 | The source to use can be supplied with the \fB\-\-pid\-from\fR option |
@@ -179,27 +205,55 @@ notation is used, it must exist in the system group database. | |||
179 | 205 | ||
180 | See also the \fB\-\-user\fR option. | 206 | See also the \fB\-\-user\fR option. |
181 | .TP | 207 | .TP |
182 | \fB\-\-no\-reload\fR | 208 | \fB\-\-no\-reload\fR |
183 | Makes \fBreload\fR equivalent to \fBrestart\fR. | 209 | Makes \fBreload\fR equivalent to \fBrestart\fR. |
184 | .TP | 210 | .TP |
185 | \fB\-p\fR, \fB\-\-program=\fIPROGRAM\fR | 211 | \fB\-p\fR, \fB\-\-program=\fIPROGRAM\fR |
186 | Name of the program to run. | 212 | Name of the program to run. |
187 | .TP | 213 | .TP |
188 | \fB\-P\fR, \fB\-\-pid\-from=\fISOURCE\fR | 214 | \fB\-P\fR, \fB\-\-pid\-from=\fISOURCE\fR |
189< |