ℹ️ The article has been re-edited, keeping its content unchanged while enhancing it where possible and making it clearer where needed.
Table of Contents
- Intro
- Prerequisites
- Preparing the virtual disk for your home
- Mounting the virtual disk on WSL
- Preparing the Linux distribution
- Creating a new session
- Configuring the new session
- Initializing the home virtual disk
- Mounting the virtual disk to the home directory
- Ready, Set, Go 🚀
- Troubleshooting
- References
Intro
I often find myself fighting with the problem of having more than one WSL session for the same Linux distribution.
💡It is not officially possible to install two or more fresh copies of the same distro unless you rename the executable downloaded from the Microsoft Store for each session you want to install.
Of course, it is possible to export a previously installed session and import it as many times as needed, but this leads to another (in my humble opinion) problem – the duplication of your home directory for every imported session. Having more independent sessions, on the other hand, introduces the challenge of mirroring your home directory between each session, thereby necessitating a shared home directory.
To address this issue, I conducted research on the internet to find a solution that worked for me. I then documented it in a step-by-step guide (or more like a memo for myself), putting it in writing for future reference.
DISCLAIMER: The following steps require running Windows 10/11 and performing actions that demand Administrator privileges. Incorrect execution can lead to disastrous results. While these steps have proven successful on my system, there is no guarantee they will work on yours. Proceed only if you are confident in your understanding of the process, and I cannot be held responsible if any issues arise.
Prerequisites
To follow this guide, it is expected that the system has the following:
- Windows 10/11 Education/Pro/Enterprise (Home edition is supported but may require additional steps)
- Windows Subsystem for Linux version 2 installed
- Sufficient disk space for sessions' and home's virtual disks
- Administrator privileges
- One or more Linux rootfs tarballs
- Basic understanding of shell commands
Preparing the virtual disk for your home
⚠️ This step is required ONLY if you haven't already created your own virtual disk for the home directory.
The initial step is to create a virtual disk serving as our shared home partition across all sessions. Various methods can achieve this.
Option 1: Disk Management snap-in
It can be created via the Disk Management snap-in (diskmgmt.msc
) by following these steps:
Option 2: Windows Settings
The same result can be achieved through the Windows Settings panel by selecting Create VHD in Disks & volumes under Settings > System > Storage > Advanced storage settings.
ℹ️ To perform these steps, it is necessary to run the console with Administrator privileges. The same result can be achieved via the command line using diskpart ( where Option 3: Diskpart
diskpart.exe
). Once the console (cmd.exe
) is opened, simply type:
diskpart.exe
DISKPART> create vdisk file="<path>" maximum=<size> type=expandable
<path>
is the file path for the virtual disk, and <size>
represents the maximum size (in KiB) to be assigned to the virtual disk.
ℹ️ Running PowerShell with Administrator privileges is necessary. Users of Windows Home edition need to complete an additional step before being able to use the Hyper-V module. In PowerShell it is possible to use the where Option 4: Hyper-V
New-VHD
cmdlet from the Hyper-V
module:
New-VHD -Path <path> -Dynamic -SizeBytes <size>
<path>
is the file path to the virtual disk, and <size>
represents the maximum size, specified in MiB, GiB, or TiB, to be assigned to it.
⚠️ Ensure that you have sufficient space for the virtual disk, as its minimum size will significantly increase once formatted in
ext4
. To estimate the required space, you can use the following formula.
As example, for a 10GiB virtual disk formatted in ext4:
Mounting the virtual disk on WSL
After creating the virtual disk, it is necessary to make it available in WSL for use by all sessions. In PowerShell type:
wsl.exe --mount <virtual_disk_path> --vhd --bare
This will make the virtual disk at <virtual_disk_path>
available in the current WSL, ready for mounting in every session."
ℹ️ This step is required each time a new virtual disk is created and after every system restart, as there is currently no way to automount the disks when WSL is initiated.
Preparing the Linux distribution
The guide should work with any Linux distribution that offers a rootfs tarball compatible with WSL.
For the sake of simplicity, all steps will be executed in PowerShell with Administrator privileges.
Ubuntu
You can download an image from https://cloud-images.ubuntu.com/releases/ (for releases before 22.04) or https://cloud-images.ubuntu.com/wsl/ (for releases from 22.04 and later).
Invoke-WebRequest https://cloud-images.ubuntu.com/wsl/mantic/current/ubuntu-mantic-wsl-amd64-wsl.rootfs.tar.gz -OutFile ubuntu-mantic-wsl-amd64-wsl.rootfs.tar.gz
or After downloading, it is necessary to prepare the rootfs tarball required for the import in WSL. where Arch
Additional steps are required within a Linux session to prepare Arch Linux before importing. Firstly, download the bootstrap archive from the Arch repository https://archmirror.it/repos/iso/:
wget https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.gz
wget https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.zstd
sudo tar -xzf archlinux-bootstrap-x86_64.tar.gz
# or, if tar ball is compressed with zstd
sudo tar --zstd -xf archlinux-bootstrap-x86_64.tar.std
cd root.x86_64
sudo tar -czvf ArchWSL.tar.gz .
sudo cp ArchWSL.tar.gz /mnt/<path_for_tarball>
<path_for_tarball>
represents the location on your Windows system where the tarball will be stored for future imports.
Creating a new session
To create a new Linux session in WSL, the first step is to import the chosen rootfs tarball. In PowerShell, type
wsl.exe --import <session> <session_path> <rootfs_tarball_path> --version 2
where <session>
is the name to assign to the newly created Linux session, <session_path>
is the directory where the session's virtual disk will be created by WSL (the virtual disk always has the name ext4.vhdx
, so it is mandatory to specify a different directory for each unique instance), and <rootfs_tarball_path>
is the path to the tarball downloaded in the previous step.
Then, start the session to allow WSL to install the distribution:
wsl.exe -d <session>
At this point, the bare minimum Linux session is ready. However, unlike the default installation procedure via wsl --install
, which installs a session with Ubuntu and an already configured home directory, the session just created only has the root user. Further configuration is required to connect an user home directory to the previously created home virtual disk.
Configuring the new session
WSL sessions can be configured using the wsl.conf
configuration file. This is the first step required to configure the newly created session. Open the file with your preferred editor (here, nano
is used for the sake of simplicity).
nano /etc/wsl.conf
Type in the following, save, and then exit:
[boot]
systemd=true
[user]
default=<user_name>
where <user_name>
is the default non-root login user when the session starts.
💡Further information about the configuration parameters available for the
wsl.conf
file can be found in the documentation on the Microsoft website.
Now, create the user and add it to the sudoers group.
Ubuntu
USERNAME=<user_name> adduser $USERNAME; passwd $USERNAME; adduser $USERNAME sudo; mkdir /home/$USERNAME; chown $USERNAME: /home/$USERNAME
In Arch, you can create a file in Since Arch does not come configured as Ubuntu does, it is necessary to initialize and update Pacman: And setup the locale:Arch
USERNAME=<user_name> useradd $USERNAME; passwd $USERNAME; mkdir /home/$USERNAME; chown $USERNAME: /home/$USERNAME
/etc/sudoers.d/
with the following data:
<user_name> ALL=(ALL:ALL) ALL
curl -s "https://gitlab.archlinux.org/pacman/pacman-contrib/-/raw/master/src/rankmirrors.sh.in" > rankmirrors.sh
chmod +x rankmirrors.sh
COUNTRY=US curl -s "https://www.archlinux.org/mirrorlist/?country=${COUNTRY}&protocol=https&ip_version=4" | cut -b 2- | ./rankmirrors.sh -n 10 - > /etc/pacman.d/mirrorlist
pacman -Syu
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
Initializing the home virtual disk
⚠️ These steps are required ONLY if the virtual disk has not yet been initialized and formatted. DO NOT PERFORM THESE STEPS ON AN EXISTING VIRTUAL DISK, OR YOU WILL LOSE ALL THE DATA ON IT.
The first thing to do is to search for the device mounted in WSL:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
...
sdc 8:48 0 10G 0 disk
...
In the example above, the device is sdc
with a size of 10G
. You will need to identify the device for the virtual disk you prepared as your home.
Once found, it must be initialized by creating the partition table using the parted
command. You can install it on Ubuntu with apt install parted
, or on Arch with pacman -S parted
.
parted /dev/sdc mklabel msdos
parted -a optimal /dev/sdc mkpart primary ext4 0% 100%
Here, replace /dev/sdc
with the specific device you previously found.
If everything went OK , a new partition will be shown under the device you specified:
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT /dev/sdc
NAME FSTYPE SIZE MOUNTPOINT
sdc 10G
└─sdc1 10G
It is not done yet. The new partition still needs to be formatted:
mkfs.ext4 /dev/sdc1
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 2621184 4k blocks and 655360 inodes
Filesystem UUID: c91c874f-28fb-4d81-8eea-004fee865db0
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
And labeled (this is not mandatory, but it can be useful later as a replacement for the UUID value):
e2label /dev/sdc1 wsl-home
Mounting the virtual disk to the home directory
This step is no different from the usual procedure used to mount external devices in your Linux filesystem.
Once found the device:
blkid
...
/dev/sdc1: LABEL="wsl-home" UUID="e9999b9b-5a8e-41e1-9881-a2f766838798" BLOCK_SIZE="4096" TYPE="ext4" ....
...
You can use its LABEL
or UUID
value for the home mount point. Open the /etc/fstab
file and add:
UUID=<device_UUID> /home/<user_name> ext4 defaults 0 2
Alternatively (if you are sure no other devices with the same label are mounted in WSL):
LABEL=<device_label> /home/<user_name> ext4 defaults 0 2
Ready, Set, Go 🚀
If you've reached this point without any problems, you're almost done!
The last thing to do is to log out from the current session:
exit
Restart it:
wsl.exe -t <session>
wsl.exe -d <session>
And configure it according to your needs.
Troubleshooting
However, if you are using Windows 10/11 Home edition, it is possible to modify the system to support Hyper-V through a workaround. ⚠️ This is an unsupported method to enable Windows 10/11 Home edition to run the Hyper-V service. As mentioned, it's not officially supported by Microsoft, there's no guarantee it will work on your machine, it could lead to unexpected issues, and it may potentially violate the terms of the software's license agreement. Use it at your own risk. Create a batch file that will be executed as Administrator, and it will install and enable the service on the machine. Open your preferred text editor and type: Save it (e.g., No Hyper-V installed on the system
To use the New-VHD
cmdlet in PowerShell, the Hyper-V service must be enabled. This feature is supported only with Windows 10/11 Education, Pro, or Enterprise editions:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
.DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V
.
pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hyper-v.txt
dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL
pause
Enable-Hyper_V.bat
), and once executed, the service should be available on your machine.
However, with a bit of hacking, it is possible to achieve this result. Task Scheduler: Startup Folder: By doing so, every time Windows will restart, the specified virtual disk will be mounted into WSL and made ready for all the Linux sessions. Replace the default startup command line for the specific Linux session in the Windows Terminal With this hack, WSL will attempt to mount the virtual disk and change to the home ( The (minor) issue with this workaround is that the Windows Terminal won't recognize the started process as a Linux session but rather as a PowerShell process running a script. For this reason, Option 1 is the preferred choice to solve the problem.Missing device on system reboot
As far as I know, there is currently no officially supported way to have your (virtual) external drives mounted in WSL when the operating system starts.
Option 1: Task Scheduler or Startup Folder
WIN+R
) the snap-in taskschd.msc
Create Task...
Name
: "WSL Home Mount" for exampleRun only when user is logged on
Windows 10
for Configure for
New...
, create On Access
trigger, and set it for your userNew...
, create Start Program
, set C:\Windows\System32\wsl.exe
for Program or Script
, and --mount <virtual_disk_path> --vhd --bare
for Arguments
Don't start a new instance
if the task is already running
WIN+R
, shell:startup
wsl_home_mount.bat
)@echo off; C:\Windows\System32\wsl.exe --mount <virtual_disk_path> --vhd --bare
Option 2: Windows Terminal settings
pwsh.exe -Command "wsl.exe -d <session> --mount <virtual_disk_path> --vhd --bare --cd ~ | out-null; wsl.exe -d <session> --cd ~"
~
) directory every time the session starts, if not already mounted.
To solve the issue, just type:VSCode and other Windows executables do not start
This problem may arise with certain Linux distributions, and it is connected to the fact that WSL does not correctly configure the Linux Kernel Support for Binary Formats to work with the WSL interoperability.
sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'
sudo systemctl restart systemd-binfmt
Given that all sessions share the same home directory, it is not recommended to work with different sessions simultaneously to prevent race conditions and compromise the data integrity on the mounted virtual disk for the home directory.Home directory permissions and race conditions
As the home directory is shared between different Linux sessions, it is advisable for each session to use the same username to prevent conflicts and permission issues. (You may still need to run a chown -R $(whoami): /home/$(whoami)
if any issues arise when switching from one session to another.)
References
- https://www.ubackup.com/enterprise-backup/windows-11-hyper-v-not-showing.html
- https://superuser.com/questions/1515246/how-to-add-second-wsl2-ubuntu-distro-fresh-install
- https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/
- https://learn.microsoft.com/en-us/windows/wsl/wsl-config#wslconf
- https://anthony-f-tannous.medium.com/wsl2-how-to-prepare-and-attach-virtual-drives-vhd-ac17b1fc7a61
- https://learn.microsoft.com/en-us/windows/wsl/wsl2-mount-disk
- https://superuser.com/a/1727367/215993
- https://github.com/microsoft/WSL/issues/8952#issuecomment-1568212651
- https://www.reddit.com/r/bashonubuntuonwindows/comments/gxbufo/running_arch_on_wsl_from_the_source_images_the/
- https://wiki.archlinux.org/title/Users_and_groups
I hope this guide has been helpful in resolving the problem I was stuck in for a while. I will try to keep it updated with new useful information.
That's all, folks!
Top comments (0)