Going Overboard with WSL metadata
Nerd Sniped
It all started with a simple tweet from @nunixtech:
@VirtualScooley @richturn_ms @tara_msft @CraigWilhite @benhillis In order to Thank You for the new Distros, here is a small hack from your "favorite" WSLCorsair. the mount options might need some review though. @bketelsen this might help you (do I enter the HAT gift list? ?) pic.twitter.com/7ouUX5Jm3h
— Nuno do Carmo (@nunixtech) March 6, 2018
Nuno showed how to use new metadata support in Windows Subsystem For Linux to enable Linux permissions and metadata on a mounted Windows share. Never content to let a good hack go unexplored, I wanted to see if it was possible to make a Windows folder be my WSL home directory with no adverse side-effects.
The Setup
I started with an existing and well-used WSL installation of Ubuntu. My first step was to replicate Nuno's example, mounting a Windows shared drive with appropriate Linux metadata. It worked well. But I wanted to make that directory my $HOME
, and have access from both Windows and WSL with no penalties or worries about permissions or corrupted files.
I created a folder on my C:\
drive called home
. I then shared the directory as Nuno did so it could be mounted from /etc/fstab
on the WSL side of things.
First Attempt
The first thing I tried doing was changing my /etc/fstab
entry for the mounted share to mount it at /home/bketelsen
. It worked, but of course it replaced my existing home directory with the mounted one. I reversed my change in fstab
and made a new mountpoint at /home/bketelsen2
. I mounted the Windows share there, then used rsync
to copy my old WSL-only home into the mounted directory:
$> rsync -azvh /home/bketelsen/ /home/bketelsen2
This took quite a while to complete because my home directory in WSL was full of code. When it finished, I had a full copy of my WSL home /home/bketelsen2
directory which was mounted from C:\home
. On the Windows side, the C:\home
directory shows all of my WSL files:
That's pretty slick! Now all I needed to do was make that my $HOME and I'd be set.
Narrator: Nothing is ever that easy.
Nuno's post shows mounting the Windows share using /etc/fstab
which works, but I couldn't get the extra metadata
flag in the mount line to actually make metadata support work. I don't know if this is by design, or an omission, but I didn't notice it until I tried making an ssh connection and my ssh keys had overly broad permissions. After changing the keys' permissions, it still failed. The chmod
command didn't apply the expected permissions.
Second Attempt
I pondered a bit and realized that I was dealing with Linux, and mounting the share at /home/bketelsen
was only one way to solve the problem. The other way is to change my home directory's location in the Linux user database. Specifically, using the usermod
command:
sudo usermod -d /mnt/c/home bketelsen
This is the right command, but it fails because the WSL process is spawned as a bash
process started by my user, bketelsen
. There can be no processes running as bketelsen
when you make the usermod
change, so that approach wouldn't work. I searched for ways to launch WSL directly as the root user, but in the middle of that search I remembered that the home directory is actually specified in /etc/passwd
:
bketelsen:x:1000:1000:,,,:/home/bketelsen:/bin/bash
YES! I edited this file to reflect my new desired $HOME directory:
bketelsen:x:1000:1000:,,,:/mnt/c/home:/bin/bash
Closing and re-opening WSL confirmed that my WSL $HOME
directory was now /mnt/c/home
which contained all the files that were previously stored in /home/bketelsen
. I quickly created a text file from the Windows side at C:\home\thing.txt
and verified that it existed on the WSL mount too.
SUCCESS
With this setup, I have a single folder -- C:\home
-- available in Windows, but also mounted as my WSL $HOME
, too. Files can be modified on either side, with no apparent ill effects. Editors Note: This is unproven, and not for risk-averse people. Use this setup at your own risk. Backup your data.
One More Thing
Because too much is never enough, I wanted to prove that this would work for more than one WSL installation. So I installed the just-announced Debian WSL app, and applied exactly the same change to my /etc/passwd
file and /etc/wsl.conf
files.
Now I have two different Linux installations in WSL: Ubuntu and Debian. They have separate root filesystems, but a single shared $HOME
directory:
This is extremely cool. I set up my Go development environment on the Windows side using Visual Studio Code but set the $GOPATH
to C:\home\go
, which is the same as $HOME/go
on the WSL side. Now I can develop in Windows or WSL/Linux against the exact same code without any strange permission problems. Most of the time I'll probably stay in neovim
, because it's my first love. But there are no issues when I use VS Code from the Windows side. I can compile and test from both Windows and Linux with the same source directory.
Here's the contents of my /etc/wsl.conf
for your perusal:
# Enable extra metadata options by default
[automount]
enabled = true
options = "metadata,umask=22,fmask=11"
mountFsTab = true
# Enable DNS – even though these are turned on by default, we’ll specify here just to be explicit.
[network]
generateHosts = true
generateResolvConf = true
Thank you to @nunixtech for the idea that spawned this probably-evil hack. I'm unreasonably delighted with how cool this little hack is, and it opens a lot of other possibilities for other potentially unauthorized or dangerous hacks, too. If you've done something equally unorthodox with your WSL install, tell me about it on twitter!
Update
I realized after this worked that the next logical progression of this experiment was to share the same $HOME between Windows and WSL. TLDR; It works perfectly. I updated my /etc/passwd
home directory entry to /mnt/c/Users/bkete
, moved the contents of the c:\home
directory into c:\Users\bkete
, and now I have a single shared home directory between Windows and WSL. Here's a picture of my OneDrive directory being accessed from WSL as $HOME/OneDrive
: