summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-12-05 01:28:41 +0000
committerLaurent Bercot <ska@appnovation.com>2022-12-05 01:28:41 +0000
commitcac30eda3f3dbb3c690715df5b2867d22b1fc497 (patch)
tree11e79858775a823babaedbe60dfe51425ad4b243
parent40aff8c8e78c4e83325dcbfc3fa5f99ed7321a2f (diff)
downloads6-cac30eda3f3dbb3c690715df5b2867d22b1fc497.tar.xz
s6-svwait shouldn't exit early on supervisor death
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--src/supervision/s6-svlisten.c28
-rw-r--r--src/supervision/s6-svlisten.h2
-rw-r--r--src/supervision/s6-svlisten1.c10
-rw-r--r--src/supervision/s6-svwait.c8
-rw-r--r--src/supervision/s6_svlisten_loop.c11
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)