aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runit/Config.in9
-rw-r--r--runit/runsvdir.c143
2 files changed, 88 insertions, 64 deletions
diff --git a/runit/Config.in b/runit/Config.in
index 8a7deea72..beff1e7e2 100644
--- a/runit/Config.in
+++ b/runit/Config.in
@@ -20,6 +20,15 @@ config RUNSVDIR
a directory, in the services directory dir, up to a limit of 1000
subdirectories, and restarts a runsv process if it terminates.
+config FEATURE_RUNSVDIR_LOG
+ bool "Enable scrolling argument log"
+ depends on RUNSVDIR
+ default n
+ help
+ Enable feature where second parameter of runsvdir holds last error
+ message (viewable via top/ps). Otherwise (feature is off
+ or no parameter), error messages go to stderr only.
+
config SV
bool "sv"
default n
diff --git a/runit/runsvdir.c b/runit/runsvdir.c
index 0dedd5c77..8099ebf5c 100644
--- a/runit/runsvdir.c
+++ b/runit/runsvdir.c
@@ -35,8 +35,13 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define MAXSERVICES 1000
+/* Should be not needed - all dirs are on same FS, right? */
+#define CHECK_DEVNO_TOO 0
+
struct service {
+#if CHECK_DEVNO_TOO
dev_t dev;
+#endif
ino_t ino;
pid_t pid;
smallint isgone;
@@ -45,28 +50,30 @@ struct service {
struct globals {
struct service *sv;
char *svdir;
- char *rplog;
int svnum;
+#if ENABLE_FEATURE_RUNSVDIR_LOG
+ char *rplog;
int rploglen;
struct fd_pair logpipe;
struct pollfd pfd[1];
unsigned stamplog;
- smallint check; /* = 1; */
+#endif
+ smallint need_rescan; /* = 1; */
smallint set_pgrp;
};
#define G (*(struct globals*)&bb_common_bufsiz1)
-#define sv (G.sv )
-#define svdir (G.svdir )
-#define rplog (G.rplog )
-#define svnum (G.svnum )
-#define rploglen (G.rploglen )
-#define logpipe (G.logpipe )
-#define pfd (G.pfd )
-#define stamplog (G.stamplog )
-#define check (G.check )
-#define set_pgrp (G.set_pgrp )
+#define sv (G.sv )
+#define svdir (G.svdir )
+#define svnum (G.svnum )
+#define rplog (G.rplog )
+#define rploglen (G.rploglen )
+#define logpipe (G.logpipe )
+#define pfd (G.pfd )
+#define stamplog (G.stamplog )
+#define need_rescan (G.need_rescan )
+#define set_pgrp (G.set_pgrp )
#define INIT_G() do { \
- check = 1; \
+ need_rescan = 1; \
} while (0)
static void fatal2_cannot(const char *m1, const char *m2)
@@ -82,10 +89,12 @@ static void warn2_cannot(const char *m1, const char *m2)
{
warn3x("cannot ", m1, m2);
}
+#if ENABLE_FEATURE_RUNSVDIR_LOG
static void warnx(const char *m1)
{
warn3x(m1, "", "");
}
+#endif
static void runsv(int no, const char *name)
{
@@ -116,7 +125,7 @@ static void runsv(int no, const char *name)
sv[no].pid = pid;
}
-static void runsvdir(void)
+static void do_rescan(void)
{
DIR *dir;
direntry *d;
@@ -140,13 +149,16 @@ static void runsvdir(void)
continue;
if (stat(d->d_name, &s) == -1) {
warn2_cannot("stat ", d->d_name);
- errno = 0;
continue;
}
if (!S_ISDIR(s.st_mode))
continue;
for (i = 0; i < svnum; i++) {
- if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
+ if ((sv[i].ino == s.st_ino)
+#if CHECK_DEVNO_TOO
+ && (sv[i].dev == s.st_dev)
+#endif
+ ) {
sv[i].isgone = 0;
if (!sv[i].pid)
runsv(i, d->d_name);
@@ -157,66 +169,43 @@ static void runsvdir(void)
/* new service */
struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
if (!svnew) {
- warn3x("cannot start runsv ", d->d_name,
- " too many services");
+ warn2_cannot("start runsv ", d->d_name);
continue;
}
sv = svnew;
svnum++;
memset(&sv[i], 0, sizeof(sv[i]));
sv[i].ino = s.st_ino;
+#if CHECK_DEVNO_TOO
sv[i].dev = s.st_dev;
+#endif
/*sv[i].pid = 0;*/
/*sv[i].isgone = 0;*/
runsv(i, d->d_name);
- check = 1;
+ need_rescan = 1;
}
}
- if (errno) {
+ i = errno;
+ closedir(dir);
+ if (i) {
warn2_cannot("read directory ", svdir);
- closedir(dir);
- check = 1;
+ need_rescan = 1;
return;
}
- closedir(dir);
- /* SIGTERM removed runsv's */
+ /* Send SIGTERM to runsv whose directories were not found (removed) */
for (i = 0; i < svnum; i++) {
if (!sv[i].isgone)
continue;
if (sv[i].pid)
kill(sv[i].pid, SIGTERM);
- sv[i] = sv[--svnum];
-/* BUG? we deleted sv[i] by copying over sv[last], but we will not check this newly-copied one! */
- check = 1;
+ svnum--;
+ sv[i] = sv[svnum];
+ i--; /* so that we don't skip new sv[i] (bug was here!) */
+ need_rescan = 1;
}
}
-static int setup_log(void)
-{
- rploglen = strlen(rplog);
- if (rploglen < 7) {
- warnx("log must have at least seven characters");
- return 0;
- }
- if (piped_pair(logpipe)) {
- warnx("cannot create pipe for log");
- return -1;
- }
- close_on_exec_on(logpipe.rd);
- close_on_exec_on(logpipe.wr);
- ndelay_on(logpipe.rd);
- ndelay_on(logpipe.wr);
- if (dup2(logpipe.wr, 2) == -1) {
- warnx("cannot set filedescriptor for log");
- return -1;
- }
- pfd[0].fd = logpipe.rd;
- pfd[0].events = POLLIN;
- stamplog = monotonic_sec();
- return 1;
-}
-
int runsvdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int runsvdir_main(int argc UNUSED_PARAM, char **argv)
{
@@ -230,7 +219,6 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
unsigned deadline;
unsigned now;
unsigned stampcheck;
- char ch;
int i;
INIT_G();
@@ -241,13 +229,35 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
bb_signals_recursive((1 << SIGTERM) | (1 << SIGHUP), record_signo);
svdir = *argv++;
- if (argv && *argv) {
+
+#if ENABLE_FEATURE_RUNSVDIR_LOG
+ /* setup log */
+ if (*argv) {
rplog = *argv;
- if (setup_log() != 1) {
- rplog = 0;
- warnx("log service disabled");
+ rploglen = strlen(rplog);
+ if (rploglen < 7) {
+ warnx("log must have at least seven characters");
+ } else if (piped_pair(logpipe)) {
+ warnx("cannot create pipe for log");
+ } else {
+ close_on_exec_on(logpipe.rd);
+ close_on_exec_on(logpipe.wr);
+ ndelay_on(logpipe.rd);
+ ndelay_on(logpipe.wr);
+ if (dup2(logpipe.wr, 2) == -1) {
+ warnx("cannot set filedescriptor for log");
+ } else {
+ pfd[0].fd = logpipe.rd;
+ pfd[0].events = POLLIN;
+ stamplog = monotonic_sec();
+ goto run;
+ }
}
+ rplog = NULL;
+ warnx("log service disabled");
}
+run:
+#endif
curdir = open_read(".");
if (curdir == -1)
fatal2_cannot("open current directory", "");
@@ -265,7 +275,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
if (pid == sv[i].pid) {
/* runsv has gone */
sv[i].pid = 0;
- check = 1;
+ need_rescan = 1;
break;
}
}
@@ -277,7 +287,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
stampcheck = now + 1;
if (stat(svdir, &s) != -1) {
- if (check || s.st_mtime != last_mtime
+ if (need_rescan || s.st_mtime != last_mtime
|| s.st_ino != last_ino || s.st_dev != last_dev
) {
/* svdir modified */
@@ -285,10 +295,10 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
last_mtime = s.st_mtime;
last_dev = s.st_dev;
last_ino = s.st_ino;
- check = 0;
+ need_rescan = 0;
//if (now <= mtime)
// sleep(1);
- runsvdir();
+ do_rescan();
while (fchdir(curdir) == -1) {
warn2_cannot("change directory, pausing", "");
sleep(5);
@@ -300,23 +310,28 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
warn2_cannot("stat ", svdir);
}
+#if ENABLE_FEATURE_RUNSVDIR_LOG
if (rplog) {
if ((int)(now - stamplog) >= 0) {
write(logpipe.wr, ".", 1);
stamplog = now + 900;
}
}
-
pfd[0].revents = 0;
+#endif
sig_block(SIGCHLD);
- deadline = (check ? 1 : 5);
+ deadline = (need_rescan ? 1 : 5);
+#if ENABLE_FEATURE_RUNSVDIR_LOG
if (rplog)
poll(pfd, 1, deadline*1000);
else
+#endif
sleep(deadline);
sig_unblock(SIGCHLD);
+#if ENABLE_FEATURE_RUNSVDIR_LOG
if (pfd[0].revents & POLLIN) {
+ char ch;
while (read(logpipe.rd, &ch, 1) > 0) {
if (ch) {
for (i = 6; i < rploglen; i++)
@@ -325,7 +340,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
}
}
}
-
+#endif
switch (bb_got_signal) {
case SIGHUP:
for (i = 0; i < svnum; i++)