supervise-daemon:create multiple options from --respawn-limit

This creates --respawn-delay, --respawn-max and --respawn-period. It was
suggested that it would be easier to follow if the options were
separated.

This is for #126.
This commit is contained in:
William Hubbs 2017-05-10 18:01:10 -05:00
parent 3673040722
commit 4c89e3f5fa
4 changed files with 81 additions and 41 deletions

View File

@ -167,8 +167,20 @@ Display name used for the above defined command.
Process name to match when signaling the daemon.
.It Ar stopsig
Signal to send when stopping the daemon.
.It Ar respawn_limit
Respawn limit
.It Ar respawn_delay
Respawn delay
.Xr supervise-daemon 8
will use for this daemon. See
.Xr supervise-daemon 8
for more information about this setting.
.It Ar respawn_max
Respawn max
.Xr supervise-daemon 8
will use for this daemon. See
.Xr supervise-daemon 8
for more information about this setting.
.It Ar respawn_period
Respawn period
.Xr supervise-daemon 8
will use for this daemon. See
.Xr supervise-daemon 8

View File

@ -16,6 +16,8 @@
.Nd starts a daemon and restarts it if it crashes
.Sh SYNOPSIS
.Nm
.Fl D , -respawn-delay
.Ar seconds
.Fl d , -chdir
.Ar path
.Fl e , -env
@ -26,16 +28,18 @@
.Ar arg
.Fl k , -umask
.Ar value
.Fl m , -respawn-max
.Ar count
.Fl N , -nicelevel
.Ar level
.Fl p , -pidfile
.Ar pidfile
.Fl u , -user
.Ar user
.Fl P , -respawn-period
.Ar seconds
.Fl r , -chroot
.Ar chrootpath
.Fl R , -respawn-limit
.Ar limit
.Fl u , -user
.Ar user
.Fl 1 , -stdout
.Ar logfile
.Fl 2 , -stderr
@ -84,6 +88,9 @@ Print the action(s) that are taken just before doing them.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl D , -respawn-delay Ar seconds
wait this number of seconds before restarting a daemon after it crashes.
The default is 0.
.It Fl d , -chdir Ar path
chdir to this directory before starting the daemon.
.It Fl e , -env Ar VAR=VALUE
@ -96,29 +103,21 @@ Class can be 0 for none, 1 for real time, 2 for best effort and 3 for idle.
Data can be from 0 to 7 inclusive.
.It Fl k , -umask Ar mode
Set the umask of the daemon.
.It Fl m , -respawn-max Ar count
Sets the maximum number of times a daemon will be respawned during a
respawn period. If a daemon dies more than this number of times during a
respawn period,
.Nm
will give up trying to respawn it and exit. The default is 10, and 0
means unlimited.
.It Fl N , -nicelevel Ar level
Modifies the scheduling priority of the daemon.
.It Fl P , -respawn-period Ar seconds
Sets the length of a respawn period. The default is 10 seconds. See the
description of --respawn-max for more information.
.It Fl r , -chroot Ar path
chroot to this directory before starting the daemon. All other paths, such
as the path to the daemon, chdir and pidfile, should be relative to the chroot.
.It Fl R , -respawn-limit Ar limit
Control how agressively
.Nm
will try to respawn a daemon when it fails to start. The limit argument
can be a pair of integers separated bya colon or the string unlimited.
.Pp
If a pair of integers is given, the first is a maximum number of respawn
attempts and the second is a time period. It should be interpreted as:
If the daemon dies and has to be respawned more than <first number>
times in any time period of <second number> seconds, exit and give up.
.Pp
For example, the default is 10:5.
This means if the supervisor respawns a daemon more than ten times
in any 5 second period, it gives up and exits.
.Pp
if unlimited is given as the limit, it means that the supervisor will
not exit or give up, no matter how many times the daemon it is
supervising needs to be respawned.
.It Fl u , -user Ar user
Start the daemon as the specified user.
.It Fl 1 , -stdout Ar logfile
@ -143,6 +142,15 @@ to parse its options, which allows it to accept the `--' option which will
cause it to stop processing options at that point. Any subsequent arguments
are passed as arguments to the daemon to start and used when finding a daemon
to stop or signal.
.Sh NOTE
If respawn-delay, respawn-max and respawn-period are not set correctly,
it is possible to trigger a situation in which the supervisor will
infinitely try to respawn a daemon. To avoid this, if you change the
values of --respawn-delay, --respawn-max or --respawn-period, always
make sure the settings mmake sense. For example, a respawn period of 5
seconds with a respawn max of 10 and a respawn delay of 1 second leads
to infinite respawning since there can never be 10 respawns within 5
seconds.
.Sh SEE ALSO
.Xr chdir 2 ,
.Xr chroot 2 ,

View File

@ -25,7 +25,9 @@ supervise_start()
eval supervise-daemon --start \
${chroot:+--chroot} $chroot \
${pidfile:+--pidfile} $pidfile \
${respawn_limit:+--respawn-limit} $respawn_limit \
${respawn_delay:+--respawn-delay} $respawn_delay \
${respawn_max:+--respawn-max} $respawn_max \
${respawn_period:+--respawn-period} $respawn_period \
${command_user+--user} $command_user \
$supervise_daemon_args \
$command \

View File

@ -66,38 +66,42 @@ static struct pam_conv conv = { NULL, NULL};
const char *applet = NULL;
const char *extraopts = NULL;
const char *getoptstring = "d:e:g:I:Kk:N:p:r:R:Su:1:2:" \
const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:r:Su:1:2:" \
getoptstring_COMMON;
const struct option longopts[] = {
{ "respawn-delay", 1, NULL, 'D'},
{ "chdir", 1, NULL, 'd'},
{ "env", 1, NULL, 'e'},
{ "group", 1, NULL, 'g'},
{ "ionice", 1, NULL, 'I'},
{ "stop", 0, NULL, 'K'},
{ "umask", 1, NULL, 'k'},
{ "respawn-max", 1, NULL, 'm'},
{ "nicelevel", 1, NULL, 'N'},
{ "pidfile", 1, NULL, 'p'},
{ "user", 1, NULL, 'u'},
{ "respawn-period", 1, NULL, 'P'},
{ "chroot", 1, NULL, 'r'},
{ "respawn-limit", 1, NULL, 'R'},
{ "start", 0, NULL, 'S'},
{ "user", 1, NULL, 'u'},
{ "stdout", 1, NULL, '1'},
{ "stderr", 1, NULL, '2'},
longopts_COMMON
};
const char * const longopts_help[] = {
"Set a respawn delay",
"Change the PWD",
"Set an environment string",
"Change the process group",
"Set an ionice class:data when starting",
"Stop daemon",
"Set the umask for the daemon",
"set maximum number of respawn attempts",
"Set a nicelevel when starting",
"Match pid found in this file",
"Change the process user",
"Set respawn time period",
"Chroot to this directory",
"set a respawn limit",
"Start daemon",
"Change the process user",
"Redirect stdout to file",
"Redirect stderr to file",
longopts_help_COMMON
@ -429,6 +433,7 @@ int main(int argc, char **argv)
int n;
char exec_file[PATH_MAX];
int respawn_count = 0;
int respawn_delay = 0;
int respawn_max = 10;
int respawn_period = 5;
time_t respawn_now= 0;
@ -469,6 +474,12 @@ int main(int argc, char **argv)
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
(int *) 0)) != -1)
switch (opt) {
case 'D': /* --respawn-delay time */
n = sscanf(optarg, "%d", &respawn_delay);
if (n != 1 || respawn_delay < 1)
eerrorx("Invalid respawn-delay value '%s'", optarg);
break;
case 'I': /* --ionice */
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
eerrorx("%s: invalid ionice `%s'",
@ -490,6 +501,12 @@ int main(int argc, char **argv)
applet, optarg);
break;
case 'P': /* --respawn-period time */
n = sscanf(optarg, "%d", &respawn_period);
if (n != 1 || respawn_delay < 1)
eerrorx("Invalid respawn-delay value '%s'", optarg);
break;
case 'S': /* --start */
start = true;
break;
@ -519,6 +536,12 @@ int main(int argc, char **argv)
applet, optarg);
break;
case 'm': /* --respawn-max count */
n = sscanf(optarg, "%d", &respawn_max);
if (n != 1 || respawn_max < 1)
eerrorx("Invalid respawn-max value '%s'", optarg);
break;
case 'p': /* --pidfile <pid-file> */
pidfile = optarg;
break;
@ -527,17 +550,6 @@ int main(int argc, char **argv)
ch_root = optarg;
break;
case 'R': /* --respawn-limit unlimited|count:period */
if (strcasecmp(optarg, "unlimited") == 0) {
respawn_max = 0;
respawn_period = 0;
} else {
n = sscanf(optarg, "%d:%d", &respawn_max, &respawn_period);
if (n != 2 || respawn_max < 1 || respawn_period < 1)
eerrorx("Invalid respawn-limit setting '%s'", optarg);
}
break;
case 'u': /* --user <username>|<uid> */
{
p = optarg;
@ -600,6 +612,11 @@ int main(int argc, char **argv)
if (start) {
if (!exec)
eerrorx("%s: nothing to start", applet);
if (respawn_delay * respawn_max > respawn_period) {
ewarn("%s: Please increase the value of --respawn-period to more "
"than %d to avoid infinite respawning", applet,
respawn_delay * respawn_max);
}
}
/* Expand ~ */
@ -732,6 +749,7 @@ int main(int argc, char **argv)
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
kill(child_pid, SIGTERM);
} else {
sleep(respawn_delay);
if (respawn_max > 0 && respawn_period > 0) {
respawn_now = time(NULL);
if (first_spawn == 0)