Skip to content

Instantly share code, notes, and snippets.

@onomatopellan
Last active July 18, 2024 14:51
Show Gist options
  • Save onomatopellan/90024008a0d8c8a2ed6fa57e8b64df54 to your computer and use it in GitHub Desktop.
Save onomatopellan/90024008a0d8c8a2ed6fa57e8b64df54 to your computer and use it in GitHub Desktop.
How to automount an external vhdx file in WSL2
1. Ubuntu WSL2 must be already installed in C: system drive and user should be able to call windows binaries like wsl.exe from bash.
2. We will install Alpine WSL2 distro in an external partition/disk:
Download Alpine from here:
https://github.com/yuk7/AlpineWSL/releases/download/3.11.5-1/Alpine.zip
Extract the files in an external partition/disk. (for example D:\Alpine)
Make sure WSL2 is enabled by default (wsl.exe --set-default-version 2)
Inside the Alpine folder run Alpine.exe to install the Distro. An ext4.vhdx file will be created in that same folder.
Run Alpine.exe again.
Now from the Alpine terminal we will create same user as Ubuntu. This will create the /home/onoma folder.
adduser onoma
3. On Ubuntu edit the ~/.profile file and add:
# mount external /home folder from Alpine distro
if [ ! -d /mnt/wsl/Alpine ]; then
mkdir /mnt/wsl/Alpine
wsl.exe -d Alpine mount --bind /home/onoma /mnt/wsl/Alpine/
fi
4. We will close the VM with:
wsl.exe --shutdown
5. Next time Ubuntu distro is launched it will automount the /home/onoma folder from Alpine distro to /mnt/wsl/Alpine in Ubuntu with all
the benefits and speed of ext4 mounted folders.
How it works
---------------
WSL2 runs a single lightweight VM that supports multiple distros running on the same Linux kernel.
Every time a distro is launched, its vhdx file is attached automatically to the VM as a /dev/sdc device.
Thanks to the nature of WSL interop we can launch another distro and inmediately close it from inside bash.
The folder /mnt/wsl is an undocumented WSL2 feature which is a tmpfs special folder used by applications as Docker for Desktop.
Everything mounted in that folder will also appear in every running distro under /mnt/wsl/. Just make sure you have file permissions to
access that directory. In my case I'm using user "onoma" on both Ubuntu and Alpine.
@joseph-so
Copy link

Thanks for your solution, but how do you make wsl.exe can be run in WSL? After I have upgraded to WSL2, I cannot run those windows command (like VS Code) anymore

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

@joseph-so It looks like the Opensuse team was aware of the problem. For a working Windows PATH you need to install the package aaa_base-wsl with sudo zypper in aaa_base-wsl and reopen OpenSUSE.
After that i had to use the command sudo update-ca-certificates and VSCode opens with code . again.

@joseph-so
Copy link

Thanks a lot. It works :D

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

Great! Also remember with this method you can also access your files from the external vhdx with either \\wsl$\Ubuntu\mnt\wsl\Alpine\ or \\wsl$\Alpine\ in File Explorer.

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

I would like to use @onomatopellan to mount the VHDX directly without a docker image, but fail .. the wsl command already complain my mount location is not a directory

You can ask me anything in this thread. I just follow the steps on OpenSUSE and I can mount the external vhdx and see the contents of /mnt/wsl/Alpine without problems.

@joseph-so
Copy link

Thanks a lot.

Here is what i try to do

jso@VivoMini-VC65:~> wsl.exe sudo mount --bind /mnt/d/VHD/HD.vhdx /mnt/abc
mount: /mnt/abc: mount(2) system call failed: Not a directory.

I need to add the sudo, or otherwise the system will give me error.
I have tried to do /home/ /mnt/abc then it will not complain that is not a directory

My target is to see if i can call a vhdx directly

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

I see. I think you are mixing both methods and you can't do that. The other method doesn't create a real vhdx but just a file formatted in ext4. The problem with that method is that the file has a fixed size and you won't be able to use more space than that.

