Skip to content

fix(reversesshfs): convert MSYS2 paths to native Windows paths for OpenSSH#108

Open
liketosweep wants to merge 1 commit intolima-vm:masterfrom
liketosweep:fix-msys2-paths
Open

fix(reversesshfs): convert MSYS2 paths to native Windows paths for OpenSSH#108
liketosweep wants to merge 1 commit intolima-vm:masterfrom
liketosweep:fix-msys2-paths

Conversation

@liketosweep
Copy link
Copy Markdown

What the Issue Was

Reverse SSHFS mounting of the Windows home directory fails on Lima/QEMU
(Windows host) with a Permission denied error. The hostagent accepts the
MSYS2-style Unix path (/c/Users/<user>) emitted by Cygwin/msys2 OpenSSH
but forwards it unconverted to the mount layer, which expects a native
Windows path (C:\Users\<user>). This causes chdir to fail with
No such file or directory, cascading into a fusermount3 mount failure.
The issue is reproducible locally and in CI.

Why It Was There

reversesshfs.go had detection logic for MSYS2/Cygwin-style paths on
runtime.GOOS == "windows" but no subsequent conversion step. Once the
path was identified as MSYS2 format, it was logged and passed through
as-is — Windows OpenSSH has no awareness of the MSYS2 path convention
and cannot resolve /c/Users/... as a valid filesystem location.

Solution

Introduced convertMSYS2Path(localPath string) string in reversesshfs.go.
The function targets the MSYS2 drive-letter convention — a path of the form
/X/... where X is a single alphabetic character — extracts and uppercases
the drive letter, appends :, and rewrites the remainder with backslash
separators, bypassing WSL/Linux environment path quirks entirely. Paths that
do not conform to this pattern are returned unchanged, ensuring no unintended
side effects on non-Windows or already-native paths.

The function is invoked within Start() immediately after MSYS2 path
detection, replacing rsf.LocalPath with the converted Windows-native
equivalent before the mount is attempted. The converted path is logged
for traceability.

Changes

  • pkg/reversesshfs/reversesshfs.go — Added convertMSYS2Path() and
    integrated it into the Windows path detection block in Start(), with
    a log line confirming the resolved native path.

  • pkg/reversesshfs/reversesshfs_test.go — Added TestConvertMSYS2Path
    asserting that /c/Users/lts correctly resolves to C:\\Users\\lts,
    with explicit failure messaging on mismatch.

Result

The hostagent now correctly resolves MSYS2-style paths to their Windows-native
equivalents before invoking OpenSSH, eliminating the chdir failure and
restoring reliable reverse SSHFS mounting on Windows/QEMU — both locally
and in CI.

Fixes #4810

Signed-off-by: liketosweep <liketosweep@gmail.com>
@unsuman
Copy link
Copy Markdown
Member

unsuman commented Apr 23, 2026

Thanks, could you share how you tested these changes?

@liketosweep
Copy link
Copy Markdown
Author

Hi @unsuman,

I’ve validated this patch natively on a Windows host using the qemu driver to confirm it successfully resolves the chdir "Permission denied" error.

Testing Methodology:

Environment: Windows host, Lima v2.1.1, QEMU driver, and Git's OpenSSH client.

Action: Swapped in the compiled, patched sshocker.exe and launched an Ubuntu guest with a reverse SSHFS mount targeting my local Windows directory (C:/Users/lts).

Results:
The patch correctly intercepted and translated the Windows path. The host agent passed the formatted path to sshocker , the OpenSSH client authenticated successfully, and the mount completed without permission errors.

Validation Evidence:

Host Agent Logs (Confirming successful path translation and sshfs execution):

image

Guest Shell Output (Confirming read access to the mounted Windows directory via ls -la /c/Users/lts) :

image image

Let me know if you need any further testing or logs for this PR!

@unsuman
Copy link
Copy Markdown
Member

unsuman commented Apr 29, 2026

I wonder if we should have this change inside Lima itself, which lima-vm/lima#4885 already does and solve the chdir issue

But this issue still persists:
fusermount3: mount failed: Permission denied

@liketosweep
Copy link
Copy Markdown
Author

Thank you for the feedback, @unsuman.

Regarding Redundancy with #4885

I agree that centralizing the path normalization logic natively within the core Lima codebase (#4885) is the superior architectural approach. If we are confident that the implementation in #4885 covers these specific OpenSSH pathing requirements for Windows hosts, I am happy to close this PR to avoid logic fragmentation.

Regarding the fusermount3 Permission Error

The mount failed: Permission denied error suggests a guest-side failure within the FUSE subsystem. While this PR addresses the host-side path translation, this specific error often points to:

  • Guest Permissions: The user within the VM lacking membership in the fuse group.
  • Mount Point Ownership: Restricted access to the target directory inside the guest filesystem.
  • FUSE Configuration: Constraints in /etc/fuse.conf (e.g., user_allow_other).

I will investigate if this error is an environmental blocker or a regression related to how the translated paths are being passed to the guest. If you have the full debug logs or the output of dmesg from the guest during the mount attempt, that would be extremely helpful for isolating the failure point.

How would you like to proceed - should we pivot this fix into #4885, or continue debugging the FUSE permission issue here?

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.

2 participants