Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to automount partition/drive using wsl --mount after restart? #6073

Closed
Trashmonk opened this issue Oct 11, 2020 · 36 comments
Closed
Assignees
Labels

Comments

@Trashmonk
Copy link

Is your feature request related to a problem?

I am able to mount my ext4 partition in wsl-2 using the following command in powershell:

wsl --mount \.\PHYSICALDRIVE4 --partition 1

However when I either restart my computer or run wsl --restart the partition is unmounted and I have to run the above command again. Is there a way of automounting the partition and if not could this feature be added?

Describe the solution you'd like

Have a parameter where I can set automount after restart.

Describe alternatives you've considered

A powershell script that triggers when I start Windows.

@OneBlue OneBlue self-assigned this Oct 12, 2020
@OneBlue
Copy link
Collaborator

OneBlue commented Oct 12, 2020

WSL doesn't support that per-say, but you can achieve this behavior by creating an auto-start entry.

For your scenario, something like:

REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /V "Mount PhysicalDrive4" /t REG_SZ /F /D "C:\Windows\System32\wsl.exe --mount \.\PHYSICALDRIVE4 --partition 1"

Should do the trick.

@OneBlue OneBlue closed this as completed Oct 12, 2020
@wandersonca
Copy link

@OneBlue , this seams like a valid feature request. Having to modify the system registry seems like a hack.

Having the ability for WSL2 to auto mount an ext4 volume would be very useful.

@OneBlue
Copy link
Collaborator

OneBlue commented Dec 3, 2020

I do agree that this feature would be nice to have, but for now running wsl --mount at startup is the simplest way to achieve this.

This doesn't have to be done in the registry though, a startup app or a scheduled task would work as well.

@jibbers42
Copy link

