From e00d2c4d88c90ccc6d091bde07d412936f8886d3 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 13 Oct 2015 16:05:05 +0000 Subject: - added stage2_finish support - s6 dep bumped to 2.2.2.0 --- INSTALL | 2 +- doc/index.html | 2 +- doc/s6-linux-init-maker.html | 38 ++++++++++++++++++++++++ doc/upgrade.html | 3 +- examples/rc.init | 4 +++ examples/rc.shutdown | 19 ++++++++++++ examples/rc.tini | 3 ++ src/init/s6-linux-init-maker.c | 67 ++++++++++++++++++++++++++++++++++++++++-- 8 files changed, 132 insertions(+), 6 deletions(-) create mode 100755 examples/rc.init create mode 100755 examples/rc.shutdown create mode 100755 examples/rc.tini diff --git a/INSTALL b/INSTALL index c93d004..90f83e3 100644 --- a/INSTALL +++ b/INSTALL @@ -10,7 +10,7 @@ Build Instructions - execline version 2.1.4.1 or later: http://skarnet.org/software/execline/ - s6-portable-utils version 2.0.5.3 or later: http://skarnet.org/software/s6-portable-utils/ - s6-linux-utils version 2.0.2.3 or later: http://skarnet.org/software/s6-linux-utils/ - - s6 version 2.2.1.1 or later: http://skarnet.org/software/s6/ + - s6 version 2.2.2.0 or later: http://skarnet.org/software/s6/ Note that all those are build-time dependencies, and they are *also* run-time dependencies when you use the init binary created diff --git a/doc/index.html b/doc/index.html index 260b286..f328f44 100644 --- a/doc/index.html +++ b/doc/index.html @@ -58,7 +58,7 @@ a small FAQ.
  • s6-linux-utils version 2.0.2.3 or later
  • s6 version -2.2.1.1 or later
  • +2.2.2.0 or later

    diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index 530cd41..95c0101 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -50,6 +50,7 @@ machine - else the scripts will crash. [ -g early_getty ] \ [ -2 stage2 ] \ [ -r ] \ + [ -Z ] stage2_finish \ [ -3 stage3 ] \ [ -p initial_path ] \ [ -m initial_umask ] \ @@ -186,6 +187,37 @@ do not hold any file descriptor to a filesystem that would need to be unmounted. +

    + When s6-svscan receives a signal such as SIGINT, typically sent by the +Ctrl-Alt-Del key combination or a reboot or poweroff +command, it will run the corresponding script in +tmpfsdir/service/.s6-svscan, which will first run +stage2_finish, then send an exit command to s6-svscan as +described above. This is useful if some commands need to be run before +s6-svscan executes into stage3: for instance, if the machine +state is maintained by a service manager such as +s6-rc, all the +services can be turned off in stage2_finish while s6-svscan +is still alive, and then the last steps of the shutdown procedure can +be performed in stage3. +

    + +

    + Generally speaking, stage2_finish should undo what +stage2 has done at boot time, so stage3 has very +little work to do. +

    + +

    + The examples/ subdirectory of the s6-linux-init package +contains an example of /etc/rc.init, /etc/rc.tini +and /etc/rc.shutdown scripts, suitable for +stage2, stage2_finish and stage3 +respectively. Those scripts can practically be used as is if the machine +is managed by the s6-rc +service manager. +

    +

    s6-linux-init-maker options

    in 0.0.1.3

    diff --git a/examples/rc.init b/examples/rc.init new file mode 100755 index 0000000..e0b2b72 --- /dev/null +++ b/examples/rc.init @@ -0,0 +1,4 @@ +#!/bin/execlineb -P + +if { s6-rc-init /run/service } +s6-rc -u change ok-all diff --git a/examples/rc.shutdown b/examples/rc.shutdown new file mode 100755 index 0000000..5589903 --- /dev/null +++ b/examples/rc.shutdown @@ -0,0 +1,19 @@ +#!/bin/execlineb -S0 + +foreground { s6-echo "Syncing disks." } +foreground { s6-sync } +foreground { s6-echo "Sending all processes the TERM signal." } +foreground { s6-nuke -th } +s6-sleep 2 +foreground { s6-echo "Sending all processes the KILL signal." } +foreground { s6-nuke -k } +wait { } + +foreground { s6-echo "Syncing disks." } +foreground { s6-sync } +foreground { s6-echo "Unmounting disks." } +foreground { s6-umount -a } +foreground { s6-mount -o ro,remount /dev/root / } + +foreground { s6-echo "\nPerforming "${1}"." } +s6-${1} diff --git a/examples/rc.tini b/examples/rc.tini new file mode 100755 index 0000000..abefb22 --- /dev/null +++ b/examples/rc.tini @@ -0,0 +1,3 @@ +#!/bin/execlineb -P + +s6-rc -da change diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c index b0663e2..87d3787 100644 --- a/src/init/s6-linux-init-maker.c +++ b/src/init/s6-linux-init-maker.c @@ -18,7 +18,7 @@ #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 ] [ -r ] [ -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 ] [ -Z finish_script ] [ -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") ; @@ -35,6 +35,7 @@ static char const *slashrun = "/run" ; static char const *robase = "/etc/s6-linux-init" ; static char const *init_script = "/etc/rc.init" ; +static char const *tini_script = "/etc/rc.tini" ; static char const *shutdown_script = "/etc/rc.shutdown" ; static char const *bindir = "/bin" ; static char const *initial_path = SKALIBS_DEFAULTPATH ; @@ -117,6 +118,57 @@ static int finish_script (buffer *b) return 0 ; } +static int sig_script (buffer *b, char c) +{ + unsigned int sabase = satmp.len ; + if (!put_shebang(b) + || buffer_puts(b, "foreground { ") < 0 + || !string_quote(&satmp, tini_script, str_len(tini_script))) return 0 ; + if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; + satmp.len = sabase ; + if (buffer_puts(b, " }\ns6-svscanctl -") < 0 + || buffer_put(b, &c, 1) < 0 + || buffer_puts(b, " -- ") < 0 + || !string_quote(&satmp, slashrun, str_len(slashrun))) return 0 ; + if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; + satmp.len = sabase ; + if (buffer_puts(b, "/service\n") < 0) return 0 ; + return 1 ; + err: + satmp.len = sabase ; + return 0 ; +} + +static int sigterm_script (buffer *b) +{ + return sig_script(b, 't') ; +} + +static int sighup_script (buffer *b) +{ + return sig_script(b, 'h') ; +} + +static int sigquit_script (buffer *b) +{ + return sig_script(b, 'q') ; +} + +static int sigint_script (buffer *b) +{ + return sig_script(b, '6') ; +} + +static int sigusr1_script (buffer *b) +{ + return sig_script(b, '7') ; +} + +static int sigusr2_script (buffer *b) +{ + return sig_script(b, '0') ; +} + static void cleanup (char const *base) { int e = errno ; @@ -205,6 +257,12 @@ static inline void make_image (char const *base) auto_dir(base, "run-image/service/.s6-svscan", 0, 0, 0755) ; auto_script(base, "run-image/service/.s6-svscan/crash", &crash_script) ; auto_script(base, "run-image/service/.s6-svscan/finish", &finish_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGTERM", &sigterm_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGHUP", &sighup_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGQUIT", &sigquit_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGINT", &sigint_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGUSR1", &sigusr1_script) ; + auto_script(base, "run-image/service/.s6-svscan/SIGUSR2", &sigusr2_script) ; auto_dir(base, "run-image/service/s6-svscan-log", 0, 0, 0755) ; auto_fifo(base, "run-image/service/s6-svscan-log/fifo") ; auto_script(base, "run-image/service/s6-svscan-log/run", &s6_svscan_log_script) ; @@ -280,7 +338,7 @@ static inline int make_init_script (buffer *b) || buffer_put(b, satmp.s + pos2, satmp.len - pos2) < 0 || buffer_puts(b, "\n}\nunexport !\ncd ") < 0 || buffer_put(b, satmp.s + sabase, pos - sabase) < 0 - || buffer_puts(b, "/service\nfdmove -c 2 1\ns6-svscan -t0\n") < 0) goto err ; + || buffer_puts(b, "/service\nfdmove -c 2 1\ns6-svscan -st0\n") < 0) goto err ; return 1 ; err: satmp.len = sabase ; @@ -295,7 +353,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:r3:p:m:t:d:e:", &l) ; + register int opt = subgetopt_r(argc, argv, "c:l:b:u:g:2:rZ:3:p:m:t:d:e:", &l) ; if (opt == -1) break ; switch (opt) { @@ -306,6 +364,7 @@ int main (int argc, char const *const *argv) case 'g' : early_getty = l.arg ; break ; case '2' : init_script = l.arg ; break ; case 'r' : redirect_stage2 = 1 ; break ; + case 'Z' : tini_script = l.arg ; 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 ; @@ -327,6 +386,8 @@ int main (int argc, char const *const *argv) strerr_dief3x(100, "initial location for binaries ", bindir, " is not absolute") ; if (init_script[0] != '/') strerr_dief3x(100, "stage 2 script location ", init_script, " is not absolute") ; + if (tini_script[0] != '/') + strerr_dief3x(100, "stage 2 finish script location ", tini_script, " is not absolute") ; if (shutdown_script[0] != '/') strerr_dief3x(100, "stage 3 script location ", shutdown_script, " is not absolute") ; if (timestamp_style > 3) -- cgit v1.3.1