From b1b5cca013c200014799953dd40d0b9e2ea88e63 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 22 Oct 2025 03:03:53 +0000 Subject: Add some doc, improve s6-background-watch --- .gitignore | 1 + doc/s6-applyuidgid.html | 2 +- doc/s6-background-watch.html | 128 ++++++++++++++++++++++++++++++++++ doc/servicedir.html | 28 +++++++- package/targets.mak | 2 - s6-background-watch | Bin 34056 -> 0 bytes src/supervision/s6-background-watch.c | 11 +-- src/supervision/s6-supervise.c | 30 +++++--- 8 files changed, 181 insertions(+), 21 deletions(-) create mode 100644 doc/s6-background-watch.html delete mode 100755 s6-background-watch diff --git a/.gitignore b/.gitignore index b6cb47e..4a9ae96 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,4 @@ /s6-instance-control /s6-instance-status /s6-instance-list +/s6-background-watch diff --git a/doc/s6-applyuidgid.html b/doc/s6-applyuidgid.html index c532d30..9502ca6 100644 --- a/doc/s6-applyuidgid.html +++ b/doc/s6-applyuidgid.html @@ -48,7 +48,7 @@ value overrides the environment variable.
  • -z : unexport. The UID, GID and GIDLIST variables will be removed from the process environment.
  • - +

    Notes

    +
  • An optional regular file named pidfile. +Creating such a file is not recommended, but is a workaround — and only +a workaround — for daemons that background themselves. If this file +exists, it must contain the path (either absolute or relative to the service +directory) to a pid file, followed by a newline; the path must be shorter than +512 bytes. The following behaviour is then expected: + +If the file does not exist, s6-supervise only +supervises daemons that do not background themselves, which is the normal case.
  • +
  • A fifodir named event. It is automatically created by s6-supervise if it does not exist. foo/event diff --git a/package/targets.mak b/package/targets.mak index 30900d6..cea504b 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -61,8 +61,6 @@ s6-instance-delete \ s6-instance-control \ s6-instance-status \ s6-instance-list \ - -LIBEXEC_TARGETS := \ s6-background-watch \ LIB_DEFS := S6=s6 diff --git a/s6-background-watch b/s6-background-watch deleted file mode 100755 index 4fa40e2..0000000 Binary files a/s6-background-watch and /dev/null differ diff --git a/src/supervision/s6-background-watch.c b/src/supervision/s6-background-watch.c index cfb1fb7..847e844 100644 --- a/src/supervision/s6-background-watch.c +++ b/src/supervision/s6-background-watch.c @@ -124,7 +124,8 @@ static inline int handle_signals (pid_t pid, int issr, int *code) } -/* BSD part. kevent is a unique snowflake in the shape of a dildo */ +/* BSD part. kevent is a unique dildo-shaped snowflake, so we need to run it + in its own thread for it to play nicely with our regular iopause loop. */ #ifdef SKALIBS_HASKEVENT @@ -162,7 +163,6 @@ static void keventstart (pid_t pid, int *fd, pthread_t *th) EV_SET(&ke, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, 0) ; if (kevent(t.kq, &ke, 1, 0, 0, 0) == -1) strerr_diefu1sys(111, "register kevent") ; if (pipe(p) == -1) strerr_diefu2sys(111, "pipe") ; - if (coe(p[0]) t.fdw = p[1] ; t.pid = pid ; e = pthread_attr_init(&attr) ; @@ -201,7 +201,7 @@ static gol_arg const rgola[GOLA_N] = int main (int argc, char const *const *argv) { - iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ, .revents = 0 } } ; + iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = -2, .events = IOPAUSE_READ, .revents = 0 } } ; tain tto = TAIN_INFINITE_RELATIVE ; tain deadline ; unsigned int notif = 0 ; @@ -238,7 +238,6 @@ int main (int argc, char const *const *argv) #ifdef SKALIBS_HASPRSETCHILDSUBREAPER if (prctl(PR_SET_CHILD_SUBREAPER, 1) == -1) strerr_diefu1sys(111, "prctl to become a subreaper") ; - x[1].fd = -2 ; #endif pid = cspawn(argv[1], argv + 1, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ; @@ -259,8 +258,10 @@ int main (int argc, char const *const *argv) } pid = get_pid_from_pidfile(argv[0], argv[1]) ; + if (kill(pid, 0) == -1) strerr_diefu1sys(111, "check daemon with a null signal") ; + #ifdef SKALIBS_HASKEVENT - pthread_t th ; + pthread_t th = PTHREAD_NULL ; keventstart(pid, &x[1].fd, &th) ; #endif if (notif) diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c index 6feb7c4..8567bb1 100644 --- a/src/supervision/s6-supervise.c +++ b/src/supervision/s6-supervise.c @@ -297,16 +297,18 @@ static void trystart (void) [0] = { .type = CSPAWN_FA_CLOSE }, [1] = { .type = CSPAWN_FA_MOVE }, } ; - char lkfmt[UINT_FMT] ; - char const *cargv[8] = { S6_BINPREFIX "s6-setlock", "-d", lkfmt, "--", SLCK, "./run", servicename, 0 } ; - size_t orig = 5 ; + char const *cargv[8] ; int notifyp[2] = { -1, -1 } ; unsigned int lk = 0, notif = 0 ; uint16_t cspawnflags = CSPAWN_FLAGS_SELFPIPE_FINISH | CSPAWN_FLAGS_SETSID ; + uint8_t m = 0 ; + char lkfmt[UINT_FMT] ; + + if (check_file("flag-newpidns")) cspawnflags |= CSPAWN_FLAGS_NEWPIDNS ; if (read_uint("lock-fd", &lk)) { - if (lk > maxfd) strerr_warnw2x("invalid ", "lock-fd") ; + if (!lk || lk > maxfd) strerr_warnw2x("invalid ", "lock-fd") ; else { struct stat st ; @@ -342,14 +344,18 @@ static void trystart (void) strerr_warnw1x("another instance of the service is already running, child will block") ; fd_close(lfd) ; lkfmt[uint_fmt(lkfmt, lk)] = 0 ; - orig = 0 ; + cargv[m++] = S6_BINPREFIX "s6-setlock" ; + cargv[m++] = "-d" ; + cargv[m++] = lkfmt ; + cargv[m++] = "--" ; + cargv[m++] = SLCK ; } } if (read_uint("notification-fd", ¬if)) { - if (notif > maxfd) strerr_warnw2x("invalid ", "notification-fd") ; - if (!orig && notif == lk) + if (!notif || notif > maxfd) strerr_warnw2x("invalid ", "notification-fd") ; + if (notif == lk) { settimeout_infinite() ; strerr_warnwu1x("start service: notification-fd and lock-fd are the same") ; @@ -366,12 +372,14 @@ static void trystart (void) fa[1].x.fd2[1] = notifyp[1] ; } - if (check_file("flag-newpidns")) cspawnflags |= CSPAWN_FLAGS_NEWPIDNS ; - status.pid = cspawn(cargv[orig], cargv + orig, (char const *const *)environ, cspawnflags, fa, notifyp[1] >= 0 ? 2 : 0) ; + cargv[m++] = "./run" ; + cargv[m++] = servicename ; + cargv[m++] = 0 ; + status.pid = cspawn(cargv[0], cargv, (char const *const *)environ, cspawnflags, fa, notifyp[1] >= 0 ? 2 : 0) ; if (!status.pid) { settimeout(60) ; - strerr_warnwu3sys("spawn ", cargv[orig], " (waiting 60 seconds)") ; + strerr_warnwu3sys("spawn ", cargv[0], " (waiting 60 seconds)") ; goto errn ; } @@ -382,7 +390,7 @@ static void trystart (void) } status.pgid = getpgid(status.pid) ; if (status.pgid == -1) - strerr_warnwu1sys("getpgid() (process group control commands will have no effect)") ; + strerr_warnwu1sys("getpgid (process group control commands will have no effect)") ; settimeout_infinite() ; nextstart = tain_zero ; state = UP ; -- cgit v1.3.1