Package: runit Version: 2.1.2-32 Severity: wishlist Tags: patch Hi!
As I glanced over discussion of adding runit support into init-system-helpers (thx, Lorenzo), it seemed that it would simplify things to have a way to force runsvdir re-scan service directory without waiting for up to 5 seconds. I prepared prelimitary patch, that implements this feature. When runsvdir receives SIGALRM, it rescans service directory and writes timestamp into `.force-rescan' file. Here I request review. Is this feature really needed. Is timestamp file needed? Maybe there are simplier ways to implement it? Making `runit-init` to forward SIGALRM to `runsvdir' does not seems hard, if we agree on this design. Here is code: From fd2712368863c3661bc04d9507883b72e71e3f70 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov <[email protected]> Date: Mon, 15 Jul 2019 23:51:43 +0000 Subject: [PATCH 1/2] Make runsvdir(8) rescan directory on SIGALARM Generally runsvdir(8) rescans service directory every 5 seconds. This patch makes it possbile to force rescan by sending SIGALARM. This feature is wanted by maintainer scripts of packages that want to perform some action after service was started. Obliviously, hanging installation process for 5 seconds is sub-optimal in such situation. --- runit-2.1.2/src/Makefile | 4 ++-- runit-2.1.2/src/runsvdir.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/runit-2.1.2/src/Makefile b/runit-2.1.2/src/Makefile index a5f3558..28db6fd 100644 --- a/runit-2.1.2/src/Makefile +++ b/runit-2.1.2/src/Makefile @@ -14,8 +14,8 @@ runit-init: load runit-init.o unix.a byte.a runsv: load runsv.o unix.a byte.a time.a ./load runsv unix.a byte.a time.a -runsvdir: load runsvdir.o unix.a byte.a time.a - ./load runsvdir unix.a byte.a time.a +runsvdir: load runsvdir.o unix.a fmt_ptime.o byte.a time.a byte.a + ./load runsvdir unix.a fmt_ptime.o byte.a time.a byte.a runsvstat: load runsvstat.o unix.a byte.a time.a ./load runsvstat unix.a byte.a time.a diff --git a/runit-2.1.2/src/runsvdir.c b/runit-2.1.2/src/runsvdir.c index c45b4ee..7ac7999 100644 --- a/runit-2.1.2/src/runsvdir.c +++ b/runit-2.1.2/src/runsvdir.c @@ -15,10 +15,17 @@ #include "iopause.h" #include "sig.h" #include "ndelay.h" +#include "fmt_ptime.h" #define USAGE " [-P] dir" #define VERSION "$Id: ecebd0a50510e91639c6a45dda8b0947aa8eb885 $" +/* + * After rescan of {svdir} that was forced by sig_alarm (as opposed to regular + * rescan once every 5 seconds) is finished, timestamp is written to this path + * (relative to {svdir}). + */ +#define FORCED_RESCAN "./.forced-rescan" #define MAXSERVICES 1000 char *progname; @@ -40,6 +47,7 @@ iopause_fd io[1]; struct taia stamplog; int exitsoon =0; int pgrp =0; +int siga =0; void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); } void fatal(char *m1, char *m2) { @@ -53,6 +61,28 @@ void warn3x(char *m1, char *m2, char *m3) { } void s_term() { exitsoon =1; } void s_hangup() { exitsoon =2; } +void s_alarm() { siga = 1; } + +void report_forced_rescan() { + struct taia stamp; + char buf[26]; + int fd; + + taia_now(&stamp); + fmt_taia(buf, &stamp); + buf[25] =0; + + fd =open_trunc(FORCED_RESCAN); + if (fd == -1) { + warn3x("failed to open", FORCED_RESCAN, buf); + return; + } + + if (write(fd, buf, 25) != 25) + warn3x("failed to write", FORCED_RESCAN, buf); + + close(fd); +} void runsv(int no, char *name) { int pid; @@ -70,6 +100,7 @@ void runsv(int no, char *name) { prog[2] =0; sig_uncatch(sig_hangup); sig_uncatch(sig_term); + sig_uncatch(sig_alarm); if (pgrp) setsid(); pathexec_run(*prog, prog, (char * const *)environ); fatal("unable to start runsv ", name); @@ -183,6 +214,7 @@ int main(int argc, char **argv) { sig_catch(sig_term, s_term); sig_catch(sig_hangup, s_hangup); + sig_catch(sig_alarm, s_alarm); svdir =*argv++; if (argv && *argv) { rplog =*argv; @@ -236,6 +268,10 @@ int main(int argc, char **argv) { if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime)) sleep(1); runsvdir(); + if (siga) { + report_forced_rescan(); + siga =0; + } while (fchdir(curdir) == -1) { warn("unable to change directory, pausing", 0); sleep(5); From d9e37e0f9f303a3d25eb31a5a78d277e176b29c6 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov <[email protected]> Date: Fri, 26 Jul 2019 07:23:35 +0000 Subject: [PATCH 2/2] Add regression test for forced-rescan feature --- runit-2.1.2/src/Makefile | 1 + runit-2.1.2/src/t/runtest.sh | 41 +++++++++++++++++++++++++++++++++ runit-2.1.2/src/t/timestamp/run | 3 +++ 3 files changed, 45 insertions(+) create mode 100755 runit-2.1.2/src/t/runtest.sh create mode 100755 runit-2.1.2/src/t/timestamp/run diff --git a/runit-2.1.2/src/Makefile b/runit-2.1.2/src/Makefile index 28db6fd..07cbff7 100644 --- a/runit-2.1.2/src/Makefile +++ b/runit-2.1.2/src/Makefile @@ -4,6 +4,7 @@ default: sysdeps $(IT) check: $(IT) ./check-local $(IT) + cd t && runsvdir=../runsvdir ./runtest.sh runit: load runit.o unix.a byte.a ./load runit unix.a byte.a diff --git a/runit-2.1.2/src/t/runtest.sh b/runit-2.1.2/src/t/runtest.sh new file mode 100755 index 0000000..c9fc5b3 --- /dev/null +++ b/runit-2.1.2/src/t/runtest.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -eu + +: "${runsvdir:=runsvdir}" + +rm -rf timestamp/supervise/ service/ +rm -f ./timestamp.txt + +mkdir service + +"${runsvdir}" ./service & +echo "pid = $!" +# Wait till runsvdir scans directory and concludes it is empty +sleep 1 +now=$(date +%s) +echo "now = ${now}" +ln -sf ../timestamp service/ +kill -ALRM $! +sleep 0.5 +kill -0 $! + +# Wait until runsvdir discovers "service/timestamp" symbolic link +# and executes "service/timestamp/run" script, which would create +# "./timestamp" file. + +while ! test -f ./timestamp.txt ; do + sleep 0.01 +done + +new=$(cat timestamp.txt) +echo "new = ${new}" +kill -HUP $! + +if [[ $((new - now)) -lt 2 ]] ; then + echo "fine. forced-rescan seems to work" + exit 0 +else + echo "bad. forced-rescan took too long" + exit 1 +fi + diff --git a/runit-2.1.2/src/t/timestamp/run b/runit-2.1.2/src/t/timestamp/run new file mode 100755 index 0000000..4c13d68 --- /dev/null +++ b/runit-2.1.2/src/t/timestamp/run @@ -0,0 +1,3 @@ +#!/bin/sh +date +%s > ../timestamp.txt +sv down .
pgpRq6xazVbga.pgp
Description: PGP signature

