FreeBSD Bugzilla – Attachment 239046 Details for
Bug 268580
Add shutdown delay to daemon(8)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Diff to add shutdown_delay to daemon utility
daemon.diff (text/plain), 4.87 KB, created by
Nathan Huff
on 2022-12-26 22:08:30 UTC
(
hide
)
Description:
Diff to add shutdown_delay to daemon utility
Filename:
MIME Type:
Creator:
Nathan Huff
Created:
2022-12-26 22:08:30 UTC
Size:
4.87 KB
patch
obsolete
>diff --git a/usr.sbin/daemon/daemon.8 b/usr.sbin/daemon/daemon.8 >index c4f20548d4a2..70ee51ba9d93 100644 >--- a/usr.sbin/daemon/daemon.8 >+++ b/usr.sbin/daemon/daemon.8 >@@ -60,6 +60,11 @@ The options are as follows: > .It Fl c > Change the current working directory to the root > .Pq Dq Pa / . >+.It Fl d Ar shutdown_delay >+When the daemon process receives SIGTERM forward the SIGTERM signal to >+the supervised process. If it has not exited in delay seconds send SIGKILL >+to the supervised process. The daemon process will wait for the supervised process >+to exit continuing to log any output if requested. > .It Fl f > Redirect standard input, standard output and standard error to > .Pa /dev/null . >@@ -169,6 +174,7 @@ If any of the options > .Fl T , > .Fl m , > .Fl S , >+.Fl d , > or > .Fl l > are specified, the program is executed in a spawned child process. >diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c >index e8cdaa230caa..3b5834063970 100644 >--- a/usr.sbin/daemon/daemon.c >+++ b/usr.sbin/daemon/daemon.c >@@ -69,6 +69,7 @@ static void restrict_process(const char *); > static void handle_term(int); > static void handle_chld(int); > static void handle_hup(int); >+static void handle_alarm(int); > static int open_log(const char *); > static void reopen_log(struct log_params *); > static int listen_child(int, struct log_params *); >@@ -86,7 +87,7 @@ int > main(int argc, char *argv[]) > { > const char *pidfile, *ppidfile, *title, *user, *outfn, *logtag; >- int ch, nochdir, noclose, restart, dosyslog, child_eof; >+ int ch, nochdir, noclose, restart, dosyslog, child_eof, delay; > sigset_t mask_susp, mask_orig, mask_read, mask_term; > struct log_params logpar; > int pfd[2] = { -1, -1 }, outfd = -1; >@@ -104,9 +105,10 @@ main(int argc, char *argv[]) > restart = 0; > dosyslog = 0; > log_reopen = 0; >+ delay = 0; > outfn = NULL; > title = NULL; >- while ((ch = getopt(argc, argv, "cfHSp:P:ru:o:s:l:t:l:m:R:T:")) != -1) { >+ while ((ch = getopt(argc, argv, "cfHSp:P:ru:o:s:l:t:l:m:R:T:d:")) != -1) { > switch (ch) { > case 'c': > nochdir = 0; >@@ -164,6 +166,11 @@ main(int argc, char *argv[]) > case 'u': > user = optarg; > break; >+ case 'd': >+ delay = strtol(optarg, &p, 0); >+ if (p == optarg || delay < 0) >+ errx(6, "invalid shutdown delay"); >+ break; > default: > usage(); > } >@@ -210,7 +217,7 @@ main(int argc, char *argv[]) > * and syslog. > */ > pid = -1; >- if (pidfile || ppidfile || restart || outfd != -1 || dosyslog) { >+ if (pidfile || ppidfile || restart || outfd != -1 || dosyslog || delay) { > struct sigaction act_term, act_chld, act_hup; > > /* Avoid PID racing with SIGCHLD and SIGTERM. */ >@@ -355,7 +362,7 @@ main(int argc, char *argv[]) > if (child_gone && child_eof) { > break; > } else if (terminate) { >- goto exit; >+ goto cleanup; > } else if (!child_eof) { > if (sigprocmask(SIG_BLOCK, &mask_read, NULL)) { > warn("sigprocmask"); >@@ -390,6 +397,42 @@ main(int argc, char *argv[]) > pfd[0] = -1; > goto restart; > } >+ >+cleanup: >+ /* >+ * If shutdown delay is set and the child process is still running >+ * wait for up to delay seconds for it to exit. While we wait try and >+ * output any last messages from the process. If we get to the >+ * elapsed time send sigkill to the child process. At that point we >+ * should get a SIGCHLD signal to set child_gone and we break out of >+ * our read loop. >+ */ >+ if (!child_gone && delay) { >+ struct sigaction act_alarm; >+ memset(&act_alarm, 0, sizeof(act_alarm)); >+ act_alarm.sa_handler = handle_alarm; >+ sigemptyset(&act_alarm.sa_mask); >+ /* Don't want to race with SIGCHLD handler setting child_gone */ >+ sigaddset(&act_alarm.sa_mask, SIGCHLD); >+ >+ if (sigaction(SIGALRM, &act_alarm, NULL) == -1) { >+ warn("sigaction"); >+ goto exit; >+ } >+ alarm(delay); >+ while (!child_eof) { >+ child_eof = !listen_child(pfd[0], &logpar); >+ } >+ /* Block SIGCHLD while we test if child is gone */ >+ if (sigprocmask(SIG_BLOCK, &mask_susp, &mask_orig)) { >+ warn("sigprocmask"); >+ goto exit; >+ } >+ while(!child_gone) { >+ sigsuspend(&mask_orig); >+ } >+ alarm(0); >+ } > exit: > close(outfd); > close(pfd[0]); >@@ -556,6 +599,14 @@ do_output(const unsigned char *buf, size_t len, struct log_params *logpar) > printf("%.*s", (int)len, buf); > } > >+static void >+handle_alarm(int signo __unused) >+{ >+ if (pid > 0 && !child_gone) { >+ kill(pid, SIGKILL); >+ } >+} >+ > /* > * We use the global PID acquired directly from fork. If there is no valid > * child pid, the handler should be blocked and/or child_gone == 1. >@@ -615,7 +666,7 @@ usage(void) > { > (void)fprintf(stderr, > "usage: daemon [-cfHrS] [-p child_pidfile] [-P supervisor_pidfile]\n" >- " [-u user] [-o output_file] [-t title]\n" >+ " [-u user] [-o output_file] [-t title] [-d shutdown_delay]\n" > " [-l syslog_facility] [-s syslog_priority]\n" > " [-T syslog_tag] [-m output_mask] [-R restart_delay_secs]\n" > "command arguments ...\n");
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 268580
: 239046