The available init system choices on Ubuntu are two:

systemd, which is the default and the one best tested/supported

upstart/sysv-init, on the way out but still working quite good from my experience

What if one wants to try something more exotic, like runit for example? Does it work out of the box?

runit has no logo, so I made this. Ultima runes are cool.

Spoiler: no.

I describe here how to patch your Ubuntu system to take the combination of runit+Ubuntu up to a reasonable working state. Along the way, we also acknowledge that sysv-init scripts are broken for good in Xenial and will be completely gone in Yakkety Yak and further releases.

For the impatient kids

This PPA contains the modified initscripts and runit package as described in this post:

After activating the PPA you have to:

replace systemd with upstart/sysV (runit uses sysV init scripts for the startup/shutdown stages)

install runit and initscripts packages

enable the kernel init in grub (see below)

enable getty-5/sshd or any other service that you wish to use.

All the bugs discovered during the write up of this post are fixed in the initscripts and runit packages provided by the PPA.

Configuring runit

First you should setup some configuration for runit:

$ rsync -va /usr/share/doc/runit/debian/ /etc/runit

$ chmod +x /etc/runit/*

The chmod is necessary as apparently there is a bug in the runit package (they should have executable bit by default); it is fixed in my PPA and I have moved the Debian etc files in /usr/share/runit/etc.

A second bug is that runit looks for active services in /service, while the package creates an /etc/service directory. I solved it by editing the last line of /etc/runit/2:

runsvdir -P /etc/service 'log: ...<omitted>

Let’s enable a terminal on tty5:

$ ln -s /etc/sv/getty-5 /etc/service/

This is the only available runit service provided by the runit package, you can find others here:

Pro-tip: don’t unlink the runit symlink for the getty service you are currently using. Yes, it will terminate it immediately.

Changing the init

These are the steps to set runit as init:

comment the lines starting with GRUB_HIDDEN* in your /etc/default/grub

run update-grub

reboot, then at GRUB2 menu type ‘e’, append init=/sbin/runit-init to the kernel line

press ctrl+x to boot your modified boot definition

To speed up your boot attempts with runit, I suggest you create a custom stanza in /etc/grub.d/40_custom (copy a generated one from /boot/grub/grub.cfg and add your init= line).

First attempt

This is the first boot up screen with runit-init:

Click to enlarge this post-modern init system art

It seems like some expected sysV scripts are not there, most notably /lib/init/mount-functions.sh. Let’s find out why.

A bit of history

I have been digging the history of sysvinit and initscripts (sysvinit is the repo that generates initscripts and other packages) on Debian/Ubuntu, and it is indeed an interesting one. It shows the high flux these packages are recently going through.

This changelog (tip is Yakkety Yak) gives the idea: https://launchpad.net/ubuntu/+source/sysvinit/+changelog

My excerpt of the changes that are relevant for the issue at hand:

init scripts were customized to ease the transition from Trusty to Xenial

since upstart was taking care of all the init work, /lib/init/mount-functions.sh (and others) were removed, although the scripts do still reference them

during the development of Yakkety Yak the Debian unstable version was merged back into sysvinit, probably to reduce the delta and have easier merges in future

in Yakkety Yak the initscripts package is no more built

(On a side note, you should probably be concerned about the last fact, as it means upstart+sysv will not work in Yakkety Yak anymore, leaving us to systemd alone for init system choices).

I have compared with meld the current initscripts from Debian with those provided in Ubuntu Xenial: