From 1bfba3b0be32306b078f5ee527b864e758b2c77b Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 26 Apr 2019 15:52:54 +0000 Subject: Make a single hpr. Full doc, first draft. --- doc/s6-linux-init-maker.html | 451 +++++++++++++++++++++---------------------- 1 file changed, 224 insertions(+), 227 deletions(-) (limited to 'doc/s6-linux-init-maker.html') diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index a512501..45284ab 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -21,27 +21,25 @@

s6-linux-init-maker reads configuration options on the command line, and outputs a directory to place in the -root filesystem. That directory contains a script suitable -as an init program, as well as support file hierarchies to -get a complete +root filesystem. That directory contains +a script that is suitable as an /sbin/init program +as well as all the necessary files that this script needs +to properly boot and bring up a full s6 -infrastructure running when the system is booted on that -script. +infrastructure.

s6-linux-init-maker only writes scripts. At boot time, these scripts will call commands provided by other skarnet.org packages such as -execline or +execline and s6. It is the responsibility of the administrator to make sure that all the dependencies are properly installed at boot time, and that the -correct options have been given to s6-linux-init-maker so that -the programs are found on the root filesystem of the -machine - else the scripts will crash. -

- +correct options have been given to s6-linux-init-maker +so that the programs are found on the root filesystem of the +machine. If it is not the case, the system will fail to boot.

Interface and usage

@@ -49,7 +47,7 @@ machine - else the scripts will crash.
      s6-linux-init-maker \
        [ -c basedir ] \
-       [ -u log_uid -g log_gid | -U ] \
+       [ -u log_user ] \
        [ -G early_getty ] \
        [ -1 ] \
        [ -L ] \
@@ -59,13 +57,15 @@ machine - else the scripts will crash.
        [ -d dev_style ] \
        [ -s env_store ] \
        [ -e initial_envvar ] ... \
-       [ -E stage2_envvar ] ... \
        [ -q ] finalsleeptime
+       [ -D initdefault ] \
+       [ -U utmp_user ] \
        dir
 

- dir should then be copied by the administrator to the place -declared as basedir. Be careful: it contains fifos, files with + Once the command has been run and dir has been created, there +are a few manual steps to take: +

+ +
    +
  1. s6-linux-init-maker has copied some scripts from the +/etc/s6-linux-init/skel directory (or the directory you +gave as an argument to the --skeldir configure option at +build time) to the dir/scripts directory. You +should edit these scripts and adapt them to your use case. +(Or you could edit the skeleton scripts before running +s6-linux-init-maker.) The scripts are: +
      +
    • rc.init: this script will be run as stage 2 +initialization, i.e. the initialization that happens once +s6-svscan +is running as process 1, and should contain all your normal +system bootup tasks. Typically, it should initialize the service +manager and then order it to bring the machine state to its +fully operational state. rc.init is given the default +runlevel as a first argument (i.e. the name of the state +the machine should be brought to, traditionally default +for OpenRC and 2 or 5 for sysv-rc), and the +rest of the command line is made of the kernel's command line +except for the kernel arguments of the key=value form, +which have been stored into env_store.
    • +
    • rc.shutdown: this script will be run as the +shutdown sequence, when the administrator runs the +shutdown, halt, poweroff or reboot +command. (As well as init 0, init 6. +telinit 0 and telinit 6 for compatibility +reasons.) It should ask the service manager to bring all the +services down, and exit when it's done (in other words: it should +not try to perform a hard halt/poweroff/reboot itself.) +No arguments are given to this script.
    • +
    • runlevel: this script will be invoked for every +runlevel change, i.e. change of machine states. It is +given one argument: the name of the runlevel to change to. +Typically, the runlevel script should just invoke the +service manager, asking it to bring the machine state to the +wanted runlevel.
    • +
  2. +
  3. Copy the dir directory to the place declared as +basedir (/etc/s6-linux-init/current by default). + Be careful: it contains fifos, files with precise uid/gid permissions, and files with non-standard access rights, so be sure to copy it verbatim. The s6-hiercopy -tool can do it, as well as the GNU or busybox cp -a or mv commands. -

    - -

    - The basedir/bin directory contains scripts, or -links to programs, that are suitable as System V-compatible programs -of the same name; the administrator should copy them to (or symlink -them from) a place where those programs are usually found, typically -/sbin. -

    - -

    - In particular, the basedir/bin/init script -suitable as a "stage 1" init program, i.e. the first program -run by the kernel (possibly after an initramfs execution). -Once this script is copied to, or symlinked from, -/sbin/init, the machine will be ready to boot on the -new s6-based system. -

    +tool can do it, as well as the GNU or busybox cp -a or mv commands.
  4. +
  5. Back up your /sbin. Then copy, link or symlink all the scripts +and symlinks in the basedir/bin directory into /sbin. + In particular, the basedir/bin/init script should +be accessible as /sbin/init.
  6. +

Boot sequence

When the kernel boots, it may run an initramfs first, but in any case it then runs the basedir/init script, -also known as stage 1. This is what happens during stage 1: -

- - - -

- initscript is the responsibility of the administrator - it will -not be written automatically! -It should -contain all the necessary initialization sequence to bring up a proper -system. When initscript is executed, the machine state is as follows: -

- - - -

- There is nothing else. In particular, no filesystem has been -mounted yet, including /proc and /sys; and no one-time -initialization -has been performed. The point of stage 1 is only to make it -possible to run initscript with a logging infrastructure and a -supervision infrastructure already available, and all the -real machine and service initialization should happen in initscript, -also known as stage 2. -

- -

Shutdown sequence

- - - -

- The examples/ subdirectory of the s6-linux-init package -contains an example of /etc/rc.init -and /etc/rc.shutdown scripts, suitable for -initscript and shutdownscript -respectively. Those scripts can practically be used as is if the machine -is managed by the s6-rc -service manager. +also known as stage 1. This script is just an execution +of the s6-linux-init program with +some command-line options that are directly transferred from the +s6-linux-init-maker invocation. Refer to the +s6-linux-init man page to know +exactly what it does.

s6-linux-init-maker options

@@ -248,60 +149,50 @@ service manager.
  • -c basedir : at boot time, stage 1, which should be accessible as basedir/init, will read its read-only data from basedir. After running -s6-linux-init-maker, the administrator should make sure to copy the +s6-linux-init-maker, you should make sure to copy the created directory dir to basedir. basedir must be absolute. Default is -/etc/s6-linux-init.
  • - -

  • -u log_uid : the catch-all -logger will run with the uid log_uid. Default is 0.
  • - -

  • -g log_gid : the catch-all -logger will run with the gid log_gid. Default is 0.
  • +/etc/s6-linux-init/current.

    -

  • -U : the correct log_uid and -log_gid values for the catch-all logger will be read from the -UID and GID environment variables that have been passed to -s6-linux-init-maker. This allows for invocations such as -s6-envuidgid nobody s6-linux-init-maker -U ... so that -the catch-all logger runs as the nobody user. Be aware that -this option is only safe when the user database on the -boot-time machine is the same as on the run-time -machine, else the catch-all logger may run with an unexpected uid -and gid.
  • +

  • -u log_user : the catch-all +logger will run as the log_user user. Default is root.
  • -G early_getty : if this option -is set, s6-linux-init-maker will define a service that will run -very early, before stage2 is executed. This early service -should be a getty, to allow logins even if stage2 fails. +is set, s6-linux-init-maker will define an additional s6 service +that will be named s6-linux-init-early-getty and started +at the same time rc.init is executed. This early service +should be a getty, or equivalent, to allow logins even if stage2 fails. early_getty should be a simple command line: for instance, "/sbin/getty 38400 tty1". By default, no early service is defined.
  • -1 : make it so that all the messages that are sent to the catch-all logger (i.e. all the error messages that are not -caught by a dedicated logger, as well as the output from stage2) +caught by a dedicated logger, as well as the output from rc.init, +runlevel and rc.shutdown, are also copied to /dev/console. 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 an early -getty.
  • +getty. A common workaround is to make the early getty start on +tty2 and leave tty1 for /dev/console to print on.

    + +

  • -L : add an early s6-linux-init-logouthookd +service to clean up utmp records at user logout time. Check the +s6-linux-init-logouthookd page +for details.
  • -p initial_path : the value to set the PATH environment variable to, for all the starting processes. -This will be done as early as possible in stage 1. It is -absolutely necessary for -execline, -s6, -s6-portable-utils and -s6-linux-utils +It is absolutely necessary for +execline and +s6 binaries to be accessible via initial_path, else the machine will not boot. Default is /usr/bin:/bin.
  • -m initial_umask : the value of the initial file umask for all the starting processes, in octal. -Default is -022.
  • +Default is 022.

  • -t timestamp_style : how logs are timestamped by the catch-all logger. 0 means no @@ -319,39 +210,37 @@ devtmpfs automounted by the kernel at boot time. Default is 2.
  • -s env_store : stage 1 init sometimes -inherits a few environment variables from the kernel. It empties its -environment before spawning stage2 and executing into s6-svscan, in +inherits a few environment variables from the kernel. (These variables +correspond to the arguments on the kernel command line that are of the +form key=value.) It empties its +environment before spawning rc.init and executing into s6-svscan, in order to prevent those "kernel" environment variables from leaking into the whole process tree. However, sometimes those variables are needed at a later time; in that case, giving the -s option -to s6-linux-init-maker makes stage 1 init dump the "kernel" environment -variables into the env_store directory, via the -s6-dumpenv -program, before erasing them. env_store should obviously be -a writable directory, so it should be located under tmpfsdir! -If this option is not given (which is the default), the environment -inherited from the kernel isn't saved anywhere.
  • +to s6-linux-init-maker makes stage 1 init dump the "kernel" environment +variables into the env_store directory (under a format that is +later readable with +s6-envdir -fn) +before erasing them. env_store should obviously be +a writable directory, so it should be located under /run +(or your chosen tmpfsdir)! +If this option is not given, the environment inherited from the kernel +isn't saved anywhere - which is the default.

  • -e initial_envvar : this option -can be repeated. For every initial_envvar, s6-linux-init-maker +can be repeated. For every initial_envvar, s6-linux-init-maker will adjust the global environment directory in dir/env. initial_envvar must either be of the form VAR, to make sure that VAR does not appear in the global environment, or of the form VAR=VALUE, to add an environment variable VAR with the value VALUE. The global environment is the environment that every supervised -process (as well as the stage2 script) will run with, +process (as well as the rc.init script) will run with, so it will be inherited by default by every process running on the system. The TZ variable, for instance, is a good candidate to be set in the global environment.
  • -

  • -E stage2_envvar : same behaviour -as the -e option, except that every declared -stage2_envvar will be put in the environment run by the -stage2 script. They will not be put in the global -environment.
  • -
  • -q finalsleeptime : when the machine shuts down, all processes that have not already been killed during shutdownscript will receive a SIGTERM or a SIGHUP to allow @@ -361,10 +250,113 @@ will go on. This option configures the amount of time that will elapse between the SIGTERM/SIGHUP and the SIGKILL. Default is 2000, meaning a grace period of 2 seconds.
  • +

  • -D initdefault : boot the system with +a runlevel set to initdefault, which can be an arbitrary +string, but is usually 2, 3, 5 (traditional +sysvinit behaviour) or default (OpenRC behaviour). Default is +default. Note that if a 2, 3, 4, +5, or default argument is encountered in the kernel +command line, it will be interpreted as the runlevel to boot the system +on, and will override the default given here.
  • + +

  • -U utmp_user : this option is only +available when the s6-linux-init package has been built with the +--enable-utmps configure option, that enables support for the +utmps package. The option +defines the user that the utmpd and wtmpd services +will run as. Default is utmp.
  • + + +

    Organization of the created directory

    + +

    + If s6-linux-init-maker returns successfully, dir +contains data that will be used at boot time. (Actually, +basedir will be used at boot time, not dir. Do not +forget to copy dir to basedir once you have checked +you are happy with what s6-linux-init-maker has created.) +

    + +

    + This boot-time data is made of several subdirectories: +

    + + + +

    + If s6-linux-init has been built with +utmps support, some more +directories may exist: +

    + +

    Notes

    +

    + A directory created by s6-linux-init-maker is only valid on +the machine it has been created on. Pre-creating init directories for +other machines is not supported. +

    +

    The difficult parts of running @@ -380,22 +372,27 @@ tree's output away from /dev/console (which is fine for a first process invocation but impractical for log management of a whole process tree) and into a logger that is itself managed by the supervision tree it's reading data from. +

  • Keeping appearances of compatibility with another init system +is difficult: in particular, the mechanisms around the shutdown +procedure are fundamentally different from about any other init +system, so even a simple command such as reboot needs an +ad-hoc implementation.
  • - The main benefit of s6-linux-init-maker is that it automates those -parts. This means that it has been designed for real hardware -where the above issues apply. - If you are building an init system for a -virtual machine, a container, or anything similar that does not -have the /dev/console issue or the read-only rootfs issue, -you will probably not reap much benefit from using s6-linux-init-maker: + The main benefit of s6-linux-init-maker is that it offers +transparent compatibility while automating the tricky technical part. +That means that s6-linux-init-maker has been designed for +real hardware, or at least full-fledged Linux systems, +where the above issues apply. If you are building an init system for a +container, or anything similar that does not +have the /dev/console issue, the read-only rootfs issue, +or the need for sysvinit compatibility, +you will probably not reap much benefit from using s6-linux-init-maker: you could probably invoke s6-svscan directly as your process 1, or build a script by hand, which would result in a simpler init with less dependencies. -Nevertheless, if you prefer using s6-linux-init-maker, it -supports this case via the -n option.

    -- cgit v1.3.1