|
root / base / usr / src / zyginit / services / swap
swap Plain Text 84 lines 2.5 KB
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# swap — Enable swap devices from /etc/vfstab

[service]
name = "swap"
description = "Enable swap devices"
type = "oneshot"

[exec]
start = "/etc/zyginit/services/swap/start.sh"
stop = "/etc/zyginit/services/swap/stop.sh"

[runlevel]
# Useful in single-user mode for tmpfs backing and emergency repair tools
# that may want to spill memory.
mode = "always"

[dependencies]
requires = ["root-fs"]

[restart]
on = "never"
#!/bin/zsh
# swap start — enable swap devices listed in /etc/vfstab
#
# Race: zvol device nodes under /dev/zvol/dsk/<pool>/<vol> are created
# asynchronously after `zpool import`. The root pool is imported by the
# loader before zyginit runs, but the kernel still has to walk the
# config and create minor nodes via /etc/devices machinery. On a fresh
# alpha8 deploy (2026-05-29) the swap service ran ~40s before the zvol
# symlink existed, causing `swapadd` to fail with "No such file or
# directory" and bringing the service up as failed.
#
# Wait up to 30s for every swap entry's device path to appear before
# invoking swapadd. nawk reads /etc/vfstab and emits each fstype=swap
# device path.

set -e
set -u

# zyginit spawns services with an empty PATH.  /etc/zshenv sets one for
# interactive shells, but `#!/bin/zsh` scripts don't always pick it up,
# and the PATH= line below was *still* not enough on the 2026-06-03
# clean alpha8 deploy ("command not found: sleep" 8x in zygctl log swap)
# — likely because zyginit's spawn env wins after the script's own
# assignments somehow.  Use absolute paths for every external command so
# we never depend on PATH lookups inside zyginit-spawned scripts.
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH

waitfor() {
    local path=$1
    local tries=30
    while (( tries-- > 0 )); do
        [[ -e $path ]] && return 0
        /bin/sleep 1
    done
    /bin/echo "swap: device not ready after 30s: $path" >&2
    return 1
}

# Skip comment lines and the special `swap` tmpfs backing entry
# (fstype=swap, special=swap — used for /tmp).
/bin/nawk '/^[^#]/ && $4=="swap" && $1 != "swap" { print $1 }' /etc/vfstab |
while read dev; do
    waitfor "$dev" || exit 1
done

exec /sbin/swapadd
#!/bin/zsh
# swap stop — disable all swap devices before halt/reboot

set -e
set -u

# swap -l lists active entries with the device path in column 1
# (skipping the header line). Disable each.
if /sbin/swap -l >/dev/null 2>&1; then
    /sbin/swap -l | awk 'NR>1 {print $1}' | while read dev; do
        /sbin/swap -d "$dev" || true
    done
fi

exit 0