@OneBlue I feel like @wandersonca was attempting to subtly object to closing this issue. Can this be reopened to serve as a feature request (or maybe you have a link to where it's already being tracked)?

@wandersonca
Copy link

Yup, not sure why this was closed. It's a valid feature request. Having users muck around in the registry to automount is not a good experience.

@mrwensveen
Copy link

The workaround proposed by @OneBlue doesn't work when restarting the WSL instance. Can we reopen this feature request?

@atkinson
Copy link

atkinson commented Feb 9, 2022

The reg hack workaround doesn't work because "Administrator access is needed to mount a disk".

@huangzhenming
Copy link

The reg hack workaround doesn't work because "Administrator access is needed to mount a disk".

No, it does not work.

But i find a workaround. Here's my trick.

  1. create a windows batch file, mount your disk by using this script.
    for ex: wsl --mount \.\PHYSICALDRIVE0 --partition 2
  2. create a windows scheduled task, here's my setting:
    regular setting: check the last check box "run with highest user permission"
    trigger: any user login
    operations: run "c:\data\mount_wsl_disks.bat"
    then you can logout and login again to see if it work.

@arashi01
Copy link

arashi01 commented May 23, 2022

@OneBlue This issue doesn't seem to have a workaround that covers all the use-cases mentioned here and in #6414 and #8032. Can this be re-examined and/or re-opened?

@gjf7
Copy link

gjf7 commented Jul 9, 2022

Any updates on this ?

@JessicaMulein
Copy link

+1
I'm using WSL to host some personal websites and all my old docker infra depends on an IP per site. It'd be nice to persist this reliably on bootup in .wslconfig or wsl.conf

@ghost
Copy link

ghost commented Sep 8, 2022

i'm very, very upset with being unable to do this properly

@Penumbra69
Copy link

Q: If I'm in a shell, and I do 'wsl --shutdown` - which one of these workaround options given above will re-mount when WSL is invoked again?

A: None.

Please re-open this and track as a feature request at least, or point us to the place it is being tracked and we'll pile on there. I have MANY ext4/etc. drives I need access to, and it's becoming imperative that they stay attached, or at the very least re-attach themselves like a modern OS knows how to do. If we can trick it via 'fstab' - I'm in .. I just need SOME kind of mechanism to ensure these drives stay mounted.

Thanks.
P

@charlie0129
Copy link

charlie0129 commented Oct 4, 2022

I have a workaround which can handle manual WSL restarts. Since WSL can execute Windows commands, we can let WSL mount a drive when WSL starts.

By doing this, the drive can always be automatically mounted whenever WSL starts (including manually restating WSL). The WSL experience will stay the same.

Here's how.

  1. Create a task that will mount the drives

Use Task Scheduler to create a task called mount-wsl-disks. WSL will execute this task later to mount the drives.

This is just to get elevated permissions without seeing UAC dialogs (so that we can mount something). If you have UAC completely disabled, this is not required.

Something to note:

  • Check Gerneral->Run with highest privileges
  • Add your mount command wsl --mount xxx to Actions
  1. Edit /etc/wsl.conf to execute a script whenever WSL starts

Note: only available in Windows 11

[boot]
command="bash /boot.sh"
  1. Create /boot.sh

Inside /boot.sh, just execute another script called /wsl-boot.sh, so we can keep its output inside /wsl-boot.log for debugging purposes.

#!/bin/bash
/bin/bash /wsl-boot.sh > /wsl-boot.log 2>&1
  1. Create /wsl-boot.sh
#!/bin/bash
# This will be executed whenever WSL starts.

# Execute the task we created before.
/mnt/c/Windows/system32/schtasks.exe /run /tn "mount-wsl-disks"
# Since mounting will take some time, if you need to do something with the mounted drives later,
# you will need to write some logic to wait for it to be ready.

By doing these 4 steps, the drive should be able to automatically mount.

@akash07k
Copy link

akash07k commented Nov 3, 2022

Thanks a lot for the workaround.
It's really helpful.

I have a workaround which can handle manual WSL restarts. Since WSL can execute Windows commands, we can let WSL mount a drive when WSL starts.

By doing this, the drive can always be automatically mounted whenever WSL starts (including manually restating WSL). The WSL experience will stay the same.

Here's how.

  1. Create a task that will mount the drives

Use Task Scheduler to create a task called mount-wsl-disks. WSL will execute this task later to mount the drives.

This is just to get elevated permissions without seeing UAC dialogs (so that we can mount something). If you have UAC completely disabled, this is not required.

Something to note:

  • Check Gerneral->Run with highest privileges
  • Add your mount command wsl --mount xxx to Actions
  1. Edit /etc/wsl.conf to execute a script whenever WSL starts

Note: only available in Windows 11

[boot]
command="bash /boot.sh"
  1. Create /boot.sh

Inside /boot.sh, just execute another script called /wsl-boot.sh, so we can keep its output inside /wsl-boot.log for debugging purposes.

#!/bin/bash
/bin/bash /wsl-boot.sh > /wsl-boot.log 2>&1
  1. Create /wsl-boot.sh
#!/bin/bash
# This will be executed whenever WSL starts.

# Execute the task we created before.
/mnt/c/Windows/system32/schtasks.exe /run /tn "mount-wsl-disks"
# Since mounting will take some time, if you need to do something with the mounted drives later,
# you will need to write some logic to wait for it to be ready.

By doing these 4 steps, the drive should be able to automatically mount.

@akash07k
Copy link

akash07k commented Nov 3, 2022

I wish that this feature can be added natively. will make the life quite easy

@crjmichiels
Copy link

Although @charlie0129 method works, this really should be a feature of WSL.

@ImpatientTurtle
Copy link

ImpatientTurtle commented Nov 5, 2022

I agree. I've been using his method as well as creating a PowerShell script to start docker containers that depend on the drive being mounted as restart: unless-stopped starts before the drive is mounted. Below is what I've been using to start the docker containers after the drive is mounted as a scheduled task to start 1 minute after login.
wsl.exe docker compose --file /home/user/pms-docker/docker-compose.yaml up --detach

@PaintOnBrush
Copy link

PaintOnBrush commented Nov 6, 2022

I have a oneline bat file that i use to detect my ocz trion drive and automount it:

it uses awk and grep.

i use chocolatey's awk and wimm's wit grep. just what I had onhand.

mountsdd.bat

@echo off
for  /f "usebackq tokens=*" %%i in (`wmic diskdrive list brief ^| grep -i ocz-trion100 ^| awk "{print $2}"`) do wsl --mount %%i --partition 1


.:edit:.
Be sure to replace "ocz-trion100" with a substring in the line of your drive (I used the Model column) listed in:

wmic diskdrive list brief

@akash07k
Copy link

akash07k commented Nov 6, 2022

@PaintOnBrush Thanks buddy, It's simple and neat. will try it

I have a oneline bat file that i use to detect my ocz trion drive and automount it:

it uses awk and grep.

i use chocolatey's awk and wimm's wit grep. just what I had onhand.

mountsdd.bat

@echo off
for  /f "usebackq tokens=*" %%i in (`wmic diskdrive list brief ^| grep -i ocz-trion100 ^| awk "{print $2}"`) do wsl --mount %%i --partition 1

@mhanuel26
Copy link

Hi @charlie0129 ,

I did all your steps (Windows 11) and I am getting issues, the log file indicates

<3>init: (11) ERROR: UtilAcceptVsock:244: accept4 failed 110

I know the task work as I have run it from the TaskScheduler.

I have follow exactly your steps. To test the start yo task I have restarted the wsl service Lxssmanager.

Any input?

Thanks.

@eternalphane
Copy link

@charlie0129's solution won't work if systemd is enabled (core.systemd and core.command seems conflict with each other). A workaround would be to utilize systemd to mount the virtual drive on boot.

/etc/wsl.conf

[automount]
mountFsTab=false

[boot]
systemd=true

mount-vhdx.service

[Unit]
Description=Mount VHDX for /etc/fstab
Before=local-fs-pre.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/mount-vhdx.sh

[Install]
WantedBy=multi-user.target

/usr/local/sbin/mount-vhdx.sh

#!/bin/bash

wsl='/mnt/c/Users/<username>/AppData/Local/Microsoft/WindowsApps/wsl.exe'
vhdx='<path to vhdx>'
export WSLENV="$WSLENV:WSL_UTF8/wp" WSL_UTF8=1
"$wsl" --mount --vhd "$vhdx" --bare > >(tr -d $'\r') 2> >(tr -d $'\r' >&2)

@HippocampusGirl
Copy link

Thank you for writing up these amazing workarounds!

I discovered that for mounting a physical disk, it can be necessary to ask for elevated permissions. This can be done by changing @eternalphane's /usr/local/sbin/mount-vhdx.sh like this:

#!/bin/bash

powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
"$powershell" \
        Start-Process \
        -Verb "RunAs" \
        -FilePath "wsl.exe" \
        -ArgumentList \"--mount\",\"--bare\",\"\\\\.\\PHYSICALDRIVE0\" \
        -Wait

@charlie0129
Copy link

@charlie0129's solution won't work if systemd is enabled (core.systemd and core.command seems conflict with each other).

I have no idea what caused the conflict. I have been using systemd too, but I don't have this issue in my experience.

@LetrixZ
Copy link

LetrixZ commented Feb 27, 2023

I discovered that for mounting a physical disk, it can be necessary to ask for elevated permissions. This can be done by changing @eternalphane's /usr/local/sbin/mount-vhdx.sh like this:

#!/bin/bash

powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
"$powershell" \
        Start-Process \
        -Verb "RunAs" \
        -FilePath "wsl.exe" \
        -ArgumentList \"--mount\",\"--bare\",\"\\\\.\\PHYSICALDRIVE0\" \
        -Wait

This works, but it makes the UAC appear.

@merc4derp
Copy link

@charlie0129

This method works but only when running as logged in user, which creates annoying terminal popups every time the task runs.

If set to run when any user is logged in, it does nothing. No error returned on the wsl log nor the task scheduler. It just doesn't work.

What gives?

@shaoyangdl
Copy link

shaoyangdl commented Aug 5, 2023

To mount a physical disk, simply create sh script with the code given by @LetrixZ and @eternalphane and add it to ~/.profile, that works for me

#!/bin/bash

powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
"$powershell" \
        Start-Process \
        -Verb "RunAs" \
        -FilePath "wsl.exe" \
        -ArgumentList \"--mount\",\"--bare\",\"\\\\.\\PHYSICALDRIVE0\" \
        -Wait

@arshadlab
Copy link

Thanks @charlie0129 for the nice workaround. Works great. Can use belowlogic to add wait for mount to appear.

#!/bin/bash
# This will be executed whenever WSL starts.

# Execute the task we created before.
/mnt/c/Windows/system32/schtasks.exe /run /tn "mount-wsl-disks"
# Since mounting will take some time, if you need to do something with the mounted drives later,
# you will need to write some logic to wait for it to be ready.
timeout=10  # seconds
interval=1  # check every second

elapsed=0

# Assuming /dev/sdd3 will be the mount drive
while [ ! -e /dev/sdd3 ]; do
    if [ $elapsed -ge $timeout ]; then
        echo "Timed out waiting for /dev/sdd4 to be ready."
        exit 1
    fi

    echo "Waiting for /dev/sdd3 to be ready..."
    sleep $interval
    elapsed=$((elapsed + interval))
done

mount /dev/sdd3 ~/mountpoint

@perara
Copy link

perara commented Oct 22, 2023

Based on all of these excellent comments i ended up with the following for mounting bare-disks automatically

Creating Task for mounting disk to wsl

@echo off
setlocal

:: Set your physical drive variable
set PHYSICAL_DRIVE=PHYSICALDRIVE2

:: Create the task
schtasks /create /tn "mount-wsl-disks" /tr "C:\Windows\System32\wsl.exe --mount \\.\%PHYSICAL_DRIVE% --bare" /sc onstart /ru "NT AUTHORITY\SYSTEM" /rl highest /f

:: Note:
:: /tn specifies the name of the task
:: /tr specifies the command to run
:: /sc specifies the schedule, in this case, "onstart" for when the system starts
:: /ru specifies the user context under which the task should run
:: /rl specifies to run with highest privileges
:: /f forces the creation of the task and overwrites if exists

endlocal

Boot script in linux

Configure mount point and disk partition. sudo nano /mount.sh

#!/bin/bash

# Task name
task_name="mount-wsl-disks"

# Windows system path
windows_sys_path="/mnt/c/Windows/system32"

# Command to execute task
task_command="schtasks.exe /run /tn"

# Timeout and interval in seconds
timeout=10
interval=1

# Drive to check and mount
target_drive="/dev/sdf1"

# Mount point
mount_point="~/mnt/disk"

# Execute the task
$windows_sys_path/$task_command "$task_name"

# Initialize elapsed time counter
elapsed=0

# Wait for the target drive to be ready
while [ ! -e $target_drive ]; do
    if [ $elapsed -ge $timeout ]; then
        echo "Timed out waiting for $target_drive to be ready."
        exit 1
    fi

    echo "Waiting for $target_drive to be ready..."
    sleep $interval
    elapsed=$((elapsed + interval))
done

# Mount the target drive
mount $target_drive $mount_point

Configure wsl.conf

[boot]
command="bash /boot.sh"

This works flawlessly on my system. Creds goes to everyone above :)

@arshadlab
Copy link

arshadlab commented Oct 23, 2023

Thanks for the script version of creating task however I am getting "Access denied" when running task in mount-wsl-disks. This is due to "NT AUTHORITY\SYSTEM". Error goes away when using regular user name to create task. Another modification could be to replace onstart with 'once' else the task will trigger on every boot even before wsl is loaded. The start date can be any far future date.

USER_NAME="username"
:: Create the task
schtasks /create /tn "mount-wsl-disks" /tr "C:\Windows\System32\wsl.exe --mount \.%PHYSICAL_DRIVE% --bare" /sc once /sd 01/01/2100 /st 00:00 /it /ru %USER_NAME% /rl highest /f

@stefan-berkner-tilotech

I create a full guide on how to set this up with an encrypted disk: https://medium.com/@stefan.berkner/automatically-starting-an-external-encrypted-ssd-in-windows-subsystem-wsl-6403c34e9680
Thanks everyone for your input. It took way too long to figure this stuff out.

@razamatan
Copy link

razamatan commented Feb 18, 2024

following on @stefan-berkner-tilotech's script based solution, i made a gist that integrates this with an openrc init. you can do something similar if you're running w/ systemd and adapt my openrc solution.

https://gist.github.com/razamatan/dcdc7188b0bd643401adeeccbc8164c8

@FeignMan
Copy link

FeignMan commented Apr 23, 2024

Wow, just passing by, but this thread right here is a great example of what's wrong with Tech.

@OneBlue , this seams like a valid feature request. Having to modify the system registry seems like a hack.

Having the ability for WSL2 to auto mount an ext4 volume would be very useful.

This clearly needs to be a feature, it has been stated multiple times, and in spite of this extremely clear comment, someone proposed a (broken) workaround, and then closed the entire thread, never to be seen again. GG WP

What's the excuse for not implementing this as a clean feature, instead making the community run around in circles for 3.5 years? Is it because Microsoft is a cash-strapped non-profit that's making WSL for the public good?

Big thanks to everyone else here for their solutions and ideas.

@SheepReaper
Copy link

To mount a physical disk, simply create sh script with the code given by @LetrixZ and @eternalphane and add it to ~/.profile, that works for me

#!/bin/bash

powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
"$powershell" \
        Start-Process \
        -Verb "RunAs" \
        -FilePath "wsl.exe" \
        -ArgumentList \"--mount\",\"--bare\",\"\\\\.\\PHYSICALDRIVE0\" \
        -Wait

This here I used as a single solution. I'm ok with accepting UAC whenever wsl restarts. In my case, since I mounted the bare drive and then initialized it to gpt with fdisk and then formatted it to ext4, I had to provide some additional options. The simple path check was so that I wouldn't get duplicate prompts with every new session started (launching vscode multiple times). The path to check is the autogenerated one that wsl creates from the PhysicalDrive + number + partition. This won't work if you have things that require the volume sooner, but it gets the job done for me with minimal effort.

I went the PhysicalDrive route even though this is a vhdx, because it stays mounted through restarts, though I suppose passing --vhd to the wsl --mount <path to vhdx> command might work as well, but I was getting some file/device in use errors. Letting disk manager take it, seemed simpler and might reduce shared access problems. (Not that I need that for my use case.)

if [ ! -d "/mnt/wsl/PhysicalDrive12p1" ]; then
    powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
    "$powershell" \
        Start-Process \
        -Verb "RunAs" \
        -FilePath "wsl.exe" \
        -ArgumentList \"--mount\",\"\\\\.\\PhysicalDrive12\",\"--partition\",\"1\",\"--type\",\"ext4\" \
        -Wait
fi

@skeppern
Copy link

skeppern commented Jun 23, 2024

I use this as a workaround to mount two VHDX drives and it is working perfectly. If you do not have a NOPASSWD for your user in sudoers the WSL instance will ask for your password at startup since sudo commands is needed to make this work.

Put this in your ~/.profile or ~/.bashrc or ~/.zshrc or what default shell you are using.

# Run the wsl.exe from within the WSL instance to mount the actual VHDX files to WSL.
sudo /mnt/c/Users/<your_windows_username>/AppData/Local/Microsoft/WindowsApps/wsl.exe -d Ubuntu-20.04 --mount --vhd E:/vhd/1tb.vhdx --bare
sudo /mnt/c/Users/<your_windows_username>/AppData/Local/Microsoft/WindowsApps/wsl.exe -d Ubuntu-20.04 --mount --vhd F:/vhd/4tb.vhdx --bare

# Create folders to mount if they do not exist, i chose the /mnt/wsl/ because its shared between wsl's like Docker Desktop.
if [ ! -d /mnt/wsl/mount1 ]; then
    sudo mkdir /mnt/wsl/mount1
fi
if [ ! -d /mnt/wsl/mount2 ]; then
    sudo mkdir /mnt/wsl/mount2
fi

# Finally mount the drives as specified in /fstab or mount them one by one manually here or later.
sudo mount -a

@SheepReaper
Copy link

I use this as a workaround to mount two VHDX drives and it is working perfectly. If you do not have a NOPASSWD for your user in sudoers the WSL instance will ask for your password at startup since sudo commands is needed to make this work.

Put this in your ~/.profile or ~/.bashrc or ~/.zshrc or what default shell you are using.

# Run the wsl.exe from within the WSL instance to mount the actual VHDX files to WSL.
sudo /mnt/c/Users/<your_windows_username>/AppData/Local/Microsoft/WindowsApps/wsl.exe -d Ubuntu-20.04 --mount --vhd E:/vhd/1tb.vhdx --bare
sudo /mnt/c/Users/<your_windows_username>/AppData/Local/Microsoft/WindowsApps/wsl.exe -d Ubuntu-20.04 --mount --vhd F:/vhd/4tb.vhdx --bare

# Create folders to mount if they do not exist, i chose the /mnt/wsl/ because its shared between wsl's like Docker Desktop.
if [ ! -d /mnt/wsl/mount1 ]; then
    sudo mkdir /mnt/wsl/mount1
fi
if [ ! -d /mnt/wsl/mount2 ]; then
    sudo mkdir /mnt/wsl/mount2
fi

# Finally mount the drives as specified in /fstab or mount them one by one manually here or later.
sudo mount -a

wsl.exe also takes a --name option. That becomes the mount point under /mnt/wsl/ you shouldn't need to explicitly create the mount points. using fstab might not be necessary either, depending on your use case. If you just need to mount a specific partition from the disk, you can use --partition and --type (if it's not ext4). Your use of --bare is what's preventing the mount inside of Ubuntu. The device is mounted but not the partitions. (Though that might be intentional for your use case, idk, can't read minds.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests