feat(fleet): give the media servers an I/O share that actually exists
A Plex section scan walked 50k files at ~850 r/s and nothing bounded it. `IOWeight=` in a quadlet looks like the fix and does nothing: systemd delegates `cpu memory pids` to user@.service and NOT io, and it drops a resource line it cannot honour without a word — the container boots healthy and its cgroup has no io.weight file at all. Same family as RequiresMountsFor= (inert in the user manager) and ConditionPathIsMountPoint= (fail-dead). Place the two system drop-ins that make the controller reachable (user.slice IOAccounting=yes puts io in user.slice/cgroup.subtree_control, measured immediately; user@1000.service DelegateControllers gains io and lands at the next reboot, because restarting the user manager would kill every rootless container on the host), then ask for the share: IOWeight=10 on jellyfin and plex. 10 is a convention, not a measured optimum — proportional share, only bites under contention, only requirement is far below the default 100. ensure_user_io_delegate places both from git and prints NOTE: io is not delegated … inert until the next reboot, so the quadlet line never reads as live config. Verified on the host: subtree_control flipped to `cpu io memory pids`, the drop-in is attached and parsed (systemctl cat), and the podman 5.7 generator emits IOWeight=10 for both units (bare key; UnitConfigItem= not needed). Two limits recorded instead of hidden: a container's weight covers its whole cgroup (scan and playback share it), and the comparison happens inside user.slice, so it cannot push a rootless unit below a root unit such as frank-archon — that pairing is user.slice's own weight, a separate call. Docs: Quadlet Lifecycle 4b (the three-command read of the chain), Pi-hole (all rootless containers share one 10.0.2.100, so one chatty container throttles DNS for the host — 8 events today), E2E Suite gotcha 7 (the gate depends on the runner's resolver: 21 reds on a lost wired link, 37/37 minutes later). Seam: an in-repo IOWeight= may only exist when both drop-ins exist AND the deployer places them. ./tests/run.sh: 789 ok, exit 0.
This commit is contained in:
1 parent
6d274acc47
commit
183a6d5442
9 files changed
+146
-4
No files matched your search
@@ -0,0 +1,14 @@
|
||||
# The io controller is what makes IOWeight= mean anything, and systemd does not
|
||||
# enable it below `user.slice` by default: with io accounting off, `io` never
|
||||
# appears in `user.slice/cgroup.subtree_control`, so no rootless container can
|
||||
# have an `io.weight` file and `IOWeight=` in a quadlet is silently inert.
|
||||
# Measured on Dankserver 2026-10-31: setting this property flipped
|
||||
# `user.slice/cgroup.subtree_control` from `cpu memory pids` to `cpu io memory
|
||||
# pids` immediately, with nothing restarted.
|
||||
#
|
||||
# This is half the fix; the other half is delegating io to user@1000.service
|
||||
# (user@1000.service.d/io-delegate.conf). Both must be in place before a reboot,
|
||||
# because the delegation is read when the user manager starts. Law and the
|
||||
# verification command: [[Quadlet Lifecycle]].
|
||||
[Slice]
|
||||
IOAccounting=yes
|
||||
Reference in new issue
Block a user