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:
parent
79c0d7332a
commit
bcb5764822
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user