Compare commits

..

15 Commits
0.25 ... 0.26

Author SHA1 Message Date
William Hubbs
e4bfb4530a update ChangeLog 2017-05-11 22:00:41 -05:00
William Hubbs
78e0042ecc man/rc-status: document changes for supervised daemons
rc-status now shows the amount of time a supervised daemon has been
active as well as the number of times it has been respawned during the
current respawn period.
2017-05-11 21:55:31 -05:00
William Hubbs
82e12e3092 rc-status: show uptimes and respawn counts for supervised daemons 2017-05-11 21:39:03 -05:00
William Hubbs
1ebef0d7a3 fix to_time_t to honor dst 2017-05-11 18:13:13 -05:00
William Hubbs
6b4050ab9c fix from_time_t function 2017-05-11 16:22:12 -05:00
William Hubbs
cf5e9aa2bb Move time_t conversions to rc-misc.c so they can be shared 2017-05-11 16:06:12 -05:00
William Hubbs
a3250e77d4 supervise-daemon: save start time and respawn count
This will allow rc-status to display an uptime and restart count for
supervised processes.
2017-05-11 13:54:20 -05:00
William Hubbs
df027ca472 supervise-daemon: fix our status when we give up on the child process 2017-05-11 11:36:42 -05:00
William Hubbs
4c89e3f5fa 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.
2017-05-10 18:13:23 -05:00
William Hubbs
3673040722 supervise-daemon: add a --respawn-limit option
Allow limiting the number of times supervise-daemon will attempt to respawn a
daemon once it has died to prevent infinite respawning. Also, set a
reasonable default limit (10 times in a 5 second period).

This is for issue #126.
2017-05-09 18:30:08 -05:00
William Hubbs
96c8ba2fb5 supervise-daemon: mark all open file descriptors FD_CLOEXEC 2017-04-29 13:48:45 -05:00
William Hubbs
47cf1d0c70 supervise-daemon:remove the controlling tty in the supervisor 2017-04-29 12:04:15 -05:00
William Hubbs
06a6a27e44 supervise-daemon: fix access to tty_fd and devnull_fd
Both the child and supervisor need access to these file descriptors.
2017-04-29 10:12:16 -05:00
William Hubbs
5de3798afc supervise-daemon: mark the service started when the supervisor is active 2017-04-29 09:41:07 -05:00
William Hubbs
6ac094a59c version 0.26 2017-04-19 17:24:44 -05:00
10 changed files with 349 additions and 68 deletions

157
ChangeLog
View File

@@ -1,3 +1,114 @@
commit 78e0042eccaf5a5554b195ad391b3ab0b8974cf6
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
man/rc-status: document changes for supervised daemons
rc-status now shows the amount of time a supervised daemon has been
active as well as the number of times it has been respawned during the
current respawn period.
commit 82e12e309247bc84abf29aca04b3a2dd845fa11b
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
rc-status: show uptimes and respawn counts for supervised daemons
commit 1ebef0d7a38ec0a9635418b75c3aabb564c1577e
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
fix to_time_t to honor dst
commit 6b4050ab9cf9d678a1d6b7af7af7494f8533dbca
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
fix from_time_t function
commit cf5e9aa2bbcdf1783fadeab26586c1134929d928
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Move time_t conversions to rc-misc.c so they can be shared
commit a3250e77d412f2290e381b9e7569930d95e4fc5b
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: save start time and respawn count
This will allow rc-status to display an uptime and restart count for
supervised processes.
commit df027ca4722c8755b23a65db75728b835ccca807
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: fix our status when we give up on the child process
commit 4c89e3f5fa1c65ccd0c843f98e4013c2085f243f
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
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.
commit 3673040722b75c0a4d06fbeb272f917c7d1ea7c4
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: add a --respawn-limit option
Allow limiting the number of times supervise-daemon will attempt to respawn a
daemon once it has died to prevent infinite respawning. Also, set a
reasonable default limit (10 times in a 5 second period).
This is for issue #126.
commit 96c8ba2fb5f91a711ef5bfcfd8affe0b74ad18fe
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: mark all open file descriptors FD_CLOEXEC
commit 47cf1d0c707dc88d216bebc15be3f39d5eb47fa9
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon:remove the controlling tty in the supervisor
commit 06a6a27e441372164872c7712b80728527a6ec05
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: fix access to tty_fd and devnull_fd
Both the child and supervisor need access to these file descriptors.
commit 5de3798afc55ce147e65926f863ec9c9cef60e79
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
supervise-daemon: mark the service started when the supervisor is active
commit 6ac094a59cf7b51d8527af15b07feca707a635c8
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
version 0.26
commit 84c81ca02d7077a619dc704ff654385846fcd2b4
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
update ChangeLog
commit 0e3f8720984d7d5752a78a4135cd268e4f83b3d7
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
@@ -1368,49 +1479,3 @@ Commit: Anthony G. Basile <blueness@gentoo.org>
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=533828
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
commit 92e2f2c7cc958effcec0ef773dda954a153d8e42
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
killprocs: remove calls to sleep
X-Gentoo-Bug: 487084
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=487084
commit ad23d5b8dbee70815c02271c78f415bcd7088076
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
openrc-run: clean up runscript deprecation message
commit 62410eaf4ba92516a58a550717d7f3faf63bb79f
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
add daemon supervisor
The supervise-daemon process is meant to be a lightweight supervisor
which can monitor and restart a daemon if it crashes.
commit fd80b6fc67ec6a0fe4853167fb67ee40bb51b742
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
localmount/netmount: clean up critical mount processing
Fix a typo and do not fail if a path in critical_mounts is not listed as
a critical mount does not get mounted.
commit 5d130cc45cd334fd38b0c6874bcc81ac74636217
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
localmount/netmount: allow mount points to be marked critical
In previous releases, we either treated no mount points as critical or
all of them.
Now both localmount and netmount support a critical_mounts setting. If
mount points listed in this setting fail to mount, localmount and
netmount will fail.

View File

@@ -1,3 +1,3 @@
NAME= openrc
VERSION= 0.25
VERSION= 0.26
PKG= ${NAME}-${VERSION}

View File

@@ -167,6 +167,24 @@ 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_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
for more information about this setting.
.It Ar retry
Retry schedule to use when stopping the daemon. It can either be a
timeout in seconds or multiple signal/timeout pairs (like SIGTERM/5).

View File

@@ -25,6 +25,12 @@ in different runlevels. The default behavior is to show information
about the current runlevel and any unassigned services that are not stopped,
but any runlevel can be quickly examined.
.Pp
If an active service is being supervised by
.Xr supervise-daemon 8,
the amount of time the daemon has been active along with the number of
times it has been respawned in the current respawn period will be
displayed.
.Pp
The options are as follows:
.Bl -tag -width ".Fl test , test string"
.It Fl a , -all
@@ -57,5 +63,6 @@ dependency order if the dependency tree is available.
.Sh SEE ALSO
.Xr openrc 8 ,
.Xr rc-update 8
.Xr supervise-daemon 8
.Sh AUTHORS
.An Roy Marples <roy@marples.name>

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,14 +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 u , -user
.Ar user
.Fl 1 , -stdout
.Ar logfile
.Fl 2 , -stderr
@@ -82,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
@@ -94,8 +103,18 @@ 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.
@@ -123,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,6 +25,9 @@ supervise_start()
eval supervise-daemon --start \
${chroot:+--chroot} $chroot \
${pidfile:+--pidfile} $pidfile \
${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

@@ -23,6 +23,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "helpers.h"
@@ -68,5 +69,7 @@ RC_DEPTREE *_rc_deptree_load (int, int *);
bool _rc_can_find_pids(void);
RC_SERVICE lookup_service_state(const char *service);
void from_time_t(char *time_string, time_t tv);
time_t to_time_t(char *timestring);
#endif

View File

@@ -442,3 +442,35 @@ RC_SERVICE lookup_service_state(const char *service)
return service_bits[i].bit;
return 0;
}
void from_time_t(char *time_string, time_t tv)
{
strftime(time_string, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv));
}
time_t to_time_t(char *timestring)
{
int check = 0;
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int min = 0;
int sec = 0;
struct tm breakdown = {0};
time_t result = -1;
check = sscanf(timestring, "%4d-%2d-%2d %2d:%2d:%2d",
&year, &month, &day, &hour, &min, &sec);
if (check == 6) {
breakdown.tm_year = year - 1900; /* years since 1900 */
breakdown.tm_mon = month - 1;
breakdown.tm_mday = day;
breakdown.tm_hour = hour;
breakdown.tm_min = min;
breakdown.tm_sec = sec;
breakdown.tm_isdst = -1;
result = mktime(&breakdown);
}
return result;
}

View File

@@ -76,10 +76,55 @@ print_level(const char *prefix, const char *level)
printf("%s\n", level);
}
static void get_uptime(const char *service, char *uptime, int uptime_size)
{
RC_SERVICE state = rc_service_state(service);
char *start_count;
time_t now;
char *start_time_string;
time_t start_time;
double time_diff;
double diff_tmp;
double diff_days;
double diff_hours;
double diff_mins;
uptime[0] = '\0';
if (state & RC_SERVICE_STARTED) {
start_count = rc_service_value_get(service, "start_count");
start_time_string = rc_service_value_get(service, "start_time");
if (start_count && start_time_string) {
start_time = to_time_t(start_time_string);
now = time(NULL);
time_diff = difftime(now, start_time);
diff_tmp = time_diff;
if (diff_tmp > 86400.0) {
diff_days = diff_tmp / 86400.0;
diff_tmp -= diff_days * 86400.0;
}
if (diff_tmp > 3600.0) {
diff_hours = diff_tmp / 3600.0;
diff_tmp -= diff_hours * 3600.0;
}
if (diff_tmp > 60.0) {
diff_mins = diff_tmp / 60.0;
diff_tmp -= diff_mins * 60.0;
}
if ((int) diff_days > 0)
snprintf(uptime, uptime_size, "%.0f days %02.0f:%02.0f (%s)",
diff_days, diff_hours, diff_mins, start_count);
else
snprintf(uptime, uptime_size, "%02.0f:%02.0f (%s)",
diff_hours, diff_mins, start_count);
}
}
}
static void
print_service(const char *service)
{
char status[10];
char status[60];
char uptime [40];
int cols = printf(" %s", service);
const char *c = ecolor(ECOLOR_GOOD);
RC_SERVICE state = rc_service_state(service);
@@ -101,7 +146,8 @@ print_service(const char *service)
{
snprintf(status, sizeof(status), " crashed ");
} else {
snprintf(status, sizeof(status), " started ");
get_uptime(service, uptime, 40);
snprintf(status, sizeof(status), " started %s", uptime);
color = ECOLOR_GOOD;
}
} else if (state & RC_SERVICE_SCHEDULED) {

View File

@@ -66,36 +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: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'},
{ "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",
"Start daemon",
"Change the process user",
"Redirect stdout to file",
"Redirect stderr to file",
longopts_help_COMMON
@@ -165,7 +171,8 @@ static pid_t get_pid(const char *pidfile)
return pid;
}
static void child_process(char *exec, char **argv)
static void child_process(char *exec, char **argv, char *svcname,
int start_count)
{
RC_STRINGLIST *env_list;
RC_STRING *env;
@@ -177,6 +184,9 @@ static void child_process(char *exec, char **argv)
char *np;
char **c;
char cmdline[PATH_MAX];
time_t start_time;
char start_count_string[20];
char start_time_string[20];
#ifdef HAVE_PAM
pam_handle_t *pamh = NULL;
@@ -226,6 +236,7 @@ static void child_process(char *exec, char **argv)
/* Close any fd's to the passwd database */
endpwent();
/* remove the controlling tty */
#ifdef TIOCNOTTY
ioctl(tty_fd, TIOCNOTTY, 0);
close(tty_fd);
@@ -321,7 +332,7 @@ static void child_process(char *exec, char **argv)
dup2(stderr_fd, STDERR_FILENO);
for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
fcntl(i, F_SETFD, FD_CLOEXEC);
*cmdline = '\0';
c = argv;
@@ -331,6 +342,13 @@ static void child_process(char *exec, char **argv)
c++;
}
syslog(LOG_INFO, "Running command line: %s", cmdline);
if (svcname) {
start_time = time(NULL);
from_time_t(start_time_string, start_time);
rc_service_value_set(svcname, "start_time", start_time_string);
sprintf(start_count_string, "%i", start_count);
rc_service_value_set(svcname, "start_count", start_count_string);
}
execvp(exec, argv);
#ifdef HAVE_PAM
@@ -423,7 +441,14 @@ int main(int argc, char **argv)
char *p;
char *token;
int i;
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;
time_t first_spawn= 0;
struct passwd *pw;
struct group *gr;
FILE *fp;
@@ -460,6 +485,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'",
@@ -481,6 +512,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;
@@ -510,6 +547,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;
@@ -580,6 +623,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 ~ */
@@ -639,10 +687,12 @@ int main(int argc, char **argv)
* result would be the same. */
if (pidfile && exists(pidfile))
unlink(pidfile);
if (svcname)
if (svcname) {
rc_service_daemon_set(svcname, exec,
(const char *const *)argv,
pidfile, false);
rc_service_mark(svcname, RC_SERVICE_STOPPED);
}
exit(EXIT_SUCCESS);
}
@@ -674,6 +724,10 @@ int main(int argc, char **argv)
if (child_pid != 0)
exit(EXIT_SUCCESS);
#ifdef TIOCNOTTY
tty_fd = open("/dev/tty", O_RDWR);
#endif
devnull_fd = open("/dev/null", O_RDWR);
child_pid = fork();
if (child_pid == -1)
eerrorx("%s: fork: %s", applet, strerror(errno));
@@ -682,18 +736,22 @@ int main(int argc, char **argv)
/* this is the supervisor */
umask(numask);
#ifdef TIOCNOTTY
tty_fd = open("/dev/tty", O_RDWR);
#endif
devnull_fd = open("/dev/null", O_RDWR);
fp = fopen(pidfile, "w");
if (! fp)
eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
fprintf(fp, "%d\n", getpid());
fclose(fp);
if (svcname)
rc_service_daemon_set(svcname, exec,
(const char * const *) argv, pidfile, true);
/* remove the controlling tty */
#ifdef TIOCNOTTY
ioctl(tty_fd, TIOCNOTTY, 0);
close(tty_fd);
#endif
/*
* Supervisor main loop
*/
@@ -704,6 +762,23 @@ 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)
first_spawn = respawn_now;
if (respawn_now - first_spawn > respawn_period) {
respawn_count = 0;
first_spawn = 0;
} else
respawn_count++;
if (respawn_count >= respawn_max) {
syslog(LOG_INFO, "respawned \"%s\" too many times, "
"exiting", exec);
exiting = true;
continue;
}
}
if (WIFEXITED(i))
syslog(LOG_INFO, "%s, pid %d, exited with return code %d",
exec, child_pid, WEXITSTATUS(i));
@@ -714,15 +789,19 @@ int main(int argc, char **argv)
if (child_pid == -1)
eerrorx("%s: fork: %s", applet, strerror(errno));
if (child_pid == 0)
child_process(exec, argv);
child_process(exec, argv, svcname, respawn_count);
}
}
if (svcname)
if (pidfile && exists(pidfile))
unlink(pidfile);
if (svcname) {
rc_service_daemon_set(svcname, exec,
(const char * const *) argv, pidfile, true);
(const char *const *)argv,
pidfile, false);
rc_service_mark(svcname, RC_SERVICE_STOPPED);
}
exit(EXIT_SUCCESS);
} else if (child_pid == 0)
child_process(exec, argv);
child_process(exec, argv, svcname, respawn_count);
}