The method of this thread uses a small external distro (Alpine is just 64Mb in size) with its real vhdx file. That vhdx file is a dynamic vdisk that can grow until 256Gb in size. Right now is not possible to attach directly a vhdx file to WSL2 so this is the method used by professional solutions as Docker.
The mount directory needs to be a directory inside /mnt/wsl since it's a special tmpfs mount. Every mount point you create there will disappear after shutting down the WSL2 VM. That's why the script lines in step 3 create a directory (if it wasn't created before) inside /mnt/wsl before mounting the Alpine vhdx at launch.

If you want to try this method, first you should shutdown the WSL2 VM with wsl.exe --shutdown.
If you exactly follow the steps of this thread with the same directory names it should work. Then you only need to cd to /mnt/wsl/Alpine/ and clone the SVN repositories there.

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

My bad. I just discovered a mistake that shows Permission denied because the user in Alpine needs to be the same as the main distro. I'll update the steps. Sorry about that.

@onomatopellan
Copy link
Author

onomatopellan commented May 23, 2020

Done. Please try the updated steps and it should work now. With lsblk you can see if it was mounted correctly.

:~> lsblk
NAME MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda    8:0    0  256G  0 disk
sdb    8:16   0  256G  0 disk /
sdc    8:32   0  256G  0 disk /mnt/wsl/Alpine

@joseph-so
Copy link

Thanks a lot. will have a test

Copy link

ghost commented Jun 1, 2020

I was also using this method without any issues, but over the last couple of days I noticed that my Alpine distribution was not getting mounted. After some inspection I found out that my /mnt/wsl mount point now belongs to root and that is the cause of the issue. Did you encounter this issue as well? Is there a possible workaround for this?

Annotation 2020-06-01 112346

@onomatopellan
Copy link
Author

onomatopellan commented Jun 1, 2020

It's normal if /mnt/wsl belongs to root. It's the folder inside (Alpine in my case) the one that needs to be created by the user.

Ubuntu$ ll /mnt/wsl/
total 8
drwxrwxrwt 3 root  root    60 May 29 12:55 ./
drwxr-xr-x 8 root  root  4096 May 25 22:23 ../
drwxr-sr-x 3 onoma onoma 4096 Jun  1 15:23 Alpine/

What's the line you are using for mounting the Alpine distro? In my case is wsl.exe -d Alpine mount --bind /home/onoma /mnt/wsl/Alpine/

But if you have permission problems you can specify the user like this
wsl.exe -d Alpine -u root mount --bind /home/onoma /mnt/wsl/Alpine/

Copy link

ghost commented Jun 1, 2020

I think I found an workaround by mixing your solution with something I tried.

Basically, I'm using ZSH and I couldn't make this code work in my .profile file, but switching this bit of code to my .zshrc file did the trick. I also added the -u root flag to make everything work perfectly.

Thanks for your help!

@BeenLi
Copy link

BeenLi commented Jan 7, 2021

Great! Also remember with this method you can also access your files from the external vhdx with either \\wsl$\Ubuntu\mnt\wsl\Alpine\ or \\wsl$\Alpine\ in File Explorer.

hi, I can't access the \\wsl$\Alpine, but I can access the \\wsl$\Ubuntu-20.04\mnt\wsl\Alpine. And I can't find the file in my Alpine diso in /home/beenli/ directory which appeas in my ubuntu diso /mnt/wsl/Alpine directory.How does it happen?
problems

@BeenLi
Copy link

BeenLi commented Jan 8, 2021

sorry, I have solved this problem by upgrading Alpine from wsl1 to wsl2. But I encounter another problem, copying the output directory generated by buildroot to my wsl2 ubuntu fails and if I copy the directory to my windows directory such as D:, it becomes very slow and consums me nealy 1 hours. Is this because the Windows and Linux file systems are incompatible?

Any help is appreciated!

@Shyamal-Shah
Copy link

I had an Ubuntu 20.04 LTS installed on WSL2, but due to an error during Windows update I cannot boot using that drive. So, I have installed fresh copy of windows on another drive and copied the contents of original drive. As Ubuntu was in WSL2 I cannot directly access those files. But I want to know if there is any possible way that I use my existing ubuntu ext4 filesystem and at least get my files. To be clear I have the whole folder for containing Ubuntu.

Thank you for any help in advanced.

@mwoodpatrick
Copy link

Worked well for me, definitely simpler than my previous approach. Many thanks

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