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:
parent
3673040722
commit
4c89e3f5fa
@ -167,8 +167,20 @@ Display name used for the above defined command.
|
|||||||
Process name to match when signaling the daemon.
|
Process name to match when signaling the daemon.
|
||||||
.It Ar stopsig
|
.It Ar stopsig
|
||||||
Signal to send when stopping the daemon.
|
Signal to send when stopping the daemon.
|
||||||
.It Ar respawn_limit
|
.It Ar respawn_delay
|
||||||
Respawn limit
|
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
|
.Xr supervise-daemon 8
|
||||||
will use for this daemon. See
|
will use for this daemon. See
|
||||||
.Xr supervise-daemon 8
|
.Xr supervise-daemon 8
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
.Nd starts a daemon and restarts it if it crashes
|
.Nd starts a daemon and restarts it if it crashes
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Fl D , -respawn-delay
|
||||||
|
.Ar seconds
|
||||||
.Fl d , -chdir
|
.Fl d , -chdir
|
||||||
.Ar path
|
.Ar path
|
||||||
.Fl e , -env
|
.Fl e , -env
|
||||||
@ -26,16 +28,18 @@
|
|||||||
.Ar arg
|
.Ar arg
|
||||||
.Fl k , -umask
|
.Fl k , -umask
|
||||||
.Ar value
|
.Ar value
|
||||||
|
.Fl m , -respawn-max
|
||||||
|
.Ar count
|
||||||
.Fl N , -nicelevel
|
.Fl N , -nicelevel
|
||||||
.Ar level
|
.Ar level
|
||||||
.Fl p , -pidfile
|
.Fl p , -pidfile
|
||||||
.Ar pidfile
|
.Ar pidfile
|
||||||
.Fl u , -user
|
.Fl P , -respawn-period
|
||||||
.Ar user
|
.Ar seconds
|
||||||
.Fl r , -chroot
|
.Fl r , -chroot
|
||||||
.Ar chrootpath
|
.Ar chrootpath
|
||||||
.Fl R , -respawn-limit
|
.Fl u , -user
|
||||||
.Ar limit
|
.Ar user
|
||||||
.Fl 1 , -stdout
|
.Fl 1 , -stdout
|
||||||
.Ar logfile
|
.Ar logfile
|
||||||
.Fl 2 , -stderr
|
.Fl 2 , -stderr
|
||||||
@ -84,6 +88,9 @@ Print the action(s) that are taken just before doing them.
|
|||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width indent
|
.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
|
.It Fl d , -chdir Ar path
|
||||||
chdir to this directory before starting the daemon.
|
chdir to this directory before starting the daemon.
|
||||||
.It Fl e , -env Ar VAR=VALUE
|
.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.
|
Data can be from 0 to 7 inclusive.
|
||||||
.It Fl k , -umask Ar mode
|
.It Fl k , -umask Ar mode
|
||||||
Set the umask of the daemon.
|
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
|
.It Fl N , -nicelevel Ar level
|
||||||
Modifies the scheduling priority of the daemon.
|
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
|
.It Fl r , -chroot Ar path
|
||||||
chroot to this directory before starting the daemon. All other paths, such
|
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.
|
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
|
.It Fl u , -user Ar user
|
||||||
Start the daemon as the specified user.
|
Start the daemon as the specified user.
|
||||||
.It Fl 1 , -stdout Ar logfile
|
.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
|
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
|
are passed as arguments to the daemon to start and used when finding a daemon
|
||||||
to stop or signal.
|
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
|
.Sh SEE ALSO
|
||||||
.Xr chdir 2 ,
|
.Xr chdir 2 ,
|
||||||
.Xr chroot 2 ,
|
.Xr chroot 2 ,
|
||||||
|
@ -25,7 +25,9 @@ supervise_start()
|
|||||||
eval supervise-daemon --start \
|
eval supervise-daemon --start \
|
||||||
${chroot:+--chroot} $chroot \
|
${chroot:+--chroot} $chroot \
|
||||||
${pidfile:+--pidfile} $pidfile \
|
${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 \
|
${command_user+--user} $command_user \
|
||||||
$supervise_daemon_args \
|
$supervise_daemon_args \
|
||||||
$command \
|
$command \
|
||||||
|
@ -66,38 +66,42 @@ static struct pam_conv conv = { NULL, NULL};
|
|||||||
|
|
||||||
const char *applet = NULL;
|
const char *applet = NULL;
|
||||||
const char *extraopts = 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;
|
getoptstring_COMMON;
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
|
{ "respawn-delay", 1, NULL, 'D'},
|
||||||
{ "chdir", 1, NULL, 'd'},
|
{ "chdir", 1, NULL, 'd'},
|
||||||
{ "env", 1, NULL, 'e'},
|
{ "env", 1, NULL, 'e'},
|
||||||
{ "group", 1, NULL, 'g'},
|
{ "group", 1, NULL, 'g'},
|
||||||
{ "ionice", 1, NULL, 'I'},
|
{ "ionice", 1, NULL, 'I'},
|
||||||
{ "stop", 0, NULL, 'K'},
|
{ "stop", 0, NULL, 'K'},
|
||||||
{ "umask", 1, NULL, 'k'},
|
{ "umask", 1, NULL, 'k'},
|
||||||
|
{ "respawn-max", 1, NULL, 'm'},
|
||||||
{ "nicelevel", 1, NULL, 'N'},
|
{ "nicelevel", 1, NULL, 'N'},
|
||||||
{ "pidfile", 1, NULL, 'p'},
|
{ "pidfile", 1, NULL, 'p'},
|
||||||
{ "user", 1, NULL, 'u'},
|
{ "respawn-period", 1, NULL, 'P'},
|
||||||
{ "chroot", 1, NULL, 'r'},
|
{ "chroot", 1, NULL, 'r'},
|
||||||
{ "respawn-limit", 1, NULL, 'R'},
|
|
||||||
{ "start", 0, NULL, 'S'},
|
{ "start", 0, NULL, 'S'},
|
||||||
|
{ "user", 1, NULL, 'u'},
|
||||||
{ "stdout", 1, NULL, '1'},
|
{ "stdout", 1, NULL, '1'},
|
||||||
{ "stderr", 1, NULL, '2'},
|
{ "stderr", 1, NULL, '2'},
|
||||||
longopts_COMMON
|
longopts_COMMON
|
||||||
};
|
};
|
||||||
const char * const longopts_help[] = {
|
const char * const longopts_help[] = {
|
||||||
|
"Set a respawn delay",
|
||||||
"Change the PWD",
|
"Change the PWD",
|
||||||
"Set an environment string",
|
"Set an environment string",
|
||||||
"Change the process group",
|
"Change the process group",
|
||||||
"Set an ionice class:data when starting",
|
"Set an ionice class:data when starting",
|
||||||
"Stop daemon",
|
"Stop daemon",
|
||||||
"Set the umask for the daemon",
|
"Set the umask for the daemon",
|
||||||
|
"set maximum number of respawn attempts",
|
||||||
"Set a nicelevel when starting",
|
"Set a nicelevel when starting",
|
||||||
"Match pid found in this file",
|
"Match pid found in this file",
|
||||||
"Change the process user",
|
"Set respawn time period",
|
||||||
"Chroot to this directory",
|
"Chroot to this directory",
|
||||||
"set a respawn limit",
|
|
||||||
"Start daemon",
|
"Start daemon",
|
||||||
|
"Change the process user",
|
||||||
"Redirect stdout to file",
|
"Redirect stdout to file",
|
||||||
"Redirect stderr to file",
|
"Redirect stderr to file",
|
||||||
longopts_help_COMMON
|
longopts_help_COMMON
|
||||||
@ -429,6 +433,7 @@ int main(int argc, char **argv)
|
|||||||
int n;
|
int n;
|
||||||
char exec_file[PATH_MAX];
|
char exec_file[PATH_MAX];
|
||||||
int respawn_count = 0;
|
int respawn_count = 0;
|
||||||
|
int respawn_delay = 0;
|
||||||
int respawn_max = 10;
|
int respawn_max = 10;
|
||||||
int respawn_period = 5;
|
int respawn_period = 5;
|
||||||
time_t respawn_now= 0;
|
time_t respawn_now= 0;
|
||||||
@ -469,6 +474,12 @@ int main(int argc, char **argv)
|
|||||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
||||||
(int *) 0)) != -1)
|
(int *) 0)) != -1)
|
||||||
switch (opt) {
|
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 */
|
case 'I': /* --ionice */
|
||||||
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
|
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
|
||||||
eerrorx("%s: invalid ionice `%s'",
|
eerrorx("%s: invalid ionice `%s'",
|
||||||
@ -490,6 +501,12 @@ int main(int argc, char **argv)
|
|||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
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 */
|
case 'S': /* --start */
|
||||||
start = true;
|
start = true;
|
||||||
break;
|
break;
|
||||||
@ -519,6 +536,12 @@ int main(int argc, char **argv)
|
|||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
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> */
|
case 'p': /* --pidfile <pid-file> */
|
||||||
pidfile = optarg;
|
pidfile = optarg;
|
||||||
break;
|
break;
|
||||||
@ -527,17 +550,6 @@ int main(int argc, char **argv)
|
|||||||
ch_root = optarg;
|
ch_root = optarg;
|
||||||
break;
|
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> */
|
case 'u': /* --user <username>|<uid> */
|
||||||
{
|
{
|
||||||
p = optarg;
|
p = optarg;
|
||||||
@ -600,6 +612,11 @@ int main(int argc, char **argv)
|
|||||||
if (start) {
|
if (start) {
|
||||||
if (!exec)
|
if (!exec)
|
||||||
eerrorx("%s: nothing to start", applet);
|
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 ~ */
|
/* Expand ~ */
|
||||||
@ -732,6 +749,7 @@ int main(int argc, char **argv)
|
|||||||
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
|
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
|
||||||
kill(child_pid, SIGTERM);
|
kill(child_pid, SIGTERM);
|
||||||
} else {
|
} else {
|
||||||
|
sleep(respawn_delay);
|
||||||
if (respawn_max > 0 && respawn_period > 0) {
|
if (respawn_max > 0 && respawn_period > 0) {
|
||||||
respawn_now = time(NULL);
|
respawn_now = time(NULL);
|
||||||
if (first_spawn == 0)
|
if (first_spawn == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user