README (11256B)
1 RAdix iniT Suite 2 ================ 3 4 RATS is an init suite forked from sinit to extend the features 5 so it could be used standalone. 6 7 Why? 8 ---- 9 Even though sinit is pretty good, unfortunately, I want service 10 supervision, dependency management, logging, etc all in one instead 11 of using separate utilities bootstrapped together. My old setup was 12 using sinit + nitro with a bunch of shell scripting to handle things 13 I felt that the init is okay to do. 14 15 General boot process 16 -------------------- 17 kernel -> init=/sbin/origo 18 |- origo mounts /proc /sys /dev /dev/pts 19 |- origo runs /etc/rc.boot (which sources /etc/rc.local) 20 |- origo spawns serva 21 |- serva scans /etc/ssv/{boot,default,...} 22 |- serva starts services in (stage, name) alphabetical order 23 |- serva listens on /run/serva.sock 24 |- origo enters signal loop (sigwait) 25 * SIGCHLD - reap zombies, respawn serva if dead 26 * SIGUSR1 - poweroff 27 * SIGUSR2 - reboot 28 * SIGINT - reboot (CtrlAltDel) 29 * SIGTERM - single-user (rc.single or /bin/sh) 30 31 32 Project Overview 33 ================ 34 35 origo: PID 1 - minimal init. 36 ---------------------------- 37 Mounts /proc /sys /dev /dev/pts /dev/shm, runs /etc/rc.boot, 38 spawns+respawns serva, handles poweroff/reboot/single-user. 39 Signal mapping (same as sinit): 40 - SIGINT -> reboot (CtrlAltDel) 41 - SIGUSR1 -> poweroff 42 - SIGUSR2 -> reboot 43 - SIGTERM -> single-user 44 45 NOTE: origo won't mount `/run` nor `/tmp` to tmpfs because they are 46 optional in most setups. For users who want to mount these at boot, 47 you can edit your `/etc/fstab` to do so: This applies to those who 48 install the optional example rc.boot script but you can do so yourself 49 by invoking `mount -a` in your own rc.boot scripts to have your system 50 respect `/etc/fstab`. 51 52 origo will do the following on shutdown/reboot: 53 1. stopping serva (which stops all supervised services) 54 2. kills all remaining processes 55 3. remount the root read-only 56 4. syncs the fs 57 58 serva: a simple service supervisor. 59 ----------------------------------- 60 Scans /etc/ssv/ for stage directories, forks run per service in 61 (stage, name) alphabetical order, restarts with backoff. 62 63 It is entirely possible to use either numerical or words for stages 64 if desired. 65 66 Pipes stdout/stderr to log (logger) if present (has to be executable). 67 Listens on /run/serva.sock for svc control commands. 68 69 Layout: 70 /etc/ssv/ 71 <stage>/ stage directory (e.g. boot, default) 72 <service>/ 73 run run executable (required; $1 = @-arg) 74 log logger executable (optional) 75 once touch-file: run once, don't supervise 76 noreset touch-file: run but don't restart on exit 77 down touch-file: don't auto-start; svc -u works 78 need/<name> hard dep: wait for <name> to be running 79 after/<name> soft hint: start after <name> if possible 80 81 Symlink templates (names ending with @ are skipped): 82 /etc/ssv/boot/tty@/ template directory 83 /etc/ssv/boot/tty@tty1 symlink -> tty@; "tty1" passed as $1 84 85 Service identifiers for svc: 86 sshd first match across all stages 87 boot/sshd specific stage + service 88 89 90 NOTE: to the logger, serva sets the following environment variables: 91 - SVC_NAME : Service name (e.g. sshd) 92 - SVC_STAGE : Stage name (e.g. default) 93 - SVC_ARG : @ -arg if applicable (e.g. tty1 if getty@tty1) 94 95 you can use these in the log script: 96 97 #!/bin/sh 98 exec slog -d "/var/log/$SVC_NAME-$SVC_ARG" 99 100 More information on slog later. 101 102 This design makes serva logger-agnostic, you are free to use whatever you like 103 as long as you can pipe the output into your logger of choice. 104 105 svc: control client for serva. 106 ------------------------------ 107 Talks to /run/serva.sock over a Unix socket. 108 109 usage: svc [-udrkts] [-a] [name...] 110 -u bring up -d bring down -r restart 111 -k kill (SIGKILL) -t terminate -s status (optionally per-service) 112 -a all services (with -u or -d) 113 114 Multiple names are handled one at a time. svc exits with status 1 if a 115 request fails or serva returns ERR, and status 2 if closing stdout fails. 116 117 slog: simple logging daemon. 118 ---------------------------- 119 Reads stdin, writes to <dir>/current, rotates on size. Existing current 120 file contents count toward the threshold. Rotation happens after a read 121 chunk is written, so a file may exceed the threshold by up to 4095 bytes. 122 Rotated files: <dir>/0, <dir>/1, ..., <dir>/<n-1> 123 124 example: 125 /var/log/sshd/current - active log 126 /var/log/sshd/0 - most recent rotation 127 /var/log/sshd/1 128 ... 129 /var/log/sshd/9 - oldest, deleted on next rotation 130 131 usage: slog [-d dir] [-s bytes] [-n count] 132 -d log directory (default: .) 133 -s max size per file in bytes (default: 1048576 = 1MB) 134 -n max number of rotated files (default: 10) 135 136 slog works perfectly fine outside of serva: 137 138 some-daemon 2>&1 | slog -d /var/log/some-daemon -s 524288 -n 5 139 140 What does slog NOT do: 141 - No syslog protocol. It reads stdin, writes files. If you need syslog 142 (/dev/log socket), run a real syslogd as a service. 143 - No timestamps. The service's run script should add them if needed 144 (e.g. pipe throughts or use a logger that adds timestamps). Or modify 145 slog to prepend timestamps, it's a 5-line change. Most daemons already 146 provide timestamps anyways. 147 - No compression. Rotated files are plain text. Add a cron job to gzip 148 them if needed. 149 150 151 Requirements 152 ============ 153 154 cc POSIX.1-2008-compliant C compiler (pcc, etc) 155 make POSIX make (aruu make, pdpmake, gmake, bmake) 156 157 158 Portability across UNIX systems 159 ============================== 160 161 origo currently uses Linux mount and reboot interfaces. The example rc 162 scripts also use Linux utilities. serva and svc target POSIX.1-2008; 163 serva additionally uses XSI realpath(). Other UNIX systems have not been 164 tested. 165 166 Control socket access currently relies on pathname permissions. Linux 167 enforces these permissions, but POSIX does not require this. Supporting 168 another UNIX system requires checking its socket access rules or adding 169 peer credential checks. See [unix(7)](https://man7.org/linux/man-pages/man7/unix.7.html). 170 171 172 Building 173 ======== 174 175 Building this project is trivial, to build the suite: 176 177 make 178 179 Configuration is in config.mk, you can override compile flags via make. 180 181 NOTE: by default RATS will try to build statically, you can override this by passing `LDFLAGS=`. 182 Basically, just make LDFLAGS empty. 183 184 Run the integration tests with: 185 186 make check 187 188 Tests use a separate directory under tests/sandbox/ for each run and 189 leave their logs there. The tracked service fixtures are copied into it. 190 191 192 Installation 193 ============ 194 195 Follows regular make install conventions ($DESTDIR and $PREFIX). 196 Additionally, you are able to set SBIN_DIR and BIN_DIR (/sbin, /bin). 197 198 make install # will install to /usr/local by default 199 200 Install example rc.* files along with poweroff/reboot commands: 201 202 make install-files 203 204 205 Installed Files 206 =============== 207 208 Below are the executables that are installed when invoking `make install`, you are expected 209 to provide your own rc.* scripts, unless you install the optional example files. 210 211 $(PREFIX)/sbin/origo # PID 1 212 $(PREFIX)/sbin/serva # supervisor 213 $(PREFIX)/bin/svc # control client 214 $(PREFIX)/bin/slog # logging daemon 215 216 NOTE: sbin/bin can be changed via the make envs `$BIN_DIR` and `$SBIN_DIR`; these are for 217 systems (me) that don't have an sbin, or prefer some other binary directory. 218 219 Optional Installed Files 220 ------------------------ 221 All files below are example files that are installed when invoking `make install-files`, 222 it's entirely possible to run a system with these example files with little to no changes. 223 224 /etc/rc.boot # (REQUIRED) first run before serva 225 /etc/rc.shutdown # (REQUIRED) run before full shutdown 226 227 /etc/rc.local # (optional) rc.boot should source this 228 /etc/rc.single # (optional) single-user script, else origo will run /bin/sh 229 230 NOTE: Below are shell scripts. 231 232 $(PREFIX)/bin/poweroff # sends SIGUSR1 to PID1 233 $(PREFIX)/bin/reboot # sends SIGINT to PID1 234 235 236 Source Layout 237 ============= 238 239 config.mk build configuration 240 Makefile posix (should work with any *competent* make impl) 241 tests/ 242 run.sh run this to test init suite (currently only serva/svc) 243 Makefile build serva/svc test binaries 244 ssv/* dummy ssv 245 sandbox/ temporary test state (not tracked) 246 files/ 247 rc.* optional example configurations 248 bin/* optional scripts to use along with RATS 249 *.c c files 250 *.h headers 251 252 253 TODO 254 ==== 255 256 manpages - someone else needs to do this or I'm going to die learning troff 257 serva -- primarily with handling errors coming from the services itself, 258 | or at least returning ERR when that's the case. 259 | 260 |- svc -s now reports per-service run count, uptime, and last 261 exit status/signal; svc -s <name> focuses a single service. 262 Streaming service logs through svc is still open. 263 user - still thinking on this one, I think it would be interesting to 264 have something like dinit. It might be an overreach for this project 265 but it can be used for "bloated" setups where users need dbus-session, 266 pipewire, etc. to run when booted. 267 268 269 Contribution 270 ============ 271 272 Sending patches is trivial, the main site of development is on the 273 [stagit repo](https://git.daat.foo/rats/log.html). 274 This means that all patches aren't sent via PRs on any of the mirrors. 275 276 Run a quick `git format-patch HEAD~1` and send to *cowmonk@based.pt* with the 277 subject head of `[PATCH] RATS`. Consider reading the manpages of `git-send-email` 278 if you are interested in moving towards email for development. 279 280 I *strongly* suggest pgp encrypting your email, in which case my public keys can be 281 found on `keys.openpgp.org` or here: 282 283 -----BEGIN PGP PUBLIC KEY BLOCK----- 284 Comment: 52B0 852C 5A4C 823C FAB7 420A 2F73 9BCA BDD5 B880 285 Comment: cowmonk@based.pt 286 287 xjMEaSJi8xYJKwYBBAHaRw8BAQdAEVP64bLVXCxZYH5rItmtvThKyTrRZ4HFCZ42 288 IqFx+crNEGNvd21vbmtAYmFzZWQucHTCiQQTFggAGgQLCQgHAhUIAhYBAhkABYJp 289 ImLzAp4BApsDACEJEC9zm8q91biAFiEEUrCFLFpMgjz6t0IKL3Obyr3VuIBOEQEA 290 +gIa9t3yKL3FAHg5VT2xV8M2VdLf1ZqaFlCPyGhXBZsA+QGGstK6+YsUbmP+H6I5 291 r4AgLawGeB9IH7WC0w4dhTsKzjgEaSJi8xIKKwYBBAGXVQEFAQEHQMsmen1ddl9a 292 ddXu4ktm8BATTlEy2k4zMzo6RnyRB+d4AwEIB8J4BBgWCAAJBYJpImLzApsMACEJ 293 EC9zm8q91biAFiEEUrCFLFpMgjz6t0IKL3Obyr3VuIA9AQD/S/EL51hMSBI35Lr3 294 RjuNFtqnlgYpfkMxgPvp2bWRY60A/2NhDRNUjY2wA4+mESlCIf94FVvqcfclnSZU 295 A7wM/YAB 296 =nZZp 297 -----END PGP PUBLIC KEY BLOCK----- 298 299 300 LICENSE 301 ======= 302 303 See ./LICENSE for details. 304 305 Portions of this software are partially based on code written by Aruu authors and 306 contributors, with portions within itself derived from various BSD/MIT-licensed 307 open source projects.