README.md (3419 bytes)
1 [blog post](https://therealtruex.com/posts/Using-an-init-system-for-many-instances-of-simple-programs) 2 [feed/newsletter](https://therealtruex.com/mailing-list) 3 4 Using OpenRC runlevels to have lots of instances of simple (network) 5 programs like quark for multiple http serving locally or [ii](https://tools.suckless.org/ii/) (or [sic](https://tools.suckless.org/sic/)) 6 for IRC server connections. 7 8 To keep programs simple, they should not do the same process for 9 unrelated uses. It is much more complicated to configure and manage 10 multiple webservers in the same process (like how nginx does it) than 11 just one. Init systems are designed to manage processes, and should be 12 used instead. Do one thing etc. etc. 13 14 This is how to use the OpenRC runlevels for quark and ii runlevels 15 as examples. 16 17 ## The Tree (on my machine) 18 19 ```sh 20 /etc/runlevels 21 ├── boot 22 │ └── ... 23 ├── default 24 │ └── ... 25 ├── irc-base 26 │ ├── oftc -> /etc/init.d/oftc 27 │ ├── liberachat -> /etc/init.d/liberachat 28 │ └── ... 29 ├── net-base 30 │ ├── default -> ../default 31 │ └── quark -> ../quark 32 ├── net-offline 33 │ ├── default -> ../default 34 │ └── net-base -> ../net-base 35 ├── net-dns 36 │ ├── dnscrypt-proxy -> /etc/init.d/dnscrypt-proxy 37 │ └── unbound -> /etc/init.d/unbound 38 ├── net-wifi 39 │ ├── dhcpcd -> /etc/init.d/dhcpcd 40 │ ├── net-base -> /etc/runlevels/net-base 41 │ ├── net-dns -> /etc/runlevels/net-dns 42 │ └── wpa_supplicant -> /etc/init.d/wpa_supplicant 43 ├── net-wifi-irc 44 │ ├── irc-base -> ../irc-base 45 │ └── net-wifi -> ../net-wifi 46 ├── quark 47 │ ├── quark-docs -> /etc/init.d/quark-docs 48 │ ├── quark-equwal -> /etc/init.d/quark-equwal 49 │ └── ... 50 ├── shutdown 51 │ └── ... 52 └── sysinit 53 └── ... 54 ``` 55 as you can see, IRC is connected after the real internet on wifi 56 (net-wifi), but quark runs on any network runlevel using net-base. 57 58 ## How To: 59 60 OpenRC has its own commands for making the runlevels, but I find them 61 confusing. Let's just edit the files. 62 63 ```sh 64 # make runlevel 65 mkdir /etc/runlevels/quark 66 # add services (as many as needed) 67 ln -s /etc/int.d/quark-whatever /etc/runlevels/quark 68 # add runlevel to parent 69 ln -s /etc/runlevels/default /etc/runlevels/quark 70 # Reload since openrc is in default 71 openrc default 72 ``` 73 74 That works, but what about for networked IRC on a custom networking runlevel? Just add it to the networking runlevel. 75 ```sh 76 # (first, make a network runlevel that contains default! Without default the system will crash, obviously.) 77 mkdir /etc/runlevels/net-wifi 78 ln -s /etc/runlevels/net-wifi /etc/runlevels/default 79 ln -s /etc/init.d/wpa_supplicant /etc/runlevels/net-wifi 80 # etc. 81 # Now add the irc-base to the network runlevel 82 mkdir /etc/runlevels/irc-base 83 ln -s /etc/init.d/liberachat irc-base 84 ln -s /etc/init.d/oftc irc-base 85 ln -s /etc/runlevels/irc-base /etc/runlevels/net-wifi 86 openrc net-wifi 87 ``` 88 89 ## Tool: restart-runlevel 90 Openrc wants switch the whole stack `openrc runlevel` so I made a little 91 tool to just restart a specific runlevel. Nice for debugging. 92 93 ```sh 94 #!/bin/bash 95 96 for link in /etc/runlevels/${1}/* 97 do [[ -L "$link" && "$(readlink "$link")" == /etc/init.d/* ]] && \ 98 rc-service "$(basename "$link")" restart 99 done 100 ```