# sysconfig — Misc one-time boot configuration (grab-bag) [service] name = "sysconfig" description = "Misc boot config: core, dump, keymap, scheduler, rctl, tmp cleanup" type = "oneshot" [exec] start = "/etc/zyginit/services/sysconfig/start.sh" [dependencies] requires = ["filesystem"] [restart] on = "never" #!/bin/zsh # sysconfig — misc one-time boot configuration # # Each command is deliberately wrapped in || true for commands where a # specific failure (no device present, no config file, etc.) is acceptable. # A truly mandatory setting would be its own service. # Use absolute paths for every external command — first-boot-of-fresh-deploy # can transiently fail bare-command lookups under I/O pressure (devfsadm + # reconfigure + parallel service start). See [[zyginit-service-empty-path]] # for the investigation that disproved the original "empty PATH" theory. # # The remaining failure mode for this script (sysconfig exit=-1 still # observed on 2026-06-08 fresh-deploy boots, with an empty service log) # is suspected to be inside coreadm/dumpadm/dispadmin/rctladm: they # exec() internal helpers that themselves do PATH-based lookup, and if # any of those misses, the parent hangs and zyginit eventually SIGKILLs # the oneshot (-> exit=-1). Diagnostic markers below pin down which # command was running when zyginit's timeout fired. PATH=/usr/sbin:/usr/bin:/sbin:/bin export PATH set -u # Note: NOT using set -e — individual failures are handled per-command. # --- Diagnostic step markers ------------------------------------------ # zyginit captures stderr to /var/log/zyginit/sysconfig.log. Emit a # timestamped marker before and after each suspect command so the LAST # marker in the log identifies the hang point on a fresh-deploy failure. # Cheap: ~14 lines on a happy-path boot. # Builtin `print` resolves at shell startup (no external lookup); /bin/date # is an absolute external path so it can't lose to a transient PATH race. mark() { print -r -- ">>> $(/bin/date +%T.%N) $*" >&2; } # Core files: enable per-process pattern, apply config from /etc/coreadm.conf mark "coreadm --init" /usr/bin/coreadm --init 2>/dev/null || true mark "coreadm done" # Crash dump: use configured dump device (set once per system, may be a zvol) mark "dumpadm -u" /sbin/dumpadm -u 2>/dev/null || true mark "dumpadm done" # Keyboard map: -i reads layout from /etc/default/kbd (non-interactive). # -s would prompt the operator at the console, blocking boot. if [[ -x /usr/bin/kbd ]]; then mark "kbd -i" /usr/bin/kbd -i 2>/dev/null || true mark "kbd done" fi # Scheduler default dispatch table (TS = time-share, usual default) mark "dispadmin -d TS" /usr/sbin/dispadmin -d TS 2>/dev/null || true mark "dispadmin done" # Resource controls (/etc/project-based rctls) — reload into kernel if [[ -x /usr/sbin/rctladm ]]; then mark "rctladm -u" /usr/sbin/rctladm -u 2>/dev/null || true mark "rctladm done" fi # Clean up /tmp on boot (tmpfs is usually empty after reboot but defend) if [[ -d /tmp ]]; then mark "tmp cleanup" /usr/bin/find /tmp -mindepth 1 -maxdepth 1 -exec /bin/rm -rf {} + 2>/dev/null || true mark "tmp cleanup done" fi # rpcbind needs /var/run/rpc_door (mode 1777) to exist before it starts # (matches the SMF rpc-bind method). Create it here so it's ready by the # time tier 4 brings up rpcbind. mark "rpc_door" /bin/mkdir -p /var/run/rpc_door /bin/chmod 1777 /var/run/rpc_door mark "exit 0" exit 0