Skip to content

Clean stale runtime state on init so containers recover from unclean shutdowns#171

Open
junkerderprovinz wants to merge 1 commit into
linuxserver:masterfrom
junkerderprovinz:fix/clean-stale-runtime-state
Open

Clean stale runtime state on init so containers recover from unclean shutdowns#171
junkerderprovinz wants to merge 1 commit into
linuxserver:masterfrom
junkerderprovinz:fix/clean-stale-runtime-state

Conversation

@junkerderprovinz

Copy link
Copy Markdown

linuxserver.io


  • I have read the contributing guideline and understand that I have made the correct modifications

Description:

Two supposed-to-be-ephemeral runtime locations survive an unclean container stop (host power loss, hard reboot) because they live on paths that are never wiped:

  1. XDG_RUNTIME_DIR is pointed at $HOME/.XDG, which sits on the persistent /config volume. On a normal shutdown the session cleans up after itself, but after an unclean stop stale sockets and session state (wayland/dbus/pipewire leftovers) are still there on the next boot and confuse the fresh session.
  2. PULSE_RUNTIME_PATH is /defaults (set in the Dockerfile), so PulseAudio's pid and native socket files persist too. svc-selkies gates its sink setup on until [ -f /defaults/pid ], so after an unclean stop that gate passes immediately against the dead previous instance's pid file. The pactl load-module calls then fail against a stale socket, but the script still ran touch /dev/shm/audio.lock, which permanently skips sink setup for the rest of that boot, leaving the session without its sinks.

This PR makes the runtime state actually ephemeral and the readiness gate meaningful again:

  • init-selkies-config: after the existing $HOME/.XDG handling, wipe the directory contents on every boot (find "$HOME/.XDG" -mindepth 1 -delete) and remove stale /defaults/pid and /defaults/native so the pulse pid file only exists once the current PulseAudio instance has written it.
  • svc-selkies: only touch /dev/shm/audio.lock when both pactl load-module calls actually succeeded, so a failed sink setup can retry on service restart instead of being skipped for the whole boot.

Both changes are under root/, which is shared by Dockerfile and Dockerfile.aarch64, so both arches are covered with no Dockerfile changes.

Out of scope: after a power loss PulseAudio's own database files under /config/.config/pulse (*.tdb) can also end up corrupt; pulse generally recovers from those itself and handling them would mean deleting user-owned config, so this PR deliberately leaves them alone.

Benefits of this PR and context:

Fixes #166. Users reported that after an unexpected host restart, over half of their selkies containers came up broken (endless wss reconnects in the WebUI, failing http resources) until they manually deleted the non-app data in /config. With this change a fresh boot no longer inherits stale runtime state, so containers come up clean after an unclean stop without manual intervention.

How Has This Been Tested?

  • bash -n passes on both modified scripts.
  • Reproduced the failure mode logically from the scripts: pre-seeding a stale /defaults/pid lets the until gate pass instantly while pactl cannot connect, and previously audio.lock was still created; with this change the lock is only created after both sinks load, and a service restart retries the setup.
  • The $HOME/.XDG wipe runs after the create/chown block in the same init script, so ownership and the XDG_RUNTIME_DIR export are unchanged; on a clean first boot the directory is simply empty and the find/rm -f are no-ops.

Source / References:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

[BUG] Container status corrupted after host restarts unexpectedly

2 participants