s6-linux-init is a package that provides a set of minimalistic tools to help create a 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.
- 1 Installation
- 2 Configuration
- 3 Usage
- 4 Removal
- 5 See also
USE flags for sys-apps/s6-linux-init Generates an init binary for s6-based init systems
emerge --ask sys-apps/s6-linux-init
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, 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.
- UID - The catch-all logger's user ID set by s6-linux-init-maker when invoked with the
- GID - The catch-all logger's group ID set by s6-linux-init-maker when invoked with the
- /etc/s6-linux-init/run-image - Default directory containing the generated stage1 script's scan directory and catch-all logger's logging directory images.
- /etc/s6-linux-init/env - Default environment directory used by the generated stage1 script to set up the init system's supervision tree environment.
- /etc/rc.init - Default pathname of the stage2 init expected by the generated stage1 script.
- /etc/rc.shutdown - Default pathname of the shutdown file expected by the generated s6-svscan diverted signal handlers.
- /run/service - Default scan directory set up by the generated stage1 script for s6-svscan.
- /run/service/s6-svscan-log - Default pathname of the s6 service directory for the generated catch-all logger.
- /run/service/s6-linux-init-early-getty - Default pathname of the s6 service directory for the generated early getty service.
- /run/uncaught-logs - Default catch-all logger's logging directory.
The package provides the s6-linux-init-maker program, which helps create several components of an s6-based init system, and the s6-halt, s6-poweroff and s6-reboot programs, which can shut the machine down if these init system components are used unmodified.
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 directory pathname. It creates a directory at with specified pathname, which must not exist beforehand, containing several init system components:
- An execline script named init, that is a stage1 init.
- A subdirectory named run-image, which contains:
- An s6 scan directory image.
- An empty directory named uncaught-logs.
- A directory named env, that might be empty.
To use these components to make an init system, they must be copied to the target machine —which might be the same as the host machine, i.e. the machine that s6-linux-init-maker was run on— in appropriate locations. The init file 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 argument 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 must be copied to the location the init script expects them to be. Care must be taken to ensure that owner, group and permissions of files and subdirectories are preserved, 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. 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.
Because execline scripts require the absolute path of the execlineb program in the shebang line (i.e. the first line of the file, that starts with '#!'), s6-linux-init-maker accepts a
-b option to specify the path prefix for this program, and defaults it to /bin.
The default execlineb pathname generated by s6-linux-init-maker matches that from Gentoo's dev-lang/execline package.
The generated stage1 init and the s6-svscan diverted signal handlers need two files that must be supplied by the user to complete the init system: a stage2 init, and a shutdown file that is shared by all signal handlers. This means that s6-linux-init-maker will not generate them, as they are higly system-dependent and subject to distribution policy, but generated components will expect them to be present. The package provides examples of both, they are the /etc/rc.init and /etc/rc.shutdown files, respectively, in the example directory of the package's /usr/share/doc subdirectory.
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 the options that customize it follows.
The stage1 script
This is an execline script that runs as process 1 during the machine's boot sequence and performs these actions:
- Sets the working directory to /.
- Sets the PATH environment variable to a specified or default value.
- Mounts a read-write tmpfs with options
mode=0755using program s6-mount from s6-linux-utils.
- Copies the run-image directory created by s6-linux-init-maker to the tmpfs, preserving owner, group and permissions of files and subdirectories, using program s6-hiercopy from s6-portable-utils.
- Optionally mounts a devtmpfs on /dev, again using s6-mount.
- Optionally dumps the enviroment set up by the kernel to a specified enviroment store, using program s6-dumpenv from s6-portable-utils. The environment store is a directory that, for every environment variable VAR, contains a text file named VAR. Each file has a single line containing the variable's value.
- Unsets all enviroment variables except PATH.
- Adjusts the enviroment according to the env directory created by s6-linux-init-maker, using s6-envdir from s6.
- Spawns the stage2 init as a session leader using s6-setsid from s6, with its standard input redirected to /dev/null.
- Replaces itself with s6-svscan.
The stage1 script makes s6-svscan execute as process 1 with signal diversion turned on, periodic scanning turned off (
-t 0), its standard input redirected to /dev/null, and its standard output and error redirected to the catch-all logger.
Aspects of the stage1 script that can be customized via s6-linux-init-maker options are:
- The location of the run-image and env directories:
-c. Default: /etc/s6-linux-init.
- The pathname of the user-provided stage2 init:
-2. Default: /etc/rc.init.
- The mountpoint for the read-write tmpfs:
-l. Default: /run.
- The value the PATH environment variable is set to:
-p. This value affects all programs invoked by the script, 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:/bin.
- The value of the initial file umask for all the starting processes:
-m. Default: 022.
- Whether a devtmps filesystem is mounted on /dev or not:
-d. Default: /dev is left untouched.
- The pathname of a read-write directory for storing the kernel's environment variables:
-s. If no
-soptions is given, the environment set up by the kernel is discarded before the stage1 script 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 directory env as an environment directory with all the variable settings specified by repeated use of this option. The stage1 script expects this directory to be in the same directory as run-image; therefore, its absolute pathname will be /etc/s6-linux-init/env with s6-linux-init-maker's defaults. If no
-eoptions are given, s6-svscan's environment only has the PATH variable, and env will be empty.
The stage2 init
The stage2 init must be provided by the user, runs as a child process of the stage1 script, and blocks until s6-svscan starts running as process 1. 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, 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.
The init system's scan directory
The scan directory image contains:
- An s6 service directory for the init system's catch-all logger, named s6-svscan-log.
- 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, and .s6-svscan/finish is the init system's stage3 init.
This scan directory image is copied to the tmpfs by the stage1 script, and becomes s6-svscan's scan directory when it starts running as process 1.
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 this option is supplied, 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 given, 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 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 script. Therefore, its absolute pathname will be /run/uncaught-logs with s6-linux-init-maker's defaults. The standard output of the s6-log process are redirected to /dev/null, and its standard error, to /dev/console, i.e. the machine's console.
The run file opens the logger's FIFO for reading, which is created by s6-linux-init-maker in the service directory with the name fifo, uses s6-applyuidgid from s6 to set the effective user and group, and then invokes s6-log with the
-p option, so that it cannot be killed by the
s6-linux-init-maker creates the run-image/uncaught-logs directory with an owner and group that match s6-log's effective user and group, and the stage1 script copies it to the tmpfs.
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:
-U. They can be specified as a numeric user ID (UID) and group ID (GID) valid for the target machine with the
-goptions, respectively, or read from environment variables UID and GID, respectively, if the
-Uoption 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', as defined in the host machine's account database, assuming this is also appropriate for the target machine. If any of these options is specifed, s6-linux-init-maker creates the run-image/uncaught-logs directory with permissions 2700 (i.e. it has set-group-ID on execution enabled and the ls -l command would show
drwx--S---). Otherwise, s6-log's effective user and group are those that correspond to UID 0 and GID 0, and s6-linux-init-maker creates the run-image/uncaught-logs directory with permissions 0700 (i.e. the ls -l command would show
drwx------). Therefore, on Gentoo, if no
-Uoptions are given, s6-log would run with effective user set to root.
- How logged lines of text are timestamped:
-t. Default: timestamps in external TAI64N format are used, as generated by s6-log's t directive.
The diverted signal handlers
All s6-svscan diverted signal handlers are execline scripts that invoke a common shutdown file, wait for it to finish its 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 script. The shutdown file must be provided by the user, and runs with its standard input redirected to /dev/null, and its standard output and error redirected to the catch-all logger.
The behaviour of the different signals sent to process 1 when these handlers are used is:
SIGHUP: Makes s6-svscan send a
SIGHUPsignal to all its s6-supervise children before performing its finish procedure, using an s6-svscanctl -h command.
SIGQUIT: Makes s6-svscan send a
SIGTERMsignal 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
SIGINTto process 1 when key combination Ctrl+Alt+Del is pressed, resulting in a machine reboot too.
SIGTERM: currently equivalent to
SIGUSR1: powers the machine off using an s6-svscanctl -7 command.
SIGUSR2: halts the machine using an s6-svscanctl -0 command.
Aspects of the signal handlers that can be customized via s6-linux-init-maker options are:
- The pathname of the shutdown file:
-Z. Default: /etc/rc.shutdown.
The stage3 script
This is an execline script that runs as process 1 during the machine's shutdown sequence, and performs these actions:
- Sets the working directory to /.
- Redirects its standard output and error to /dev/console, i.e. the machine's console.
- Uses an s6-svc -X command to make the catch-all logger exit.
- Syncs all disks, flushing all the dirty system buffers, using program s6-sync from s6-portable-utils.
- Sends a
SIGHUPsignal to all remaining processes, to allow them to exit on their own, using program s6-nuke from s6-portable-utils.
- After a grace period, sends a
SIGKILLsignal to all remaining processes to kill them, again using s6-nuke.
- Unmounts all filesystems according to /proc/mounts using program s6-umount from s6-linux-utils.
- Remounts the root filesystem read-only using program s6-mount from s6-linux-utils.
- Invokes the s6-halt, s6-poweroff or s6-reboot program with the
-foption to shut the machine down.
Aspects of the stage3 script that can be customized via s6-linux-init-maker options are:
- Grace period given to remaining processes after tearing down the supervision tree:
-q. Default: 2 seconds.
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. Because both files are provided by the user, the s6-linux-init does not have, or need, any specific support for s6-rc. Nevertheless, the /etc/rc.init and /etc/rc.shutdown execline scripts provided by the package as examples illustrate an s6-rc setup.
s6-halt, s6-poweroff and s6-reboot
These programs can be used in combination with the init system components generated by s6-linux-init-maker to shut the machine down: s6-halt to halt it, s6-poweroff to power it off, and s6-reboot to reboot it.
These programs support an
-f ('force') option, just like their sysvinit counterparts (sys-apps/sysvinit), 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.
emerge --ask --depclean --verbose sys-apps/s6-linux-init
If the init system relies on s6-halt, s6-poweroff and s6-reboot, this can render it non-functional unless the machine has replacements with equivalent functionality.