feat(deploy): cgroup-v2 cpuset drop-ins pin system to core 0, game to rest

Computes NPROC at deploy time. Defaults LEFT4ME_SYSTEM_CPUS=0 and
LEFT4ME_GAME_CPUS=1-(NPROC-1). Single-core hosts skip cpuset writes
with a stderr warning unless an env var override is set. Spec:
docs/superpowers/specs/2026-05-09-l4d2-cpu-isolation-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mwiegand 2026-05-09 11:06:34 +02:00
parent c91c029c38
commit af3171102a
No known key found for this signature in database
2 changed files with 61 additions and 0 deletions

View file

@ -138,6 +138,34 @@ $sudo_cmd cp /opt/left4me/deploy/files/usr/local/lib/systemd/system/left4me-web.
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/lib/systemd/system/left4me-server@.service /usr/local/lib/systemd/system/left4me-server@.service
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/lib/systemd/system/l4d2-game.slice /usr/local/lib/systemd/system/l4d2-game.slice
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/lib/systemd/system/l4d2-build.slice /usr/local/lib/systemd/system/l4d2-build.slice
# CPU isolation via cgroup-v2 AllowedCPUs= drop-ins. Pin everything that
# isn't a live game server to core 0; give game servers cores 1..N-1.
# See docs/superpowers/specs/2026-05-09-l4d2-cpu-isolation-design.md.
NPROC=$(nproc)
SYSTEM_CPUS=${LEFT4ME_SYSTEM_CPUS:-0}
if [ "${LEFT4ME_GAME_CPUS+x}" = x ]; then
GAME_CPUS=$LEFT4ME_GAME_CPUS
else
GAME_CPUS="1-$((NPROC - 1))"
fi
if [ "$NPROC" -lt 2 ] && [ "${LEFT4ME_SYSTEM_CPUS+x}${LEFT4ME_GAME_CPUS+x}" = "" ]; then
printf 'left4me deploy: skipping CPU isolation (nproc=%s); cpuset drop-ins not written.\n' "$NPROC" >&2
else
for slice_drop_in in \
/etc/systemd/system/system.slice.d/99-left4me-cpuset.conf \
/etc/systemd/system/user.slice.d/99-left4me-cpuset.conf \
/etc/systemd/system/l4d2-build.slice.d/99-left4me-cpuset.conf; do
$sudo_cmd mkdir -p "$(dirname "$slice_drop_in")"
printf '[Slice]\nAllowedCPUs=%s\n' "$SYSTEM_CPUS" \
| $sudo_cmd install -m 0644 -o root -g root /dev/stdin "$slice_drop_in"
done
$sudo_cmd mkdir -p /etc/systemd/system/l4d2-game.slice.d
printf '[Slice]\nAllowedCPUs=%s\n' "$GAME_CPUS" \
| $sudo_cmd install -m 0644 -o root -g root /dev/stdin \
/etc/systemd/system/l4d2-game.slice.d/99-left4me-cpuset.conf
fi
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/libexec/left4me/left4me-systemctl /usr/local/libexec/left4me/left4me-systemctl
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/libexec/left4me/left4me-journalctl /usr/local/libexec/left4me/left4me-journalctl
$sudo_cmd cp /opt/left4me/deploy/files/usr/local/libexec/left4me/left4me-overlay /usr/local/libexec/left4me/left4me-overlay

View file

@ -170,6 +170,39 @@ def test_deploy_script_installs_perf_artifacts():
assert "sysctl --system" in script
def test_deploy_script_writes_cpuset_drop_ins():
script = DEPLOY_SCRIPT.read_text()
# Reads nproc and binds defaults via ${VAR:-...}.
assert "nproc" in script
assert "LEFT4ME_SYSTEM_CPUS" in script
assert "LEFT4ME_GAME_CPUS" in script
assert "${LEFT4ME_SYSTEM_CPUS:-0}" in script
# Default game-core upper bound is computed from nproc; accept either
# the NPROC-1 form or LEFT4ME_GAME_CPUS:-1- prefix.
assert (
"1-$((NPROC - 1))" in script
or "1-$((NPROC-1))" in script
or "1-$((nproc-1))" in script
or "LEFT4ME_GAME_CPUS:-1-" in script
)
# All four drop-in paths.
for slice_name in ("system", "user", "l4d2-build", "l4d2-game"):
assert (
f"/etc/systemd/system/{slice_name}.slice.d/99-left4me-cpuset.conf"
in script
)
# Drop-ins use the existing install pattern.
assert "install -m 0644 -o root -g root" in script
# Single-core host: skip with a warning to stderr.
assert ("-lt 2" in script) or ("< 2" in script) or ("-ge 2" in script)
assert "skipping CPU isolation" in script
def _fake_command(tmp_path, command_name):
marker = tmp_path / f"{command_name}.args"
command = tmp_path / command_name