commit 597dc96fec06714019afe95487cd1065239b8049
parent f59b79de8c8f49ffd5133b2a37e11a52edc2bdbd
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date: Wed, 15 Jan 2020 14:15:42 +0000
Add console holder functionality to s6-svscan
Diffstat:
5 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/COPYING b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2019 Laurent Bercot <ska-skaware@skarnet.org>
+Copyright (c) 2011-2020 Laurent Bercot <ska-skaware@skarnet.org>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/NEWS b/NEWS
@@ -7,6 +7,7 @@ In 2.9.1.0
- execline support is now optional. Some functionality is not available
when execline support is disabled.
- New '?' directive to s6-log, to spawn a processor with /bin/sh.
+ - New console holder functionality for easier s6-svscan-log support.
In 2.9.0.1
diff --git a/doc/s6-svscan.html b/doc/s6-svscan.html
@@ -27,7 +27,7 @@ the root or a branch of a <em>supervision tree</em>.
<h2> Interface </h2>
<pre>
- s6-svscan [ -S | -s ] [ -d <em>notif</em> ] [ -c max ] [ -t <em>rescan</em> ] [ <em>scandir</em> ]
+ s6-svscan [ -S | -s ] [ -d <em>notif</em> ] [ -X <em>consoleholder</em> ] [ -c max ] [ -t <em>rescan</em> ] [ <em>scandir</em> ]
</pre>
<ul>
@@ -73,6 +73,14 @@ even that the relevant <a href="s6-supervise.html">s6-supervise</a> processes ha
been started. If you need to test for <em>deep readiness</em>, meaning that all the
services in the supervision tree have been started and are ready, you cannot rely
on this option. </li>
+ <li> <tt>-X <em>consoleholder</em></tt> : assume the output console is available
+on descriptor <em>consoleholder</em>. If this option is given, and a <tt>s6-svscan-log</tt>
+service exists, the <a href="s6-supervise.html">s6-supervise</a> process for that service
+will be run with <em>consoleholder</em> as its standard error. This is mainly useful
+for a setup done via <a href="//skarnet.org/software/s6-linux-init/">s6-linux-init</a>,
+where all error messages go to the <tt>s6-svscan-log</tt> catch-all logger service by
+default, except messages from this service itself, which fall back to <em>consoleholder</em>.
+If you're not sure what to use this option for, or how, you don't need it. </li>
<li> <tt>-c <em>max</em></tt> : maintain services for up to <em>max</em>
service directories. Default is 500. Lower limit is 2. There is no upper limit, but:
<ul>
diff --git a/doc/upgrade.html b/doc/upgrade.html
@@ -28,6 +28,9 @@ disabled when execline support is disabled. </li>
<li> A new '?' directive has been added to <a href="s6-log.html">s6-log</a>,
it declares a processor command line that is spawned with the <tt>/bin/sh</tt>
interpreter. </li>
+ <li> A new <tt>-X</tt> option has been added to <a href="s6-svscan.html>s6-svscan</a>
+to better support <a href="//skarnet.org/software/s6-linux-init/">s6-linux-init</a>
+installations. </li>
</ul>
<h2> in 2.9.0.1 </h2>
diff --git a/src/supervision/s6-svscan.c b/src/supervision/s6-svscan.c
@@ -21,13 +21,14 @@
#include <s6/config.h>
#include <s6/s6-supervise.h>
-#define USAGE "s6-svscan [ -S | -s ] [ -c maxservices ] [ -t timeout ] [ -d notif ] [ dir ]"
+#define USAGE "s6-svscan [ -S | -s ] [ -c maxservices ] [ -t timeout ] [ -d notif ] [ -X consoleholder ] [ dir ]"
#define dieusage() strerr_dieusage(100, USAGE)
#define FINISH_PROG S6_SVSCAN_CTLDIR "/finish"
#define CRASH_PROG S6_SVSCAN_CTLDIR "/crash"
#define SIGNAL_PROG S6_SVSCAN_CTLDIR "/SIG"
#define SIGNAL_PROG_LEN (sizeof(SIGNAL_PROG) - 1)
+#define SPECIAL_LOGGER_SERVICE "s6-svscan-log"
#define DIR_RETRY_TIMEOUT 3
#define CHECK_RETRY_TIMEOUT 4
@@ -52,6 +53,7 @@ static int wantreap = 1 ;
static int wantscan = 1 ;
static unsigned int wantkill = 0 ;
static int cont = 1 ;
+static unsigned int consoleholder = 0 ;
static void panicnosp (char const *) gccattr_noreturn ;
static void panicnosp (char const *errmsg)
@@ -298,6 +300,10 @@ static void trystart (unsigned int i, char const *name, int islog)
if (services[i].flaglog)
if (fd_move(!islog, services[i].p[!islog]) == -1)
strerr_diefu2sys(111, "set fds for ", name) ;
+ if (consoleholder
+ && !strcmp(name, SPECIAL_LOGGER_SERVICE)
+ && fd_move(2, consoleholder) < 0) /* autoclears coe */
+ strerr_diefu1sys(111, "restore console fd for service " SPECIAL_LOGGER_SERVICE) ;
xpathexec_run(S6_BINPREFIX "s6-supervise", cargv, (char const **)environ) ;
}
}
@@ -458,7 +464,7 @@ int main (int argc, char const *const *argv)
unsigned int t = 0 ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "Sst:c:d:", &l) ;
+ int opt = subgetopt_r(argc, argv, "Sst:c:d:X:", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -471,6 +477,11 @@ int main (int argc, char const *const *argv)
if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
if (fcntl(notif, F_GETFD) < 0) strerr_dief1sys(100, "invalid notification fd") ;
break ;
+ case 'X' :
+ if (!uint0_scan(l.arg, &consoleholder)) dieusage() ;
+ if (consoleholder < 3) strerr_dief1x(100, "console holder fd must be 3 or more") ;
+ if (fcntl(consoleholder, F_GETFD) < 0) strerr_dief1sys(100, "invalid console holder fd") ;
+ break ;
default : dieusage() ;
}
}
@@ -487,6 +498,7 @@ int main (int argc, char const *const *argv)
*/
if (argc && (chdir(argv[0]) < 0)) strerr_diefu1sys(111, "chdir") ;
+ if (consoleholder && coe(consoleholder) < 0) strerr_diefu1sys(111, "coe console holder") ;
x[1].fd = s6_supervise_lock(S6_SVSCAN_CTLDIR) ;
x[0].fd = selfpipe_init() ;
if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
@@ -509,7 +521,6 @@ int main (int argc, char const *const *argv)
}
if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ;
}
-
if (notif)
{
fd_write(notif, "\n", 1) ;