author | Olivier Brunel
<jjk@jjacky.com> 2018-01-22 21:06:54 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2018-01-23 17:16:51 UTC |
parent | 3b7a0401879126395e618143bb6f850ada95a14c |
doc/aa-stage0.pod | +17 | -14 |
doc/aa-stage2.pod | +8 | -3 |
doc/aa-stage3.pod | +9 | -1 |
doc/aa-stage4.pod | +11 | -2 |
src/scripts/aa-stage0 | +10 | -12 |
src/scripts/aa-stage2 | +17 | -27 |
src/scripts/aa-stage3 | +7 | -1 |
src/scripts/aa-stage4 | +5 | -1 |
diff --git a/doc/aa-stage0.pod b/doc/aa-stage0.pod index 8aded55..4d4130e 100644 --- a/doc/aa-stage0.pod +++ b/doc/aa-stage0.pod @@ -30,17 +30,20 @@ I</root-fs/sys> and I</root-fs/run> It is also up to them to load required kernel modules in order to do so. -Once B<aa-start>(1) is done, B<aa-stage0>(1) will mount bind the rootfs (of the -initramfs) onto I</root-fs/run/initramfs> (so it's possible to pivot back into -it at the end of stage 3) before doing a mount move of I</root-fs> onto I</> and -executing (via B<aa-chroot>(1)) into I</sbin/init>, or whatever was specified -via I<init> on the kernel command line. - -If B<aa-start>(1) exits non-zero, e.g. if an essential service failed to be -started, B<aa-stage0>(1) assumes the root file system couldn't be mounted, and -tries to open a shell (I<sh -i>) to give you a possibility to fix things. -Exiting the shell will resume the process. - -You can also specify I<break> on the kernel command line to open a shell after -B<aa-start>(1) succesfully completed, before moving I</root-fs> to I</> (also -before mount binding the rootfs). +After B<aa-start>(1) has run, and if it exists, B<aa-stage0>(1) will execute +I</services/.anopa/post-stage0> with B<aa-start>(1)'s return code as +argument. This allows to e.g. open a shell if something went terribly wrong. + +Note that file descriptor 3 will remain open for writing and connected to the +logger, so anything written there will be timestamped & logged. + +For an example, see B<aa-post-stage0>(1) + +If "break" was specified on the kernel command line, an interactive shell will +be open. Once you "exit" the shell, process continues. + +Then B<aa-stage0>(1) will mount bind the rootfs (of the initramfs) onto +I</root-fs/run/initramfs> (so it's possible to pivot back into it at the end of +stage 3) before doing a mount move of I</root-fs> onto I</> and executing (via +B<aa-chroot>(1)) into I</sbin/init>, or whatever was specified via I<init> on +the kernel command line. diff --git a/doc/aa-stage2.pod b/doc/aa-stage2.pod index d57643a..afb4044 100644 --- a/doc/aa-stage2.pod +++ b/doc/aa-stage2.pod @@ -19,6 +19,11 @@ It starts all services via B<aa-start>(1) using I</etc/anopa/listdirs/onboot> as listdir, unless argument B<aa> was specified on kernel command line, in which case I</etc/anopa/listdirs/ARGVALUE> is used as listdir intead. -If B<aa-start>(1) exits non-zero, it assumes there might not even be a getty -running, and will try to open a shell (I<sh -i>). Else, the system is assumed to -be ready. +After B<aa-start>(1) has run, and if it exists, B<aa-stage2>(1) will execute +I</run/services/.anopa/post-stage2> with B<aa-start>(1)'s return code as +argument. This allows to e.g. open a shell if something went terribly wrong. + +Note that file descriptor 3 will remain open for writing and connected to the +logger, so anything written there will be timestamped & logged. + +For an example, see B<aa-post-stage2>(1) diff --git a/doc/aa-stage3.pod b/doc/aa-stage3.pod index e2d8de1..1bdfca4 100644 --- a/doc/aa-stage3.pod +++ b/doc/aa-stage3.pod @@ -19,6 +19,13 @@ service I<uncaught-logs> to catch all possible logs as long as possible. The B<s6-supervise> process of that service will be sent command 'x' so it simply exits when the supervised process will. +After B<aa-stop>(1) has run, and if it exists, B<aa-stage3>(1) will execute +I</run/services/.anopa/post-stage3> with B<aa-stop>(1)'s return code as +argument. This allows to e.g. open a shell if something went terribly wrong. + +Note that file descriptor 3 will remain open for writing and connected to the +logger, so anything written there will be timestamped & logged. + Signal SIGTERM is then sent to (almost) all processes, using B<aa-kill>(1) with option B<--skip>; Then SIGKILL is sent similarly. @@ -27,4 +34,5 @@ exec into I</shutdown> will the same argument it received from B<s6-svscan>, so either "halt", "reboot" or "poweroff". If B<aa-pivot>(1) fails, it will try to open a shell (I<sh -i>) to let you deal -with things manually. +with things manually. Again, fd 3 will be still be opened to the logger at this +point. diff --git a/doc/aa-stage4.pod b/doc/aa-stage4.pod index 1cdcc6f..ab0bf56 100644 --- a/doc/aa-stage4.pod +++ b/doc/aa-stage4.pod @@ -21,6 +21,15 @@ Services are meant to unmount the root file system from I</root-fs> as well as all API file systems in there: I</root-fs/dev>, I</root-fs/proc>, I</root-fs/sys> and I</root-fs/run> +After B<aa-stop>(1) has run, and if it exists, B<aa-stage4>(1) will execute +I</services/.anopa/post-stage4> with B<aa-stop>(1)'s return code as +argument. This allows to e.g. open a shell if something went terribly wrong. + +Note that obviously by this point there's no more logger, and unlike at other +stages file descriptor 3 isn't open anymore. + Then it will mount I</dev> and I</proc> in order to run B<aa-terminate>(1) to -make sure everything is closed/unmounted. It then performs the requested action -(on stage 3) via B<aa-reboot>(1). +make sure everything is closed/unmounted. If B<aa-terminate>(1) exits non-zero, +an interactive shell (I<sh -i>) is opened. + +It then performs the requested action (on stage 3) via B<aa-reboot>(1). diff --git a/src/scripts/aa-stage0 b/src/scripts/aa-stage0 index 92264c2..d2046ca 100755 --- a/src/scripts/aa-stage0 +++ b/src/scripts/aa-stage0 @@ -43,24 +43,22 @@ cd / umask 022 # Start services -foreground { if -n -{ - if { emptyenv -c s6-setsid aa-ctty -O3 -s aa-start -O3 -r /services -l onboot } - foreground { - # if "break" was specified on kernel cmdline, let's open a shell +foreground { + foreground { + emptyenv -c s6-setsid aa-ctty -O3 -s aa-start -O3 -r /services -l onboot + } + if { aa-test -e /services/.anopa/post-stage0 } + importas -u RC ? emptyenv -c /services/.anopa/post-stage0 $RC +} + +# if "break" was specified on kernel cmdline, let's open a shell +foreground { if -t { aa-incmdline -O3 -qf /root-fs/proc/cmdline break } foreground { aa-echo -O3 -B "Break requested" } foreground { aa-echo -O3 -t "Trying to open a shell; " +g exit +w " to continue" } emptyenv -c sh -i - } } -# aa-start failed (i.e. an essential service failed to be started), so we assume -# the root fs wasn't mounted: try a shell so user has a chance to fix things -foreground { aa-echo -O3 -Be "Mouting root file system failed" } -foreground { aa-echo -O3 -t "Trying to open a shell; " +g exit +w " to continue" } -emptyenv -c sh -i -} if { aa-echo -O3 -B "Moving /root-fs to /..." } # First we mount bind the rootfs (initramfs) onto /run/initramfs so we can come diff --git a/src/scripts/aa-stage2 b/src/scripts/aa-stage2 index 3d13a90..fe66e18 100755 --- a/src/scripts/aa-stage2 +++ b/src/scripts/aa-stage2 @@ -33,32 +33,22 @@ background fdclose 3 fdmove 3 4 -if -n -t -{ - # We want the actual tty on stdin - backtick -n TTY { aa-tty } - importas -u TTY TTY - redirfd -r 0 ${TTY} - # Reopen the console - redirfd -w 1 /dev/console - fdmove -c 2 1 - # And start everything - foreground { aa-echo -O3 -B "Stage 2: Initializing system..." } - backtick -n -D onboot LISTDIR { aa-incmdline -rs aa } - importas -u LISTDIR LISTDIR - # We have a tty in stdin, become session leader and set controlling terminal. - # This is so Ctrl+C will trigger a SIGINT to aa-start, so one can manually - # timeout a service. - if { emptyenv -c s6-setsid aa-ctty -O3 aa-start -O3 -l /etc/anopa/listdirs/${LISTDIR} } - aa-echo -O3 -B "System ready." -} - -# Something went wrong, likely aa-start failed (i.e. an essential service failed -# to be started), so we assume there's not event a getty: try a shell so user -# has a chance to fix things -redirfd -r 0 /dev/console +# We want the actual tty on stdin +backtick -n TTY { aa-tty } +importas -u TTY TTY +redirfd -r 0 ${TTY} +# Reopen the console redirfd -w 1 /dev/console fdmove -c 2 1 -foreground { aa-echo -O3 -Be "System initialization failed" } -foreground { aa-echo -O3 -t "Trying to open a shell..." } -emptyenv -c sh -i +# And start everything +foreground { aa-echo -O3 -B "Stage 2: Initializing system..." } +backtick -n -D onboot LISTDIR { aa-incmdline -rs aa } +importas -u LISTDIR LISTDIR +# We have a tty in stdin, become session leader and set controlling terminal. +# This is so Ctrl+C will trigger a SIGINT to aa-start, so one can manually +# timeout a service. +foreground { + emptyenv -c s6-setsid aa-ctty -O3 aa-start -O3 -l /etc/anopa/listdirs/${LISTDIR} +} +if { aa-test -e /run/services/.anopa/post-stage2 } +importas -u RC ? emptyenv -c /run/services/.anopa/post-stage2 $RC diff --git a/src/scripts/aa-stage3 b/src/scripts/aa-stage3 index d129269..fdf91d1 100755 --- a/src/scripts/aa-stage3 +++ b/src/scripts/aa-stage3 @@ -47,7 +47,13 @@ foreground { aa-echo -O3 -B "Stage 3: Preparing ${1}..." } # Stop all running services -- s6-svscan did only exec into us, leaving the # whole supervised tree intact. Here we stop everything (longrun & oneshot) in # order, save for the catch-all (it will get an 'x' though). -foreground { emptyenv -c s6-setsid aa-ctty -O3 -s aa-stop -O3 -aak uncaught-logs -t20 } +foreground { + foreground { + emptyenv -c s6-setsid aa-ctty -O3 -s aa-stop -O3 -aak uncaught-logs -t20 + } + if { aa-test -e /run/services/.anopa/post-stage3 } + importas -u RC ? emptyenv -c /run/services/.anopa/post-stage3 $RC +} # Now stop the catch-all logger (its supervisor will then exit) foreground { emptyenv -c s6-setsid aa-stop -O3 uncaught-logs } diff --git a/src/scripts/aa-stage4 b/src/scripts/aa-stage4 index 85f8c5a..8e09547 100755 --- a/src/scripts/aa-stage4 +++ b/src/scripts/aa-stage4 @@ -24,7 +24,11 @@ /bin/emptyenv /bin/s6-envdir /etc/anopa/env /bin/exec foreground { aa-echo -B "Stage 4: Unmounting root file system..." } -foreground { emptyenv -c aa-stop -r /services -a } +foreground { + foreground { emptyenv -c aa-stop -r /services -a } + if { aa-test -e /services/.anopa/post-stage4 } + importas -u RC ? emptyenv -c /services/.anopa/post-stage4 $RC +} # At this point everything should be unmounted, so we need to remount what's # needed for aa-terminate to work. We can't not umount /proc & /dev in aa-stop