s6-linux-init
Software
skarnet.org
Quickstart and FAQ for s6-linux-init
Quickstart
- Install all the s6-linux-init dependencies:
- Save and remove your old /etc/s6-linux-init directory, if you have one.
- Install s6-linux-init itself.
- Save your old /sbin/init, /sbin/telinit, /sbin/shutdown,
/sbin/halt, /sbin/poweroff and /sbin/reboot binaries.
- Make sure you have a /run directory.
- Edit the scripts in /etc/s6-linux-init/skel.
- Check that your devtmpfs is automounted by your kernel at boot time. If it is not,
add the -d /dev option to the s6-linux-init-maker command line below.
- As root, run:
rm -rf /tmp/blah
s6-linux-init-maker -1 -G "/sbin/getty 38400 tty1" /tmp/blah
rm -rf /etc/s6-linux-init/current
mv /tmp/blah /etc/s6-linux-init/current
cp -a /etc/s6-linux-init/current/bin/* /sbin/
- Reboot. Warning: use your old reboot command, that you saved, not the new one
that has just been created by s6-linux-init-maker, because you're still running on
your old init system and need to use a reboot command that matches it.
- After the reboot: congratulations! your machine is now running an s6-based init system.
- To shut the machine down, use /sbin/shutdown, /sbin/halt,
/sbin/poweroff or /sbin/reboot as usual.
FAQ
How do I convert a runit setup to an s6 one?
A runit and an s6 setup are very similar. There are just three things you
need to pay attention to:
- runsv supports
customized controls, whereas
s6-supervise does
not. Fortunately, very few services use the customized control feature of
runit; and s6 supports customizing the termination signal to a process via the
down-signal file,
which can replace 99% of the legit uses of customized control. So, you should
check your service directories for control/ subdirectories, and
adapt them depending on how your service handles controls. If a service does
not use customized controls, you don't need to make any change and the service
will run under s6-supervise as is.
- The interface of svlogd,
runit's logger, is different from the interface of
s6-log, s6's logger.
Namely, svlogd reads a config file in its log directory, while s6-log reads its
configuration on its command line. If you have logging services that use svlogd,
you should read their configuration in their logdir, and translate it to the
proper s6-log invocation.
- And, finally, the init process. Understanding how s6-linux-init works may
seem daunting, but using it really is a lot simpler than it looks.
In a runit setup, you have
the runit program running as
pid 1, and sequentially spawning /etc/runit/1, then /etc/runit/2
which contains the invocation of
runsvdir, and finally
/etc/runit/3 at shutdown time when runsvdir is dead.
In a s6 setup that you have booted via
s6-linux-init, the scanner,
s6-svscan (the equivalent
of runsvdir), runs as
pid 1, very early, and remains there for the whole lifetime of the machine. At
boot time, the /etc/s6-linux-init/current/scripts/rc.init script is run, with
the supervision tree already in place; when it exits, the system is supposed to
be in a fully-booted, stable state. At shutdown time (on receipt of a shutdown
command), the /etc/s6-linux-init/current/scripts/rc.shutdown script is run,
with the supervision tree still in place; when it exits, the
filesystems will be unmounted and the machine will be rebooted and/or stopped.
So, the quickest way to port a runit setup to an s6-linux-init one is to:
- Copy your /etc/runit/1 to /etc/s6-linux-init/current/scripts/rc.init.
The only thing you should remove here is the creation of /run, because s6-linux-init
has already mounted a tmpfs on /run. But basically all the rest should stay.
- Also copy the parts of /etc/runit/2, if any, that come before the
runsvdir invocation, to
/etc/s6-linux-init/current/scripts/rc.init.
- At the end of /etc/s6-linux-init/current/scripts/rc.init, symlink all
your runit service directories to /run/service, and call
s6-svscanctl -a /run/service. This will start and supervise all the services
that you have symlinked, the way the original runsvdir invocation would have.
- Copy your /etc/runit/3 to /etc/s6-linux-init/current/scripts/rc.shutdown,
removing the parts that unmount the filesystems and reboot the machine.
Once you have done that, you have a literal translation of your runit system into a
s6 system, and it should boot, and work, albeit in a non-idiomatic, unoptimized way.
If you don't want to overwrite your /sbin/init binary, you can boot with
init=/etc/s6-linux-init/current/bin/init as a kernel command line argument
to reach the s6-linux-init entry point.
Further work to make the setup prettier can include:
- Identifying daemons you run in /etc/s6-linux-init/current/scripts/rc.init
and making them early services instead.
- Or, more idiomatically, analyze your whole boot sequence in
/etc/s6-linux-init/current/scripts/rc.init and the daemons in your runit
service directories, and convert the boot sequence so it can be handled by a service manager,
for instance s6-rc.
Colin Booth has a
series
of posts on Reddit that go into more detail on how to use a Void Linux distribution,
which natively uses runit, with the s6 ecosystem instead; there are step-by-step tutorials
as well as turnkey solutions, and it is recommended reading even if you do not use Void.