--- /dev/null
+## 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.
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# Example dhcpcd script.
+
+type = process
+command = /usr/sbin/dhcpcd -B -M --logfile /var/log/dhcpcd-service.log enp3s0
+restart = false
+depends-on = rcboot
--- /dev/null
+# Early (virtual) filesystems - /proc, /sys, etc
+
+type = scripted
+command = /etc/dinit.d/early-filesystems.sh start
+restart = false
+onstart = rw_ready
--- /dev/null
+#!/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
--- /dev/null
+# 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
--- /dev/null
+#!/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;
--- /dev/null
+# 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
--- /dev/null
+#!/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
--- /dev/null
+# Virtual service run before login is enabled.
+
+type = internal
+restart = false
+runs-on-console = yes
+
+depends-on = rcboot
+waits-for = dbusd
+waits-for = udevd
--- /dev/null
+# 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
--- /dev/null
+#!/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;
--- /dev/null
+# 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
--- /dev/null
+#!/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;
--- /dev/null
+# 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
--- /dev/null
+type = process
+command = /bin/sh
+restart = false
+runs-on-console = true
--- /dev/null
+type = process
+command = /sbin/agetty tty1 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = process
+command = /sbin/agetty tty2 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = process
+command = /sbin/agetty tty3 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = process
+command = /sbin/agetty tty4 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = process
+command = /sbin/agetty tty5 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = process
+command = /sbin/agetty tty6 linux-c
+restart = true
+depends-on = loginready
+termsignal = HUP
--- /dev/null
+type = scripted
+command = /bin/udevadm settle
+restart = false
+waits-for = udevd
+waits-for = udev-trigger
--- /dev/null
+#!/bin/sh
+
+if [ "$1" = start ]; then
+ udevadm trigger --action=add
+ udevadm settle
+fi
--- /dev/null
+# 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
--- /dev/null
+# 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