# What termrc and cpurc actually contain Taken from reading both scripts and from `ps` on a booted machine, which is the more reliable of the two — the scripts are full of conditionals that never fire. Kernel processes (0K, `Wakeme`/`Idle`: `pager`, `alarm`, `etherread4`, `iasata`, …) are not in scope. They are not started by anything in userspace. ## Adopted — init can stop these but never starts them Started by `bootrc`, before init exists. No `exec=`, `adopt=yes`, stop only. | what | evidence | how to stop it | |---|---|---| | `hjfs` | pids 320–328, `/srv/hjfs.cmd` | `stop=write:/srv/hjfs.cmd:halt` | | `factotum` | pid 260, `/srv/factotum` | note | | `paqfs` | pid 8, serves the boot archive | note | `hjfs` is the one that must be stopped last, after everything using it. ## Base namespace — init does these directly, they are not services None of this survives as a service, because a service runs in its own namespace group and so cannot change anyone else's. - `for(i in P S f æ t L A J '$') bind -qa '#'^$i /dev` - `mount -qb /srv/cons /dev` - binding the `mntgen` channels onto `/n`, `/mnt`, `/mnt/exportfs` - `mount /srv/factotum /mnt/factotum` and the `bind -q` after it ## Services | service | evidence | ready | needs | notes | |---|---|---|---|---| | `slashn` | pid 11 | `srv:slashn` | | `mntgen` for `/n` | | `slashmnt` | pid 14 | `srv:slashmnt` | | `mntgen` for `/mnt` | | `mntexport` | pid 17 | `srv:mntexport` | | `mntgen` for `/mnt/exportfs` | | `kbdfs` | pids 70–74 | `exec` | | posts nothing in `/srv` | | `usbd` | pids 82–83 | `exec` | | from `nusbrc` | | `kb` | pids 91–92 | `exec` | `usbd` | from `nusbrc` | | `cs` | pid 372 | `srv:cs` | | | | `dns` | pid 446 | `srv:dns` | `cs` | | | `timesync` | pid 450 | `exec` | `dns` | needs a name to resolve | | `realemu` | pids 456–457 | `exec` | | vga real-mode calls | | `webfs` | pid 500 | `exec` | `dns` | | | `webcookies` | pid 497 | `exec` | | | | `plumber` | pids 503–504 | see below | | | | `ipconfig-ra6` | pid 439/440 | `exec` | | the lingering RA listener | Only on a machine that is meant to accept logins: | service | from | ready | needs | |---|---|---|---| | `listen` | `cpurc` | `exec` | `cs` | | `keyfs` | `cpurc`, auth branch | `srv:keyfs` | | | `authsrv` | `cpurc`, auth branch | `dial:tcp!*!567` | `keyfs` | ## Oneshots — `ready=exit` - `diskparts` - `swap` (only when `/dev/sd*/swap` exists) - `ip/ipconfig -h $sysname ether $ether` — the DHCP one, as opposed to the RA listener above, which stays - setting `/dev/sysname` - `screenrc` ## What simply disappears - **The `service=` branch itself.** `termrc` and `cpurc` are 80% identical: the same device binds, the same `mntgen` lines, the same `factotum` mount, the same `cs`/`dns`/`diskparts`/`swap`. The difference is which of two nearly identical scripts runs. - **The role detection block.** `cpurc` decides whether this machine is an authentication server by comparing `$sysname` against the `auth` attribute in ndb, and starts `keyfs` plus a different `listen` if it matches. That is the archetype logic, in one `if`. It becomes: is `keyfs` enabled or not. - **`serviced=` selection** — `/cfg/$sysname/service`, `/cfg/default/service`, `/rc/bin/service`, in that order. Replaced by `/lib/svc`. - **The `.local` and `/cfg/$sysname` hooks** — `cpurc.local`, `termrc.local`, `/cfg/$sysname/cpurc`, `/cfg/$sysname/cpustart`. Four hook points that exist because a shell script has no other way to be extended. A directory of service files does not need them. - **`rm -f /env/i`, `rm -f /env/disk`, `rm -f /env/ether /env/addrs /env/addr`** — these clean up after `for` loops and backquote assignments. They exist only because this is a shell script, and vanish with it. - **`NPROC`, `prompt`, `fn term%`** — shell configuration that has no business in system startup. Belongs in `profile`. - **`dontkill`** — a list of process names protected from `kill`. Worth revisiting rather than porting: with a supervisor that knows what it started, protecting things by name is the wrong shape. ## Two problems this turned up **`plumber`'s `/srv` name is dynamic.** It posts `/srv/plumb.glenda.502` — user and pid baked into the name. `ready=srv:name` cannot express that, and neither can `stop=write:...`. Options: allow a glob in `ready=srv:`, accept `ready=exec` and lose the liveness check, or treat it as a general escape and add `ready=file:pattern`. Unresolved, and it will not be the only such server. **`ipconfig` appears twice with different lifetimes.** One does DHCP and exits (a oneshot); the other listens for router advertisements and stays (a service). They are the same binary with different arguments, so they must be two service files with different names. Fine, but it means service name and program name cannot be assumed to match — which the current implementation already allows, since `svc=` and `exec=` are separate. ## Also worth noting There is no `aux/listen` running on this machine, because it booted as `service=terminal`. Every service above marked "only on a machine meant to accept logins" is absent purely because of one word in `plan9.ini` — which is the whole argument, visible in `ps`.