From 701540827e27a4f07ac725db3ce361d3be0c106f Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Mon, 19 Jan 2015 16:11:24 +0000 Subject: - added the s6_fdholder library to libs6. (Nothing useful yet.) - fixed execline invocation in s6-log with slashpackage - integrated s6_svc_main.c's functionality into s6-svscanctl and deleted it - integrated Olivier Brunel's suggestions for wstat report in supervise/status - minor fixes to s6-supervise's status reports - separated sigaction calls in ftrigw_notifyb, this spares a few syscalls in s6-supervise - updated doc to reflect the changes - version bumped to 2.1.0.0 because API breakage (./finish, s6-svstat) --- src/supervision/s6-supervise.c | 30 +++++++++++------------ src/supervision/s6-svscan.c | 7 +++--- src/supervision/s6-svscanctl.c | 55 +++++++++++++++++++++++++++++++++++++++++- src/supervision/s6-svstat.c | 48 +++++++++++++++++++++++++++++++----- 4 files changed, 114 insertions(+), 26 deletions(-) (limited to 'src/supervision') diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c index 65cbd9d..bb4e761 100644 --- a/src/supervision/s6-supervise.c +++ b/src/supervision/s6-supervise.c @@ -45,7 +45,7 @@ typedef void action_t (void) ; typedef action_t *action_t_ref ; static tain_t deadline ; -static s6_svstatus_t status = { .stamp = TAIN_ZERO, .pid = 0, .flagwant = 1, .flagwantup = 1, .flagpaused = 0, .flagfinishing = 0 } ; +static s6_svstatus_t status = { .stamp = TAIN_ZERO, .pid = 0, .flagwant = 1, .flagwantup = 1, .flagpaused = 0, .flagfinishing = 0, .wstat = 0 } ; static state_t state = DOWN ; static int flagsetsid = 1 ; static int cont = 1 ; @@ -166,7 +166,7 @@ static void trystart (void) if (flagsetsid) setsid() ; execve("./run", (char *const *)cargv, (char *const *)environ) ; fd_write(p[1], "", 1) ; - strerr_dieexec(111, "run") ; + strerr_dieexec(127, "run") ; } fd_close(p[1]) ; { @@ -194,7 +194,7 @@ static void trystart (void) status.pid = pid ; tain_copynow(&status.stamp) ; announce() ; - ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'u') ; + ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ; } static void downtimeout (void) @@ -230,7 +230,7 @@ static void down_d (void) announce() ; } -static void tryfinish (int wstat, int islast) +static inline void tryfinish (int islast) { register pid_t pid = fork() ; if (pid < 0) @@ -238,7 +238,6 @@ static void tryfinish (int wstat, int islast) strerr_warnwu2sys("fork for ", "./finish") ; if (islast) bail() ; state = DOWN ; - status.pid = 0 ; settimeout(1) ; return ; } @@ -248,16 +247,15 @@ static void tryfinish (int wstat, int islast) char fmt1[UINT_FMT] ; char *cargv[4] = { "finish", fmt0, fmt1, 0 } ; selfpipe_finish() ; - fmt0[uint_fmt(fmt0, WIFSIGNALED(wstat) ? 255 : WEXITSTATUS(wstat))] = 0 ; - fmt1[uint_fmt(fmt1, WTERMSIG(wstat))] = 0 ; + fmt0[uint_fmt(fmt0, WIFSIGNALED(status.wstat) ? 256 : WEXITSTATUS(status.wstat))] = 0 ; + fmt1[uint_fmt(fmt1, WTERMSIG(status.wstat))] = 0 ; if (flagsetsid) setsid() ; execve("./finish", cargv, (char *const *)environ) ; - _exit(111) ; + _exit(127) ; } status.pid = pid ; status.flagfinishing = 1 ; state = islast ? LASTFINISH : FINISH ; - settimeout(5) ; } static void uptimeout (void) @@ -268,18 +266,20 @@ static void uptimeout (void) static void uplastup_z (int islast) { - int wstat = status.pid ; + status.wstat = status.pid ; status.pid = 0 ; tain_copynow(&status.stamp) ; + tryfinish(islast) ; announce() ; - ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'd') ; + ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "d", 1) ; if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT) strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ; - tryfinish(wstat, islast) ; + settimeout(5) ; } static void up_z (void) { + status.flagpaused = 0 ; uplastup_z(0) ; } @@ -401,7 +401,7 @@ static void handle_signals (void) if (errno != ECHILD) strerr_diefu1sys(111, "wait_pid_nohang") ; else break ; else if (!r) break ; - status.pid = wstat ; + status.pid = wstat ; /* don't overwrite status.wstat if it's ./finish */ (*actions[state][V_CHLD])() ; } break ; @@ -490,7 +490,7 @@ int main (int argc, char const *const *argv) settimeout(0) ; tain_copynow(&status.stamp) ; announce() ; - ftrigw_notify(S6_SUPERVISE_EVENTDIR, 's') ; + ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ; while (cont) { @@ -506,7 +506,7 @@ int main (int argc, char const *const *argv) } } - ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'x') ; + ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "x", 1) ; } return 0 ; } diff --git a/src/supervision/s6-svscan.c b/src/supervision/s6-svscan.c index 8b0f82e..e07ff35 100644 --- a/src/supervision/s6-svscan.c +++ b/src/supervision/s6-svscan.c @@ -29,7 +29,7 @@ #define DIR_RETRY_TIMEOUT 3 #define CHECK_RETRY_TIMEOUT 4 -struct svinfo +struct svinfo_s { dev_t dev ; ino_t ino ; @@ -39,9 +39,8 @@ struct svinfo unsigned int flagactive : 1 ; unsigned int flaglog : 1 ; } ; -#define SVINFO_ZERO { -1, -1, { TAIN_ZERO, TAIN_ZERO }, { 0, 0 }, { -1, -1 }, 0, 0, 0 } ; -static struct svinfo *services ; +static struct svinfo_s *services ; static unsigned int max = 500 ; static unsigned int n = 0 ; static tain_t deadline, defaulttimeout ; @@ -452,7 +451,7 @@ int main (int argc, char const *const *argv) { - struct svinfo blob[max] ; /* careful with that stack, Eugene */ + struct svinfo_s blob[max] ; /* careful with that stack, Eugene */ services = blob ; tain_now_g() ; diff --git a/src/supervision/s6-svscanctl.c b/src/supervision/s6-svscanctl.c index 48e6420..6529e9c 100644 --- a/src/supervision/s6-svscanctl.c +++ b/src/supervision/s6-svscanctl.c @@ -1,12 +1,65 @@ /* ISC license. */ +#include +#include #include #include #define USAGE "s6-svscanctl [ -phratszbnNiq0678 ] svscandir" +#define dieusage() strerr_dieusage(100, USAGE) + +#define DATASIZE 64 int main (int argc, char const *const *argv) { + char data[DATASIZE] ; + unsigned int datalen = 0 ; + int r ; PROG = "s6-svscanctl" ; - return s6_svc_main(argc, argv, "phratszbnNiq0678", USAGE, ".s6-svscan") ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "phratszbnNiq0678", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'p' : + case 'h' : + case 'r' : + case 'a' : + case 't' : + case 's' : + case 'z' : + case 'b' : + case 'n' : + case 'N' : + case 'i' : + case 'q' : + case '0' : + case '6' : + case '7' : + case '8' : + { + if (datalen >= DATASIZE) strerr_dief1x(100, "too many commands") ; + data[datalen++] = opt ; + break ; + } + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + } + if (!argc) dieusage() ; + + { + unsigned int arglen = str_len(*argv) ; + char tmp[arglen + 20] ; + byte_copy(tmp, arglen, *argv) ; + byte_copy(tmp + arglen, 20, "/.s6-svscan/control") ; + r = s6_svc_write(tmp, data, datalen) ; + } + if (r < 0) strerr_diefu2sys(111, "control ", *argv) ; + else if (!r) strerr_diefu3x(100, "control ", *argv, ": supervisor not listening") ; + return 0 ; } diff --git a/src/supervision/s6-svstat.c b/src/supervision/s6-svstat.c index c986b8d..a4facf5 100644 --- a/src/supervision/s6-svstat.c +++ b/src/supervision/s6-svstat.c @@ -1,27 +1,46 @@ /* ISC license. */ -#include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include #include -#define USAGE "s6-svstat servicedir" +#define USAGE "s6-svstat [ -n ] servicedir" +#define dieusage() strerr_dieusage(100, USAGE) int main (int argc, char const *const *argv) { s6_svstatus_t status ; - char fmt[UINT_FMT] ; + int flagnum = 0 ; int isup, normallyup ; + char fmt[UINT_FMT] ; PROG = "s6-svstat" ; - if (argc < 2) strerr_dieusage(100, USAGE) ; - argv++ ; argc-- ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "n", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'n' : flagnum = 1 ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + } + if (!argc) dieusage() ; + if (!s6_svstatus_read(*argv, &status)) strerr_diefu2sys(111, "read status for ", *argv) ; @@ -48,7 +67,24 @@ int main (int argc, char const *const *argv) buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, status.pid)) ; buffer_putnoflush(buffer_1small, ") ", 2) ; } - else buffer_putnoflush(buffer_1small, "down ", 5) ; + else + { + buffer_putnoflush(buffer_1small, "down (", 6) ; + if (WIFSIGNALED(status.wstat)) + { + buffer_putnoflush(buffer_1small, "signal ", 7) ; + if (flagnum) + buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, WTERMSIG(status.wstat))) ; + else + buffer_putsnoflush(buffer_1small, sig_name(WTERMSIG(status.wstat))) ; + } + else + { + buffer_putnoflush(buffer_1small, "exitcode ", 9) ; + buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, WEXITSTATUS(status.wstat))) ; + } + buffer_putnoflush(buffer_1small, ") ", 2) ; + } buffer_putnoflush(buffer_1small, fmt, uint64_fmt(fmt, status.stamp.sec.x)) ; buffer_putnoflush(buffer_1small," seconds", 8) ; -- cgit v1.2.3