diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2017-08-28 08:12:20 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2017-08-28 08:12:20 +0000 |
commit | c29368d9e34fee0e2fe0fae2fdf2865580be4ae0 (patch) | |
tree | 066714d4ec6c52ea2bb450b0f84e7ffb9ebea0da | |
parent | 17c03cf8f0a6339d78ad8fb968ef3b999d658034 (diff) | |
download | s6-linux-init-c29368d9e34fee0e2fe0fae2fdf2865580be4ae0.tar.xz |
Add namespaces support, prepare for 0.3.1.0
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | INSTALL | 10 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | doc/index.html | 12 | ||||
-rw-r--r-- | doc/s6-linux-init-maker.html | 11 | ||||
-rw-r--r-- | doc/upgrade.html | 15 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | src/init/hpr.c | 63 | ||||
-rw-r--r-- | src/init/s6-linux-init-maker.c | 48 |
9 files changed, 149 insertions, 20 deletions
@@ -1,4 +1,4 @@ -Copyright (c) 2015-2016 Laurent Bercot <ska-skaware@skarnet.org> +Copyright (c) 2015-2017 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 @@ -6,15 +6,15 @@ Build Instructions - A Linux-based system with a standard C development environment - GNU make version 3.81 or later - - skalibs version 2.5.0.0 or later: http://skarnet.org/software/skalibs/ + - skalibs version 2.6.0.0 or later: http://skarnet.org/software/skalibs/ The scripts generated by the s6-linux-init-maker program have some additional dependencies: - - execline version 2.3.0.0 or later: http://skarnet.org/software/execline/ - - s6-portable-utils version 2.2.0.0 or later: http://skarnet.org/software/s6-portable-utils/ - - s6-linux-utils version 2.3.0.0 or later: http://skarnet.org/software/s6-linux-utils/ - - s6 version 2.5.0.0 or later: http://skarnet.org/software/s6/ + - execline version 2.3.0.2 or later: http://skarnet.org/software/execline/ + - s6-portable-utils version 2.2.1.1 or later: http://skarnet.org/software/s6-portable-utils/ + - s6-linux-utils version 2.4.0.0 or later: http://skarnet.org/software/s6-linux-utils/ + - s6 version 2.6.1.0 or later: http://skarnet.org/software/s6/ This software is Linux-specific. It will run on a Linux kernel, version 2.6.32 or later. However, it should not be too hard to port to @@ -1,5 +1,11 @@ Changelog for s6-linux-init. +In 0.3.1.0 +---------- + + - Support for running in Linux containers + + In 0.3.0.0 ---------- diff --git a/doc/index.html b/doc/index.html index 4c1ff7d..dd93276 100644 --- a/doc/index.html +++ b/doc/index.html @@ -50,15 +50,15 @@ a small FAQ. <li> A Linux-based system with a standard C development environment </li> <li> GNU make, version 3.81 or later </li> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version -2.5.0.0 or later </li> +2.6.0.0 or later </li> <li> <a href="//skarnet.org/software/execline/">execline</a> version -2.3.0.0 or later </li> +2.3.0.2 or later </li> <li> <a href="//skarnet.org/software/s6-portable-utils/">s6-portable-utils</a> version -2.2.0.0 or later </li> +2.2.1.1 or later </li> <li> <a href="//skarnet.org/software/s6-linux-utils/">s6-linux-utils</a> version -2.3.0.0 or later </li> +2.4.0.0 or later </li> <li> <a href="//skarnet.org/software/s6/">s6</a> version -2.5.0.0 or later </li> +2.6.1.0 or later </li> </ul> <p> @@ -87,7 +87,7 @@ against the shared version of the skalibs library, it also becomes a <ul> <li> The current released version of s6-linux-init is -<a href="s6-linux-init-0.3.0.0.tar.gz">0.3.0.0</a>. </li> +<a href="s6-linux-init-0.3.1.0.tar.gz">0.3.1.0</a>. </li> <li> Alternatively, you can checkout a copy of the <a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-linux-init/">s6-linux-init git repository</a>: diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index b7648ed..41d8372 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -63,6 +63,7 @@ machine</em> - else the scripts will crash. [ -d <em>dev_style</em> ] \ [ -s <em>env_store</em> ] \ [ -e <em>initial_envvar</em> ] ... \ + [ -n ] \ <em>dir</em> </pre> @@ -374,6 +375,14 @@ environment, or of the form <em>VAR=VALUE</em>, to add an environment variable <em>VAR</em> with the value <em>VALUE</em>. The TZ variable, for instance, is a good candidate to be set in the global environment. </li> <p /> + + <li> <tt>-n</tt> : 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 <tt>.s6-svscan/finish</tt>, <tt>.s6-svscan/SIGHUP</tt> +and <tt>.s6-svscan/SIGINT</tt> 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. </li> <p /> </ul> <h2> Notes </h2> @@ -407,6 +416,8 @@ you could probably invoke <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a> directly as your process 1, or build a script by hand, which would result in a simpler init with less dependencies. +Nevertheless, if you prefer using s6-linux-init-maker, it +supports this case via the <tt>-n</tt> option. </p> </body> diff --git a/doc/upgrade.html b/doc/upgrade.html index 8108b4d..38e6ac1 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -18,6 +18,21 @@ <h1> What has changed in s6-linux-init </h1> +<h2> in 0.3.1.0 </h2> + +<ul> + <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> +dependency bumped to 2.6.0.0. </li> + <li> <a href="//skarnet.org/software/execline/">execline</a> +dependency bumped to 2.3.0.2. </li> + <li> <a href="//skarnet.org/software/s6-portable-utils/">s6-portable-utils</a> +dependency bumped to 2.2.1.1. </li> + <li> <a href="//skarnet.org/software/s6-linux-utils/">s6-linux-utils</a> +dependency bumped to 2.4.0.0. </li> + <li> <a href="//skarnet.org/software/s6/">s6</a> +dependency bumped to 2.6.1.0. </li> +</ul> + <h2> in 0.3.0.0 </h2> <ul> diff --git a/package/info b/package/info index c63cb84..a3417c4 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=s6-linux-init -version=0.3.0.0 +version=0.3.1.0 category=admin package_macro_name=S6_LINUX_INIT diff --git a/src/init/hpr.c b/src/init/hpr.c index faa0a7c..b587dba 100644 --- a/src/init/hpr.c +++ b/src/init/hpr.c @@ -1,13 +1,61 @@ /* ISC license. */ +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> #include <unistd.h> #include <signal.h> +#include <errno.h> #include <sys/reboot.h> #include <skalibs/strerr2.h> #include <skalibs/sgetopt.h> +#include <skalibs/sig.h> +#include <skalibs/djbunix.h> #define USAGE PROGNAME " [ -h | -p | -r ] [ -f ]" +#ifdef SKALIBS_HASNSGETPARENT + +#include <sys/ioctl.h> +#include <linux/nsfs.h> + +static int test_in_namespace (void) +{ + int r ; + int fd = open_read("/proc/1/ns/pid") ; + if (fd < 0) return 0 ; + r = ioctl(myfd, NS_GET_PARENT) ; + close(fd) ; + return r >= 0 ; +} + +#else + + /* + When in doubt, always trap signals. This incurs a small race: + if ctrl-alt-del is pressed at the wrong time, the process will + exit and cause a kernel panic. But the alternatives are WAY + more hackish than this. + */ + +static int test_in_namespace (void) +{ + return 1 ; +} + +#endif + +static void sigint_handler (int sig) +{ + (void)sig ; + _exit(1) ; +} + +static void sighup_handler (int sig) +{ + (void)sig ; + _exit(0) ; +} + int main (int argc, char const *const *argv) { int what = WHATDEFAULT ; @@ -32,9 +80,24 @@ int main (int argc, char const *const *argv) argc -= l.ind ; argv += l.ind ; } + if (geteuid()) + { + errno = EPERM ; + strerr_dief1sys(100, "nice try, peon") ; + } + if (force) { sync() ; + if (getpid() == 1) + { + if (test_in_namespace()) + { + if (sig_catch(SIGINT, &sigint_handler) < 0 + || sig_catch(SIGHUP, &sighup_handler) < 0) + strerr_diefu1sys(111, "catch signals") ; + } + } reboot(what == 3 ? RB_AUTOBOOT : what == 2 ? RB_POWER_OFF : RB_HALT_SYSTEM) ; strerr_diefu1sys(111, "reboot()") ; } diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c index 802d924..2aa28da 100644 --- a/src/init/s6-linux-init-maker.c +++ b/src/init/s6-linux-init-maker.c @@ -16,11 +16,12 @@ #include <skalibs/sgetopt.h> #include <skalibs/skamisc.h> -#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_uid -g log_gid | -U ] [ -G early_getty_cmd ] [ -2 stage2_script ] [ -r ] [ -Z finish_script ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -s env_store ] [ -e initial_envvar ... ] dir" +#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_uid -g log_gid | -U ] [ -G early_getty_cmd ] [ -2 stage2_script ] [ -r ] [ -Z finish_script ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -s env_store ] [ -e initial_envvar ... ] [ -n ] 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 EXITCODENAME "file\\ created\\ by\\ s6-linux-init,\\ storing\\ a\\ container's\\ exit\\ code" #define CRASH_SCRIPT \ "redirfd -r 0 /dev/console\n" \ @@ -45,6 +46,7 @@ static unsigned int initial_umask = 022 ; static unsigned int timestamp_style = 1 ; static unsigned int slashdev_style = 2 ; static int redirect_stage2 = 0 ; +static int in_namespace = 0 ; typedef int writetobuf_func_t (buffer *) ; typedef writetobuf_func_t *writetobuf_func_t_ref ; @@ -101,10 +103,22 @@ static int finish_script (buffer *b) size_t sabase = satmp.len ; if (buffer_puts(b, "#!") < 0 || buffer_puts(b, bindir) < 0 - || buffer_puts(b, "/execlineb -S0\n\n" - "cd /\nredirfd -w 2 /dev/console\nfdmove -c 1 2\nforeground { s6-svc -X -- ") < 0 + || buffer_puts(b, "/execlineb -S0\n\n") < 0 || !string_quote(&satmp, slashrun, strlen(slashrun))) return 0 ; - if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; + + if (in_namespace) + { + if (buffer_puts(b, "ifelse { redirfd -r 0 ") < 0 + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0 + || buffer_puts(b, "/" EXITCODENAME " exit 0 }\n{ redirfd -r 0 ") < 0 + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0 + || buffer_puts(b, "/" EXITCODENAME " withstdinas -in CODE foreground { s6-rmrf ") < 0 + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0 + || buffer_puts(b, "/" EXITCODENAME " } importas -ui CODE CODE exit ${CODE} }\n") < 0) goto err ; + } + + if (buffer_puts(b, "cd /\nredirfd -w 2 /dev/console\nfdmove -c 1 2\nforeground { s6-svc -X -- ") < 0 + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; satmp.len = sabase ; if (buffer_puts(b, "/service/s6-svscan-log }\nunexport ?\nwait -r -- { }\n") < 0 || !string_quote(&satmp, shutdown_script, strlen(shutdown_script))) return 0 ; @@ -138,6 +152,25 @@ static int sig_script (buffer *b, char c) return 0 ; } +static int onlyexit (buffer *b, char c) +{ + size_t sabase = satmp.len ; + if (!put_shebang(b) + || buffer_puts(b, "foreground { redirfd -w 1 ") < 0 + || !string_quote(&satmp, slashrun, strlen(slashrun)) + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0 + || buffer_puts(b, "/" EXITCODENAME " s6-echo -- ") < 0 + || buffer_put(b, &c, 1) < 0 + || buffer_puts(b, " }\ns6-svscanctl -b ") < 0 + || buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0 + || buffer_puts(b, "/service\n") < 0) goto err ; + satmp.len = sabase ; + return 1 ; + err: + satmp.len = sabase ; + return 0 ; +} + static int sigterm_script (buffer *b) { return sig_script(b, 't') ; @@ -145,7 +178,7 @@ static int sigterm_script (buffer *b) static int sighup_script (buffer *b) { - return sig_script(b, 'h') ; + return in_namespace ? onlyexit(b, '0') : sig_script(b, 'h') ; } static int sigquit_script (buffer *b) @@ -155,7 +188,7 @@ static int sigquit_script (buffer *b) static int sigint_script (buffer *b) { - return sig_script(b, '6') ; + return in_namespace ? onlyexit(b, '1') : sig_script(b, '6') ; } static int sigusr1_script (buffer *b) @@ -361,7 +394,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:l:b:u:g:UG:2:rZ:3:p:m:t:d:s:e:", &l) ; + int opt = subgetopt_r(argc, argv, "c:l:b:u:g:UG:2:rZ:3:p:m:t:d:s:e:n", &l) ; if (opt == -1) break ; switch (opt) { @@ -390,6 +423,7 @@ int main (int argc, char const *const *argv, char const *const *envp) case 'd' : if (!uint0_scan(l.arg, &slashdev_style)) dieusage() ; break ; case 's' : env_store = l.arg ; break ; case 'e' : if (!stralloc_catb(&satmp, l.arg, strlen(l.arg) + 1)) dienomem() ; break ; + case 'n' : in_namespace = 1 ; break ; default : dieusage() ; } } |