runsv: update to match version 2.1.2 of runit
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 15 May 2017 17:44:48 +0000 (19:44 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 15 May 2017 17:44:48 +0000 (19:44 +0200)
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>
runit/runsv.c

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