s6-linux-init (package)

From Gentoo Wiki
(Redirected from S6-linux-init)
Jump to: navigation, search

s6-linux-init is a package that provides a set of tools to help create an s6-based init system, with optional s6-rc support, on top of the Linux kernel. The package's documentation is provided in HTML format, and can be read on a text user interface using for example www-client/links.

Installation

USE flags

USE flags for sys-apps/s6-linux-init Generates an init binary for s6-based init systems

static !!do not set this during bootstrap!! Causes binaries to be statically linked instead of dynamically
static-libs Build static versions of dynamic libraries as well
sysv-utils Install sysvinit compatibility symlinks for telinit, halt, poweroff, reboot, and shutdown

Important
The sysv-utils USE flag is set by default for this package, causing a blocker with sysvinit. Because s6-based init systems are not officially supported by Gentoo yet, it is recommended to unset this flag in /etc/portage/package.use.

Emerge

root #emerge --ask sys-apps/s6-linux-init
Important
s6-linux-init is currently on the testing branch. Users with systems on the stable branch will need to add the package to /etc/portage/package.accept_keywords (if using Portage) to be able to install it, and also add dev-libs/skalibs, as well as its runtime dependencies: dev-lang/execline, sys-apps/s6 and, for the 0.4.x.x series of s6-linux-init, sys-apps/s6-linux-utils and sys-apps/s6-portable-utils. While it is generally not advised to mix packages of stable and testing branches, the skarnet.org software stack only depends on the libc, so in this case it should be safe.

Configuration

Environment variables

  • UID — For the 0.4.x.x series of s6-linux-init, the numeric user ID of the catch-all logger's effective user set by s6-linux-init-maker when invoked with the -U option.
  • GID — For the 0.4.x.x series of s6-linux-init, the numeric group ID of the catch-all logger's effective group set by s6-linux-init-maker when invoked with the -U option.

Files

  • /etc/s6-linux-init/current/scripts/rc.init — For s6-linux-init-1.0.0.0 and later, default stage2 init expected by s6-linux-init.
  • /etc/s6-linux-init/current/scripts/rc.shutdown — For s6-linux-init-1.0.0.0 and later, default shutdown file expected by s6-linux-init-shutdownd.
  • /etc/s6-linux-init/current/scripts/runlevel — For s6-linux-init-1.0.0.0 and later, default runlevel changer script expected by s6-linux-init-telinit.
  • /etc/s6-linux-init/current/env — For s6-linux-init-1.0.0.0 and later, default environment directory used by s6-linux-init to set up the init system's supervision tree environment.
  • /etc/s6-linux-init/current/run-image — For s6-linux-init-1.0.0.0 and later, default run image containing the init system's initial scan directory and catch-all logger's logging directory images.
  • /etc/s6-linux-init/env — For the 0.4.x.x series of s6-linux-init, default environment directory used by the generated stage1 script to set up the init system's supervision tree environment.
  • /etc/s6-linux-init/run-image — For the 0.4.x.x series of s6-linux-init, default run image containing the init system's initial scan directory and catch-all logger's logging directory images.
  • /etc/rc.init — For the 0.4.x.x series of s6-linux-init, default stage2 init expected by the generated stage1 script.
  • /etc/rc.shutdown — For the 0.4.x.x series of s6-linux-init, default shutdown file expected by the generated s6-svscan diverted signal handlers.
  • /etc/shutdown.allow — For s6-linux-init-1.0.0.0 and later, list of account names used by s6-linux-init-shutdown when invoked with an -a option, to decide whether the machine shutdown request should be allowed to proceed or not.
  • /run/service — The init system's default scan directory.
  • /run/uncaught-logs — The init system's catch-all logger's default logging directory.

Usage

The package provides the s6-linux-init-maker program, which helps create several components of an s6-based init system, programs for shutting the machine down when the generated init system components are used, and support programs. Version 1.0.0.0 and later also provides tools for implementing runlevel-like functionality similar to that of sysvinit.

s6-linux-init-maker

The s6-linux-init-maker program must be run as root, so that it can create files and directories with appropriate owner, group and permissions, and must be invoked with a pathname as its argument. It creates a directory at the specified pathname, which must not exist beforehand, containing several init system components:

  • For the 0.4.x.x series of s6-linux-init, an execline script named init, that is a stage1 init. For s6-linux-init-1.0.0.0 and later, the directory does not contain the init script; instead, the package provides a program, also named s6-linux-init, that is used as the stage1 init.
  • A subdirectory named run-image, which contains:
    • An s6 scan directory image.
    • An empty directory named uncaught-logs.
  • A subdirectory named env, that might be empty.
  • For s6-linux-init-1.0.0.0 and later, a subdirectory named scripts, containing shell scripts named rc.init, rc.shutdown and runlevel.
  • For s6-linux-init-1.0.0.0 and later, a subdirectory named bin, containing sysvinit compatibility execline scripts.

To use these components to make an init system, they must be copied to appropriate filesystem locations. The init script, which, for s6-linux-init-1.0.0.0 and later, is contained in the bin subdirectory of the generated directory, must be copied to the place where the kernel is configured to find the program it'll run as process 1. For example, if the bootloader is configured to pass an init=/sbin/s6-imkr-init parameter to the kernel, then the init file generated by s6-linux-init-maker must be copied to /sbin and renamed as s6-imkr-init. The run-image and env directories, and, for s6-linux-init-1.0.0.0 and later, the scripts directory, must be copied to the location the stage1 init expects them to be. For the sysvinit compatibility scripts, see here. Care must be taken to ensure that owner, group and permissions of files and subdirectories are preserved when copied to their destination place, e.g. by using GNU or BusyBox cp with the -a option, or the s6-hiercopy program from s6-portable-utils (sys-apps/s6-portable-utils).

s6-linux-init-maker accepts a set of options that customize all these components. For the 0.4.x.x series of s6-linux-init, many of them use programs from packages s6-linux-utils (sys-apps/s6-linux-utils) and s6-portable-utils internally, so they are pulled in as runtime depencencies (RDEPEND). The only build-time dependency that s6-linux-init-maker needs itself is dev-libs/skalibs. sys-apps/s6-linux-init-1.0.0.0 and later only depend on sys-apps/s6 and its dependencies.

The generated init system needs two files that must be supplied by the user to complete it: a stage2 init and a shutdown file, that must be executable. For the 0.4.x.x series of s6-linux-init, the shutdown file is used by the generated s6-svscan diverted signal handlers, and for s6-linux-init-1.0.0.0 and later, it is used by the shutdown daemon. For s6-linux-init-1.0.0.0 and later, the generated init system also needs a third file that must also be supplied by the user, a runlevel changer script that is used by the s6-linux-init-telinit program.

For the full description of s6-linux-init-maker, please consult the HTML documentation in the package's /usr/share/doc subdirectory. A summary of each init system component and some of s6-linux-init-maker's options that customize it follows.

The stage1 init

The init system's stage1 init runs as process 1 during the machine's boot sequence. The 0.4.x.x series of s6-linux-init creates it as an execline script named init. For s6-linux-init-1.0.0.0 and later, it is a program supplied by the package, also named s6-linux-init, and s6-linux-init-maker creates a compatibility script that just calls this program with suitable arguments.

In both cases, the stage1 init expects to access the contents of a certain base directory, and performs these actions:

  • It sets the PATH environment variable to a specified or default value.
  • It sets the working directory to /.
  • It sets the file mode creation mask to a specified or default value using a POSIX umask() call, via execline's umask program in the execline script case.
  • It makes itself the leader of a new process group using a POSIX setpgid(0, 0) call, via an s6-setsid -b command in the execline script case.
  • It mounts a read-write tmpfs with options mode=0755, using s6-mount from sys-apps/s6-linux-utils in the execline script case. s6-linux-init also adds options nodev and nosuid, and unmounts any other filesystem that might be mounted on the tmpfs mountpoint. Additionally:
    • If an -n option is passed to s6-linux-init, it assumes a tmpfs is already mounted, and remounts it with options mode=0755, nodev, nosuid and remount. This is useful when an initramfs is used that mounts the tmpfs itself and writes data to it that must be preserved.
    • If an -N option is passed to s6-linux-init, it assumes a tmpfs is already mounted, and does nothing. This is useful when an initramfs is used and it remains as the (read-write) rootfs of the machine.
  • Optionally, it mounts a devtmpfs on /dev, again using s6-mount in the execline script case. s6-linux-init adds options noexec and nosuid.
  • Optionally, it dumps the enviroment set up by the kernel to a specified enviroment store, using s6-dumpenv from sys-apps/s6-portable-utils in the execline script case. The environment store is an environment directory suitable for s6-envdir.
  • It copies the run-image subdirectory of the base directory to the tmpfs, preserving owner, group and permissions of files and subdirectories, using program s6-hiercopy from s6-portable-utils in the execline script case.
  • It unsets all enviroment variables except PATH, using execline's emptyenv program in the execline script case.
  • It adjusts the enviroment according to the env subdirectory of the base directory, using s6-envdir in the execline script case.
  • It spawns the stage2 init as a session leader using a POSIX setsid() call, via s6-setsid in the execline script case, with its standard input redirected to /dev/null.
  • It redirects its standard output and error to the catch-all logger's FIFO, and replaces itself with s6-svscan, passing it the -s (divert signals) and -t 0 (do not periodically scan the scan directory) options.

Aspects of the stage1 init that can be customized via s6-linux-init-maker options are:

  • The (absolute) pathname of the base directory: -c. Default: /etc/s6-linux-init for the 0.4.x.x series of s6-linux-init, and /etc/s6-linux-init/current for s6-linux-init-1.0.0.0 and later.
  • The value the PATH environment variable is initially set to: -p. This value affects all programs invoked by the execline script version of the stage1 init, the stage2 init, and s6-svscan, and will be the initial value of PATH for all the init system's supervision tree processes. Default: /usr/bin:/usr/sbin:/bin:/sbin for the 0.4.x.x series of s6-linux-init, and /usr/bin:/bin for s6-linux-init-1.0.0.0 and later.
  • The initial value of the file mode creation mask for all the starting processes: -m. Default: 0022.
  • (0.4.x.x series of s6-linux-init only) The (absolute) pathname of the mountpoint for the read-write tmpfs: -l. Default: /run.
  • Whether a devtmps filesystem is mounted on /dev or not: -d. Default: /dev is left unmodified. Note that in order to make the stage1 init mount a devtmps, the syntax for the option is -d 1 (the number one) for the 0.4.x.x series of s6-linux-init, and -d /dev for s6-linux-init-1.0.0.0 and later.
  • The (absolute) pathname of a read-write directory for storing the kernel's environment variables (i.e. the environment store): -s. If no -s option is given, the environment set up by the kernel is discarded before the stage1 init replaces itself with s6-svscan.
  • The initial environment of s6-svscan, and therefore, of all the init system's supervision tree processes: -e. s6-linux-init-maker constructs subdirectory env of its created directory as an environment directory with all the variable settings specified by repeated use of this option. This directory must be copied to the base directory, where the stage1 init expects it to be. If no -e options are given, s6-svscan's environment will only have the PATH variable, and env will be empty.
  • (0.4.x.x series of s6-linux-init only) The (absolute) pathname of the user-provided stage2 init: -2. Default: /etc/rc.init.

For s6-linux-init-1.0.0.and later, the s6-linux-init program expects the stage2 init to be named rc.init and located in the scripts subdirectory of the base directory, and, on Gentoo, mounts the read-write tmpfs on /run. s6-linux-init-maker forwards the -c, -p, -m, -d and -s options, if specified, to s6-linux-init (via the sysvinit compatibility script), and accepts options -n and -N, which it also forwards to s6-linux-init.

The stage2 init

The stage2 init must be provided by the user, runs as a child process of the stage1 init, and blocks until s6-svscan starts running as process 1. For the 0.4.x.x series of s6-linux-init, if s6-linux-init-maker is passed an -r option ("redirect"), the stage1 script redirects the stage2 init's standard output and error to the catch-all logger's FIFO, i.e. all messages will be logged in its logging directory. Otherwise, the stage2 init's standard output and error are redirected to /dev/console, i.e. the machine's console. The stage2 init is invoked with no arguments. An example stage2 init is provided, it is the rc.init execline script in the examples directory of the package's /usr/share/doc subdirectory.

For s6-linux-init-1.0.0.0 and later, the stage2 init's standard output and error are redirected to the catch-all logger's FIFO, and it is invoked with at least one argument: an initial runlevel. The initial runlevel is specified by passing a -D option to s6-linux-init-maker, which it forwards to the s6-linux-init program. Every argument of s6-linux-init is also forwarded to the stage2 init after the default runlevel. Arguments can be passed to s6-linux-init by specifying them in the kernel's command line (e.g. using the bootloader's available mechanisms): every argument in the command line after a "--" (double hyphen) marker is passed to process 1, as is every argument before the marker, if present, that does not contain an equals sign ('=') or dot ('.'), and that is not recognized as a kernel parameter. For the meaning of runlevels in s6-linux-init, see here.

If no -D option is specified, s6-linux-init scans its arguments and, if one of them is default, 2, 3, 4 or 5 then it is interpreted as the default runlevel, and passed to the stage2 init as its first argument (note that this means that this argument will be passed twice: as the first argument, and later again in the position is has in the kernel's command line), otherwise, the default runlevel passed to the stage2 init as its first argument is default.

For s6-linux-init-1.0.0.0 and later, the s6-linux-init-maker program copies the stage2 init, rc.init, from a directory that can be specified with the -f option, to the scripts subdirectory of its generated directory. If no -f option is specified, directory /etc/s6-linux-init/skel is used on Gentoo. The package installs an example stage2 init in /etc/s6-linux-init/skel, that is a shell script containing only comments.

The init system's scan directory

The scan directory image is the run-image/service subdirectory of the stage1 init's base directory, and contains:

  • An s6 service directory for the init system's catch-all logger, named s6-svscan-log.
  • For s6-linux-init-1.0.0.0 and later, an s6 service directory for the runlevel changer service, named s6-linux-init-runleveld.
  • For s6-linux-init-1.0.0.0 and later, an s6 service directory for the shutdown service, named s6-linux-init-shutdownd.
  • An optional s6 service directory for an early getty service, named s6-linux-init-early-getty.
  • The .s6-svscan subdirectory with finish and crash files, as well as s6-svscan diverted signal handlers. All of these files are execline scripts.

This scan directory image is copied to the tmpfs by the stage1 init, and becomes s6-svscan's scan directory when it starts running as process 1. Therefore, the init system's scan directory's pathname, relative to the tmpfs' mountpoint, is service, and, in most cases, its absolute pathname will be /run/service.

The generated .s6-svscan/crash and .s6-svscan/finish files are execline scripts used by s6-svscan's finish procedure and, for the 0.4.x.x series of s6-linux-init, the latter will be the init system's stage3 init. For s6-linux-init-1.0.0.0 and later, the .s6-svscan/finish file simply prints an "s6-svscan exited. Rebooting." message, and reboots the machine with an s6-linux-init-hpr -r -f command.

s6-linux-init-maker accepts a -G option followed by a suitable invocation (program name and arguments) of some getty implementation, for example, -G '/sbin/agetty 38400 tty1 linux' for Gentoo. If it is invoked with this option, the early getty service directory contains a run execline script with the specified getty invocation, which means that a (single) getty process will be spawned by s6-svscan as soon as it starts running as process 1. This allows logging in to the machine from its console as early as possible. If no -G option is specified, there will be no early getty service, and any getty setup must be done by the user-provided stage2 init.

The catch-all logger

The catch-all logger generated by s6-linux-init-maker is an s6-log process that logs to a logging directory named uncaught-logs, and placed in the read-write tmpfs mounted by the stage1 init. Therefore, in most cases, the logging directory's absolute pathname will be /run/uncaught-logs. The standard output of the s6-log process is redirected to /dev/null, and its standard error, to /dev/console, i.e. the machine's console.

The run file of its s6 service directory opens the logger's FIFO for reading, and then invokes s6-log with the -p option, so that it cannot be killed by the SIGTERM signal, and with the -b (blocking) option, which makes s6-log stop reading from the FIFO while it has unflushed buffers. This avoids unbound memory use if there is a lot of output to write. For s6-linux-init-1.0.0.0 and later, the run file alsso passes a -d 3 option to s6-log, which makes it signal readiness to its s6-supervise parent process, using file descriptor 3 for the notification channel. The catch-all logger's FIFO is created by s6-linux-init-maker in its service directory with the name fifo.

Aspects of the catch-all logger that can be customized via s6-linux-init-maker options are:

  • The s6-log process' effective user and group. Default: s6-log runs as root.
    • For the 0.4.x.x series of s6-linux-init: -u, -g and -U. A numeric user ID and group ID can be specified with the -u and -g options, respectively, or be read from environment variables UID and GID, respectively, if the -U option is used. This allows, for example the invocation of s6-linux-init-maker as s6-envuidgid larry s6-linux-init-maker -U dir to make s6-log run with effective user set to 'larry'.
    • For s6-linux-init-1.0.0.0 and later: -u. This option must be followed by an account database username.
  • How logged lines of text are timestamped: -t. Default: timestamps in external TAI64N format are used, as generated by s6-log's t directive.
  • (s6-linux-init-1.0.0.0 and later only) Whether the catch-all logger also prints logged lines to the machine's console: -1 (the number one). This is generally useful to debug a system at a glance, but if a failing program keeps sending error messages, it may interfere with comfortable usage of kernel virtual terminals. This can be avoided by not using /dev/tty1 for any getty process.

s6-linux-init-maker creates the run-image/uncaught-logs subdirectory of its generated directory with an owner and group that are suitable for s6-log's effective user and group, and the stage1 init copies it to the tmpfs.

The runlevel changer service

The runlevel changer service generated by s6-linux-init-maker is an s6-sudod process that executes a user-provided runlevel changer script. The s6-sudoc - s6-sudod mechanism allows executing the script in a controlled, reproducible environment, i.e. the one set up for the init system's supervision tree processes. This is similar to the s6rc-oneshot-runner service that s6-rc uses for oneshots. The runlevel changer script runs with its standard input and output redirected to /dev/null, and its standard error logged by the catch-all logger.

This service is used by the s6-linux-init-telinit program.

The shutdown service and daemon

The shutdown service generated by s6-linux-init-maker is a supervised s6-linux-init-shutdownd process. It is used by the s6-linux-init-shutdown program.

s6-linux-init-1.0.0.0 and later provide the s6-linux-init-sutdownd program, which is a shutdown daemon that takes care of performing the shutdown sequence. It runs as a long-lived process, and performs the following actions:

  1. It reads from a FIFO, which is created by s6-linux-init-maker in its s6 service directory with the name fifo, waiting for either machine shutdown requests, or shutdown cancellation requests. A shutdown request consists of an action, that can be halt, poweroff, reboot, or the special action S, a time value that specifies a delay until actual shutdown, and an optional grace period.
  2. If a shutdown request was received, it waits until the specified shutdown delay expires, and keeps reading from the FIFO in the meantime.
  3. If a shutdown cancellation request was received, it cancels any pending machine shutdown that has been previously requested.
  4. If the shutdown delay expires and the shutdown request has not been canceled, it starts the shutdown sequence by executing a shutdown file as a child process, and waiting for it to finish execution. The shutdown file must be provided by the user and, because s6-linux-init-sutdownd is part of the init system's supervision tree, it runs with the same environment that was set up for s6-linux-init-sutdownd, its standard input redirected to /dev/null, and its standard output and error logged by the catch-all logger.
  5. If the action specified in the shutdown request was S, it does nothing and starts reading again from the FIFO. This allows the implementation of a behaviour that is similar to sysvinit's single user mode. Otherwise:
  6. It redirects its standard output and error to /dev/console, i.e. the machine's console.
  7. It creates an execline script named stage 4 in its s6 service directory.
  8. It stops all processes from the supervision tree except the catch-all logger, by renaming their service directories with a name that starts with a dot ('.'), and performing the equivalent of an s6-svc -dx command. The renaming of the servicedirs prevents s6-svscan from restarting their corresponding s6-supervise process when it exits.
  9. It syncs all disks, flushing all the dirty system buffers, using a POSIX sync() call.
  10. It kills all remaining processes by sending them a SIGTERM signal followed by a SIGCONT signal, using POSIX kill(-1, SIGTERM) and kill(-1, SIGCONT) calls, and waits for the expiry of either the grace period specified in the shutdown request, or the default grace period.
  11. It kills all remaining processes by sending them a SIGKILL signal using a kill(-1, SIGKILL) call. If s6-linux-init-sutdownd did not get killed by the signal, it exits.
  12. The shutdown service's corresponding s6-supervise process restarts s6-linux-init-sutdownd.
  13. s6-linux-init-sutdownd notes that there is a file named stage 4 in its service directory, and replaces itself with it using a POSIX execve() call.
  14. The execline script unmounts all mounted filesystem according to /proc/mounts using auxiliary program s6-linux-init-umountall.
  15. The execline script invokes the s6-linux-init-hpr program with an -f option to shut the machine down, passing an -h, -p or -r option to it according to the action specified in the shutdown request (i.e. halt, poweroff or reboot).

s6-linux-init-sutdownd expects the shutdown file to be named rc.shutdown and located in the scripts subdirectory of the stage1 init's base directory. It accepts a -c option that specifies the absolute pathname of this directory, and a -g option followed by a time value in milliseconds, specifying the duration of the default grace period. If no -c option is specified, it assumes the base directory is /etc/s6-linux-init/current, and if no -g option is specified, the default grace period is 3 seconds. The grace period is capped to 5 minutes if the time value specified with a -g option or in shutdown requests received via s6-linux-init-sutdownd's FIFO is greater than that.

For further information about s6-linux-init-shutdownd, please consult the HTML documentation in the package's /usr/share/doc subdirectory. s6-linux-init-maker copies the shutdown file from a directory that can be specified with the -f option, to the scripts subdirectory of its generated directory. If no -f option is specified, directory /etc/s6-linux-init/skel is used on Gentoo. The s6-linux-init package installs a shutdown file in /etc/s6-linux-init/skel, that is a shell script containing only comments.

Aspects of the shutdown service that can be customized via s6-linux-init-maker options are:

  • The default grace period: -q. Default: 3 seconds.

s6-linux-init-maker forwards the -c option, if specified, to s6-linux-shutdownd (via the generated shutdown service's run file), and passes a -g option to it using the value specified with the -q option.

The diverted signal handlers

For the 0.4.x.x series of s6-linux-init, all s6-svscan diverted signal handlers are execline scripts that invoke a common shutdown file, wait for it to finish execution, and then invoke the s6-svscanctl program to make s6-svscan perform its finish procedure, which tears down the init system's supervision tree and initiates execution of the stage3 init. The shutdown file must be provided by the user and, because diverted signal handlers execute as child processes of s6-svscan, it runs with the same environment that was set up by the stage1 init for s6-svscan, its standard input redirected to /dev/null, and its standard output and error logged by the catch-all logger. An example shutdown file is provided, it is the rc.shutdown execline script in the examples directory of the package's /usr/share/doc subdirectory.

The behaviour of the different signals sent to process 1 when these handlers are used is:

  • SIGHUP: makes s6-svscan send a SIGHUP signal to all its s6-supervise children before performing its finish procedure, using an s6-svscanctl -h command.
  • SIGQUIT: makes s6-svscan send a SIGTERM signal to all its s6-supervise children before performing its finish procedure, using an s6-svscanctl -q command.
  • SIGINT: reboots the machine using an s6-svscanctl -6 command. The operating system is usually configured to send a SIGINT to process 1 when key combination Ctrl+Alt+Del is pressed.
  • SIGTERM: equivalent to SIGINT.
  • SIGUSR1: powers the machine off using an s6-svscanctl -7 command.
  • SIGUSR2: halts the machine using an s6-svscanctl -0 command.

For s6-linux-init-1.0.0.0 and later, the generated diverted signal handlers are also execline scripts, and the behaviour of the different signals sent to process 1 when these handlers are used is:

  • SIGHUP: does nothing.
  • SIGQUIT: does nothing.
  • SIGINT: reboots the machine using an s6-linux-init-shutdown -a -r -- now command.
  • SIGTERM: does nothing.
  • SIGUSR1: powers the machine off using an s6-linux-init-shutdown -a -p -- now command.
  • SIGUSR2: halts the machine using an s6-linux-init-shutdown -a -h -- now command.

Aspects of the signal handlers that can be customized via s6-linux-init-maker options are:

  • (0.4.x.x series of s6-linux-init only) The (absolute) pathname of the user-provided shutdown file: -Z. Default: /etc/rc.shutdown.

The stage3 init

For the 0.4.x.x series of s6-linux-init, the finish file in the .s6-svscan subdirectory of the init system's scan directory is a stage3 init. It is an execline script that runs as process 1 during the machine's shutdown sequence, and performs these actions:

  1. It sets the working directory to /.
  2. It redirects its standard output and error to /dev/console, i.e. the machine's console.
  3. It uses an s6-svc -X command to make the catch-all logger exit.
  4. It syncs all disks, flushing all the dirty system buffers, using program s6-sync from sys-apps/s6-portable-utils.
  5. It kills all remaining processes by sending them a SIGTERM signal followed by a SIGCONT signal followed by a SIGHUP signal, using program s6-nuke from s6-portable-utils, and waits for the expiry of a specified or default grace period.
  6. It kills all remaining processes by sending them a SIGKILL signal, again using s6-nuke.
  7. It unmounts all mounted filesystem according to /proc/mounts using program s6-umount from sys-apps/s6-linux-utils.
  8. Remounts the root filesystem read-only using program s6-mount from s6-linux-utils.
  9. Invokes the s6-halt, s6-poweroff or s6-reboot program with the -f option to shut the machine down.

Aspects of the stage3 init that can be customized via s6-linux-init-maker options are:

  • (0.4.x.x series of s6-linux-init only) The duration of the grace period: -q. Default: 2 seconds.

Runlevels

s6-linux-init-1.0.0.0 and later allows the implementation of runlevel-like functionality similar to that of sysvinit. An s6-linux-init runlevel normally represents a service set, and entering a runlevel normally means to start all services in the corresponding set, and stopping all services not in it. Each runlevel has an alphanumerical identifier. The package uses two components to implement a service: the s6-linux-init-telinit program, and the generated runlevel changer service, s6-linux-init-runleveld.

What happens when a runlevel is entered is defined by a runlevel changer script that must be provided by the user. s6-linux-init-runleveld expects the script to be named runlevel and located in the scripts subdirectory of the stage1 init's base directory. It is normally an execline or shell script that relies on some service manager to actually perform the necessary service transitions.

The s6-linux-init-telinit program accepts a runlevel identifier as its argument, and uses an s6-sudo -e -T 3600000 command to connect to s6-linux-init-runleveld's socket (i.e. the s6-sudod process' listening socket), and pass it the runlevel identifier. The -e option avoids passing variables from s6-linux-init-telinit's enviromnent to the the runlevel script, and the -T option prevents it from running for more than an hour. s6-linux-init-runleveld then executes runlevel with the runlevel identifier as its argument.

Integration with OpenRC can be achieved by having the runlevel changer script execute the openrc program when invoked. In this case, s6-linux-init runlevels are OpenRC runlevels.

For compatibility with sysvinit, if s6-linux-init-telinit is invoked with 0 or 6 as its argument, after passing it to s6-linux-init-runleveld as the runlevel identifier and waiting for the s6-sudo process to terminate, it uses an s6-linux-init-shutdown -h 0 or s6-linux-init-shutdown -p 0 command to initiate machine shutdown.

For further information about s6-linux-init-telinit, please consult the HTML documentation in the package's /usr/share/doc subdirectory. s6-linux-init-maker copies the runlevel changer script from a directory that can be specified with the -f option, to the scripts subdirectory of its generated directory. If no -f option is specified, directory /etc/s6-linux-init/skel is used on Gentoo. The s6-linux-init package installs a runlevel changer shell script in /etc/s6-linux-init/skel, containing only comments that illustrate integration with both OpenRC and s6-rc.

s6-rc support

All the necessary setup needed to make s6-rc part of the init system is done in the stage2 init and in the shutdown file invoked by either the s6-svscan diverted signal handlers or the shutdown daemon. Because both files are provided by the user, the s6-linux-init package does not have, or need, any specific support for s6-rc. Nevertheless, the stage2 init and shutdown file provided by the package illustrate an s6-rc setup.

Integration of s6-linux-init-telinit with s6-rc can be achieved by having the runlevel changer script use its argument in a s6-rc -pa change command. In this case, s6-linux-init runlevels are s6-rc service bundle names.

Shutdown and reboot

The 0.4.x.x series of s6-linux-init provides the s6-halt, s6-poweroff and s6-reboot programs, that can be used in combination with the init system components generated by s6-linux-init-maker to shut the machine down. These programs halt it, power it off, and reboot it, respectively. They accept an -f ("force") option, just like their sysvinit counterparts, to perform their respective action without going through the init system (using the Linux reboot() system call). Otherwise, they just send a signal to process 1 that corresponds to the diverted signal handler generated by s6-linux-init-maker for the requested shutdown operation. For further information about these programs, please consult the HTML documentation in the package's /usr/share/doc subdirectory.

s6-linux-init-1.0.0.0 and later provides the s6-linux-init-shutdown and s6-linux-init-hpr programs for the same purpose. The former conforms to the LSB shutdown interface[1], modeled after sysvinit's shutdown, and the latter replaces s6-halt, s6-poweroff and s6-reboot. Therefore, s6-linux-init-shutdown accepts a time specification, an optional message to be shown to logged in users, and the -h (halt after shutdown), -r (reboot after shutdown), -c (cancel shutdown), -k (do not really shutdown; only warn), -t (grace period between SIGTERM and SIGKILL) and -a (access control) options, with the same meaning as for sysvinit's shutdown. For compatibility with the LSB, it accepts -f (ask the rc subsystem to skip checking filesystems with fsck after next boot) and -F (ask the rc subsystem to make fsck check filesystems after next boot, even if they are marked clean) options, that it ignores. It also accepts -H (halt), -p and -P (poeweroff) options, that combine with -h according to the following table:

s6-linux-init-shutdown option Results in Comments
-h Halting Note that Gentoo's patched shutdown powers off in this case.
-H Halting Same as Gentoo's patched shutdown
-P Powering off Same as Gentoo's patched shutdown
-h -H Halting Compatible with upstream sysvinit
-h -P Powering off Compatible with upstream sysvinit


Unless it was invoked with the -k option, s6-linux-init-shutdown connects to the shutdown service's FIFO and sends a shutdown request, or shutdown cancellation request if the -c option has been specified, to the shutdown daemon, s6-linux-init-shutdownd. If no -h, -p, -H or -H option was specified, it sends a special 'S' shutdown request to s6-linux-init-shutdownd, that only makes it execute the shutdown script, but not actually shut the machine down. This allows the implementation of a behaviour that is similar to sysvinit's single user mode.

If it was invoked with the -a option, s6-linux-init-shutdown performs access control using file /etc/shutdown.allow just like sysvinit's shutdown. POSIX setutxent(), getutxent() and endutxent() calls are used to read user accounting database (/var/run/utmp for GNU libc) user process records (i.e. struct utmpx objects with ut_type == USER_PROCESS), and their ut_user user field is matched against account usernames in /etc/shutdown.allow. If the duration of the grace time specified with the -t option is greater that 5 seconds, it is capped to that value.

For further information about s6-linux-init-shutdown, please consult the HTML documentation in the package's /usr/share/doc subdirectory.

The s6-linux-init-hpr program must be invoked either with an -h option, a -p option, or an -r option, to halt, poweroff, or reboot the machine, respectively. In either case, it first writes a shutdown record to the user accounting log file (/var/log/wtmp for GNU libc), using the libc's updwtmpx() function. The shutdown record is a runlevel record (i.e. a struct utmpx object with ut_type == RUN_LVL) that has ut_user set to "shutdown" (or "reboot" if s6-linux-init-hpr was invoked with the -r option), ut_id set to the empty string, ut_line set to "~~", ut_pid set to s6-linux-init-hpr's process ID, ut_session set to s6-linux-init-hpr's session ID (as returned by a POSIX getsid(0) call), ut_tv set to the current time, and ut_host set to the name returned by the POSIX gethostname() call (or the null string if the call fails). Then, unless it was invoked with a -W (capital 'w') option, it prints a warning about the system going down immediatly to logged in users, and finally sends a shutdown request to s6-linux-init-shutdownd, specifying that machine shutdown should be initiated immediately. That is, s6-linux-init-hpr -h is equivalent to s6-linux-init-shutdown -h now, s6-linux-init-hpr -p, to s6-linux-init-shutdown -p now, and s6-linux-init-hpr -r, to s6-linux-init-shutdown -r now.

Just like sysvinit's halt, poweroff and reboot, if s6-linux-init-hpr is invoked with a -w (small 'w') option, it only writes the shutdown record to the user accounting log file, without actually shutting the machine down, and if it is invoked with a -d option, no shutdown record is written to the user accounting log file.

If s6-linux-init-hpr is invoked with an -f ("force") option, it syncs all disks, flushing all the dirty system buffers, using the POSIX sync() call, and directly performs the shutdown action requested by the -h, -p or -r option, using the Linux reboot() system call. No shutdown record is written to the user accounting log file, no warning is printed a to logged in users, and options -W, -w and -d are ignored.

For further information about s6-linux-init-hpr, please consult the HTML documentation in the package's /usr/share/doc subdirectory.

sysvinit compatibility scripts

For s6-linux-init-1.0.0.0 and later, s6-linux-init-maker creates the following execline scripts in the bin subdirectory of its generated directory:

  • init, which calls the s6-linux-init program with the -c (base directory) and -m (file mode creation mask) options, and, if they were specified to s6-linux-init-maker, the -p (value of PATH), -d (mount a devtmpfs), -s (environment store), -D (initial runlevel), -n (remount the tmpfs) and -N (do not mount a tmpfs) options.
  • halt, which calls the s6-linux-init-hpr program with the -h option (halt) and all the supplied arguments.
  • poweroff, which calls the s6-linux-init-hpr program with the -p option (poweroff) and all the supplied arguments.
  • reboot, which calls the s6-linux-init-hpr program with the -r option (reboot) and all the supplied arguments.
  • telinit, which calls the s6-linux-init-telinit program with all the supplied arguments.
  • shutdown, which calls the s6-linux-init-shutdown program with all the supplied arguments.

These compatibility scripts are provided as replacements of the sysvinit programs of the same name in pure s6-based setups, and are installed by the Gentoo ebuild in /sbin if the sysv-utils USE flag is set. This, however, does not allow having sys-apps/sysvinit and sys-apps/s6-linux-init simultaneously installed, and therefore, switching between init systems with a reboot. In fact, installing sys-apps/s6-linux-init with this USE flag set on a machine with sys-apps/sysvinit already installed results in a blocker. So, to be able to have both packages, sys-apps/s6-linux-init must be installed with the sysv-utils USE flag unset, and the compatibility scripts, if wanted, must be (manually) installed with different names. For example:

  • halt, poweroff and reboot could be installed in /sbin with the names s6-halt, s6-poweroff and s6-reboot since, for s6-linux-init-1.0.0.0 and later, those programs are replaced by s6-linux-init-hpr and no longer provided. Or alternatively, the administrator could use s6-linux-init-hpr directly, and not install the compatilibity scripts.
  • init might be installed in /sbin as, for example, s6-imkr-init, and an init=/sbin/s6-imkr-init parameter could be passed to the kernel. Or alternatively, the s6-linux-init program could be specified in the init= parameter, its agruments could be specified in the kernel command line after an '--' marker, and the compatilibity script could be left uninstalled.
  • The administrator could use s6-linux-init-telinit and s6-linux-init-shutdown directly, and not install the telinit and shutdown compatilibity scripts.

Support programs

s6-linux-init-1.0.0.0 and later provides two support programs for init system components created by s6-linux-init-maker.

The s6-linux-init-echo program is used by the .s6-svscan/finish and .s6-svscan/crash files, and is an exact duplicate of s6-echo from sys-apps/s6-portable-utils. Its inclusion in s6-linux-init avoids creating a runtime dependency on that package.

The s6-linux-init-umountall program is used by the stage 4 execline script created by the shutdown daemon, s6-linux-init-shutdownd, and it unmounts all filesystems, processing /proc/mounts in reverse order, starting with the most recently mounted partition and ending with the rootfs. It behaves in a similar way to that of the s6-umount program from sys-apps/s6-linux-utils when the -a option is specified. Its inclusion in s6-linux-init again avoids creating a runtime dependency on that package.

Removal

Unmerge

root #emerge --ask --depclean --verbose sys-apps/s6-linux-init

If s6-linux-init's programs and components generated by s6-linux-init-maker are being used as the init system, an alternative one must be installed in parallel, and the machine rebooted to use it (possibly by reconfiguring the bootloader), before the package is removed, or otherwise the machine will become unbootable.

See also

External resources

  • Adélie Linux, a distribution of Linux and musl that supports using s6-linux-init-1.0.0.0 and later + OpenRC as its init system, as an alternative to sysvinit + OpenRC (currently in beta stage).

References

  1. Linux Standard Base Core Specification 5.0.0, Generic Part, Chapter 17, "Commands and Utilities", 17.2, "Command Behavior", shutdown. Retrieved on September 9th, 2019.