runsv: update to match version 2.1.2 of runit

Backport from upstream versions:
2.1.0
Thu, 24 Sep 2009 22:49:33 +0000
  * runsv.c: exit with error if [log/]supervise/control exists, but is
    not a fifo.
    [Code abstracted into a separate function to make it more compact
    for BusyBox.]

1.9.0
Mon, 05 May 2008 22:00:13 +0000
  * runsv.c: create temporary new status files for log/supervise/
    actually in log/supervise/.

1.7.2
Tue, 21 Nov 2006 15:13:47 +0000
  * runsv.c: really don't act on commands in state finish; minor.

function                                             old     new   delta
open_control                                           -     135    +135
update_status                                        553     612     +59
custom                                               223     242     +19
ctrl                                                 426     422      -4
warn_cannot                                           21      10     -11
runsv_main                                          1786    1662    -124
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/3 up/down: 213/-139)           Total: 74 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-05-15 19:44:48 +02:00
parent 79c0d7332a
commit bcb5764822

View File

@ -134,9 +134,13 @@ static void fatal2x_cannot(const char *m1, const char *m2)
bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2);
/* was exiting 111 */ /* was exiting 111 */
} }
static void warn2_cannot(const char *m1, const char *m2)
{
bb_perror_msg("%s: warning: can't %s%s", dir, m1, m2);
}
static void warn_cannot(const char *m) static void warn_cannot(const char *m)
{ {
bb_perror_msg("%s: warning: cannot %s", dir, m); warn2_cannot(m, "");
} }
static void s_child(int sig_no UNUSED_PARAM) static void s_child(int sig_no UNUSED_PARAM)
@ -165,10 +169,25 @@ static void update_status(struct svdir *s)
ssize_t sz; ssize_t sz;
int fd; int fd;
svstatus_t status; svstatus_t status;
const char *fstatus ="log/supervise/status";
const char *fstatusnew ="log/supervise/status.new";
const char *f_stat ="log/supervise/stat";
const char *fstatnew ="log/supervise/stat.new";
const char *fpid ="log/supervise/pid";
const char *fpidnew ="log/supervise/pid.new";
if (!s->islog) {
fstatus += 4;
fstatusnew += 4;
f_stat += 4;
fstatnew += 4;
fpid += 4;
fpidnew += 4;
}
/* pid */ /* pid */
if (pidchanged) { if (pidchanged) {
fd = open_trunc_or_warn("supervise/pid.new"); fd = open_trunc_or_warn(fpidnew);
if (fd < 0) if (fd < 0)
return; return;
if (s->pid) { if (s->pid) {
@ -177,14 +196,13 @@ static void update_status(struct svdir *s)
write(fd, spid, size); write(fd, spid, size);
} }
close(fd); close(fd);
if (rename_or_warn("supervise/pid.new", if (rename_or_warn(fpidnew, fpid))
s->islog ? "log/supervise/pid" : "log/supervise/pid"+4))
return; return;
pidchanged = 0; pidchanged = 0;
} }
/* stat */ /* stat */
fd = open_trunc_or_warn("supervise/stat.new"); fd = open_trunc_or_warn(fstatnew);
if (fd < -1) if (fd < -1)
return; return;
@ -220,8 +238,7 @@ static void update_status(struct svdir *s)
close(fd); close(fd);
} }
rename_or_warn("supervise/stat.new", rename_or_warn(fstatnew, f_stat);
s->islog ? "log/supervise/stat" : "log/supervise/stat"+4);
/* supervise compatibility */ /* supervise compatibility */
memset(&status, 0, sizeof(status)); memset(&status, 0, sizeof(status));
@ -237,18 +254,17 @@ static void update_status(struct svdir *s)
if (s->ctrl & C_TERM) if (s->ctrl & C_TERM)
status.got_term = 1; status.got_term = 1;
status.run_or_finish = s->state; status.run_or_finish = s->state;
fd = open_trunc_or_warn("supervise/status.new"); fd = open_trunc_or_warn(fstatusnew);
if (fd < 0) if (fd < 0)
return; return;
sz = write(fd, &status, sizeof(status)); sz = write(fd, &status, sizeof(status));
close(fd); close(fd);
if (sz != sizeof(status)) { if (sz != sizeof(status)) {
warn_cannot("write supervise/status.new"); warn2_cannot("write ", fstatusnew);
unlink("supervise/status.new"); unlink(fstatusnew);
return; return;
} }
rename_or_warn("supervise/status.new", rename_or_warn(fstatusnew, fstatus);
s->islog ? "log/supervise/status" : "log/supervise/status"+4);
} }
static unsigned custom(struct svdir *s, char c) static unsigned custom(struct svdir *s, char c)
@ -266,26 +282,26 @@ static unsigned custom(struct svdir *s, char c)
if (st.st_mode & S_IXUSR) { if (st.st_mode & S_IXUSR) {
pid = vfork(); pid = vfork();
if (pid == -1) { if (pid == -1) {
warn_cannot("vfork for control/?"); warn2_cannot("vfork for ", a);
return 0; return 0;
} }
if (pid == 0) { if (pid == 0) {
/* child */ /* child */
if (haslog && dup2(logpipe.wr, 1) == -1) if (haslog && dup2(logpipe.wr, 1) == -1)
warn_cannot("setup stdout for control/?"); warn2_cannot("setup stdout for ", a);
execl(a, a, (char *) NULL); execl(a, a, (char *) NULL);
fatal_cannot("run control/?"); fatal2_cannot("run ", a);
} }
/* parent */ /* parent */
if (safe_waitpid(pid, &w, 0) == -1) { if (safe_waitpid(pid, &w, 0) == -1) {
warn_cannot("wait for child control/?"); warn2_cannot("wait for child ", a);
return 0; return 0;
} }
return WEXITSTATUS(w) == 0; return WEXITSTATUS(w) == 0;
} }
} else { } else {
if (errno != ENOENT) if (errno != ENOENT)
warn_cannot("stat control/?"); warn2_cannot("stat ", a);
} }
return 0; return 0;
} }
@ -387,13 +403,13 @@ static int ctrl(struct svdir *s, char c)
case 'd': /* down */ case 'd': /* down */
s->sd_want = W_DOWN; s->sd_want = W_DOWN;
update_status(s); update_status(s);
if (s->pid && s->state != S_FINISH) if (s->state == S_RUN)
stopservice(s); stopservice(s);
break; break;
case 'u': /* up */ case 'u': /* up */
s->sd_want = W_UP; s->sd_want = W_UP;
update_status(s); update_status(s);
if (s->pid == 0) if (s->state == S_DOWN)
startservice(s); startservice(s);
break; break;
case 'x': /* exit */ case 'x': /* exit */
@ -403,22 +419,22 @@ static int ctrl(struct svdir *s, char c)
update_status(s); update_status(s);
/* FALLTHROUGH */ /* FALLTHROUGH */
case 't': /* sig term */ case 't': /* sig term */
if (s->pid && s->state != S_FINISH) if (s->state == S_RUN)
stopservice(s); stopservice(s);
break; break;
case 'k': /* sig kill */ case 'k': /* sig kill */
if (s->pid && !custom(s, c)) if ((s->state == S_RUN) && !custom(s, c))
kill(s->pid, SIGKILL); kill(s->pid, SIGKILL);
s->state = S_DOWN; s->state = S_DOWN;
break; break;
case 'p': /* sig pause */ case 'p': /* sig pause */
if (s->pid && !custom(s, c)) if ((s->state == S_RUN) && !custom(s, c))
kill(s->pid, SIGSTOP); kill(s->pid, SIGSTOP);
s->ctrl |= C_PAUSE; s->ctrl |= C_PAUSE;
update_status(s); update_status(s);
break; break;
case 'c': /* sig cont */ case 'c': /* sig cont */
if (s->pid && !custom(s, c)) if ((s->state == S_RUN) && !custom(s, c))
kill(s->pid, SIGCONT); kill(s->pid, SIGCONT);
s->ctrl &= ~C_PAUSE; s->ctrl &= ~C_PAUSE;
update_status(s); update_status(s);
@ -426,7 +442,7 @@ static int ctrl(struct svdir *s, char c)
case 'o': /* once */ case 'o': /* once */
s->sd_want = W_DOWN; s->sd_want = W_DOWN;
update_status(s); update_status(s);
if (!s->pid) if (s->state == S_DOWN)
startservice(s); startservice(s);
break; break;
case 'a': /* sig alarm */ case 'a': /* sig alarm */
@ -450,11 +466,26 @@ static int ctrl(struct svdir *s, char c)
} }
return 1; return 1;
sendsig: sendsig:
if (s->pid && !custom(s, c)) if ((s->state == S_RUN) && !custom(s, c))
kill(s->pid, sig); kill(s->pid, sig);
return 1; return 1;
} }
static void open_control(const char *f, struct svdir *s)
{
struct stat st;
mkfifo(f, 0600);
if (stat(f, &st) == -1)
fatal2_cannot("stat ", f);
if (!S_ISFIFO(st.st_mode))
bb_error_msg_and_die("%s: fatal: %s exists but is not a fifo", dir, f);
s->fdcontrol = xopen(f, O_RDONLY|O_NDELAY);
close_on_exec_on(s->fdcontrol);
s->fdcontrolwrite = xopen(f, O_WRONLY|O_NDELAY);
close_on_exec_on(s->fdcontrolwrite);
update_status(s);
}
int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int runsv_main(int argc UNUSED_PARAM, char **argv) int runsv_main(int argc UNUSED_PARAM, char **argv)
{ {
@ -554,19 +585,9 @@ int runsv_main(int argc UNUSED_PARAM, char **argv)
close_on_exec_on(svd[1].fdlock); close_on_exec_on(svd[1].fdlock);
} }
mkfifo("log/supervise/control"+4, 0600); open_control("log/supervise/control"+4, &svd[0]);
svd[0].fdcontrol = xopen("log/supervise/control"+4, O_RDONLY|O_NDELAY);
close_on_exec_on(svd[0].fdcontrol);
svd[0].fdcontrolwrite = xopen("log/supervise/control"+4, O_WRONLY|O_NDELAY);
close_on_exec_on(svd[0].fdcontrolwrite);
update_status(&svd[0]);
if (haslog) { if (haslog) {
mkfifo("log/supervise/control", 0600); open_control("log/supervise/control", &svd[1]);
svd[1].fdcontrol = xopen("log/supervise/control", O_RDONLY|O_NDELAY);
close_on_exec_on(svd[1].fdcontrol);
svd[1].fdcontrolwrite = xopen("log/supervise/control", O_WRONLY|O_NDELAY);
close_on_exec_on(svd[1].fdcontrolwrite);
update_status(&svd[1]);
} }
mkfifo("log/supervise/ok"+4, 0600); mkfifo("log/supervise/ok"+4, 0600);
fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY); fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY);