From 5199738f4e32773f4f752a94998593e18e3af36f Mon Sep 17 00:00:00 2001
From: Laurent Bercot
Date: Tue, 16 Apr 2019 11:53:30 +0000
Subject: Small fixes before reorganizing
---
doc/s6-linux-init-maker.html | 81 +++++++++++++++++--------------------
src/init/s6-linux-init-maker.c | 50 +++++++++++++----------
src/init/s6-linux-init.c | 16 ++++----
src/state/s6-linux-init-shutdown.c | 1 -
src/state/s6-linux-init-shutdownd.c | 43 ++------------------
5 files changed, 75 insertions(+), 116 deletions(-)
diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html
index 4c0b51d..6f3d204 100644
--- a/doc/s6-linux-init-maker.html
+++ b/doc/s6-linux-init-maker.html
@@ -49,20 +49,18 @@ machine - else the scripts will crash.
s6-linux-init-maker \
[ -c basedir ] \
- [ -l tmpfsdir ] \
[ -b execline_bindir ] \
[ -u log_uid -g log_gid | -U ] \
[ -G early_getty ] \
- [ -2 initscript ] \
- [ -r ] \
- [ -Z ] shutdownscript \
+ [ -1 ] \
+ [ -L ] \
[ -p initial_path ] \
[ -m initial_umask ] \
[ -t timestamp_style ] \
[ -d dev_style ] \
[ -s env_store ] \
[ -e initial_envvar ] ... \
- [ -n ] \
+ [ -E stage2_envvar ] ... \
[ -q ] finalsleeptime
dir
@@ -87,18 +85,28 @@ tool can do it, as well as the GNU or busybox cp -a or mv comm
- The basedir/init script
-is then suitable as a "stage 1" init program, i.e. the first program
-run by the kernel. The administrator should make a symbolic link
-from /sbin/init to basedir/init; the
-machine will then be ready to boot
+ The basedir/bin directory contains scripts, or
+links to programs, that are suitable as System V-compatible programs
+of the same name; the administrator should copy them to (or symlink
+them from) a place where those programs are usually found, typically
+/sbin.
+
+
+
+ In particular, the basedir/bin/init script
+suitable as a "stage 1" init program, i.e. the first program
+run by the kernel (possibly after an initramfs execution).
+Once this script is copied to, or symlinked from,
+/sbin/init, the machine will be ready to boot on the
+new s6-based system.
Boot sequence
- When the kernel boots, it runs the basedir/init script,
-also known as stage 1. and this is what happens:
+ When the kernel boots, it may run an initramfs first, but in any
+case it then runs the basedir/init script,
+also known as stage 1. This is what happens during stage 1:
@@ -246,11 +254,6 @@ created directory dir to basedir. basedir
must be absolute. Default is
/etc/s6-linux-init.
- - -l tmpfsdir : at boot time, a tmpfs will
-be mounted on tmpfsdir. The directory should already exist in
-the root filesystem, and be empty. tmpfsdir must be absolute. Default is
-/run.
-
- -b execline_bindir : init is run by the kernel
without a PATH, and since it is a script, it is necessary to tell it where
to find the
@@ -285,27 +288,13 @@ should be a getty, to allow logins even if stage2 fails.
"/sbin/getty 38400 tty1". By default, no early service
is defined.
- - -2 initscript : initscript is
-the location of the stage 2 script that will be run when the
-system has an operational supervision tree. It must be absolute. Default is
-/etc/rc.init.
-
- - -r : redirect. By default, stage2 is
-run with stdout and stderr pointing to /dev/console, so that
-users can see what init scripts print. However, it may conflict
-with an early getty, or be undesirable for other reasons. The
--r option redirects stage2's stdout and stderr
-to the catch-all logger, so the output will be made available
-in the tmpfsdir/uncaught-logs directory.
-
- - -Z shutdownscript :
-shutdownscript is the location of the script that will be
-run when s6-svscan receives a signal that tells it to stop the
-machine, before it executes into the final shutdown sequence. It must be
-absolute. Default is /etc/rc.shutdown.
-Note that this script is run with its stdout and stderr
-redirected to the tmpfsdir/uncaught-logs logging
-directory, so its output will not appear on the system's console.
+ - -1 : make it so that all the messages that are
+sent to the catch-all logger (i.e. all the error messages that are not
+caught by a dedicated logger, as well as the output from stage2)
+are also copied to /dev/console. This is generally useful to
+debug a system at a glance, but if a failing program keeps sending
+error messages, it may interfere with comfortable usage of an early
+getty.
- -p initial_path : the value to
set the PATH environment variable to, for all the starting processes.
@@ -360,16 +349,18 @@ will adjust the global environment directory in dir/env.
to make sure that VAR does not appear in the global
environment, or of the form VAR=VALUE, to add an
environment variable VAR with the value VALUE.
+The global environment is the environment that every supervised
+process (as well as the stage2 script) will run with,
+so it will be inherited by default by every process running on
+the system.
The TZ variable, for instance, is a good candidate to be set in
the global environment.
- - -n : tells s6-linux-init-maker that the init script
-is going to run in a container, as pid 1 in a non-root namespace.
-This modifies the .s6-svscan/finish, .s6-svscan/SIGHUP
-and .s6-svscan/SIGINT scripts slightly, in order to provide
-adequate functionality when the containerized system is asked to
-shutdown. Do not add this option if the init script is going to run
-in the root pid namespace.
+ - -E stage2_envvar : same behaviour
+as the -e option, except that every declared
+stage2_envvar will be put in the environment run by the
+stage2 script. They will not be put in the global
+environment.
- -q finalsleeptime : when the machine
shuts down, all processes that have not already been killed during
diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c
index 48c95c6..ede9a52 100644
--- a/src/init/s6-linux-init-maker.c
+++ b/src/init/s6-linux-init-maker.c
@@ -22,7 +22,7 @@
#include "defaults.h"
#include "initctl.h"
-#define USAGE "s6-linux-init-maker [ -c basedir ] [ -b execline_bindir ] [ -u log_uid -g log_gid | -U ] [ -G early_getty_cmd ] [ -r ] [ -L ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d slashdev ] [ -s env_store ] [ -e initial_envvar ... ] [ -q default_grace_time ] dir"
+#define USAGE "s6-linux-init-maker [ -c basedir ] [ -b execline_bindir ] [ -u log_uid -g log_gid | -U ] [ -G early_getty_cmd ] [ -1 ] [ -L ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d slashdev ] [ -s env_store ] [ -e initial_envvar ... ] [ -q default_grace_time ] dir"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb") ;
@@ -48,7 +48,7 @@ static gid_t uncaught_logs_gid = 0 ;
static unsigned int initial_umask = 0022 ;
static unsigned int timestamp_style = 1 ;
static unsigned int finalsleep = 3000 ;
-static int redirect_stage2 = 0 ;
+static int console = 0 ;
static int logouthookd = 0 ;
typedef int writetobuf_func_t (buffer *, void *) ;
@@ -102,19 +102,31 @@ static int s6_svscan_log_script (buffer *b, void *data)
{
char fmt[UINT64_FMT] ;
(void)data ;
- return put_shebang(b)
- && buffer_puts(b,
- "redirfd -w 2 /dev/console\n"
- "redirfd -w 1 /dev/null\n"
- "redirfd -rnb 0 " LOGGER_FIFO "\n"
- "s6-applyuidgid -u ") >= 0
- && buffer_put(b, fmt, uid_fmt(fmt, uncaught_logs_uid)) >= 0
- && buffer_puts(b, " -g ") >= 0
- && buffer_put(b, fmt, gid_fmt(fmt, uncaught_logs_gid)) >= 0
- && buffer_puts(b, " --\ns6-log -bpd3 -- ") >= 0
- && buffer_puts(b, timestamp_style & 1 ? "t " : "") >= 0
- && buffer_puts(b, timestamp_style & 2 ? "T " : "") >= 0
- && buffer_puts(b, S6_LINUX_INIT_TMPFS "/" UNCAUGHT_DIR "\n") >= 0 ;
+ if (!put_shebang(b)
+ || buffer_puts(b,
+ "redirfd -w 2 /dev/console\n"
+ "redirfd -w 1 /dev/") < 0
+ || buffer_puts(b, console ? "console" : "null") < 0
+ || buffer_puts(b, "\n"
+ "redirfd -rnb 0 " LOGGER_FIFO "\n"
+ "s6-applyuidgid -u ") < 0
+ || buffer_put(b, fmt, uid_fmt(fmt, uncaught_logs_uid)) < 0
+ || buffer_puts(b, " -g ") < 0
+ || buffer_put(b, fmt, gid_fmt(fmt, uncaught_logs_gid)) < 0
+ || buffer_puts(b, " --\ns6-log -bpd3 -- ") < 0)
+ return 0 ;
+ if (console)
+ {
+ if (timestamp_style & 1 && buffer_puts(b, "t ") < 0
+ || timestamp_style & 2 && buffer_puts(b, "T ") < 0
+ || buffer_puts(b, "1 ") < 0)
+ return 0 ;
+ }
+ if (timestamp_style & 1 && buffer_puts(b, "t ") < 0
+ || timestamp_style & 2 && buffer_puts(b, "T ") < 0
+ || buffer_puts(b, S6_LINUX_INIT_TMPFS "/" UNCAUGHT_DIR "\n") < 0)
+ return 0 ;
+ return 1 ;
}
static int logouthookd_script (buffer *b, void *data)
@@ -177,10 +189,6 @@ static inline int stage1_script (buffer *b)
if (buffer_puts(b, " -m 00") < 0
|| buffer_put(b, fmt, uint_ofmt(fmt, initial_umask)) < 0) return 0 ;
}
- if (redirect_stage2)
- {
- if (buffer_puts(b, " -r") < 0) return 0 ;
- }
if (initial_path)
{
if (buffer_puts(b, " -p ") < 0
@@ -399,7 +407,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "c:b:u:g:UG:rLp:m:t:d:s:e:E:q:", &l) ;
+ int opt = subgetopt_r(argc, argv, "c:b:u:g:UG:1Lp:m:t:d:s:e:E:q:", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -417,7 +425,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (!uint0_scan(x, &uncaught_logs_gid)) strerr_dieinvalid(100, "GID") ;
}
case 'G' : early_getty = l.arg ; break ;
- case 'r' : redirect_stage2 = 1 ; break ;
+ case '1' : console = 1 ; break ;
case 'L' : logouthookd = 1 ; break ;
case 'p' : initial_path = l.arg ; break ;
case 'm' : if (!uint0_oscan(l.arg, &initial_umask)) dieusage() ; break ;
diff --git a/src/init/s6-linux-init.c b/src/init/s6-linux-init.c
index 6758682..aeddbac 100644
--- a/src/init/s6-linux-init.c
+++ b/src/init/s6-linux-init.c
@@ -23,12 +23,12 @@
#include "defaults.h"
#include "initctl.h"
-#define USAGE "s6-linux-init [ -r ] [ -c basedir ] [ -p initpath ] [ -s envdumpdir ] [ -m umask ] [ -d devtmpfs ]"
+#define USAGE "s6-linux-init [ -c basedir ] [ -p initpath ] [ -s envdumpdir ] [ -m umask ] [ -d devtmpfs ]"
#define dieusage() strerr_dieusage(100, USAGE)
#define BANNER "\n s6-linux-init version " S6_LINUX_INIT_VERSION "\n\n"
-static inline void run_stage2 (char const *basedir, char const **argv, unsigned int argc, char const *const *envp, size_t envlen, stralloc *envmodifs, int redirect)
+static inline void run_stage2 (char const *basedir, char const **argv, unsigned int argc, char const *const *envp, size_t envlen, stralloc *envmodifs)
{
size_t dirlen = strlen(basedir) ;
char const *childargv[argc + 2] ;
@@ -47,10 +47,10 @@ static inline void run_stage2 (char const *basedir, char const **argv, unsigned
childargv[argc + 1] = 0 ;
setsid() ;
fd_close(1) ;
- if (open(LOGFIFO, O_WRONLY) != 1) /* blocks */
+ if (open(LOGFIFO, O_WRONLY) != 1) /* blocks until catch-all logger is up */
strerr_diefu1sys(111, "open " LOGFIFO " for writing") ;
- if (fd_copy(1 + redirect, 2 - redirect) == -1)
- strerr_diefu1sys(111, "redirect output file descriptor") ;
+ if (fd_copy(2, 1) == -1)
+ strerr_diefu1sys(111, "fd_copy stdout to stderr") ;
xpathexec_r(childargv, envp, envlen, envmodifs->s, envmodifs->len) ;
}
@@ -62,7 +62,6 @@ int main (int argc, char const **argv, char const *const *envp)
char const *slashdev = 0 ;
char const *envdumpdir = 0 ;
stralloc envmodifs = STRALLOC_ZERO ;
- int redirect = 0 ;
PROG = "s6-linux-init" ;
if (getpid() != 1)
@@ -76,11 +75,10 @@ int main (int argc, char const **argv, char const *const *envp)
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "rc:p:s:m:d:", &l) ;
+ int opt = subgetopt_r(argc, argv, "c:p:s:m:d:", &l) ;
if (opt == -1) break ;
switch (opt)
{
- case 'r' : redirect = 1 ; break ;
case 'c' : basedir = l.arg ; break ;
case 'p' : path = l.arg ; break ;
case 's' : envdumpdir = l.arg ; break ;
@@ -160,7 +158,7 @@ int main (int argc, char const **argv, char const *const *envp)
}
pid = fork() ;
if (pid == -1) strerr_diefu1sys(111, "fork") ;
- if (!pid) run_stage2(basedir, argv, argc, newenvp, !!path, &envmodifs, redirect) ;
+ if (!pid) run_stage2(basedir, argv, argc, newenvp, !!path, &envmodifs) ;
if (fd_copy(2, 1) == -1)
strerr_diefu1sys(111, "redirect output file descriptor") ;
xpathexec_r(newargv, newenvp, !!path, envmodifs.s, envmodifs.len) ;
diff --git a/src/state/s6-linux-init-shutdown.c b/src/state/s6-linux-init-shutdown.c
index eb65d1d..bb0391d 100644
--- a/src/state/s6-linux-init-shutdown.c
+++ b/src/state/s6-linux-init-shutdown.c
@@ -8,7 +8,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/src/state/s6-linux-init-shutdownd.c b/src/state/s6-linux-init-shutdownd.c
index d4ecd4b..e330ac6 100644
--- a/src/state/s6-linux-init-shutdownd.c
+++ b/src/state/s6-linux-init-shutdownd.c
@@ -45,30 +45,11 @@ static inline void prepare_shutdown (char c, unsigned int *what, tain_t *deadlin
tain_unpack(pack, deadline) ;
uint32_unpack_big(pack + TAIN_PACK, &u) ;
if (u && u <= 300000) *grace_time = u ;
- *what = byte_chr(" hpr", c, 4) ;
-}
-
-static inline void change_runlevels (char c)
-{
- pid_t pid = doublefork() ;
- if (pid == -1)
- strerr_warnwu1sys("doublefork for runlevel change") ;
- if (pid)
- {
- size_t basedirlen = strlen(basedir) ;
- char fn[basedirlen + sizeof("/scripts/runlevel")] ;
- char s[2] = { c, 0 } ;
- char const *cargv[3] = { fn, s, 0 } ;
- PROG = "s6-linux-init-shutdownd (grandchild)" ;
- memcpy(fn, basedir, basedirlen) ;
- memcpy(fn + basedirlen, "/scripts/runlevel", sizeof("/scripts/runlevel")) ;
- xpathexec_run(cargv[0], cargv, (char const *const *)environ) ;
- }
+ *what = 1 + byte_chr("hpr", c, 3) ;
}
static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned int *grace_time)
{
- char rl = 0 ;
for (;;)
{
char c ;
@@ -83,24 +64,8 @@ static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned
prepare_shutdown(c, what, deadline, grace_time) ;
break ;
case 'c' :
- *what = 0 ;
- rl = 0 ;
- tain_add_g(deadline, &tain_infinite_relative) ;
- break ;
- case 'S' :
- *what = 4 ;
- tain_copynow(deadline) ;
- break ;
- case '0' :
- case '1' :
- case '2' :
- case '3' :
- case '4' :
- case '5' :
- case '6' :
*what = 0 ;
tain_add_g(deadline, &tain_infinite_relative) ;
- rl = c ;
break ;
default :
{
@@ -110,12 +75,11 @@ static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned
break ;
}
}
- if (rl) change_runlevels(rl) ;
}
static inline void prepare_stage4 (char const *bindir, char const *basedir, unsigned int what)
{
- static char const *table[4] = { "single", "halt", "poweroff", "reboot" } ;
+ static char const *table[3] = { "halt", "poweroff", "reboot" } ;
stralloc sa = STRALLOC_ZERO ;
buffer b ;
char buf[512] ;
@@ -133,7 +97,7 @@ static inline void prepare_stage4 (char const *bindir, char const *basedir, unsi
strerr_diefu1sys(111, "string_quote") ;
if (buffer_put(&b, sa.s, sa.len) == -1
|| buffer_puts(&b, "/bin/" STAGE4 " ") == -1
- || buffer_puts(&b, table[what]) == -1
+ || buffer_puts(&b, table[what-1]) == -1
|| buffer_putsflush(&b, "\n") == -1)
strerr_diefu2sys(111, "write to ", STAGE4_FILE ".new") ;
stralloc_free(&sa) ;
@@ -213,7 +177,6 @@ int main (int argc, char const *const *argv)
handle_stdin(&what, &deadline, &grace_time) ;
}
- if (what == 4) what = 0 ;
/* Stage 3 */
--
cgit v1.2.3