nullpo-head / wsl-distrod

Distrod is a meta-distro for WSL 2 which installs Ubuntu, Arch, Debian, Gentoo, etc. with systemd in a minute for you. Distrod also has built-in auto-start feature on Windows startup and port forwarding ability.
MIT License
1.9k stars 90 forks source link

[Bug]: failed to spawn the command: no such file or directory (OS error 2) #90

Closed nerditation closed 12 months ago

nerditation commented 1 year ago

Describe the bug

I tried to enable distrod in an newly installed opensuse tumbleweed wsl instance, but I got this error, so I disabled distrod and try to troubleshoot following instructions in #9, I got the same error after many attempt, even when I try to execute the simplest command I can think of:

sudo /opt/distrod/bin/distrod-exec /bin/true true

Steps to reproduce

install opensuse-tumbleweed, from https://aka.ms/wsl-opensuse-tumbleweed install distrod sudo /opt/distrod/bin/distrod enable restart wsl instance

Expected behavior

open login shell

Windows version

windows 10 22H2 (OS build 19045.2965)

Linux kernel version

Linux LAPTOP 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Distro

opensuse-tumbleweed

How did you install that distro?

Enabled distrod in an existing WSL2 distro

Logs

~> sudo /opt/distrod/bin/distrod-exec /bin/true true
[Distrod][DEBUG] distrod-exec: exec_command_in_distro
[Distrod][DEBUG] starting /init from distrod-exec
[Distrod][DEBUG] WSL envs: "WSL_INTEROP" = "/run/WSL/58_interop"
[Distrod][DEBUG] WSL envs: "WSL_DISTRO_NAME" = "openSUSE-Tumbleweed"
[Distrod][DEBUG] WSL envs: "WSLENV" = "TERM:COLORTERM:TERM_PROGRAM:TERM_PROGRAM_VERSION"
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/run/distrod/cmdline")), target: ContainerPath("/proc/cmdline"), fstype: None, flags: MS_BIND, is_file: true
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd"
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system"
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system/portproxy.service"
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/opt/distrod/run/systemd/system/portproxy.service")), target: ContainerPath("/run/systemd/system/portproxy.service"), fstype: None, flags: MS_BIND, is_file: true
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system/systemd-tmpfiles-clean.service.d"
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf"
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/opt/distrod/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf")), target: ContainerPath("/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf"), fstype: None, flags: MS_BIND, is_file: true
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system/systemd-tmpfiles-setup.service.d"
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf"
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/opt/distrod/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf")), target: ContainerPath("/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf"), fstype: None, flags: MS_BIND, is_file: true
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/tmpfiles.d"
[Distrod][TRACE] mount_distrod_run_files: path: "/opt/distrod/run/tmpfiles.d/x11.conf"
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/mnt/wslg/.X11-unix")), target: ContainerPath("/tmp/.X11-unix"), fstype: None, flags: MS_BIND, is_file: false
[Distrod][DEBUG] DistroLauncher::launch
[Distrod][DEBUG] Container::with_mount source: Some(HostPath("/run/distrod/distrod_wsl_env-uid0")), target: ContainerPath("/run/distrod/distrod_wsl_env-uid0"), fstype: None, flags: MS_BIND, is_file: true
[Distrod][DEBUG] Spawning the command or the waiter.
[Distrod][TRACE] mounting source: Some(
    ContainerPath(
        "/run/distrod/cmdline",
    ),
), mount: ContainerMount { source: Some(HostPath("/run/distrod/cmdline")), target: ContainerPath("/proc/cmdline"), fstype: None, flags: MS_BIND, data: None, is_file: true }
[Distrod][DEBUG] Executing a command in the distro.
[Distrod][DEBUG] Failed to ignore signal Sys(EINVAL)
[Distrod][TRACE] mounting source: Some(
    ContainerPath(
        "/opt/distrod/run/systemd/system/portproxy.service",
    ),
), mount: ContainerMount { source: Some(HostPath("/opt/distrod/run/systemd/system/portproxy.service")), target: ContainerPath("/run/systemd/system/portproxy.service"), fstype: None, flags: MS_BIND, data: None, is_file: true }
[Distrod][DEBUG] Failed to ignore signal Sys(EINVAL)
[Distrod][TRACE] mounting source: Some(
    ContainerPath(
        "/opt/distrod/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf",
    ),
), mount: ContainerMount { source: Some(HostPath("/opt/distrod/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf")), target: ContainerPath("/run/systemd/system/systemd-tmpfiles-clean.service.d/exclude_wslg_sockets.conf"), fstype: None, flags: MS_BIND, data: None, is_file: true }
[Distrod][DEBUG] Distro::exec_command.
[Distrod][TRACE] mounting source: Some(
    ContainerPath(
        "/opt/distrod/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf",
    ),
), mount: ContainerMount { source: Some(HostPath("/opt/distrod/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf")), target: ContainerPath("/run/systemd/system/systemd-tmpfiles-setup.service.d/exclude_wslg_sockets.conf"), fstype: None, flags: MS_BIND, data: None, is_file: true }
[Distrod][DEBUG] Container::exec_command.
[Distrod][TRACE] mounting source: Some(
    ContainerPath(
        "/mnt/wslg/.X11-unix",
    ),
), mount: ContainerMount { source: Some(HostPath("/mnt/wslg/.X11-unix")), target: ContainerPath("/tmp/.X11-unix"), fstype: None, flags: MS_BIND, data: None, is_file: false }
[Distrod][DEBUG] Triple fork done.
[Distrod][DEBUG] dropping privilege. kmsg logging in the child ends here.
[Distrod][DEBUG] The parent of the second of three forks exits.
[Distrod][DEBUG] Spawning the command or the waiter.
[Distrod][DEBUG] Spawning the waiter.
[Distrod][DEBUG] Failed to ignore signal Sys(EINVAL)
[Distrod][DEBUG] Failed to ignore signal Sys(EINVAL)
[Distrod][TRACE] skipping an identical mount: Some(
    ContainerPath(
        "/run/distrod/distrod_wsl_env-uid0",
    ),
), ContainerMount {
    source: Some(
        HostPath(
            "/run/distrod/distrod_wsl_env-uid0",
        ),
    ),
    target: ContainerPath(
        "/run/distrod/distrod_wsl_env-uid0",
    ),
    fstype: None,
    flags: MS_BIND,
    data: None,
    is_file: true,
}
nerditation@PENG-PRO-LAPTOP:~> [Distrod][ERROR] Failed to spawn the command.

Caused by:
    No such file or directory (os error 2)

additional comment

I enabled distrod in another debian-stable wsl instance and it works fine. I don't know what's the difference between the distros and how to fix it.

nerditation commented 12 months ago

since wsl2 now has built in support for systemd, I'll close this issue.

just for the reference, it turns out opensuse by default doesn't have a /sbin/init symlink, which should point to /usr/lib/systemd/systemd. but distrod assumes /sbin/init always exists so it panics.

if I manually create the symlink, it will work fine. alternatively, zypper install wsl_systemd would also solve the crash, because the package wsl_systemd actually creates the symlink (and contains a /etc/wsl.conf config file to enable the built in systemd support).