From 70559362c2ac135621e318ec13548680c191bd03 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Sun, 19 Jun 2016 23:01:28 +0100 Subject: [PATCH] Add documentation: using Dinit as your system init on Linux --- doc/linux/DINIT-AS-INIT.md | 105 ++++++++++++++++++++++++ doc/linux/services/auxfscheck | 11 +++ doc/linux/services/boot | 14 ++++ doc/linux/services/dbusd | 21 +++++ doc/linux/services/dhcpcd | 6 ++ doc/linux/services/early-filesystems | 6 ++ doc/linux/services/early-filesystems.sh | 17 ++++ doc/linux/services/filesystems | 11 +++ doc/linux/services/filesystems.sh | 12 +++ doc/linux/services/late-filesystems | 8 ++ doc/linux/services/late-filesystems.sh | 12 +++ doc/linux/services/loginready | 9 ++ doc/linux/services/rcboot | 7 ++ doc/linux/services/rcboot.sh | 59 +++++++++++++ doc/linux/services/rootfscheck | 10 +++ doc/linux/services/rootfscheck.sh | 22 +++++ doc/linux/services/rootrw | 11 +++ doc/linux/services/single | 4 + doc/linux/services/tty1 | 5 ++ doc/linux/services/tty2 | 5 ++ doc/linux/services/tty3 | 5 ++ doc/linux/services/tty4 | 5 ++ doc/linux/services/tty5 | 5 ++ doc/linux/services/tty6 | 5 ++ doc/linux/services/udev-settle | 5 ++ doc/linux/services/udev-settle.sh | 6 ++ doc/linux/services/udev-trigger | 7 ++ doc/linux/services/udevd | 10 +++ 28 files changed, 403 insertions(+) create mode 100644 doc/linux/DINIT-AS-INIT.md create mode 100644 doc/linux/services/auxfscheck create mode 100644 doc/linux/services/boot create mode 100644 doc/linux/services/dbusd create mode 100644 doc/linux/services/dhcpcd create mode 100644 doc/linux/services/early-filesystems create mode 100755 doc/linux/services/early-filesystems.sh create mode 100644 doc/linux/services/filesystems create mode 100755 doc/linux/services/filesystems.sh create mode 100644 doc/linux/services/late-filesystems create mode 100755 doc/linux/services/late-filesystems.sh create mode 100644 doc/linux/services/loginready create mode 100644 doc/linux/services/rcboot create mode 100755 doc/linux/services/rcboot.sh create mode 100644 doc/linux/services/rootfscheck create mode 100755 doc/linux/services/rootfscheck.sh create mode 100644 doc/linux/services/rootrw create mode 100644 doc/linux/services/single create mode 100644 doc/linux/services/tty1 create mode 100644 doc/linux/services/tty2 create mode 100644 doc/linux/services/tty3 create mode 100644 doc/linux/services/tty4 create mode 100644 doc/linux/services/tty5 create mode 100644 doc/linux/services/tty6 create mode 100644 doc/linux/services/udev-settle create mode 100755 doc/linux/services/udev-settle.sh create mode 100644 doc/linux/services/udev-trigger create mode 100644 doc/linux/services/udevd diff --git a/doc/linux/DINIT-AS-INIT.md b/doc/linux/DINIT-AS-INIT.md new file mode 100644 index 0000000..2fe3219 --- /dev/null +++ b/doc/linux/DINIT-AS-INIT.md @@ -0,0 +1,105 @@ +## Dinit as init: using Dinit as your Linux system's init + +Modern linux is a relatively complex system, these days. You can use Dinit, +in conjunction with other software, to boot your system and replace your current +init system (which on most main distributions is now Systemd, Sys V init, or +OpenRC). + +The additional software required can be broken into _essential_ and +_optional_ packages, which are detailed in following sections. For example service +files, please check the "services" subdirectory. + + +# General notes + +It is common to use "devtmpfs" on /dev, and the kernel can actually mount it +there before it even starts the init process, which can be quite handy; for +one thing it means that a range of device nodes will be available by default +(including /dev/console, which dinit may need to display any output, as well +as the block device used for the root mount, which must be available in +order to perform the initial fsck). You must configure your kernel +appropriately for this to happen. + +(actually, it seems that dinit manages output without /dev/console; probably +the kernel is giving it appropriate stdin/out/err file descriptors. I'm not +sure if this was the case for older kernels). + +The /dev filesystem on linux after boot is usually managed by a "device node +manager", such as Udev (which is now distributed only with Systemd) or +Eudev. Even this is technically optional - you can still populate your root +filesystem with device nodes directly - but I highly recommend using an +automated system. + +Various other virtual filesystems are mounted as standard on Linux these +days. They include: + +- /sys - sysfs - representation of devices, buses, drivers etc; used by udev etc. +- /sys/fs/cgroup - cgroupfs - control groups +- /proc - procfs - information about running processes, and various kernel + interfaces +- /dev/shm - tmpfs - used for shared memory +- /dev/pts - devpts - pseudoterminal devices +- /run - tmpfs - storage for program state; used by udev + +These filesystems (particularly /sys, /proc and /run) need to be mounted +quite early as they will be used by early-boot processes. + +Many Linux distributions are now built around Systemd. Much of what Systemd +manages was previously managed by other utilities/daemons (syslogd, inetd, +cron, cgmanager, etc) and these can still be used to provide their original +functionality, although at the cost of the losing automated integration. + +Some packages may rely on the "logind" functionality of Systemd for +session/seat management. This same functionality is also provided by +ConsoleKit2, though I'm not to what degree nor level of compatibility. + +In general I've found it quite possible to run a desktop system with Dinit +in place of SystemD, but my needs are minimal. If you're running a +full-fledged desktop environment like Gnome or KDE you may experience +problems (which, I believe, should not be intractable, but which may require +implementation/shims of Systemd APIs in some cases). + +The basic procedure for boot (to be implemented by services) is as follows: + +- mount early virtual filesystems +- start device node manager +- trigger device node manager (udevadm trigger --action=add) to add + boot-time device nodes (possibly not necessary if using kernel-mounted + devtmpfs) +- run root filesystem check +- remount root filesystem read-write +- start syslog deamon +- start other daemons as appropriate (dhcpcd, any networking daemons) +- start getty instances virtual terminals + +The service description files and scrips in the "services" subdirectory +provide a template for accomplishing the above, but may need some adjustment +for your particular configuration. + + +# Essential packages + +First, a device node manager. I recommend "Eudev". + +- Eudev - the Gentoo fork of Udev; https://github.com/gentoo/eudev +- Vdev - "a device file manager and filesystem" and a "work in progress"; + https://github.com/jcnelson/vdev +- Mdev may also be an option; it is part of the "busybox" utility suite. + +Then, a "getty" and "login" program. Both can be found in the util-linux +package, at: https://www.kernel.org/pub/linux/utils/util-linux + + +# Optional packages + +ConsoleKit2, to act as seat/sesion manager (functionality otherwise +provided by Systemd): +https://github.com/ConsoleKit2/ConsoleKit2 + +cgmanager, the control group manager; you probably want this if you use +ConsoleKit2, and maybe if you want to use containers: +https://github.com/lxc/cgmanager + +However, I believe that cgmanage works with the old (v1) cgroups interface. +I expect that v2 cgroups together with cgroup namespaces as found in newer +kernels will render it obselete. diff --git a/doc/linux/services/auxfscheck b/doc/linux/services/auxfscheck new file mode 100644 index 0000000..0878b04 --- /dev/null +++ b/doc/linux/services/auxfscheck @@ -0,0 +1,11 @@ +# Check auxillary (non-root) filesystems. + +type = scripted +command = /sbin/fsck -A -R -C -a +restart = false +runs-on-console = true + +depends-on = early-filesystems +depends-on = udevd +depends-on = rootrw +waits-for = udev-settle diff --git a/doc/linux/services/boot b/doc/linux/services/boot new file mode 100644 index 0000000..b0eb681 --- /dev/null +++ b/doc/linux/services/boot @@ -0,0 +1,14 @@ +# This is the primary service, automatically started when the system comes up. + +type = internal + +# Each of these services starts a login prompt: +depends-on = tty1 +depends-on = tty2 +depends-on = tty3 +depends-on = tty4 +depends-on = tty5 +depends-on = tty6 + +waits-for = late-filesystems +waits-for = dhcpcd diff --git a/doc/linux/services/dbusd b/doc/linux/services/dbusd new file mode 100644 index 0000000..00c353e --- /dev/null +++ b/doc/linux/services/dbusd @@ -0,0 +1,21 @@ +# Dbus daemon. + +# Dbusd can use socket activation, which Dinit (sort-of) supports. However, this currently +# requires building Dbus against SystemD. + +# For non-socket-activated: +#type = bgprocess +#command = /usr/bin/dbus-daemon --system +#pid-file = /var/run/dbus/pid +#restart = false +#depends-on = rcboot +#logfile = /var/log/dbus-daemon.log +#smooth-recovery = yes + +# For socket-activation: +type = process +command = /usr/bin/dbus-daemon --system --nofork --nopidfile +depends-on = rcboot +logfile = /var/log/dbus-daemon.log +smooth-recovery = yes +socket-listen = /var/run/dbus/system_bus_socket diff --git a/doc/linux/services/dhcpcd b/doc/linux/services/dhcpcd new file mode 100644 index 0000000..2fa96e3 --- /dev/null +++ b/doc/linux/services/dhcpcd @@ -0,0 +1,6 @@ +# Example dhcpcd script. + +type = process +command = /usr/sbin/dhcpcd -B -M --logfile /var/log/dhcpcd-service.log enp3s0 +restart = false +depends-on = rcboot diff --git a/doc/linux/services/early-filesystems b/doc/linux/services/early-filesystems new file mode 100644 index 0000000..fb03f21 --- /dev/null +++ b/doc/linux/services/early-filesystems @@ -0,0 +1,6 @@ +# Early (virtual) filesystems - /proc, /sys, etc + +type = scripted +command = /etc/dinit.d/early-filesystems.sh start +restart = false +onstart = rw_ready diff --git a/doc/linux/services/early-filesystems.sh b/doc/linux/services/early-filesystems.sh new file mode 100755 index 0000000..ca70379 --- /dev/null +++ b/doc/linux/services/early-filesystems.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if [ "$1" = start ]; then + + PATH=/usr/bin:/usr/sbin:/bin:/sbin + + # Must have sysfs mounted for udevtrigger to function. + mount -n -t sysfs sysfs /sys + # Ideally devtmpfs will be mounted by kernel: + mount -n -t devtmpfs tmpfs /dev + mount -n -t tmpfs -o mode=775 tmpfs /run + mount -n -t proc -o hidepid=1 proc /proc + mkdir /run/udev + mkdir /dev/pts + mkdir /dev/shm + +fi diff --git a/doc/linux/services/filesystems b/doc/linux/services/filesystems new file mode 100644 index 0000000..2cfea68 --- /dev/null +++ b/doc/linux/services/filesystems @@ -0,0 +1,11 @@ +# Auxillary (non-root) filesystems + +type = scripted +command = /etc/dinit.d/filesystems.sh start +restart = false +logfile = /var/log/dinit-filesystems.log + +depends-on = udevd +depends-on = rootrw +waits-for = auxfscheck +waits-for = udev-settle diff --git a/doc/linux/services/filesystems.sh b/doc/linux/services/filesystems.sh new file mode 100755 index 0000000..268eb21 --- /dev/null +++ b/doc/linux/services/filesystems.sh @@ -0,0 +1,12 @@ +#!/bin/sh +export PATH=/usr/bin:/usr/sbin:/bin:/sbin + +if [ "$1" != "stop" ]; then + + echo "Mounting auxillary filesystems...." + mount -t tmpfs -o nodev,nosuid tmpfs /dev/shm + mount -t devpts -o gid=5 devpts /dev/pts + swapon /swapfile + mount -avt noproc,nonfs + +fi; diff --git a/doc/linux/services/late-filesystems b/doc/linux/services/late-filesystems new file mode 100644 index 0000000..a627583 --- /dev/null +++ b/doc/linux/services/late-filesystems @@ -0,0 +1,8 @@ +# Filesystems which can be mounted after login is enabled. + +type = scripted +command = /etc/dinit.d/late-filesystems.sh start +restart = false +logfile = /var/log/late-filesystems.log + +depends-on = rcboot diff --git a/doc/linux/services/late-filesystems.sh b/doc/linux/services/late-filesystems.sh new file mode 100755 index 0000000..3962e4e --- /dev/null +++ b/doc/linux/services/late-filesystems.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$1" = start ]; then + + PATH=/usr/bin:/usr/sbin:/bin:/sbin + + fsck -a /dev/sdb2 + mount /dev/sdb2 /mnt/sdb2 + mount --bind /mnt/sdb2/src /usr/src + mount --bind /mnt/sdb2 /mnt/tmp # hopefully can remove this at some point + +fi diff --git a/doc/linux/services/loginready b/doc/linux/services/loginready new file mode 100644 index 0000000..de50fdc --- /dev/null +++ b/doc/linux/services/loginready @@ -0,0 +1,9 @@ +# Virtual service run before login is enabled. + +type = internal +restart = false +runs-on-console = yes + +depends-on = rcboot +waits-for = dbusd +waits-for = udevd diff --git a/doc/linux/services/rcboot b/doc/linux/services/rcboot new file mode 100644 index 0000000..a8064cb --- /dev/null +++ b/doc/linux/services/rcboot @@ -0,0 +1,7 @@ +# Various startup operations + +type = scripted +command = /etc/dinit.d/rcboot.sh start +stop-command = /etc/dinit.d/rcboot.sh stop +restart = false +depends-on = filesystems diff --git a/doc/linux/services/rcboot.sh b/doc/linux/services/rcboot.sh new file mode 100755 index 0000000..f752ef1 --- /dev/null +++ b/doc/linux/services/rcboot.sh @@ -0,0 +1,59 @@ +#!/bin/sh +export PATH=/usr/bin:/usr/sbin:/bin:/sbin +umask 0077 + +if [ "$1" != "stop" ]; then + + # Get system time from hardware clock + /sbin/hwclock --adjust + /sbin/hwclock --hctosys + + # cleanup + # (delete /tmp etc) + : > /var/run/utmp + rm -f -r /tmp/* + rm -f -r /tmp/.[^.]* + rm -f -r /tmp/..?* + rm -f /var/locks/* + rm -f -r /var/run/dbus/* + + # Configure random number generator + cat /var/state/random-seed > /dev/urandom + + # Configure network + /sbin/ifconfig lo 127.0.0.1 + + # You can put other static configuration here: + #/sbin/ifconfig eth0 192.168.1.38 netmask 255.255.255.0 broadcast 192.168.1.255 + + /bin/hostname myhost + + # networking daemons + /usr/libexec/syslogd + /usr/sbin/sshd + /usr/libexec/inetd + + # /usr/sbin/alsactl restore + + # Prevent spurious messages from kernel to console + # (syslog will still catch them). Default in 2.4.18 is "7 4 1 7". + # in particular this prevents "unknown scancode" messages from unrecognized + # keys on funky keyboards, and module loading messages. + echo "3 4 1 7" > /proc/sys/kernel/printk + + # Printing + #/etc/init.d/hplip start + /etc/init.d/cups start + +else + + # The system is being shut down + # kill some stuff + #if [ -e /var/run/gpm.pid ]; then kill `cat /var/run/gpm.pid`; fi + + /etc/init.d/cups stop + + # echo "Saving random number seed..." + dd if=/dev/urandom of=/var/state/random-seed bs=512 count=1 2> /dev/null + +fi; diff --git a/doc/linux/services/rootfscheck b/doc/linux/services/rootfscheck new file mode 100644 index 0000000..3975d12 --- /dev/null +++ b/doc/linux/services/rootfscheck @@ -0,0 +1,10 @@ +# Check the root filesystem. This is interruptible with ^C + +type = scripted +command = /etc/dinit.d/rootfscheck.sh start +restart = false +runs-on-console = yes + +depends-on = early-filesystems +depends-on = udevd +waits-for = udev-trigger diff --git a/doc/linux/services/rootfscheck.sh b/doc/linux/services/rootfscheck.sh new file mode 100755 index 0000000..f67db80 --- /dev/null +++ b/doc/linux/services/rootfscheck.sh @@ -0,0 +1,22 @@ +#!/bin/sh +export PATH=/usr/bin:/usr/sbin:/bin:/sbin + +if [ "$1" != "stop" ]; then + + echo "Checking root file system..." + if [ -x /sbin/fsck ]; then + /sbin/fsck -C -a / + fsckresult=$? + if [ $(($fsckresult & 2)) -eq 2 ]; then + echo "***********************" + echo "WARNING WARNING WARNING" + echo "***********************" + echo "root file system has problems: rebooting..." + sleep 10 + /sbin/reboot --system -r + fi + else + echo "WARNING - Could not find /sbin/fsck" + fi + +fi; diff --git a/doc/linux/services/rootrw b/doc/linux/services/rootrw new file mode 100644 index 0000000..2dea27b --- /dev/null +++ b/doc/linux/services/rootrw @@ -0,0 +1,11 @@ +# Re-mount the root filesystem read/write. + +type = scripted +command = /bin/mount -n -o remount,rw / +restart = false +onstart = rw_ready +logfile = /run/rootrw.log + +depends-on = early-filesystems +depends-on = udevd +waits-for = rootfscheck diff --git a/doc/linux/services/single b/doc/linux/services/single new file mode 100644 index 0000000..1046717 --- /dev/null +++ b/doc/linux/services/single @@ -0,0 +1,4 @@ +type = process +command = /bin/sh +restart = false +runs-on-console = true diff --git a/doc/linux/services/tty1 b/doc/linux/services/tty1 new file mode 100644 index 0000000..844ece3 --- /dev/null +++ b/doc/linux/services/tty1 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty1 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/tty2 b/doc/linux/services/tty2 new file mode 100644 index 0000000..df3896d --- /dev/null +++ b/doc/linux/services/tty2 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty2 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/tty3 b/doc/linux/services/tty3 new file mode 100644 index 0000000..e75cc17 --- /dev/null +++ b/doc/linux/services/tty3 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty3 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/tty4 b/doc/linux/services/tty4 new file mode 100644 index 0000000..a70ad04 --- /dev/null +++ b/doc/linux/services/tty4 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty4 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/tty5 b/doc/linux/services/tty5 new file mode 100644 index 0000000..1958933 --- /dev/null +++ b/doc/linux/services/tty5 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty5 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/tty6 b/doc/linux/services/tty6 new file mode 100644 index 0000000..c6511e8 --- /dev/null +++ b/doc/linux/services/tty6 @@ -0,0 +1,5 @@ +type = process +command = /sbin/agetty tty6 linux-c +restart = true +depends-on = loginready +termsignal = HUP diff --git a/doc/linux/services/udev-settle b/doc/linux/services/udev-settle new file mode 100644 index 0000000..f8e3ddf --- /dev/null +++ b/doc/linux/services/udev-settle @@ -0,0 +1,5 @@ +type = scripted +command = /bin/udevadm settle +restart = false +waits-for = udevd +waits-for = udev-trigger diff --git a/doc/linux/services/udev-settle.sh b/doc/linux/services/udev-settle.sh new file mode 100755 index 0000000..589f789 --- /dev/null +++ b/doc/linux/services/udev-settle.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +if [ "$1" = start ]; then + udevadm trigger --action=add + udevadm settle +fi diff --git a/doc/linux/services/udev-trigger b/doc/linux/services/udev-trigger new file mode 100644 index 0000000..ab13a0b --- /dev/null +++ b/doc/linux/services/udev-trigger @@ -0,0 +1,7 @@ +# Trigger udev events for already-present devices. + +type = scripted +command = /bin/udevadm trigger --action=add +logfile = /run/udev-trigger.log +restart = false +depends-on = udevd diff --git a/doc/linux/services/udevd b/doc/linux/services/udevd new file mode 100644 index 0000000..7cbc81a --- /dev/null +++ b/doc/linux/services/udevd @@ -0,0 +1,10 @@ +# We use a scripted service for udev since (at least with eudev-3.1.2) +# there is no other way to get notification when the control socket is +# ready. (The downside is that we cannot properly supervise the process +# and restart it if it crashes). +type = scripted +command = /sbin/udevd --daemon +stop-command = /bin/udevadm control -e +logfile = /run/udevd.log +restart = false +depends-on = early-filesystems -- 2.25.1