diff options
Diffstat (limited to 'core/runit')
| -rw-r--r-- | core/runit/.footprint | 70 | ||||
| -rw-r--r-- | core/runit/.signature | 15 | ||||
| -rw-r--r-- | core/runit/1 | 155 | ||||
| -rw-r--r-- | core/runit/2 | 22 | ||||
| -rw-r--r-- | core/runit/3 | 54 | ||||
| -rw-r--r-- | core/runit/MAKEPKG | 141 | ||||
| -rw-r--r-- | core/runit/clearmem.patch | 18 | ||||
| -rw-r--r-- | core/runit/ctrlaltdel | 13 | ||||
| -rw-r--r-- | core/runit/pause.1 | 39 | ||||
| -rw-r--r-- | core/runit/pause.c | 20 | ||||
| -rw-r--r-- | core/runit/rc.local | 13 | ||||
| -rw-r--r-- | core/runit/rc.shutdown | 8 | ||||
| -rw-r--r-- | core/runit/runit-1 | 172 | ||||
| -rw-r--r-- | core/runit/runit-2 | 22 | ||||
| -rw-r--r-- | core/runit/runit-3 | 64 |
15 files changed, 826 insertions, 0 deletions
diff --git a/core/runit/.footprint b/core/runit/.footprint new file mode 100644 index 0000000..e47347c --- /dev/null +++ b/core/runit/.footprint @@ -0,0 +1,70 @@ +drwxr-xr-x root/root etc/ +-rwxr-xr-x root/root etc/rc.local +-rwxr-xr-x root/root etc/rc.shutdown +drwxr-xr-x root/root etc/runit/ +-rwxr-xr-x root/root etc/runit/1 +-rwxr-xr-x root/root etc/runit/2 +-rwxr-xr-x root/root etc/runit/3 +-rwxr-xr-x root/root etc/runit/ctrlaltdel +drwxr-xr-x root/root etc/runit/runsvdir/ +lrwxrwxrwx root/root etc/runit/runsvdir/current -> /etc/runit/runsvdir/default +drwxr-xr-x root/root etc/runit/runsvdir/default/ +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty1 -> /etc/sv/agetty-tty1 +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty2 -> /etc/sv/agetty-tty2 +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty3 -> /etc/sv/agetty-tty3 +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty4 -> /etc/sv/agetty-tty4 +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty5 -> /etc/sv/agetty-tty5 +lrwxrwxrwx root/root etc/runit/runsvdir/default/agetty-tty6 -> /etc/sv/agetty-tty6 +drwxr-xr-x root/root etc/runit/runsvdir/single/ +lrwxrwxrwx root/root etc/runit/runsvdir/single/sulogin -> /etc/sv/sulogin +drwxr-xr-x root/root etc/sv/ +drwxr-xr-x root/root etc/sv/agetty-tty1/ +-rwxr-xr-x root/root etc/sv/agetty-tty1/finish +-rwxr-xr-x root/root etc/sv/agetty-tty1/run +drwxr-xr-x root/root etc/sv/agetty-tty2/ +-rwxr-xr-x root/root etc/sv/agetty-tty2/finish +-rwxr-xr-x root/root etc/sv/agetty-tty2/run +drwxr-xr-x root/root etc/sv/agetty-tty3/ +-rwxr-xr-x root/root etc/sv/agetty-tty3/finish +-rwxr-xr-x root/root etc/sv/agetty-tty3/run +drwxr-xr-x root/root etc/sv/agetty-tty4/ +-rwxr-xr-x root/root etc/sv/agetty-tty4/finish +-rwxr-xr-x root/root etc/sv/agetty-tty4/run +drwxr-xr-x root/root etc/sv/agetty-tty5/ +-rwxr-xr-x root/root etc/sv/agetty-tty5/finish +-rwxr-xr-x root/root etc/sv/agetty-tty5/run +drwxr-xr-x root/root etc/sv/agetty-tty6/ +-rwxr-xr-x root/root etc/sv/agetty-tty6/finish +-rwxr-xr-x root/root etc/sv/agetty-tty6/run +drwxr-xr-x root/root etc/sv/agetty-ttyS0/ +-rwxr-xr-x root/root etc/sv/agetty-ttyS0/finish +-rwxr-xr-x root/root etc/sv/agetty-ttyS0/run +drwxr-xr-x root/root etc/sv/sulogin/ +-rwxr-xr-x root/root etc/sv/sulogin/run +drwxr-xr-x root/root sbin/ +-rwxr-xr-x root/root sbin/chpst +-rwxr-xr-x root/root sbin/pause +-rwxr-xr-x root/root sbin/poweroff +-rwxr-xr-x root/root sbin/reboot +-rwxr-xr-x root/root sbin/runit +-rwxr-xr-x root/root sbin/runit-init +-rwxr-xr-x root/root sbin/runsv +-rwxr-xr-x root/root sbin/runsvchdir +-rwxr-xr-x root/root sbin/runsvdir +-rwxr-xr-x root/root sbin/sv +-rwxr-xr-x root/root sbin/svlogd +-rwxr-xr-x root/root sbin/utmpset +lrwxrwxrwx root/root sbin/halt -> poweroff +lrwxrwxrwx root/root sbin/init -> runit-init +drwxr-xr-x root/root service/ +lrwxrwxrwx root/root service/agetty-tty1 -> /etc/sv/agetty-tty1 +lrwxrwxrwx root/root service/agetty-tty2 -> /etc/sv/agetty-tty2 +lrwxrwxrwx root/root service/agetty-tty3 -> /etc/sv/agetty-tty3 +lrwxrwxrwx root/root service/agetty-tty4 -> /etc/sv/agetty-tty4 +lrwxrwxrwx root/root service/agetty-tty5 -> /etc/sv/agetty-tty5 +lrwxrwxrwx root/root service/agetty-tty6 -> /etc/sv/agetty-tty6 +drwxr-xr-x root/root usr/ +drwxr-xr-x root/root usr/share/ +drwxr-xr-x root/root usr/share/man/ +drwxr-xr-x root/root usr/share/man/man1/ +-rw-r--r-- root/root usr/share/man/man1/pause.1.gz diff --git a/core/runit/.signature b/core/runit/.signature new file mode 100644 index 0000000..f63dcd5 --- /dev/null +++ b/core/runit/.signature @@ -0,0 +1,15 @@ +RWTZ9IduCSQ/mAjirwbYFrUa1qR9XBGH8s/E7C4w5KM1ZixCvtCGc6c4HwICnPCgfUYn2GHzS22Tgo1QAfhOHXI3doGdxxYxgAI= + +SHA256 (MAKEPKG) = 67befcfe381ab637c70c57904c918d2eb8036893261d3c0d1ed5d0af08a9c74c +SHA256 (.footprint) = 5682e4d42690f233f846d6303091f379ade4f285c2220eb49d0c4c42ce34980b +SHA256 (runit-2.3.1.tar.gz) = 634f23c8c4d1d440043be0fe928ddf904626289e97bfe7c5826e93aaf2cc6fe9 +SHA256 (clearmem.patch) = 668fd39e94ab68700bcdae3b222525c3255f3f28d43694db017aef9f6e6945a4 +SHA256 (pause.c) = 83091fb46163582397acf1235bd7058c2d8466fbbba6a56624f57347b0f4f1fd +SHA256 (pause.1) = 6ecfe607c4cbfa8dd7c21c17aea0c9eea9717bc11b1db85c80b83292dac42ba9 +SHA256 (runit-1) = 88f81e4450fadffd032fd56396050c2de37101c7848765510c1a0bd4ce18bb26 +SHA256 (runit-2) = ae562bf4f3be0be448817aefeede23000fadea8f0fa5f8d930ebf57e5e5dd33d +SHA256 (runit-3) = 78b7467339fb909e1491e08ad0af3a0d5fdaab854345bc0aff189f940f5f3ad2 +SHA256 (ctrlaltdel) = 4c4ccd8a997eeef0b8095620b79e4e72785d28c069bf8c4ff79582bcab074ea7 +SHA256 (rc.local) = d5ad9ed29d75e6c2e6356179b8fb8df35db3c0747b60df9b586e3aa99b88b801 +SHA256 (rc.shutdown) = f49c574801eb148ec744e744ad76659e915ebdbea693dbc48a84d4d4e58fa77c +SHA256 (runit#2.3.1-2.pkg.tar.gz) = 91c39150efc2b680bac4a87da75073154c508796380f0f597dde8a90b276ac81 diff --git a/core/runit/1 b/core/runit/1 new file mode 100644 index 0000000..19e6192 --- /dev/null +++ b/core/runit/1 @@ -0,0 +1,155 @@ +#!/bin/sh +# /etc/runit/1 - krypt/sh system boot + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH + +msg() { + printf '\033[1m%s\033[0m\n' "$1" +} + +err() { + printf '\033[1;31m%s\033[0m\n' "$1" >&2 +} + +emergency_shell() { + err "Dropping to emergency shell. Type 'exit' to reboot." + sulogin -p + printf '%s\n' "Rebooting..." + umount -a -r + mount -o remount,ro / + reboot -f + exit 0 +} + +printf '%s\n' "rawnix is starting..." + +msg "Mounting /proc..." +mountpoint -q /proc || mount -t proc proc /proc + +msg "Mounting /sys..." +mountpoint -q /sys || mount -t sysfs sysfs /sys + +msg "Mounting /run..." +mountpoint -q /run || mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs /run + +msg "Mounting /dev..." +if ! mountpoint -q /dev; then + mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev +else + mount -o remount,mode=0755,nosuid devtmpfs /dev +fi + +msg "Mounting /dev/pts..." +mkdir -m 755 -p /dev/pts +mountpoint -q /dev/pts || mount -t devpts -o gid=tty,mode=0620,noexec,nosuid devpts /dev/pts + +msg "Mounting /dev/shm..." +mkdir -m 1777 -p /dev/shm +mountpoint -q /dev/shm || mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm + +msg "Mounting cgroups v2..." +if ! mountpoint -q /sys/fs/cgroup; then + mount -t cgroup2 none /sys/fs/cgroup 2>/dev/null || + err "cgroup2 mount failed - containers will not work" +fi + +# Bootstrap udevd for coldplug; sv/udevd takes over in stage 2 +msg "Starting udevd..." +if udevd --daemon 2>/dev/null; then + msg "Triggering udev coldplug..." + udevadm trigger --type=subsystems --action=add + udevadm trigger --type=devices --action=add + + msg "Waiting for udev to settle..." + udevadm settle --timeout=30 || err "Timeout waiting for udev events" +else + err "udevd not available - continuing without hotplug" +fi + +msg "Bringing up loopback..." +ip addr add 127.0.0.1/8 dev lo 2>/dev/null +ip link set lo up 2>/dev/null + +# LUKS volumes +if [ -x /sbin/cryptsetup ] && [ -f /etc/crypttab ]; then + msg "Opening LUKS volumes..." + while IFS= read -r line; do + case "$line" in ''|\#*) continue ;; esac + name="${line%% *}" + rest="${line#* }" + device="${rest%% *}" + cryptsetup open "$device" "$name" || err "Failed to open LUKS volume: $name" + done < /etc/crypttab +fi + +msg "Remounting / read-only..." +mount -o remount,ro / + +if [ -f /forcefsck ]; then + msg "Forced filesystem check..." + FORCEFSCK="-f" +fi + +msg "Checking filesystems..." +fsck $FORCEFSCK -A -T -C -a 2>/dev/null +if [ $? -gt 1 ]; then + err "Filesystem check failed!" + err "Please repair manually. Root is mounted read-only." + err "To remount read-write: mount -n -o remount,rw /" + emergency_shell +fi + +msg "Remounting / read-write..." +mount -o remount,rw / + +msg "Seeding urandom..." +if [ -f /var/lib/random/seed ]; then + cat /var/lib/random/seed >/dev/urandom + rm -f /var/lib/random/seed +fi + +msg "Setting shared mount propagation..." +mount --make-rshared / + +msg "Activating swap..." +swapon -a 2>/dev/null + +msg "Mounting local filesystems..." +mount -a -O no_netdev 2>/dev/null || emergency_shell + +mkdir -m 0755 -p /run/user +mkdir -m 1777 -p /run/lock +: >/run/utmp + +rm -rf /forcefsck /fastboot /etc/nologin /etc/shutdownpid 2>/dev/null +rm -rf /tmp/* /tmp/.* 2>/dev/null + +if [ -x /etc/rc.modules ]; then + msg "Loading kernel modules..." + /etc/rc.modules +fi + +if [ -f /etc/sysctl.conf ]; then + msg "Setting kernel parameters..." + sysctl -p >/dev/null 2>&1 +fi + +if [ -f /etc/hostname ]; then + msg "Setting hostname: $(cat /etc/hostname)" + hostname "$(cat /etc/hostname)" +fi + +hwclock --hctosys 2>/dev/null + +[ -x /etc/rc.local ] && /etc/rc.local + +touch /etc/runit/stopit +chmod 100 /etc/runit/stopit +touch /etc/runit/reboot +chmod 100 /etc/runit/reboot + +dmesg > /var/log/boot.log 2>/dev/null + +msg "Boot complete." +exit 0 diff --git a/core/runit/2 b/core/runit/2 new file mode 100644 index 0000000..e36d340 --- /dev/null +++ b/core/runit/2 @@ -0,0 +1,22 @@ +#!/bin/sh +# /etc/runit/2 - Start service supervision + +PATH=/bin:/sbin:/usr/bin:/usr/sbin +export PATH + +runlevel=default + +for arg in $(cat /proc/cmdline); do + if [ -d "/etc/runit/runsvdir/$arg" ]; then + printf "Runlevel: %s\n" "$arg" + runlevel="$arg" + break + fi +done + +runsvchdir "$runlevel" || { + printf "Warning: runlevel '%s' failed, falling back to 'default'\n" "$runlevel" + [ "$runlevel" != default ] && runsvchdir default +} + +exec runsvdir -P /service 'log: ........................................................................................................' diff --git a/core/runit/3 b/core/runit/3 new file mode 100644 index 0000000..19540cd --- /dev/null +++ b/core/runit/3 @@ -0,0 +1,54 @@ +#!/bin/sh +# /etc/runit/3 - rawnix system shutdown + +exec 2>&1 +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH +stty onlcr 2>/dev/null + +printf '\nrawnix is shutting down...\n\n' + +printf 'Stopping services...\n' +sv force-stop /service/* 2>/dev/null +sv exit /service/* 2>/dev/null + +[ -x /etc/rc.shutdown ] && /etc/rc.shutdown + +printf 'Saving system clock...\n' +hwclock --systohc 2>/dev/null + +printf 'Saving urandom seed...\n' +mkdir -p /var/lib/random +chmod 700 /var/lib/random +dd if=/dev/urandom of=/var/lib/random/seed bs=512 count=1 2>/dev/null +chmod 600 /var/lib/random/seed + +printf 'Sending TERM signal...\n' +kill -TERM -1 2>/dev/null +sleep 2 + +printf 'Sending KILL signal...\n' +kill -KILL -1 2>/dev/null +sleep 1 + +printf 'Unmounting filesystems...\n' +sync +umount -a -d -r -t nosysfs,noproc,nodevtmpfs,notmpfs 2>/dev/null + +printf 'Closing LUKS volumes...\n' +if [ -x /sbin/cryptsetup ] && [ -f /etc/crypttab ]; then + while IFS= read -r line; do + case "$line" in ''|\#*) continue ;; esac + name="${line%% *}" + cryptsetup close "$name" 2>/dev/null + done < /etc/crypttab +fi + +printf 'Remounting root read-only...\n' +sync +mount -o remount,ro / 2>/dev/null + +swapoff -a 2>/dev/null + +printf 'Shutdown complete.\n' +exit 0 diff --git a/core/runit/MAKEPKG b/core/runit/MAKEPKG new file mode 100644 index 0000000..d38e9ea --- /dev/null +++ b/core/runit/MAKEPKG @@ -0,0 +1,141 @@ +#!/bin/mkpkg +# description: A UNIX init scheme with service supervision +# url: http://smarden.org/runit/ + +# Depends on: musl + +name=runit +version=2.3.1 +release=2 +source=(https://smarden.org/runit/$name-$version.tar.gz + clearmem.patch + pause.c + pause.1 + runit-1 + runit-2 + runit-3 + ctrlaltdel + rc.local + rc.shutdown) + +sha256sums=( + "634f23c8c4d1d440043be0fe928ddf904626289e97bfe7c5826e93aaf2cc6fe9" + "668fd39e94ab68700bcdae3b222525c3255f3f28d43694db017aef9f6e6945a4" + "83091fb46163582397acf1235bd7058c2d8466fbbba6a56624f57347b0f4f1fd" + "6ecfe607c4cbfa8dd7c21c17aea0c9eea9717bc11b1db85c80b83292dac42ba9" + "88f81e4450fadffd032fd56396050c2de37101c7848765510c1a0bd4ce18bb26" + "ae562bf4f3be0be448817aefeede23000fadea8f0fa5f8d930ebf57e5e5dd33d" + "78b7467339fb909e1491e08ad0af3a0d5fdaab854345bc0aff189f940f5f3ad2" + "4c4ccd8a997eeef0b8095620b79e4e72785d28c069bf8c4ff79582bcab074ea7" + "d5ad9ed29d75e6c2e6356179b8fb8df35db3c0747b60df9b586e3aa99b88b801" + "f49c574801eb148ec744e744ad76659e915ebdbea693dbc48a84d4d4e58fa77c" +) + +build() { + cd "admin/$name-$version" + + echo "${CC:-cc} ${CFLAGS:--O2 -Wall}" > src/conf-cc + echo "${CC:-cc} ${LDFLAGS} -s" > src/conf-ld + + patch -p1 -i "$SRC/clearmem.patch" + + ./package/compile + ./package/check + + install -d "$PKG/sbin" + install -m755 command/* "$PKG/sbin/" + ln -sf runit-init "$PKG/sbin/init" + + # Reboot/halt/poweroff wrappers (runit doesn't ship these) + printf '#!/bin/sh\ntouch /etc/runit/reboot\nchmod 100 /etc/runit/stopit\nkill -CONT 1\n' > "$PKG/sbin/reboot" + chmod 755 "$PKG/sbin/reboot" + + printf '#!/bin/sh\nrm -f /etc/runit/reboot\nchmod 100 /etc/runit/stopit\nkill -CONT 1\n' > "$PKG/sbin/poweroff" + chmod 755 "$PKG/sbin/poweroff" + + ln -sf poweroff "$PKG/sbin/halt" + + install -d "$PKG/etc/runit" + install -d "$PKG/etc/runit/runsvdir/default" + install -d "$PKG/etc/runit/runsvdir/single" + install -d "$PKG/etc/sv" + install -d "$PKG/service" + + install -m755 "$SRC/runit-1" "$PKG/etc/runit/1" + install -m755 "$SRC/runit-2" "$PKG/etc/runit/2" + install -m755 "$SRC/runit-3" "$PKG/etc/runit/3" + install -m755 "$SRC/ctrlaltdel" "$PKG/etc/runit/" + + # User-customizable rc scripts go in /etc/ + install -m755 "$SRC/rc.local" "$PKG/etc/" + install -m755 "$SRC/rc.shutdown" "$PKG/etc/" + + ln -s "/etc/runit/runsvdir/default" "$PKG/etc/runit/runsvdir/current" + + # Create agetty services for tty1-6 + for i in 1 2 3 4 5 6; do + svdir="$PKG/etc/sv/agetty-tty$i" + install -d "$svdir" + + if [ "$i" -eq 1 ]; then + printf '#!/bin/sh\nPATH=/bin:/sbin\nexec setsid agetty --noclear tty%s 38400 linux\n' "$i" > "$svdir/run" + else + printf '#!/bin/sh\nPATH=/bin:/sbin\nexec setsid agetty tty%s 38400 linux\n' "$i" > "$svdir/run" + fi + chmod 755 "$svdir/run" + + printf '#!/bin/sh\nPATH=/bin:/sbin\nexec utmpset -w tty%s\n' "$i" > "$svdir/finish" + chmod 755 "$svdir/finish" + + ln -s "/etc/sv/agetty-tty$i" "$PKG/etc/runit/runsvdir/default/" + ln -s "/etc/sv/agetty-tty$i" "$PKG/service/" + done + + # Serial getty -- shipped but deliberately NOT linked into + # default/ or /service/. A headless install (VPS, `qemu + # -nographic`) has no other console and needs it; a laptop with a + # registered but unconnected UART does not, and a getty spawning + # into a dead port is worse than no getty at all. Enable with: + # + # ln -s /etc/sv/agetty-ttyS0 /service/ + # + # ttyS0 must also be in /etc/securetty, or login refuses root there + # even with autologin: agetty execs `login -f root`, which skips the + # password but still consults securetty. + # + # The guard matters because a run script that exits immediately + # respawns forever, and on hardware with no UART the device node may + # not exist at all -- enabling this on the wrong machine would + # otherwise give a silent one-per-second fork loop. + # + # 115200 is what every provider's serial console uses. vt100 rather + # than linux: a serial client is not a Linux VT, and claiming + # otherwise breaks arrow keys and line drawing. + svdir="$PKG/etc/sv/agetty-ttyS0" + install -d "$svdir" + printf '#!/bin/sh\nPATH=/bin:/sbin\n[ -c /dev/ttyS0 ] || exec sleep 3600\nexec setsid agetty --noclear ttyS0 115200 vt100\n' > "$svdir/run" + chmod 755 "$svdir/run" + + printf '#!/bin/sh\nPATH=/bin:/sbin\nexec utmpset -w ttyS0\n' > "$svdir/finish" + chmod 755 "$svdir/finish" + + # Build and install pause(1) + ${CC:-cc} ${CFLAGS:--O2 -Wall} -o "$SRC/pause" "$SRC/pause.c" + install -m755 "$SRC/pause" "$PKG/sbin/" + install -d "$PKG/usr/share/man/man1" + install -m644 "$SRC/pause.1" "$PKG/usr/share/man/man1/" + + # Create sulogin service for single-user mode + sulogindir="$PKG/etc/sv/sulogin" + install -d "$sulogindir" + printf '#!/bin/sh\nPATH=/bin:/sbin\n[ -r conf ] && . ./conf\nread -r tty < /sys/class/tty/console/active\ntty="/dev/${tty##* }"\nexec setsid sulogin ${OPTS:=-p} < "$tty" > "$tty" 2>&1\n' > "$sulogindir/run" + chmod 755 "$sulogindir/run" + ln -s "/etc/sv/sulogin" "$PKG/etc/runit/runsvdir/single/" +} + +signify() { + untrusted comment: public key + RWTZ9IduCSQ/mL8337TEUinPwT92xFEUpD92hkS7IxcOnzTt9QdpohT3 +} + +# vim: filetype=sh diff --git a/core/runit/clearmem.patch b/core/runit/clearmem.patch new file mode 100644 index 0000000..c244c81 --- /dev/null +++ b/core/runit/clearmem.patch @@ -0,0 +1,18 @@ +--- a/src/svlogd.c ++++ b/src/svlogd.c +@@ -8,6 +8,7 @@ + #include <dirent.h> + #include <unistd.h> + #include <stdio.h> ++#include <string.h> + #include "pmatch.h" + #include "fmt_ptime.h" + #include "alloc.h" +@@ -706,6 +707,7 @@ int main(int argc, char **argv) { + coe(fdwdir); + dir =(struct logdir*)alloc(dirn *sizeof(struct logdir)); + if (! dir) die_nomem(); ++ memset(dir, 0, dirn * sizeof(struct logdir)); + for (i =0; i < dirn; ++i) { + dir[i].fddir =-1; dir[i].fdcur =-1; + dir[i].btmp =(char*)alloc(buflen *sizeof(char)); diff --git a/core/runit/ctrlaltdel b/core/runit/ctrlaltdel new file mode 100644 index 0000000..f4c2b65 --- /dev/null +++ b/core/runit/ctrlaltdel @@ -0,0 +1,13 @@ +#!/bin/sh +# /etc/runit/ctrlaltdel - Handle Ctrl+Alt+Del + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH + +touch /etc/runit/reboot +chmod 100 /etc/runit/reboot + +touch /etc/runit/stopit +chmod 100 /etc/runit/stopit + +echo 'System is going down NOW!' | wall 2>/dev/null diff --git a/core/runit/pause.1 b/core/runit/pause.1 new file mode 100644 index 0000000..1e56f20 --- /dev/null +++ b/core/runit/pause.1 @@ -0,0 +1,39 @@ +.Dd September 27, 2012 +.Dt PAUSE 1 +.Os Linux +.Sh NAME +.Nm pause +.Nd don't exit, efficiently +.Sh SYNOPSIS +.Nm pause +.Sh DESCRIPTION +.Nm pause +waits to be terminated by a signal. +It can be used when service supervision is used but there is no +long-running program to supervise. +.Nm pause +uses minimal system resources. +.Sh EXAMPLES +Setting up a static IP address with +.Xr plugsv 8 . +.Pp +.Pa /etc/netsv/eth0/run : +.Bd -literal -offset indent +#!/bin/sh +ip link set eth0 up +ip addr add 192.0.2.1/24 dev eth0 +exec pause +.Ed +.Pp +.Pa /etc/netsv/eth0/finish : +.Bd -literal -offset indent +#!/bin/sh +ip addr del 192.0.2.1/24 dev eth0 +ip link set eth0 down +.Ed +.Sh SEE ALSO +.Xr sleep 1 , +.Xr pause 2 +.Sh AUTHOR +.An Leah Neukirchen , +.Mt leah@vuxu.org . diff --git a/core/runit/pause.c b/core/runit/pause.c new file mode 100644 index 0000000..4825df6 --- /dev/null +++ b/core/runit/pause.c @@ -0,0 +1,20 @@ +#include <unistd.h> +#include <signal.h> + +static void +nop(int sig) +{ +} + +int +main() +{ + signal(SIGTERM, nop); + signal(SIGINT, nop); + signal(SIGHUP, SIG_IGN); + + pause(); + + return 0; +} + diff --git a/core/runit/rc.local b/core/runit/rc.local new file mode 100644 index 0000000..01a630b --- /dev/null +++ b/core/runit/rc.local @@ -0,0 +1,13 @@ +#!/bin/sh +# +# /etc/rc.local - Local startup commands +# + +# Run scripts in /etc/boot.d if present +if [ -d /etc/boot.d ]; then + for script in /etc/boot.d/*; do + [ -x "$script" ] && "$script" + done +fi + +# End of file diff --git a/core/runit/rc.shutdown b/core/runit/rc.shutdown new file mode 100644 index 0000000..a988c09 --- /dev/null +++ b/core/runit/rc.shutdown @@ -0,0 +1,8 @@ +#!/bin/sh +# +# /etc/rc.shutdown - Local shutdown commands +# + +# Add custom shutdown tasks here + +# End of file diff --git a/core/runit/runit-1 b/core/runit/runit-1 new file mode 100644 index 0000000..bff256b --- /dev/null +++ b/core/runit/runit-1 @@ -0,0 +1,172 @@ +#!/bin/sh +# /etc/runit/1 - rawnix system boot + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH + +msg() { + printf '\033[1m%s\033[0m\n' "$1" +} + +err() { + printf '\033[1;31m%s\033[0m\n' "$1" >&2 +} + +emergency_shell() { + err "Dropping to emergency shell. Type 'exit' to reboot." + sulogin -p + printf '%s\n' "Rebooting..." + umount -a -r + mount -o remount,ro / + reboot -f + exit 0 +} + +printf '%s\n' "rawnix is starting..." + +msg "Mounting /proc..." +mountpoint -q /proc || mount -t proc proc /proc + +msg "Mounting /sys..." +mountpoint -q /sys || mount -t sysfs sysfs /sys + +msg "Mounting /run..." +mountpoint -q /run || mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs /run + +msg "Mounting /dev..." +if ! mountpoint -q /dev; then + mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev +else + mount -o remount,mode=0755,nosuid devtmpfs /dev +fi + +msg "Mounting /dev/pts..." +mkdir -m 755 -p /dev/pts +mountpoint -q /dev/pts || mount -t devpts -o gid=tty,mode=0620,noexec,nosuid devpts /dev/pts + +msg "Mounting /dev/shm..." +mkdir -m 1777 -p /dev/shm +mountpoint -q /dev/shm || mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm + +msg "Mounting cgroups v2..." +if ! mountpoint -q /sys/fs/cgroup; then + mount -t cgroup2 none /sys/fs/cgroup 2>/dev/null || + err "cgroup2 mount failed - containers will not work" +fi + +# Bootstrap udevd for coldplug; sv/udevd takes over in stage 2 +msg "Starting udevd..." +if udevd --daemon 2>/dev/null; then + msg "Triggering udev coldplug..." + udevadm trigger --type=subsystems --action=add + udevadm trigger --type=devices --action=add + + msg "Waiting for udev to settle..." + udevadm settle --timeout=30 || err "Timeout waiting for udev events" +else + err "udevd not available - continuing without hotplug" +fi + +msg "Bringing up loopback..." +ip addr add 127.0.0.1/8 dev lo 2>/dev/null +ip link set lo up 2>/dev/null + +# LUKS volumes. The root volume is not here -- the initramfs opened it +# before this script existed. These are the extras: /home, data disks. +# +# The file is read on fd 3, not stdin. With `done < /etc/crypttab` the +# passphrase prompt for a keyless entry reads the *next line of the +# crypttab* instead of the console: the volume fails to open with no +# indication why, and the line it ate is never processed. +if command -v cryptsetup >/dev/null 2>&1 && [ -r /etc/crypttab ]; then + msg "Opening LUKS volumes..." + while read -r name device key opts <&3; do + case "$name" in ''|\#*) continue ;; esac + case ",$opts," in *,noauto,*) continue ;; esac + [ -n "$device" ] || { err "crypttab: $name has no device"; continue; } + [ -e "/dev/mapper/$name" ] && continue + + case "$device" in + UUID=*|PARTUUID=*|LABEL=*) + _d=$(blkid -t "$device" -o device 2>/dev/null | head -1) + [ -n "$_d" ] || { err "crypttab: $name: no device for $device"; continue; } + device=$_d ;; + esac + + case "$key" in + ''|none|-) cryptsetup open "$device" "$name" ;; + *) cryptsetup open --key-file "$key" "$device" "$name" ;; + esac || err "Failed to open LUKS volume: $name" + done 3< /etc/crypttab +fi + +msg "Remounting / read-only..." +mount -o remount,ro / + +if [ -f /forcefsck ]; then + msg "Forced filesystem check..." + FORCEFSCK="-f" +fi + +msg "Checking filesystems..." +fsck $FORCEFSCK -A -T -C -a 2>/dev/null +if [ $? -gt 1 ]; then + err "Filesystem check failed!" + err "Please repair manually. Root is mounted read-only." + err "To remount read-write: mount -n -o remount,rw /" + emergency_shell +fi + +msg "Remounting / read-write..." +mount -o remount,rw / + +msg "Seeding urandom..." +if [ -f /var/lib/random/seed ]; then + cat /var/lib/random/seed >/dev/urandom + rm -f /var/lib/random/seed +fi + +msg "Setting shared mount propagation..." +mount --make-rshared / + +msg "Activating swap..." +swapon -a 2>/dev/null + +msg "Mounting local filesystems..." +mount -a -O no_netdev 2>/dev/null || emergency_shell + +mkdir -m 0755 -p /run/user +mkdir -m 1777 -p /run/lock +: >/run/utmp + +rm -rf /forcefsck /fastboot /etc/nologin /etc/shutdownpid 2>/dev/null +rm -rf /tmp/* /tmp/.* 2>/dev/null + +if [ -x /etc/rc.modules ]; then + msg "Loading kernel modules..." + /etc/rc.modules +fi + +if [ -f /etc/sysctl.conf ]; then + msg "Setting kernel parameters..." + sysctl -p >/dev/null 2>&1 +fi + +if [ -f /etc/hostname ]; then + msg "Setting hostname: $(cat /etc/hostname)" + hostname "$(cat /etc/hostname)" +fi + +hwclock --hctosys 2>/dev/null + +[ -x /etc/rc.local ] && /etc/rc.local + +touch /etc/runit/stopit +chmod 100 /etc/runit/stopit +touch /etc/runit/reboot +chmod 100 /etc/runit/reboot + +dmesg > /var/log/boot.log 2>/dev/null + +msg "Boot complete." +exit 0 diff --git a/core/runit/runit-2 b/core/runit/runit-2 new file mode 100644 index 0000000..e36d340 --- /dev/null +++ b/core/runit/runit-2 @@ -0,0 +1,22 @@ +#!/bin/sh +# /etc/runit/2 - Start service supervision + +PATH=/bin:/sbin:/usr/bin:/usr/sbin +export PATH + +runlevel=default + +for arg in $(cat /proc/cmdline); do + if [ -d "/etc/runit/runsvdir/$arg" ]; then + printf "Runlevel: %s\n" "$arg" + runlevel="$arg" + break + fi +done + +runsvchdir "$runlevel" || { + printf "Warning: runlevel '%s' failed, falling back to 'default'\n" "$runlevel" + [ "$runlevel" != default ] && runsvchdir default +} + +exec runsvdir -P /service 'log: ........................................................................................................' diff --git a/core/runit/runit-3 b/core/runit/runit-3 new file mode 100644 index 0000000..f4747df --- /dev/null +++ b/core/runit/runit-3 @@ -0,0 +1,64 @@ +#!/bin/sh +# /etc/runit/3 - rawnix system shutdown + +exec 2>&1 +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH +stty onlcr 2>/dev/null + +printf '\nrawnix is shutting down...\n\n' + +# Close SSH sessions while the network is still up, so clients get a FIN +# instead of hanging until TCP timeout. sv only stops the sshd listener; +# each login is a separate sshd-session process (OpenSSH >= 9.8). +if pkill -TERM -x sshd-session 2>/dev/null; then + printf 'Closing SSH sessions...\n' + sleep 1 +fi + +printf 'Stopping services...\n' +sv force-stop /service/* 2>/dev/null +sv exit /service/* 2>/dev/null + +[ -x /etc/rc.shutdown ] && /etc/rc.shutdown + +printf 'Saving system clock...\n' +hwclock --systohc 2>/dev/null + +printf 'Saving urandom seed...\n' +mkdir -p /var/lib/random +chmod 700 /var/lib/random +dd if=/dev/urandom of=/var/lib/random/seed bs=512 count=1 2>/dev/null +chmod 600 /var/lib/random/seed + +printf 'Sending TERM signal...\n' +kill -TERM -1 2>/dev/null +sleep 2 + +printf 'Sending KILL signal...\n' +kill -KILL -1 2>/dev/null +sleep 1 + +printf 'Unmounting filesystems...\n' +sync +umount -a -d -r -t nosysfs,noproc,nodevtmpfs,notmpfs 2>/dev/null + +printf 'Closing LUKS volumes...\n' +# Only what stage 1 opened. Root is absent from crypttab by design, so +# the mapping the filesystem is still running from is never touched. +if command -v cryptsetup >/dev/null 2>&1 && [ -r /etc/crypttab ]; then + while read -r name _rest <&3; do + case "$name" in ''|\#*) continue ;; esac + [ -e "/dev/mapper/$name" ] || continue + cryptsetup close "$name" 2>/dev/null + done 3< /etc/crypttab +fi + +printf 'Remounting root read-only...\n' +sync +mount -o remount,ro / 2>/dev/null + +swapoff -a 2>/dev/null + +printf 'Shutdown complete.\n' +exit 0 |
