1

I have a existing physical Ubuntu 20.04 Desktop system running on a SSD with ext4 as the file system.

I mounted the SSD into the WSLg Ubuntu in Windows 11.

To keep the same experience as much as possible, I want to use the mounted SSD as the main system disk to replace the default installation of Ubuntu in WSLg.

Is that possible?

I have tried chroot into the SSD in WSLg and successfully ran some CLI software. But it failed to launch all those GUI applications like Jetbrains IDEs.

What's more, after migration, I wish I could still boot into the same physical Ubuntu system using the same SSD when needed.

3
  • 2
    Short answer: No, not possible or even desirable. Commented Nov 18, 2021 at 10:37
  • @ChanganAuto Just curious, what makes you so sure? You may be right, but heck, I'm a pessimist/realist by nature and I can see some hope of this working. I can at least see the possibility of solving the chroot issue by mapping the Interop socket. Commented Nov 18, 2021 at 19:12
  • @NotTheDr01ds Thanks! Could you please provide more informations about the mapping the Interop socket ? Commented Nov 20, 2021 at 3:43

2 Answers 2

2

While I'm not sure (yet) that there's a way to use the drive as a WSL instance itself, I do think we can get the chroot method working, at least to some degree.

Here's the setup that I used:

  • Ubuntu Base 21.10 rootfs image extracted (as sudo) to $HOME/chroot/Ubuntu21.10.
  • For testing, after the below configuration was completed, apt install xterm
  • For anyone attempting this with an actual rootfs, note that you should untar with the xattrs option, e.g.:
    # Download Ubuntu Base rootfs into the current directory, then:
    mkdir Ubuntu21.10
    cd !$
    sudo tar -xvz --xattrs -f ../ubuntu-base-21.10-base-amd64.tar.gz
    

Off the top of my head, I can't see a reason that this wouldn't be a semi-accurate representation of an existing SSD that you've been able to mount into a directory inside of a WSL/Ubuntu instance. However, I'm sure there will be items I didn't anticipate from your configuration. Let me know via comment here (plus possibly via new question if warranted) if you run into issues.

What's working

  • Networking
  • Running Windows .exes from within the chroot (including GUI apps)
  • Running Linux GUI apps from within the chroot (requires, of course, Windows 11)

What's known not to work

  • Cannot mount Windows drives from within the chroot (e.g. mount -t drvfs ...). This is likely due to the fact that I haven't yet been able to find a way to mount the special WSL drivers and lib filesystems. Everything else works here via either a mount of the actual filesystem into the chroot path or via a mount --bind ("bind mount") of an existing path from WSL into the chroot path.

  • The Windows path is not populated into that of the chroot (which WSL normally does via /init. This means that you will have to use the fully-qualified path to run any .exes. Populating the path isn't all that difficult to script, but this answer is long enough as it is, so I'll leave the as an exercise to the reader (or a separate question).

Not Tested

  • Audio: If it doesn't work, then it's probably just a matter of finding the right environment variables, or perhaps one more socket to mount if needed.

  • VSCode: May have issues due to "default user" expectation on VSCode's part)

  • Lots of other stuff

One-time prep

There are a few tasks to prep the chroot filesystem for the first time.

  • From inside WSL (not in the chroot), create mountpoints and copy over some WSL items:

    cd <your_chroot_mountpoint_root>
    # Create mount points
    sudo mkdir mnt/c
    sudo mkdir run/WSL
    sudo mkdir mnt/wslg
    sudo mkdir mnt/wsl
    sudo mkdir -p usr/lib/wsl/drivers usr/lib/wsl/lib
    
    # Copy WSL generated config files - Currently doesn't work, but there for future reference/use
    # sudo cp /etc/ld.so.conf.d/ld.wsl.conf etc/ld.so.conf.d
    
    # Delete existing resolv.conf and use the one generated by WSL
    sudo rm etc/resolv.conf
    sudo ln -rs mnt/wsl/resolv.conf etc/
    
    # Delete existing X socket (if exists) and use the one generated by WSL
    [ -S tmp/.X11-unix ] && sudo rm tmp/.X11-unix
    [ -f tmp/.X11-unix ] && sudo rm tmp/.X11-unix
    [ -L tmp/.X11-unix ] && sudo rm tmp/.X11-unix
    sudo ln -rs mnt/wslg/.X11-unix/ tmp/.X11-unix
    
    # Set up fstab for recurring mount points.
    
    # (0) Make sure you are in the root of the chroot
    #     (the mounted drive, in your case) before
    #     running each command.
    # (A) I suggest running these lines one-by-one to make sure
    #     they work since ...
    # (B) They are not idempotent
    # (C) Check /etc/fstab after each one.  They should be 
    # pointing to the appropriate directory in your chroot
    
    # Set up bind mounts for the WSL generated sockets and files:
    sudo sh -c 'echo "/mnt/wsl $PWD/mnt/wsl none bind 0 0" >> /etc/fstab'
    sudo sh -c 'echo "/mnt/wslg $PWD/mnt/wslg none bind 0 0" >> /etc/fstab'
    #sudo sh -c 'echo "/run/WSL $PWD/run/WSL none bind 0 0" >> /etc/fstab' # Currently causes issues
    
    # Create fstab entries for the necessary filesystems.  For
    # the most part, we do this by finding the entry in 
    # /etc/mtab that WSL generated, copying that over to
    # /etc/fstab, and substituting the chroot path.
    
    sudo sh -c "grep '^drvfs[[:space:]]\+/mnt/c\W' /etc/mtab | sed \"s-\(/mnt/c\)-${PWD}\1-\" >> /etc/fstab"
    sudo sh -c "grep '^none[[:space:]]\+/dev[[:space:]]' /etc/mtab | sed \"s-\(/dev\)-${PWD}\1-\" >> /etc/fstab"
    sudo sh -c "grep '^proc[[:space:]]\+/proc[[:space:]]' /etc/mtab | sed \"s-\(/proc\)-${PWD}\1-\" >> /etc/fstab"
    sudo sh -c "grep '^devpts[[:space:]]\+/dev/pts[[:space:]]' /etc/mtab | sed \"s-\(/dev/pts\)-${PWD}\1-\" >> /etc/fstab"
    sudo sh -c "grep '^sysfs[[:space:]]\+/sys[[:space:]]' /etc/mtab | sed \"s-\(/sys\)-${PWD}\1-\" >> /etc/fstab"
    sudo sh -c "grep '^binfmt_misc[[:space:]]\+/proc/sys/fs/binfmt_misc[[:space:]]' /etc/mtab | sed \"s-\(/proc/sys/fs/binfmt_misc\)-${PWD}\1-\" >> /etc/fstab"
    
    # Mount these newly added entries in `/etc/fstab`.  Only needed once -- From here on out, they will automount when you restart the WSL instance:
    sudo mount -a
    
  • There's one thing that doesn't quite work here. We can't seem to bind mount /run/WSL via /etc/fstab. I believe this is due to a timing issue -- WSL probably hasn't completed mounting the original /run/WSL, so we can't yet bind mount it. Attempting to do so will result in an error at WSL start-up. This error is not fatal.

    You have several options. You can either: * Run the commented-out line above to generate the fstab entry, deal with the error, and then run sudo mount -a after you restart WSL (or add it to a startup file) * Just run sudo mount --bind /run/WSL/ $PWD/run/WSL/ (from inside the chroot root directory) after a WSL restart (Or add it to a startup file).

Starting the chroot:

sudo chroot $PWD env WSL_INTEROP="$WSL_INTEROP" DISPLAY="$DISPLAY" WAYLAND_DISPLAY="$WAYLAND_DISPLAY" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" /usr/bin/bash

This populates the environment with the necessary environment variables before starting the shell. There may be additional variables that you want to map, and that's easy enough.

I recommend an apt update to start. This will at least tell you if DNS resolution is working. If not, check the /etc/resolv.conf symlink.

Other startup alternatives include creating a user with the same name as in your WSL instance and then:

sudo chroot $PWD env WSL_INTEROP="$WSL_INTEROP" DISPLAY="$DISPLAY" WAYLAND_DISPLAY="$WAYLAND_DISPLAY" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" runuser -u $USER /usr/bin/bash
6
  • did you manage to get audio working? Commented Dec 21, 2022 at 18:19
  • it is not necessary to be on windows 11 to get the above working. windows 10 build version 10.0.19045.2311 or above is sufficient to mount a linux disk on a different drive. github.com/microsoft/WSL/issues/7940#issuecomment-1320365216 Commented Dec 21, 2022 at 18:27
  • @JoannMorris I honestly haven't looked at it since the question was asked a while back. But with what I know now, I think I can get it to work. It might be a few days before I get a chance to try it out, though. Check back in regularly, and I'll Ping you when I update it. Commented Dec 21, 2022 at 18:39
  • @JoannMorris and yes, it's now possible on Windows 10 as well. I just have 100's of answers here, so I typically only spot the ones that need updating when there's new activity on it. ;-) Commented Dec 21, 2022 at 18:43
  • 1
    @NotTheDroids I got audio working. set the following variables PULSE_SERVER="/mnt/wslg/PulseServer" XDG_RUNTIME_DIR="/run/user/$chroot_id" #where chroot_id is the id of the user within linux also mount bindfs --map=$wsl_id/$chroot_id:@$wsl_group/@$chroot_group /mnt/wslg/runtime-dir $disk/run/user/$chroot_id I mounted the following for good measure mount --bind /run/systemd/ $disk/run/systemd mount --bind /run/dbus/ $disk/run/dbus mount --bind /run/WSL/ $disk/run/WSL/ Commented Dec 22, 2022 at 18:19
1

extension of @NotTheDr01ds answer. set the following variable to get audio working within chroot environment.

PULSE_SERVER="/mnt/wslg/PulseServer"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .