s6

Mirror/fork of https://skarnet.org/software/s6/
git clone https://ccx.te2000.cz/git/s6
Log | Files | Refs | README | LICENSE

commit 04876fbe6bb09832a78b013898d64b3abc921604
parent 7a991b6adb985ca13a28350a10e0324239bb39a2
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Tue,  4 Oct 2022 19:02:39 +0000

 s6-supervise QoL: only skip 1-second restart delay when service was ready

Signed-off-by: Laurent Bercot <ska@appnovation.com>

Diffstat:
Mdoc/s6-supervise.html | 4+++-
Msrc/supervision/s6-supervise.c | 36+++++++++++++++++++++++-------------
2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/doc/s6-supervise.html b/doc/s6-supervise.html @@ -171,7 +171,9 @@ to <tt>./event</tt> <em>before</em> the <tt>'D'</tt>, and it <strong>does not restart the service</strong>, as if <tt>s6-svc -O</tt> had been called. This can be used to signify permanent failure to start the service. </li> <li> There is a minimum 1-second delay between two <tt>./run</tt> spawns, to avoid busylooping -if <tt>./run</tt> exits too quickly. </li> +if <tt>./run</tt> exits too quickly. If the service has been <em>ready</em> for more +than one second, it will restart immediately, but if it not <em>ready</em> when +it dies, s6-supervise will always pause for 1 second before spawning it again. </li> <li> When killed or asked to exit, it waits for the service to go down one last time, then sends a <tt>'x'</tt> event to <tt>./event</tt> before exiting 0. </li> </ul> diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c @@ -3,6 +3,7 @@ /* For SIGWINCH */ #include <skalibs/nonposix.h> +#include <stdint.h> #include <unistd.h> #include <string.h> #include <strings.h> @@ -52,15 +53,23 @@ enum state_e LASTFINISH } ; +struct gflags_s +{ + uint8_t cont : 1 ; + uint8_t dying : 1 ; +} gflags = +{ + .cont = 1, + .dying = 0 +} ; + typedef void action_t (void) ; typedef action_t *action_t_ref ; static tain deadline ; -static tain dontrespawnbefore = TAIN_EPOCH ; +static tain nextstart = TAIN_ZERO ; static s6_svstatus_t status = S6_SVSTATUS_ZERO ; static state_t state = DOWN ; -static int flagdying = 0 ; -static int cont = 1 ; static int notifyfd = -1 ; static char const *servicename = 0 ; @@ -118,10 +127,10 @@ static void set_down_and_ready (char const *s, unsigned int n) status.pid = 0 ; status.flagfinishing = 0 ; status.flagready = 1 ; - tain_wallclock_read(&status.readystamp) ; state = DOWN ; - if (tain_future(&dontrespawnbefore)) deadline = dontrespawnbefore ; - else tain_copynow(&deadline) ; + if (tai_sec(tain_secp(&nextstart))) deadline = nextstart ; + else tain_addsec_g(&deadline, 1) ; + tain_wallclock_read(&status.readystamp) ; announce() ; ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, s, n) ; } @@ -135,7 +144,7 @@ static void nop (void) static void bail (void) { - cont = 0 ; + gflags.cont = 0 ; } static void sigint (void) @@ -359,11 +368,11 @@ static void trystart (void) fd_close(p[0]) ; notifyfd = notifyp[0] ; settimeout_infinite() ; + nextstart = tain_zero ; state = UP ; status.pid = pid ; status.flagready = 0 ; tain_wallclock_read(&status.stamp) ; - tain_addsec_g(&dontrespawnbefore, 1) ; announce() ; ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ; return ; @@ -417,7 +426,7 @@ static int uplastup_z (void) status.wstat = (int)status.pid ; status.flagpaused = 0 ; status.flagready = 0 ; - flagdying = 0 ; + gflags.dying = 0 ; tain_wallclock_read(&status.stamp) ; if (notifyfd >= 0) { @@ -491,7 +500,7 @@ static void lastup_z (void) static void uptimeout (void) { - if (flagdying) + if (gflags.dying) { killk() ; settimeout(5) ; @@ -520,7 +529,7 @@ static void up_d (void) if (timeout && tain_from_millisecs(&tto, timeout)) { tain_add_g(&deadline, &tto) ; - flagdying = 1 ; + gflags.dying = 1 ; } else settimeout_infinite() ; } @@ -613,6 +622,7 @@ static inline void handle_notifyfd (void) r = sanitize_read(fd_read(notifyfd, buf, 512)) ; if (r > 0 && memchr(buf, '\n', r)) { + tain_addsec_g(&nextstart, 1) ; tain_wallclock_read(&status.readystamp) ; status.flagready = 1 ; announce() ; @@ -806,12 +816,12 @@ int main (int argc, char const *const *argv) tain_now_set_stopwatch_g() ; settimeout(0) ; - tain_wallclock_read(&status.stamp) ; + tain_copynow(&status.stamp) ; status.readystamp = status.stamp ; announce() ; ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ; - while (cont) + while (gflags.cont) { int r ; x[2].fd = notifyfd ;