我有一个现有的物理 Ubuntu 20.04 桌面系统,运行在 SSD 上,以 ext4 作为文件系统。
我将 SSD 安装到 Windows 11 中的 WSLg Ubuntu 中。
为了尽可能保持相同的体验,我想使用挂载的SSD作为主系统磁盘来取代WSLg中Ubuntu的默认安装。
那可能吗?
我尝试在 WSLg 中 chroot 到 SSD 并成功运行了一些 CLI 软件。但它无法启动所有 GUI 应用程序,例如 Jetbrains IDE。
而且,迁移后,我希望在需要时仍然能够使用相同的 SSD 启动相同的物理 Ubuntu 系统。
答案1
虽然我还不确定是否有办法将驱动器本身用作 WSL 实例,但我确实认为我们可以使 chroot 方法发挥作用,至少在某种程度上。
以下是我使用的设置:
- Ubuntu Base 21.10 rootfs 映像提取(作为 sudo)到
$HOME/chroot/Ubuntu21.10
。 - 为了进行测试,完成以下配置后,
apt install xterm
- 对于任何尝试使用实际 rootfs 进行此操作的人,请注意您应该使用以下
xattrs
选项解压,例如:# 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
我一眼就看出来,这完全可以准确表示您能够挂载到 WSL/Ubuntu 实例内目录中的现有 SSD。但是,我确信您的配置中肯定有一些我没有预料到的项目。如果您遇到问题,请通过此处的评论(如果有必要,也可以通过新问题)告诉我。
哪些措施有效
- 联网
.exe
在 chroot 中运行 Windows (包括 GUI 应用程序)- 在 chroot 中运行 Linux GUI 应用程序(当然需要 Windows 11)
已知不起作用的方法
无法从 chroot 中挂载 Windows 驱动器(例如
mount -t drvfs ...
)。这可能是因为我还没有找到挂载特殊 WSLdrivers
和lib
文件系统的方法。其他一切都可以通过将mount
实际文件系统的 a 放入 chroot 路径或通过将mount --bind
现有路径从 WSL 放入 chroot 路径(“绑定挂载”)来工作。Windows 路径未填充到 chroot 的路径中(WSL 通常通过 执行此操作)
/init
。这意味着您必须使用完全限定路径来运行任何.exe
s。填充路径对于脚本来说并不困难,但是这个答案已经够长了,所以我将把 作为练习留给读者(或单独的问题)。
未测试
音频:如果它不起作用,那么可能只是找到正确的环境变量的问题,或者可能需要安装一个套接字(如果需要)。
VSCode: 可能由于 VSCode 的“默认用户”期望而出现问题)
还有很多其他的东西
一次性准备
首次准备 chroot 文件系统时需要完成一些任务。
从 WSL 内部(而不是在 chroot 中)创建挂载点并复制一些 WSL 项目:
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
这里有一件事不太好用。我们似乎无法
/run/WSL
通过进行绑定挂载/etc/fstab
。我认为这是由于时间问题——WSL 可能尚未完成原始的挂载/run/WSL
,因此我们还无法对其进行绑定挂载。尝试这样做将导致 WSL 启动时出错。此错误并不致命。您有多种选择。您可以:* 运行上面注释掉的行以生成 fstab 条目,处理错误,然后
sudo mount -a
在重新启动 WSL 后运行(或将其添加到启动文件)* 只需sudo mount --bind /run/WSL/ $PWD/run/WSL/
在 WSL 重新启动后运行(从 chroot 根目录内部)(或将其添加到启动文件)。
启动 chroot:
sudo chroot $PWD env WSL_INTEROP="$WSL_INTEROP" DISPLAY="$DISPLAY" WAYLAND_DISPLAY="$WAYLAND_DISPLAY" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" /usr/bin/bash
这会在启动 shell 之前用必要的环境变量填充环境。您可能还想映射其他变量,这很容易。
我建议apt update
先启动。这至少会告诉您 DNS 解析是否正常工作。如果没有,请检查/etc/resolv.conf
符号链接。
其他启动替代方案包括创建与 WSL 实例同名的用户,然后:
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
答案2
@NotTheDr01ds 答案的扩展。设置以下变量以使音频在 chroot 环境中工作。
PULSE_SERVER="/mnt/wslg/PulseServer"