summaryrefslogtreecommitdiff
path: root/core/runit
diff options
context:
space:
mode:
Diffstat (limited to 'core/runit')
-rw-r--r--core/runit/.footprint70
-rw-r--r--core/runit/.signature15
-rw-r--r--core/runit/1155
-rw-r--r--core/runit/222
-rw-r--r--core/runit/354
-rw-r--r--core/runit/MAKEPKG141
-rw-r--r--core/runit/clearmem.patch18
-rw-r--r--core/runit/ctrlaltdel13
-rw-r--r--core/runit/pause.139
-rw-r--r--core/runit/pause.c20
-rw-r--r--core/runit/rc.local13
-rw-r--r--core/runit/rc.shutdown8
-rw-r--r--core/runit/runit-1172
-rw-r--r--core/runit/runit-222
-rw-r--r--core/runit/runit-364
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