As mentioned in the comments, putting your WSL2 home directory on a Windows drive is not recommended for several reasons:
Your Linux home directory should be on a POSIX-compliant drive. Linux applications are going to expect this to be the case. While most applications will be okay, eventually you will come across something that won't work as expected. We can (and will) mitigate that somewhat with WSL settings below, but we can't change certain Windows behaviors.
Accessing Windows drives from WSL2 is extremely slow compared to the virtual ext4 filesystem. As I mention in that linked answer, a checkout of the WSL2 repo on a Windows drive under WSL2 took around 8 minutes, but only a few seconds on the "native" WSL2 filesystem.
With that in mind, the default WSL2 filesystem is in a virtual SDD (a Windows ext4.vhdx
file). The location of that file is, by default, under:
C:\Users\<windows_username>\AppData\Local\Packages\<distro_package>\LocalState\ext4.vhdx
There are (at least) three ways we can "change" the home directory so that it isn't in that location.
Option 1: Move the entire WSL virtual drive to a new location/distro
My personal preference (and I now always do this anyway) is to copy the distro itself to a new location.
Exit WSL
Launch PowerShell and run the following:
cd ~
wsl -l -v
# Confirm the name of the distro
wsl --export <distroname> wsl_backup.tar
mkdir <new_disk_location> # C:\lhome perhaps
# New distro name can be whatever you want,
# but not Ubuntu, Ubuntu-20.04, etc.
wsl --import Ubuntu_WSL2 <new_disk_location> wsl_backup.tar
wsl ~ -d Ubuntu_WSL2
You will start as the root user. You'll need to change the default username. See this answer for information on how to create or modify /etc/wsl.conf
.
Once you have confirmed that the new instance works properly, you can remove the old one with:
wsl --unregister <old_distroname>
Distributions that you have manually configured like this will not be impacted by uninstalling the Ubuntu application itself.
This method may or may not meet your particular needs for this use-case, but again, it's my personal choice.
Option 2: Create and mount a new vhdx for your home directory (Windows 11 only)
Note: I have not tested this technique (nor the next) extensively in a production system.
Since you have Windows 11, you can create and mount a separate vhdx file for your home directory. If you have the WSL Preview that can be installed from the Microsoft Store under Windows 11, it's even easier.
I'm going to cover the Preview method here, and refer you to the Microsoft docs on how to mount a VHD file in WSL if you need to go with the more complicated route.
There's a big downside to this technique, however. You must mount the virtual disk into WSL manually at this point before starting WSL. I would expect that there will eventually be an "automount" option in .wslconfig
, but it's not there yet, or at least not documented.
So if WSL shuts down or restarts, you'll need to manually issue a wsl --mount
command before relaunching it, or your home directory won't be found.
With that in mind, here's now to set up a home directory on a new virtual disk:
One-time configuration:
In an admin PowerShell, run:
New-VHD -Dynamic -SizeBytes 60gb -BlockSizeBytes 1mb -Path C:\lhome\userhome.vhdx
In your regular PowerShell session:
wsl --mount --vhd --bare C:\lhome\userhome.vhdx
wsl ~
Inside WSL:
lsblk
# Identify the proper drive (likely the last one listed, but confirm)
sudo mkfs -t ext4 /dev/<drive>
sudo mkdir /lhome
Exit WSL, and from PowerShell (as a regular user) once again:
wsl --terminate <distroname>
wsl --unmount C:\lhome\userhome.vhdx
wsl --mount --vhd --name lhome C:\lhome\userhome.vhdx
wsl ~ -u root
Inside WSL (you should be root now, based on the preceding -u root
), confirm that you have a /mnt/wsl/lhome
now mounted.
Edit fstab
:
sudo -e /etc/fstab
Add the following line at the bottom (tabs to separate fields):
/mnt/wsl/lhome /lhome none bind
Edit wsl.conf
:
sudo -e /etc/wsl.conf
Add the following:
[automount]
mountFsTab = false
[boot]
command="mount -a"
This essentially tries to work around a timing issue (hopefully) where the wsl --mount
is not made available to the instance until after /etc/fstab
is processed. It turns off the autoprocessing and then runs it manually as a startup command. It's a hacky workaround, but it's working for me.
Create your new home directory inside the mounted vhdx:
mkdir /lhome/username
# Assuming your default uid/gid is 1000, which it should be under WSL
chown 1000:1000 /lhome/username
usermod -d /lhome/username yourusername
Exit WSL. In PowerShell, issue:
wsl --terminate <distroname>
wsl ~
Your home directory should now be /lhome/username
. You can confirm this with cd ~; pwd
.
Again, this method will require that you issue the wsl --mount
command each time WSL itself restarts (via computer restart or wsl --shutdown
or other).
Option 3: A bind mount to the Windows folder
Again, this method really isn't recommended for the reasons listed at the beginning of this post, but here goes.
Assuming you want C:\lhome
in Windows to become /lhome
in WSL:
Revert any of the changes if you tried the second option above. If you did try Option 2, and you want to switch to Option 3, then make sure you wsl --shutdown
as well before proceeding.
In an administrative PowerShell:
mkdir C:\lhome
# directory must be empty
fsutil.exe file setCaseSensitiveInfo C:\lhome\ enable
This turns on case sensitivity for so that abc
and ABC
are different files. This gets us one step closer, at least, to POSIX compatibility.
In File Explorer, right-click on C:\lhome
, choose Properties -> Security and Edit the "Authenticated Users" to add "Full Permissions".
Back in WSL:
sudo mkdir /lhome
sudo -e /etc/fstab
... and add the following line at the bottom:
drvfs /lhome 9p rw,dirsync,noatime,aname=drvfs;path=C:\lhome;uid=1000;gid=1000;metadata;umask=22;fmask=11;case=dir,mmap,access=client,msize=262144,trans=virtio 0 0
This mounts the Windows C:\lhome
into /lhome
and enables metadata
and case=dir
for improved POSIX compatibility. This (again) assumes that your user is UID/GID 1000. If not, adjust it.
Exit WSL, terminate it (from PowerShell -- wsl --terminate <distro_name>
) and restart. Check that the drive is mounted with mount | grep lhome
.
Create the user home directory:
mkdir /lhome/username
Confirm that C:\lhome\username
now exists.
Exit WSL, then restart with wsl ~ -u root
and:
# Assuming your default uid/gid is 1000, which it should be under WSL
chown 1000:1000 /lhome/username
usermod -d /lhome/username yourusername
This, of course, mimics the steps from the second option above.
Exit WSL. In PowerShell, issue:
wsl --terminate <distroname>
wsl ~
Your home directory should now be /lhome/username
. You can confirm this with cd ~; pwd
. If you touch ~/abc
, you should find the file created in your C:\lhome\username
directory as well.
C:\Users
being treated differently? Also, how would changing your Linux/WSL/home/username
help with that? Thanks!