Browse Source

Add documentation: using Dinit as your system init on Linux

Davin McCall 7 years ago
parent
commit
70559362c2

+ 105 - 0
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.

+ 11 - 0
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

+ 14 - 0
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

+ 21 - 0
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

+ 6 - 0
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

+ 6 - 0
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

+ 17 - 0
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

+ 11 - 0
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

+ 12 - 0
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;

+ 8 - 0
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

+ 12 - 0
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

+ 9 - 0
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

+ 7 - 0
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

+ 59 - 0
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;

+ 10 - 0
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

+ 22 - 0
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;

+ 11 - 0
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

+ 4 - 0
doc/linux/services/single

@@ -0,0 +1,4 @@
+type = process
+command = /bin/sh
+restart = false
+runs-on-console = true

+ 5 - 0
doc/linux/services/tty1

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty1 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/tty2

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty2 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/tty3

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty3 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/tty4

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty4 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/tty5

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty5 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/tty6

@@ -0,0 +1,5 @@
+type = process
+command = /sbin/agetty tty6 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP

+ 5 - 0
doc/linux/services/udev-settle

@@ -0,0 +1,5 @@
+type = scripted
+command = /bin/udevadm settle
+restart = false
+waits-for = udevd
+waits-for = udev-trigger

+ 6 - 0
doc/linux/services/udev-settle.sh

@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if [ "$1" = start ]; then
+    udevadm trigger --action=add
+    udevadm settle
+fi

+ 7 - 0
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

+ 10 - 0
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