Re: s6-init script

From: Laurent Bercot <ska-skaware_at_skarnet.org>
Date: Wed, 27 Nov 2024 02:51:03 +0000

>| foreground { fdclose 2 umount ${TMPFSDIR} }

  It's generally a bad idea to close fd 2: it makes your system
non-conformant to POSIX, and umount, if it assumes a conformant
system, could have undefined behaviour here. If you don't want
error messages, better redirect fd 2 to /dev/null instead.
(util-linux's umount doesn't care, but that doesn't mean it's true for
all other umount implementations.)


>| redirfd -w -nb 1 ${TMPFSDIR}/service/s6-svscan-log/fifo
>|
>| background {
>| redirfd -w 2 ${TMPFSDIR}/service/s6-svscan-log/fifo
>| ${BASEDIR}/scripts/rc.init ${RUNLEVEL}
>| }
>|
>| redirfd -w -nb 2 ${TMPFSDIR}/service/s6-svscan-log/fifo

  This is dangerous, because redirfd -wnb on a fifo will briefly open
the fifo for reading (yes, it's a hack!) so depending on the scheduler
your last redirfd can unblock the previous redirfd waiting on the
catch-all logger, and spawn your rc.init too early.
  Use fdmove -c 2 1 instead of the last redirfd -wnb to ensure proper
synchronization of your rc.init.


>1. When I redirect the file descriptors 1 and 2 like above, I get, as expected,
> no output on console/tty during the boot process,
> but I do get that when using s6-linux-init.

  As Guillermo said, this is due to s6-linux-init and several components
around it doing an elaborate dance with file descriptors, in order to
have /dev/console be the absolute last resort for output, i.e. only
appearing as the stdout and stderr for the catch-all logger, while
everything else, including s6-svscan, sends all its output to the
catch-all logger, *combined with* the 1 directive in the catch-all
s6-log arguments that duplicates the data to its stdout, i.e.
/dev/console.

  It's probably the most complicated part of s6-linux-init and the one
that was the most difficult to get right, so don't worry if you don't
understand it right away. I had to draw flowcharts to make sure I knew
exactly what every fd in every process was pointing to at each step of
the early boot process. If you're writing an early boot system, in
execline or otherwise, with the same goals of having a proper logging
chain in place with the proper fallthroughs, you should probably do
the same ;)


>2. If I do not redirect them, I still get all the output on the catch all logger.

  If you don't redirect fds 1 and 2 to fifo in the main process, your
supervision tree won't log to the catch-all logger, everything will
default to /dev/console. But since you're still redirecting rc.init's
stderr to fifo, as a synchronization mechanism, all you get on stderr
from your boot process (but not stdout) will end up in the catch-all
logger.


>3. Using the script as above, my /run/uncaught-logs seems to get flooded with the same init messages over and over again during runtime.

  What init messages?
  If something floods you, it's probably that some s6-supervise is
failing to bring a service up, and is trying again one second later.
So it's likely that you just have something failing in your boot
process.

--
  Laurent
Received on Wed Nov 27 2024 - 03:51:03 CET

This archive was generated by hypermail 2.4.0 : Wed Nov 27 2024 - 03:51:36 CET