Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WSL2 - Linux relative symlinks broken when accessed from windows only for the \\wsl$\ mount-point [closed]

Problem

I am really struggling with relative symlinks on wsl2 when they are created in the linux-native filesystem and I want to access the files via the share point \\wsl$\distro-name\whatever - They are simply broken.

Environment

I have wsl2 activated in my Windows10. I have an Ubuntu-20.04:

Ubuntu in WSL2

Impact in my coding workflow

Broken symlinks forbid me to seamlessly "execute in wsl2" while "edit from an IDE in Windows".

Real use case (but not limited to): Developing two intelaced projects: A repo with an application and another repo that lives aside with a library. The application symlinks the library:

  • Main program in /files/repos/my-nice-app
  • Library also in /files/repos/my-nice-lib
  • my-nice-app/libs/my-nice-lib is a symlink to ../../my-nice-lib
  • Intelligent IDE in windows, operating on the application opening \\wsl$\Ubuntu-20.04\files\repos\my-nice-app

With this setup, the location \\wsl$\Ubuntu-20.04\files\repos\my-nice-app\libs\my-nice-lib is expected to map to \\wsl$\Ubuntu-20.04\files\repos\my-nice-lib.

But it does not work. All the code-completion in the IDE is messed up, because the symlink does not de-map well and the IDE can't read the classes and definitions of the library.

How to reproduce a working example

Working example. Step 1 - Preparation

Whenever I create a symlink from the linux in the NTFS filesystem it is properly decoded in windows.

Same the oposite side: If I create the link from windows (both with CMD and mklink or Powershell with New-Item) they are properly decoded in linux.

Imagine this scenario:

  1. I have this dir: /mnt/c/tmp which corresponds to C:\tmp.

  2. I put some contents into a file original.txt. I use the linux bash for that. Create content on NTFS

  3. From the linux, I do a relative symlink linux.txt pointing to original.txt. Create link from linux on NTFS

  4. I then do it from windows. From a CMD with the mklink command: Create link from CMD on NTFS

  5. I can even do the symlink in the windows-side with the New-Item command from an elevated powershell Create link from PowerShell on NTFS

Up to here I should have one file original.txt and three links linux.txt, cmd.txt and powershell.txt

Working example. Step 2 - Listing symlinks

Success: I do see all them listed in each of the 3 shells: linux, cmd and powershell:

Listing in NTFS

Here in Linux (1 in the image) we see they are symlinks, as well as from the CMD (2 in the image) and in the powershell (3 in the image).

Both Linux and CMD also report the "demapping" (4 in the image). As cmd.txt and linux.txt are both relative symlinks there's no magic to do behind, just understand that they are links and done.

Powershell for some reason which I don't care for this question, promoted the relative symlink to an absolute one. This shows up a very interesting effect:

Somebody behind the scenes must be doing some kind of translation work, which is being done well in this case (5 in the image): While from linux powershell.txt it is pointing to a path starting with /mnt/c/... the windows interpreter is seeing it as pointing to C:\....

Working example. Step 3 - Accessing the contents via symlinks

Now time to see if I can cat (type in windows) the contents of all of them...

Accessing in NTFS

No explanation here needed. All 9 combinations (3 creation methods x 3 consumption methods) including the relative and absolute links, all work perfectly.

Now time for the rule-breakers...

How to reproduce a failing example

I'll do the very exact same process but instead of doing it on /mnt/c/tmp I'll do it on /tmp and in windows, instead of accessing it from C:\tmp I'll access it from \\wsl$\Ubuntu-20.04\tmp.

Let's start...

Failing example. Step 1 - preparation

I start by the linux. Navigating to /tmp and creating some dummy content on the WSL2 filesystem. I continue by doing the symlink.

Creating content wsl2

When I try to go there with the CMD I really can't because it complains of being an UNC path:

Navigating UNC on CMD

I'll change my strategy and I'll do a net mount to have a drive letter, see if CMD likes it more. I'll use W: for the WSL2 filesystem. In the image: 1 = I create it, 2 = I check it is created, 3 = I navigate into tmp on the WSL2.

Creating W:

But now... oh surprise!!! When I try to do a symlink from the CMD... it denies the access:

Linking from CMD on WSL2

Let's try with an elevated PowerShell...

In this image I can see I can properly navigate to the UNC path (1 in the image) but when trying to create the link... boom... 2 in the image: "Symbolic links are not compatible with the specified path":

Linking from PowerShell on WSL2

So there's only ONE way to create the symlinks in the WSL2: From inside the linux. Let's see how can we list it and access it.

Failing example. Step 2 - listing + accessing

