From cac30eda3f3dbb3c690715df5b2867d22b1fc497 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Mon, 5 Dec 2022 01:28:41 +0000 Subject: s6-svwait shouldn't exit early on supervisor death Signed-off-by: Laurent Bercot --- src/supervision/s6-svlisten.c | 28 ++++++++++++++++------------ src/supervision/s6-svlisten.h | 2 +- src/supervision/s6-svlisten1.c | 10 +++++----- src/supervision/s6-svwait.c | 8 +++----- src/supervision/s6_svlisten_loop.c | 11 +++++++++-- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/supervision/s6-svlisten.c b/src/supervision/s6-svlisten.c index 55aa993..1e060cf 100644 --- a/src/supervision/s6-svlisten.c +++ b/src/supervision/s6-svlisten.c @@ -21,7 +21,7 @@ int main (int argc, char const **argv, char const *const *envp) int spfd ; int argc1 ; int or = 0 ; - int wantup = 1, wantready = 0, wantrestart = 0 ; + int wantup = 1, wantready = 0 ; PROG = "s6-svlisten" ; { subgetopt l = SUBGETOPT_ZERO ; @@ -32,12 +32,12 @@ int main (int argc, char const **argv, char const *const *envp) if (opt == -1) break ; switch (opt) { - case 'u' : wantup = 1 ; wantrestart = 0 ; wantready = 0 ; break ; - case 'U' : wantup = 1 ; wantrestart = 0 ; wantready = 1 ; break ; - case 'd' : wantup = 0 ; wantrestart = 0 ; wantready = 0 ; break ; - case 'D' : wantup = 0 ; wantrestart = 0 ; wantready = 1 ; break ; - case 'r' : wantup = 1 ; wantrestart = 1 ; wantready = 0 ; break ; - case 'R' : wantup = 1 ; wantrestart = 1 ; wantready = 1 ; break ; + case 'u' : wantup = 1 ; wantready = 0 ; break ; + case 'U' : wantup = 1 ; wantready = 1 ; break ; + case 'd' : wantup = 0 ; wantready = 0 ; break ; + case 'D' : wantup = 0 ; wantready = 1 ; break ; + case 'r' : wantup = 2 ; wantready = 0 ; break ; + case 'R' : wantup = 2 ; wantready = 1 ; break ; case 'a' : or = 0 ; break ; case 'o' : or = 1 ; break ; case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; @@ -51,7 +51,7 @@ int main (int argc, char const **argv, char const *const *envp) argc1 = s6_el_semicolon(argv) ; if (!argc1 || argc == argc1 + 1) dieusage() ; if (argc1 >= argc) strerr_dief1x(100, "unterminated servicedir block") ; - if (wantrestart && or) + if (wantup == 2 && or) { or = 0 ; strerr_warnw3x("-o is unsupported when combined with -", wantready ? "R" : "r", "- using -a instead") ; @@ -64,17 +64,21 @@ int main (int argc, char const **argv, char const *const *envp) { s6_svlisten_t foo = S6_SVLISTEN_ZERO ; pid_t pid ; - int e ; + unsigned int e ; uint16_t ids[argc1] ; unsigned char upstate[bitarray_div8(argc1)] ; unsigned char readystate[bitarray_div8(argc1)] ; s6_svlisten_init(argc1, argv, &foo, ids, upstate, readystate, &deadline) ; pid = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ; if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ; - if (wantrestart) s6_svlisten_loop(&foo, 0, 1, or, &deadline, spfd, &s6_svlisten_signal_handler) ; + if (wantup == 2) + { + wantup = 1 ; + e = s6_svlisten_loop(&foo, 0, 1, or, &deadline, spfd, &s6_svlisten_signal_handler) ; + if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ; + } e = s6_svlisten_loop(&foo, wantup, wantready, or, &deadline, spfd, &s6_svlisten_signal_handler) ; - if (e < 0) strerr_dief1x(102, "supervisor died") ; - else if (e > 0) strerr_dief1x(e, "some services reported permanent failure") ; + if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ; } return 0 ; } diff --git a/src/supervision/s6-svlisten.h b/src/supervision/s6-svlisten.h index 674ed2f..92636ee 100644 --- a/src/supervision/s6-svlisten.h +++ b/src/supervision/s6-svlisten.h @@ -24,6 +24,6 @@ struct s6_svlisten_s extern void s6_svlisten_signal_handler (void) ; extern int s6_svlisten_selfpipe_init (void) ; extern void s6_svlisten_init (int, char const *const *, s6_svlisten_t *, uint16_t *, unsigned char *, unsigned char *, tain const *) ; -extern int s6_svlisten_loop (s6_svlisten_t *, int, int, int, tain const *, int, action_func_ref) ; +extern unsigned int s6_svlisten_loop (s6_svlisten_t *, int, int, int, tain const *, int, action_func_ref) ; #endif diff --git a/src/supervision/s6-svlisten1.c b/src/supervision/s6-svlisten1.c index 022d9e8..7102685 100644 --- a/src/supervision/s6-svlisten1.c +++ b/src/supervision/s6-svlisten1.c @@ -19,7 +19,6 @@ int main (int argc, char const *const *argv, char const *const *envp) tain deadline, tto ; pid_t pid ; int spfd ; - int e ; int wantup = 1, wantready = 0, wantrestart = 0 ; uint16_t id ; unsigned char upstate, readystate ; @@ -53,9 +52,10 @@ int main (int argc, char const *const *argv, char const *const *envp) s6_svlisten_init(1, argv, &foo, &id, &upstate, &readystate, &deadline) ; pid = child_spawn0(argv[1], argv + 1, envp) ; if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ; - if (wantrestart) s6_svlisten_loop(&foo, 0, 1, 1, &deadline, spfd, &s6_svlisten_signal_handler) ; - e = s6_svlisten_loop(&foo, wantup, wantready, 1, &deadline, spfd, &s6_svlisten_signal_handler) ; - if (e < 0) strerr_dief1x(102, "supervisor died") ; - else if (e > 0) strerr_dief2x(1, argv[0], " failed permanently: the finish script exited 125") ; + if (wantrestart) + if (s6_svlisten_loop(&foo, 0, 1, 1, &deadline, spfd, &s6_svlisten_signal_handler)) + strerr_dief2x(1, argv[0], " failed permanently or its supervisor died") ; + if (s6_svlisten_loop(&foo, wantup, wantready, 1, &deadline, spfd, &s6_svlisten_signal_handler)) + strerr_dief2x(1, argv[0], " failed permanently or its supervisor died") ; return 0 ; } diff --git a/src/supervision/s6-svwait.c b/src/supervision/s6-svwait.c index 3633bd1..2c7a312 100644 --- a/src/supervision/s6-svwait.c +++ b/src/supervision/s6-svwait.c @@ -51,7 +51,7 @@ int main (int argc, char const *const *argv) { s6_svlisten_t foo = S6_SVLISTEN_ZERO ; - int e ; + unsigned int e ; uint16_t ids[argc] ; unsigned char upstate[bitarray_div8(argc)] ; unsigned char readystate[bitarray_div8(argc)] ; @@ -61,12 +61,10 @@ int main (int argc, char const *const *argv) { wantup = 1 ; e = s6_svlisten_loop(&foo, 0, 0, 0, &deadline, -1, 0) ; - if (e < 0) strerr_dief1x(102, "supervisor died") ; - else if (e > 0) strerr_dief1x(e, "some services reported permanent failure") ; + if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ; } e = s6_svlisten_loop(&foo, wantup, wantready, or, &deadline, -1, 0) ; - if (e < 0) strerr_dief1x(102, "supervisor died") ; - else if (e > 0) strerr_dief1x(e, "some services reported permanent failure") ; + if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ; } return 0 ; } diff --git a/src/supervision/s6_svlisten_loop.c b/src/supervision/s6_svlisten_loop.c index 6043603..97b155e 100644 --- a/src/supervision/s6_svlisten_loop.c +++ b/src/supervision/s6_svlisten_loop.c @@ -51,7 +51,7 @@ static inline int got (s6_svlisten_t const *foo, int wantup, int wantready, int return (bitarray_first(t, foo->n, or) < foo->n) == or ; } -int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tain const *deadline, int spfd, action_func_ref handler) +unsigned int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tain const *deadline, int spfd, action_func_ref handler) { iopause_fd x[2] = { { .fd = ftrigr_fd(&foo->a), .events = IOPAUSE_READ }, { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } } ; unsigned int e = 0 ; @@ -78,7 +78,14 @@ int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tai size_t j = 0 ; for (; j < sa.len ; j++) { - if (sa.s[j] == 'x') return -1 ; + if (sa.s[j] == 'x') + { + if (bitarray_peek(foo->upstate, i) != wantup + || bitarray_peek(foo->readystate, i) != wantready) + e++ ; + bitarray_poke(foo->upstate, i, wantup) ; + bitarray_poke(foo->readystate, i, wantready) ; + } else if (sa.s[j] == 'O') { if (wantup) -- cgit v1.2.3