feat(helper): overlay-based per-user game file overrides + systemd-run launching#5
Open
feat(helper): overlay-based per-user game file overrides + systemd-run launching#5
Conversation
92c2705 to
a4e0b42
Compare
Implements kernel OverlayFS mounts to give each player instance their own override files when sharing the same game installation on NTFS or other shared filesystems. Key changes: - SystemOps: add mount/umount/umount2 via nsenter into PID 1 namespace - CouchPlayHelper: SetupOverlayMount creates overlayfs with metacopy=on (upper/work on native Linux fs, lower on game path) - CouchPlayHelper: LaunchInstance uses single dir-level BindPaths with PrivateMounts=no for propagation through flatpak/pressure-vessel - CouchPlayHelper: TeardownOverlayMount with lazy umount fallback - Disk-based overlay discovery (no in-memory state tracking) - SessionRunner: setupOverlayMounts/teardownOverlayMounts orchestration - QML: editable overlay game path in session setup - 6 new tests covering mount, umount, lazy fallback, edge cases This replaces all previous failed approaches (FLATPAK_BWRAP wrapper, file-level bind mounts, global bind mounts) which don't survive pressure-vessel's mount namespace isolation.
- Remove dead LD_PRELOAD interceptor logic from install-helper.sh - Remove stale polkit action 'run-as-user' (machinectl era) - Bake PrivateTmp=false and MountFlags=shared into service file (replaces external drop-in that was required at install time) - Fix SetupOverlayMount: check /proc/mounts BEFORE cleaning workdir (prevents stale workdir data if previous mount was active) - Fix /proc/mounts check: append space to prevent partial path match - Fix SystemOps::umount2: properly map flags parameter instead of always hardcoding MNT_DETACH - Fix misleading strerror(errno) after QProcess mount failure (QProcess doesn't set errno; use generic error message) - Add QDir::cleanPath() to hashGamePath for path normalization - Add stale workdir cleanup before overlay mount (overlayfs requires empty workdir) - Use proper log categories in SessionRunner (qCWarning/qCDebug) - Move getOverridesRootPath to private (no external callers)
… teardown - Use QProcess::splitCommand() instead of naive space-split for gameCommand, properly handling quoted arguments in preset launch commands (e.g. paths with spaces) - Replace stale strerror(errno) with mount point path in error messages after nsenter-based umount calls, since errno is meaningless after subprocess execution - Fix mixed tab/space indentation in test mock
a4e0b42 to
633f668
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
machinectl shell+bash -cprocess spawning withsystemd-run --unit couchplay-<user>.servicefor proper lifecycle management, automatic cleanup on crash, andDelegate=yescgroup delegation/run/couchplay/mounts/<user>/<gameId>so each split-screen player gets isolated save/config files without full game copiesstartsWith(userHome)validation inCopyFileToUser,WriteFileToUser,CreateUserDirectoryto constrain writes under user home directories; onlychowndirectories that were actually created (not pre-existing ones)/proc/mountson setup, auto-teardown; use directnsenter -t 1 -msyscalls instead of shellmount/umountprocesses; lazy unmount fallbackFolderDialogat session profile level to select shared game directory for overlay mountsoverlayGamePathfrom per-instance (dead code) to session-level with real UI binding; remove unusedborderlessper-instance setting; defaultborderlessWindowstotrueTest Plan
cmake --build build)ctest --output-on-failure)Breaking Changes
LaunchInstancesignature gainsgamePathparameter (sssass→sssasss)io.github.hikaps.couchplay.run-as-userpolkit action removed (superseded by systemd-run)overlayGamePath,overlayEnabled,borderlessremoved from per-instance config (moved/deprecated)