Skip to content

Backend: support a data folder on an external drive (#747, part 1) - #759

Merged
aaf2tbz merged 1 commit into
mainfrom
external-data-folder-backend
Nov 2, 2026
Merged

aaf2tbz merged 1 commit into
mainfrom
external-data-folder-backend

Conversation

@aaf2tbz

@aaf2tbz aaf2tbz commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Part 1 of #747 (data folder on an external drive). This PR changes only the backend, in both builds, so it works when ~/.metalsharp is a link to /Volumes/<Drive>/MetalSharp. Part 2, the app's drive choice, disconnected-drive screen and Move in Settings, follows in a separate PR.

With the data folder internal, as it is for everyone today, behavior is unchanged: every new comparison resolves to the same path, and every new branch applies only when the data folder is on another drive.

Why

Launches already work through the link: argv, env, launch.env and the Wine wrappers all use ~/.metalsharp, and nothing renames across drives or uses clone copies. But the kernel reports each process's executable (proc_pidpath) and working directory (PROC_PIDVNODEPATHINFO) resolved, as /Volumes/<Drive>/MetalSharp/.... Wine processes show Windows command lines, so those paths are the only way to tell MetalSharp's processes apart. Compared against ~/.metalsharp/... text, they never match. Steam, games and Ubisoft Connect would never show as running, Stop would miss them, and MetalSharp could start Steam a second time.

Changes

  • Process matching: new ms_resolved_path_within(path, root) in wine_runtime.c compares against realpath(root), or the text as written when it doesn't resolve. It's used by steam_actions.c (process_cwd_within, process_executable_within: Wine Steam detection, stop and cleanup, Steam-launched games, the Ubisoft/Odyssey scans, the process list), process.c (game detection and kill) and ubisoft.c. sharp.c and gamejolt.c already resolved their roots.
  • Guards:
    • gog.c safe_gog_install_path also refuses the resolved data folder.
    • The PCSX2, shadPS4 and SharpEmu "not the emulator's own folder" checks resolve that folder.
    • steamcmd.c no longer labels the internal library (now under /Volumes/) as external.
  • Saved paths: new ms_data_path_for_keeping(home, path) converts a resolved path inside the data folder back to its ~/.metalsharp form. The Sharp library (exe_path, install_dir) and Epic custom install roots use it, so a renamed drive doesn't break saved entries.
  • Migration (migration.c): the safety copy of prefixes and games, which can be many GB, goes on the data folder's drive when that isn't /tmp's, instead of on the internal disk.
  • Steam Desktop shortcuts: .url files are copied, then removed, when rename fails across drives (EXDEV).
  • x86_64 build only, Wine Steam through the MetalSharp Steam helper: macOS can refuse the helper's Wine on an external drive after open has already succeeded. The fex build already starts Wine Steam directly for this reason. With the data folder on another drive, the helper path now waits up to 6 s for Wine Steam to appear, then starts it directly instead. With internal data it's unchanged.

Drive letters are unchanged on purpose. The data drive can also hold Steam libraries, which need their letter.

Testing

  • make -C app/src-c test and make -C app/src-c VARIANT=fex test pass. Both variants build with -Werror.
  • wine_runtime_test now builds a real linked data folder (data -> drive/MetalSharp) and checks:
    • resolved paths match through the link, its text and the folder
    • a sibling with the same name prefix doesn't match
    • roots that don't exist compare as written
    • kept paths are converted back through the link, and other paths are left alone
  • Changed lines are formatted with the repo's .clang-format.
  • Not yet run with a real data folder on an external drive. That comes with part 2, which creates the link.

The data folder can become a link to a folder on an external drive
(~/.metalsharp -> /Volumes/<Drive>/MetalSharp). The kernel reports processes'
executables and working directories resolved, so the matchers that tell
MetalSharp's Wine, Steam, games and Ubisoft processes apart now compare against
resolved roots (ms_resolved_path_within); without it nothing would be seen
running and Stop would miss it. Guards that refuse the data folder or an
emulator's own folder resolve it too; Sharp library and Epic paths inside the
data folder are kept through it, so a renamed drive keeps them valid; the
internal Steam library is not labelled external; migration keeps its copy of
prefixes on the data folder's drive; Steam's Desktop shortcuts are copied
across drives. On the x86_64 build, with the data folder on another drive,
Wine Steam starts directly when the MetalSharp Steam helper does not start it.
@aaf2tbz
aaf2tbz merged commit 3b3278e into main Nov 2, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant