From ff781adeb26caca82a717d7f1dd83c4ad94b5165 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 17 Jun 2015 18:33:06 +0000 Subject: Fix some bugs, add some doc --- doc/index.html | 24 ++++--- doc/quickstart.html | 142 +++++++++++++++++++++++++++++++++++++++++ doc/s6-linux-init-maker.html | 63 +++++++++++++++--- src/init/s6-linux-init-maker.c | 95 +++++++++++---------------- 4 files changed, 252 insertions(+), 72 deletions(-) create mode 100644 doc/quickstart.html diff --git a/doc/index.html b/doc/index.html index ad0d3b0..c3426e0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -20,9 +20,9 @@

What is it ?

- s6-linux-init is a set of minimalistic tools to create and manage -the init process on a Linux system - i.e. the first process created -by the kernel at boot time. + s6-linux-init is a set of minimalistic tools to create a +s6-based init +system, including a /sbin/init binary, on a Linux kernel.

@@ -61,11 +61,12 @@ and then you can boot your system on that init script.

- The listed dependencies are all build-time dependencies and also -boot-time dependencies, i.e. you need the tools installed to build -s6-linux-init and to boot your system. There are no run-time -dependencies, except skalibs if you linked against the shared version of -the library. + skalibs and execline are build-time dependencies. + There are no run-time dependencies. + And every listed package, save skalibs, is a boot-time dependency. + If you are using the shared version of the skalibs library, +then skalibs also becomes a run-time and a +boot-time dependency.

Licensing

@@ -101,6 +102,13 @@ the previous versions of s6-linux-init and the current one.

Reference

+

Quickstart guide and FAQ

+ +

+ There is one, + here ! +

+

Commands

diff --git a/doc/quickstart.html b/doc/quickstart.html new file mode 100644 index 0000000..da47334 --- /dev/null +++ b/doc/quickstart.html @@ -0,0 +1,142 @@ + + + + + + s6-linux-init: quickstart and FAQ + + + + + + +

+s6-linux-init
+Software
+skarnet.org +

+ +

Quickstart and FAQ for s6-linux-init

+ +

Quickstart

+ + + +

FAQ

+ +

Why is it so complicated to use s6 as an init process? It's much +simpler with runit.

+ +

+ Yes, runit is simpler, because it provides a simple +runit binary +suitable as a /sbin/init program and calls scripts to +handle the three stages of init. However, the runit design has a +few perfectible points: +

+ + + +

+ Running a s6-based init addresses those issues: +

+ + + +

+ To sum up, a s6-based init is cleaner than a runit-based +init; it's a bit more complex to set up, but it organizes the system +in a better way, without using more resources. And the goal of +s6-linux-init is to make the setup more accessible. +

+ +

My /etc/rc.init script is not printing anything!

+ +

+ You probably gave the -r option to +s6-linux-init-maker, and +your /etc/rc.init's output is being logged into the +/run/uncaught-logs directory instead of printed to +/dev/console. +

+ +

I want to run s6 in a container, and I just want to log +to stdout/stderr, without this tmpfs and /dev/console +stuff and +without having a catch-all logger inside the container. Is it +possible ?

+ +

+ Yes, it is possible, but then s6-linux-init may not be what you +are looking for. For your case, it will be simpler to run s6-svscan +directly! +

+ +

+ If you are using +Docker, there is a +s6-overlay +project specifically made for integrating s6 into Docker images. +

+ + + diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index cdf617e..530cd41 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -49,6 +49,7 @@ machine - else the scripts will crash. [ -u log_user ] \ [ -g early_getty ] \ [ -2 stage2 ] \ + [ -r ] \ [ -3 stage3 ] \ [ -p initial_path ] \ [ -m initial_umask ] \ @@ -74,7 +75,7 @@ declared as basedir. Be careful: it contains fifos, files with precise uid/gid permissions, and files with non-standard access rights, so be sure to copy it verbatim. The s6-hiercopy -tool can do it, as well as the GNU or busybox cp -a command. +tool can do it, as well as the GNU or busybox cp -a or mv commands.

@@ -133,11 +134,10 @@ system. When stage2 is executed, the machine state is as follows:

+

Notes

+ +

+ The difficult parts of +running +s6-svscan as process 1 are: +

+ + + +

+ The main benefit of s6-linux-init-maker is that it automates those +parts. This means that it has been designed for real hardware +where the above issues apply. + If you are building an init system for a +virtual machine, a container, or anything similar that does not +have the /dev/console issue or the read-only rootfs issue, +you will probably not reap much benefit from using s6-linux-init-maker: +you could probably invoke +s6-svscan +directly as your process 1, or build a script by hand, which +would result in a simpler init with less dependencies. +

+ diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c index b897115..007bd94 100644 --- a/src/init/s6-linux-init-maker.c +++ b/src/init/s6-linux-init-maker.c @@ -18,27 +18,23 @@ #include #include #include -#include -#include #include -#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_user ] [ -g early_getty_cmd ] [ -2 stage2_script ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -e initial_envvar ... ] dir" +#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_user ] [ -g early_getty_cmd ] [ -2 stage2_script ] [ -r ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -e initial_envvar ... ] dir" #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") ; +#define BANNER "*\n* init created by s6-linux-init-maker\n* see http://skarnet.org/software/s6-linux-init/\n*\n" + #define CRASH_SCRIPT \ "#!" EXECLINE_EXTBINPREFIX "execlineb -P\n\n" \ -EXECLINE_EXTBINPREFIX "redirfd -r 0 /dev/console\n" \ -EXECLINE_EXTBINPREFIX "redirfd -w 1 /dev/console\n" \ -EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" \ -EXECLINE_EXTBINPREFIX "foreground { " \ -S6_PORTABLE_UTILS_EXTBINPREFIX "s6-echo -- " \ +"redirfd -r 0 /dev/console\n" \ +"redirfd -w 1 /dev/console\n" \ +"fdmove -c 2 1\n" \ +"foreground { s6-echo -- " \ "\"s6-svscan crashed. Dropping to an interactive shell.\" }\n" \ "/bin/sh -i\n" -#define BANNER1 "s6-init: stage 1" -#define BANNER2 "s6-init: stage 2" - static char const *slashrun = "/run" ; static char const *robase = "/etc/s6-linux-init" ; static char const *init_script = "/etc/rc.init" ; @@ -51,6 +47,7 @@ static gid_t uncaught_logs_gid = 65534 ; static unsigned int initial_umask = 022 ; static unsigned int timestamp_style = 1 ; static unsigned int slashdev_style = 2 ; +static int redirect_stage2 = 0 ; typedef int writetobuf_func_t (buffer *) ; typedef writetobuf_func_t *writetobuf_func_t_ref ; @@ -70,12 +67,12 @@ static int s6_svscan_log_script (buffer *b) char fmt[UINT64_FMT] ; if (buffer_puts(b, "#!" EXECLINE_EXTBINPREFIX "execlineb -P\n\n" - EXECLINE_EXTBINPREFIX "redirfd -rnb 0 fifo\n" - S6_EXTBINPREFIX "s6-applyuidgid -u ") < 0 + "redirfd -rnb 0 fifo\n" + "s6-applyuidgid -u ") < 0 || buffer_put(b, fmt, uint64_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, " --\n" S6_EXTBINPREFIX "s6-log -bp -- ") < 0 + || buffer_puts(b, " --\ns6-log -bp -- ") < 0 || buffer_puts(b, timestamp_style & 1 ? "t " : "") < 0 || buffer_puts(b, timestamp_style & 2 ? "T " : "") < 0) return 0 ; if (!string_quote(&satmp, slashrun, str_len(slashrun))) return 0 ; @@ -240,20 +237,17 @@ static int make_init_script (buffer *b) satmp.len = sabase ; if (buffer_put(b, "\n", 1) < 0 || buffer_puts(b, bindir) < 0 - || buffer_puts(b, "/cd /\n" - EXECLINE_EXTBINPREFIX "umask 0") < 0 + || buffer_puts(b, "/cd /\numask 0") < 0 || buffer_put(b, fmt, uint_ofmt(fmt, initial_umask)) < 0 - || buffer_puts(b, "\n" - EXECLINE_EXTBINPREFIX "if { " - S6_PORTABLE_UTILS_EXTBINPREFIX "s6-echo -- \"" BANNER1 "\" }\n" - EXECLINE_EXTBINPREFIX "if { " - S6_LINUX_UTILS_EXTBINPREFIX "s6-mount -nwt tmpfs -o mode=0755 tmpfs ") < 0 + || buffer_puts(b, "\nif { s6-echo -- ") < 0) + || !string_quote(&satmp, BANNER, sizeof(BANNER) - 1) < 0) return 0 ; + if (buffer_puts(b, satmp.s, satmp.len) < 0) goto err ; + satmp.len = sabase ; + if (buffer_puts(b, " }\nif { s6-mount -nwt tmpfs -o mode=0755 tmpfs ") < 0 || !string_quote(&satmp, slashrun, str_len(slashrun))) return 0 ; pos = satmp.len ; if (buffer_put(b, satmp.s + sabase, pos - sabase) < 0 - || buffer_puts(b, " }\n" - EXECLINE_EXTBINPREFIX "if { " - S6_PORTABLE_UTILS_EXTBINPREFIX "s6-hiercopy ") < 0 + || buffer_puts(b, " }\nif { s6-hiercopy ") < 0 || !string_quote(&satmp, robase, str_len(robase))) return 0 ; pos2 = satmp.len ; if (buffer_put(b, satmp.s + pos, pos2 - pos) < 0 @@ -262,42 +256,30 @@ static int make_init_script (buffer *b) || buffer_puts(b, " }\n") < 0) goto err ; if (slashdev_style == 1) { - if (buffer_puts(b, - EXECLINE_EXTBINPREFIX "if { " - S6_LINUX_UTILS_EXTBINPREFIX "s6-mount -nt devtmpfs dev /dev }\n") < 0) - goto err ; + if (buffer_puts(b, "if { s6-mount -nt devtmpfs dev /dev }\n") < 0) goto err ; } - if (buffer_puts(b, - EXECLINE_EXTBINPREFIX "redirfd -r 0 /dev/null\n" - S6_EXTBINPREFIX "s6-envdir -I -- ") < 0 + if (buffer_puts(b, "redirfd -r 0 /dev/null\ns6-envdir -I -- ") < 0 || buffer_put(b, satmp.s + pos, pos2 - pos) < 0 - || buffer_puts(b, "/env\n" - EXECLINE_EXTBINPREFIX "background\n{\n " - S6_EXTBINPREFIX "s6-setsid --\n " - EXECLINE_EXTBINPREFIX "redirfd -w 2 ") < 0 - || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 - || buffer_puts(b, "/service/s6-svscan-log/fifo\n " - EXECLINE_EXTBINPREFIX "if { " - S6_PORTABLE_UTILS_EXTBINPREFIX "s6-echo -- \"" BANNER2 "\" }\n " - EXECLINE_EXTBINPREFIX "fdmove -c 1 2\n ") < 0 - || !string_quote(&satmp, init_script, str_len(init_script)) + || buffer_puts(b, "/env\nbackground\n{\n s6-setsid --\n ") < 0) goto err ; + if (redirect_stage2) + { + if (buffer_puts(b, "redirfd -w 2 ") < 0 + || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 + || buffer_puts(b, "/service/s6-svscan-log/fifo\n fdmove -c 1 2\n ") < 0) goto err ; + } + else + { + if (buffer_puts(b, "redirfd -w 3 ") < 0 + || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 + || buffer_puts(b, "/service/s6-svscan-log/fifo\n fdclose 3\n ") < 0) goto err ; + } + if (!string_quote(&satmp, init_script, str_len(init_script)) || buffer_put(b, satmp.s + pos2, satmp.len - pos2) < 0 - || buffer_puts(b, "\n}\n" - EXECLINE_EXTBINPREFIX "unexport !\n" - EXECLINE_EXTBINPREFIX "redirfd -wnb 1 ") < 0 + || buffer_puts(b, "\n}\nunexport !\nredirfd -wnb 1 ") < 0 || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 - || buffer_puts(b, - "/service/s6-svscan-log/fifo\n" - EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" - EXECLINE_EXTBINPREFIX "cd ") < 0 + || buffer_puts(b, "/service/s6-svscan-log/fifo\nfdmove -c 2 1\ncd ") < 0 || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 - || buffer_puts(b, "/service\n") < 0) goto err ; - if (sizeof(S6_EXTBINPREFIX) > 1) - { - if (buffer_puts(b, EXECLINE_EXTBINPREFIX "exec -a s6-svscan --\n") < 0) - goto err ; - } - if (buffer_puts(b, S6_EXTBINPREFIX "s6-svscan -t0\n") < 0) goto err ; + || buffer_puts(b, "/service\ns6-svscan -t0\n") < 0) goto err ; return 1 ; err: satmp.len = sabase ; @@ -313,7 +295,7 @@ int main (int argc, char const *const *argv) subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - register int opt = subgetopt_r(argc, argv, "c:l:b:u:g:2:3:p:m:t:d:e:", &l) ; + register int opt = subgetopt_r(argc, argv, "c:l:b:u:g:2:r3:p:m:t:d:e:", &l) ; if (opt == -1) break ; switch (opt) { @@ -323,6 +305,7 @@ int main (int argc, char const *const *argv) case 'u' : catchall_user = l.arg ; break ; case 'g' : early_getty = l.arg ; break ; case '2' : init_script = l.arg ; break ; + case 'r' : redirect_stage2 = 1 ; break ; case '3' : shutdown_script = l.arg ; break ; case 'p' : initial_path = l.arg ; break ; case 'm' : if (!uint0_oscan(l.arg, &initial_umask)) dieusage() ; break ; -- cgit v1.2.3