Starting off, linux can see linux links (of course):

Linux accessing WSL2

But when moving to CMD, the listing shows "JUNCTION" instead of "SYMLINK" as it showed it on the NTFS and additionally when trying to access it, it breaks:

CMD accessing WSL2

Finally when moving into Powershell the behaviour is similar: It it sees "it is there" but the contents can't be accessed:

PowerShell accessing WSL2

Final considerations

  • I'm even not asking for absolute path conversion (as demonstrated that in the NTFS works). I'm just happy with relative links
  • I've done this with files. But it also fails with directories.

Soooooooooo Question

How can I have a properly working symlink on WSL2 working well both in the linux side and the windows side?

If it's a bug, what module is it? The kernel? The WSL itself? The P9 protocol? I'd be more than happy to contribute but I'd even don't know what project should I contribute to.

Investigation done so far

I have deepely read in full all of these:

  • https://docs.docker.com/docker-for-windows/wsl/
  • https://medium.com/@ragin/development-under-windows-under-linux-with-wsl2-intellij-860daf601b61
  • https://docs.microsoft.com/es-es/windows/wsl/tutorials/wsl-git
  • https://docs.microsoft.com/es-es/windows/win32/fileio/hard-links-and-junctions?redirectedfrom=MSDN
  • https://docs.microsoft.com/es-es/windows/win32/fileio/creating-symbolic-links
  • https://www.docker.com/blog/new-docker-desktop-wsl2-backend/

and many more, but still no luck.

like image 376
Xavi Montero Avatar asked Oct 22 '20 19:10

Xavi Montero


People also ask

Do Linux Symlinks work on Windows?

Overview. Symlinks, or symbolic links, are “virtual” files or folders which reference a physical file or folder located elsewhere, and are an important feature built in to many operating systems, including Linux and Windows. The Windows' NTFS file system has supported symlinks since Windows Vista.

Can WSL2 access Windows files?

One of the benefits of WSL is being able to access your files via both Windows and Linux apps or tools. Using your mounted drives, you can edit code in, for example, C:\dev\myproj\ using Visual Studio / or VS Code, and build/test that code in Linux by accessing the same files via /mnt/c/dev/myproj .

How do I access WSL2 terminal?

Access Linux Files from Windows You can access WSL2 Linux files from the network path \\wsl$\ . Enter it in the File Explorer address bar or any file open dialog. Here, <yourname> is the username you defined during installation. It's best to set this as the starting folder for the distro in Windows Terminal.

How do I connect to WSL from Windows?

Install WSLInstall Windows Subsystem for Linux with the command, wsl --install. Use a Bash terminal on your Windows machine run by your preferred Linux distribution - Ubuntu, Debian, SUSE, Kali, Fedora, Pengwin, Alpine, and more are available.

How to access Linux symlink in WSL?

Some expectations for Linux symlink in WSL: can be accessed by Windows' built-in applications (like Notepad), or third-party applications. [bonus] when shown in Windows Explorer, its icon will be decorated with a link icon at bottom-left conor, just like what Windows symlink was decorated.

Why can’t I mount a WSL2 file system partition?

When a disk has been mounted via WSL2 (Linux file system), it is no longer available to mount via an ext4 driver on the Windows file system. By default, WSL 2 attempts to mount the entire disk. To mount a specific partition, run: This only works if the disk is either MBR (Master Boot Record) or GPT (GUID Partition Table).

Why can't I access WSL using \\WSL$ on Windows?

A 9p protocol file server provides the service on the Linux side to allow Windows to access the Linux file system. If you cannot access WSL using \\wsl$ on Windows, it could be because 9P did not start correctly. To check this, you can check the start up logs using: dmesg |grep 9p, and this will show you any errors.

How do I install WSL2 on Linux?

Launch your WSL2 Linux distribution. Optionally, secondary click on the top of the window, select Properties, check "Use Ctrl+Shift+C/V as Copy/Paste," and select OK. Run git clone [email protected]:<owner>/<repository> to clone this repository to your Linux file system.


1 Answers

It look like a file permission issue:
When you write in /mnt/c/tmp, you write in the Windows filesystem.
While doing the same in /tmp, you write in the Linux filesystem.
The Linux files are accessed through a Plan9 Server (9P2000L protocol) running on the Windows host with the help of a Unix socket.
The Linux filesystem is accessible through \\wsl$\distribution-name.
I can suggest the video which explain the access of Linux files in Windows.
Explanation of the access of Linux filesystem with Windows 10
9P2000L protocol

It seems the symlink issue is an open issue.

like image 122
François B. Avatar answered Oct 11 '22 03:10

François B.