runsvdir: (almost) close a signal race
We could lose a signal while processing previous one function old new delta runsvdir_main 1088 1077 -11 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
1eafd44947
commit
fa535f3e48
@ -59,7 +59,6 @@ struct globals {
|
|||||||
int svnum;
|
int svnum;
|
||||||
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
||||||
char *rplog;
|
char *rplog;
|
||||||
int rploglen;
|
|
||||||
struct fd_pair logpipe;
|
struct fd_pair logpipe;
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
unsigned stamplog;
|
unsigned stamplog;
|
||||||
@ -70,7 +69,6 @@ struct globals {
|
|||||||
#define svdir (G.svdir )
|
#define svdir (G.svdir )
|
||||||
#define svnum (G.svnum )
|
#define svnum (G.svnum )
|
||||||
#define rplog (G.rplog )
|
#define rplog (G.rplog )
|
||||||
#define rploglen (G.rploglen )
|
|
||||||
#define logpipe (G.logpipe )
|
#define logpipe (G.logpipe )
|
||||||
#define pfd (G.pfd )
|
#define pfd (G.pfd )
|
||||||
#define stamplog (G.stamplog )
|
#define stamplog (G.stamplog )
|
||||||
@ -219,15 +217,11 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
struct stat s;
|
struct stat s;
|
||||||
dev_t last_dev = last_dev; /* for gcc */
|
dev_t last_dev = last_dev; /* for gcc */
|
||||||
ino_t last_ino = last_ino; /* for gcc */
|
ino_t last_ino = last_ino; /* for gcc */
|
||||||
time_t last_mtime = 0;
|
time_t last_mtime;
|
||||||
int wstat;
|
|
||||||
int curdir;
|
int curdir;
|
||||||
pid_t pid;
|
|
||||||
unsigned deadline;
|
|
||||||
unsigned now;
|
|
||||||
unsigned stampcheck;
|
unsigned stampcheck;
|
||||||
int i;
|
int i;
|
||||||
int need_rescan = 1;
|
int need_rescan;
|
||||||
char *opt_s_argv[3];
|
char *opt_s_argv[3];
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
@ -257,8 +251,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* setup log */
|
/* setup log */
|
||||||
if (*argv) {
|
if (*argv) {
|
||||||
rplog = *argv;
|
rplog = *argv;
|
||||||
rploglen = strlen(rplog);
|
if (strlen(rplog) < 7) {
|
||||||
if (rploglen < 7) {
|
|
||||||
warnx("log must have at least seven characters");
|
warnx("log must have at least seven characters");
|
||||||
} else if (piped_pair(logpipe)) {
|
} else if (piped_pair(logpipe)) {
|
||||||
warnx("can't create pipe for log");
|
warnx("can't create pipe for log");
|
||||||
@ -287,11 +280,16 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
close_on_exec_on(curdir);
|
close_on_exec_on(curdir);
|
||||||
|
|
||||||
stampcheck = monotonic_sec();
|
stampcheck = monotonic_sec();
|
||||||
|
need_rescan = 1;
|
||||||
|
last_mtime = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
unsigned now;
|
||||||
|
unsigned sig;
|
||||||
|
|
||||||
/* collect children */
|
/* collect children */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = wait_any_nohang(&wstat);
|
pid_t pid = wait_any_nohang(NULL);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
break;
|
break;
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
@ -345,15 +343,17 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
pfd[0].revents = 0;
|
pfd[0].revents = 0;
|
||||||
#endif
|
#endif
|
||||||
deadline = (need_rescan ? 1 : 5);
|
{
|
||||||
sig_block(SIGCHLD);
|
unsigned deadline = (need_rescan ? 1 : 5);
|
||||||
|
sig_block(SIGCHLD);
|
||||||
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
||||||
if (rplog)
|
if (rplog)
|
||||||
poll(pfd, 1, deadline*1000);
|
poll(pfd, 1, deadline*1000);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
sleep(deadline);
|
sleep(deadline);
|
||||||
sig_unblock(SIGCHLD);
|
sig_unblock(SIGCHLD);
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
||||||
if (pfd[0].revents & POLLIN) {
|
if (pfd[0].revents & POLLIN) {
|
||||||
@ -361,21 +361,25 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
while (read(logpipe.rd, &ch, 1) > 0) {
|
while (read(logpipe.rd, &ch, 1) > 0) {
|
||||||
if (ch < ' ')
|
if (ch < ' ')
|
||||||
ch = ' ';
|
ch = ' ';
|
||||||
for (i = 6; i < rploglen; i++)
|
for (i = 6; rplog[i] != '\0'; i++)
|
||||||
rplog[i-1] = rplog[i];
|
rplog[i-1] = rplog[i];
|
||||||
rplog[rploglen-1] = ch;
|
rplog[i-1] = ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!bb_got_signal)
|
sig = bb_got_signal;
|
||||||
|
if (!sig)
|
||||||
continue;
|
continue;
|
||||||
|
bb_got_signal = 0;
|
||||||
|
|
||||||
/* -s SCRIPT: useful if we are init.
|
/* -s SCRIPT: useful if we are init.
|
||||||
* In this case typically script never returns,
|
* In this case typically script never returns,
|
||||||
* it halts/powers off/reboots the system. */
|
* it halts/powers off/reboots the system. */
|
||||||
if (opt_s_argv[0]) {
|
if (opt_s_argv[0]) {
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
/* Single parameter: signal# */
|
/* Single parameter: signal# */
|
||||||
opt_s_argv[1] = utoa(bb_got_signal);
|
opt_s_argv[1] = utoa(sig);
|
||||||
pid = spawn(opt_s_argv);
|
pid = spawn(opt_s_argv);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
/* Remembering to wait for _any_ children,
|
/* Remembering to wait for _any_ children,
|
||||||
@ -385,7 +389,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bb_got_signal == SIGHUP) {
|
if (sig == SIGHUP) {
|
||||||
for (i = 0; i < svnum; i++)
|
for (i = 0; i < svnum; i++)
|
||||||
if (sv[i].pid)
|
if (sv[i].pid)
|
||||||
kill(sv[i].pid, SIGTERM);
|
kill(sv[i].pid, SIGTERM);
|
||||||
@ -393,9 +397,8 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* SIGHUP or SIGTERM (or SIGUSRn if we are init) */
|
/* SIGHUP or SIGTERM (or SIGUSRn if we are init) */
|
||||||
/* Exit unless we are init */
|
/* Exit unless we are init */
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;
|
return (SIGHUP == sig) ? 111 : EXIT_SUCCESS;
|
||||||
|
|
||||||
/* init continues to monitor services forever */
|
/* init continues to monitor services forever */
|
||||||
bb_got_signal = 0;
|
|
||||||
} /* for (;;) */
|
} /* for (;;) */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user