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

distrod doesn't run user.slice? #13

Open
rockorequin opened this issue Nov 19, 2021 · 16 comments
Open

distrod doesn't run user.slice? #13

rockorequin opened this issue Nov 19, 2021 · 16 comments

Comments

@rockorequin
Copy link

After installing distrod, systemctl status only showed init.scope and system.slice running - there is no user.slice (and user-1000.slice, etc). Have I done something wrong? Or if not, there is a way perhaps to configure it to run the user systemd units? I was hoping to get gvfs-daemon running to allow nautilus to connect to sftp:// locations.

I installed distrod as per the instructions to add it to my existing distro, ie I downloaded and ran install.sh with the install argument and then ran "/opt/distrod/bin/distrod enable" (both as sudo, as the commands complain if not run as sudo). I then terminated wsl with "wsl --shutdown" (note that "wsl --terminate Distrod" as per the instructions didn't work, since I had only added distrod to my existing distro, so Distrod did not exist) and re-ran wsl.

@nullpo-head
Copy link
Owner

there is no user.slice

Yes, that's right. It is how Distrod runs today. I've been putting off implementing user slice because I didn't think there were that many use cases for it in WSL, where everyone has root. gvfs is something I missed and yes it looks reasonable use case. I add it to my backlog.

As a workaround, if you run sudo login -f user_name command once, a session under the user.slice will start. Or, you can do ssh into localhost.

@lungothrin
Copy link

+1

@rockorequin
Copy link
Author

Thanks, looking forward to it.

Once distrod automatically starts user slice, does this mean that if I run wsl:vlc from the windows Start Menu that an sftp network link will work?

@nullpo-head
Copy link
Owner

I'm not exactly sure what you want to do because I'm not familiar with wsl:vlc, but apps launched from the start menus will also run under the systemd session and slices. So, if what you want depends on just systemd's user slices, it will successfully run. Of course I have to confirm by actually implementing it, though!

@rockorequin
Copy link
Author

I was just using wsl:vlc as a short cut to saying "run vlc from wsl from the start menu". Sorry, it must have been confusing!

@nullpo-head
Copy link
Owner

@lopugit

Yes, this issue is a duplicate of #13. As a workaround, do sudo login -f username once. user slice will be implemented later.

How often do I have to do this though? Just once ever or every session or?

To just trigger user systemd services, do it once per boot of WSL instance.
To use systemctl --user, do it when you want to use systemctl --user. In the session you started y login, you can use systemctl --user.

@lopugit
Copy link

lopugit commented Nov 29, 2021

@lopugit

Yes, this issue is a duplicate of #13. As a workaround, do sudo login -f username once. user slice will be implemented later.

How often do I have to do this though? Just once ever or every session or?

To just trigger user systemd services, do it once per boot of WSL instance. To use systemctl --user, do it when you want to use systemctl --user. In the session you started y login, you can use systemctl --user.

Thanks a lot, really appreciate it

@sarim
Copy link

sarim commented Apr 16, 2022

I'm not familiar with systemd internals, but is it possible that when distrod is creating the "bottle", it also runs sudo login -f user_name and then puts the shell sessions inside that?

@sarim
Copy link

sarim commented Jun 1, 2022

@nullpo-head How can we add PAMName property when executing $SHELL? Adding that properly creates the shell with systemd user slice/session.

So long story short, I was doing a deep dive on how these systemd stuffs work and how to enable systemd user session. Geine uses this command machinectl shell -q [email protected] /bin/bash to run shell. And it creates systemd user session. After looking through systemd source for how machinectl shell executes it, I found this:

https://github.com/systemd/systemd/blob/main/src/machine/machine-dbus.c#L732

The important property here is PAMName. I can replicate it with systemd-run.

So In a distrod configued wsl distro, I can execute the following commands to get a shell with systemd user session.

# from powershell start wsl to root user
wsl -d UbuntuMain --user root
# now in ubuntu, inside systemd thanks to distrod
systemd-run --pty --service-type=simple --uid=gittu -p PAMName=login /bin/bash

# now in user session. Can run the followings succesfully
env | grep XDG
systemctl --user status

So can this be added to distrod? I don't know rust but looking at the code of distrod and geine, while geine executes commands like "machinectl daemonize unshare systemd" to do its job, distrod seems to be doing these programatically by api call? Is it a builtin or a rust library to interface with linux systemd / namespace etc... ? Maybe there is a option to add PAMName=login there?

Or you can maybe simply append systemd-run --pty --service-type=simple --uid=USERNAME -p PAMName=login to shell command?

Update:

I've created a small hack in go to run in user session: https://github.com/sarim/gbash

@mgood7123
Copy link

mgood7123 commented Jul 15, 2022

!!! WORKAROUND !!!

#64

create a /etc/wsl.conf with the contents

[user]
default=root

next edit /etc/profile.d/distrod-user-wsl-envs.sh to look like the following

#!/bin/sh

# Load additional WSL session environment variables at runtime by sourcing
# a script Distrod creates at runtime. A Linux user who launches Distrod first
# can manipulte the contents of this script, so the script file is per-user one
# to prevent the user from manipulating other user's environment variables.

if [ -e "/run/distrod/distrod_wsl_env-uid$(id -u)" ]; then
    . "/run/distrod/distrod_wsl_env-uid$(id -u)"
fi

# If the creator of the script is root, a non-root user loading it is harmless
if [ "$(id -u)" != 0 ] && [ -e "/run/distrod/distrod_wsl_env-uid0" ]; then
    . "/run/distrod/distrod_wsl_env-uid0"
fi

if [ "$(id -u)" == 0 ]; then
    # replace `archlinux` with your username
    su - archlinux -p -c "sudo -S login -f archlinux"
fi
PS C:\Users\small> wsl --shutdown
PS C:\Users\small> wsl
su: ignoring --preserve-environment, it's mutually exclusive with --login
[sudo] password for archlinux:
Last login: Fri Jul 15 22:32:05 on pts/0
[archlinux@DESKTOP-VJSURS0 ~]$ systemctl status
Failed to dump process list for 'DESKTOP-VJSURS0', ignoring: Input/output error
● DESKTOP-VJSURS0
    State: running
    Units: 201 loaded (incl. loaded aliases)
     Jobs: 0 queued
   Failed: 0 units
    Since: Fri 2022-07-15 22:32:20 AEST; 14s ago
  systemd: 251.3-1-arch
  Tainted: cgroupsv1
   CGroup: /
[archlinux@DESKTOP-VJSURS0 ~]$ systemctl status --user
● DESKTOP-VJSURS0
    State: running
    Units: 111 loaded (incl. loaded aliases)
     Jobs: 0 queued
   Failed: 0 units
    Since: Fri 2022-07-15 22:32:23 AEST; 14s ago
  systemd: 251.3-1-arch
  Tainted: cgroupsv1
   CGroup: /user.slice/user-1000.slice/[email protected]
           └─init.scope
             ├─85 /usr/lib/systemd/systemd --user
             └─86 "(sd-pam)"
[archlinux@DESKTOP-VJSURS0 ~]$

@joouha
Copy link

joouha commented Sep 6, 2022

I found that enabling user-linger means that the user-session gets launched automatically when WSL boots:

sudo loginctl enable-linger user_name

@mgood7123
Copy link

mgood7123 commented Sep 6, 2022

I found that enabling user-linger means that the user-session gets launched automatically when WSL boots:

sudo loginctl enable-linger user_name

That might break systemd, not sure

@joouha
Copy link

joouha commented Sep 8, 2022

I don't think it will break systemd. Enabling linger means that the systemd user instance is started right after boot, and kept running after the last session closes.

This basically means that my user's user-1000.slice gets started automatically without the need to run sudo login -f user_name at every boot.

It's not how I'd do things on a desktop linux install, but for my use-case with WSL it suits me.

@mgood7123
Copy link

@nullpo-head How can we add PAMName property when executing $SHELL? Adding that properly creates the shell with systemd user slice/session.

So long story short, I was doing a deep dive on how these systemd stuffs work and how to enable systemd user session. Geine uses this command machinectl shell -q [email protected] /bin/bash to run shell. And it creates systemd user session. After looking through systemd source for how machinectl shell executes it, I found this:

https://github.com/systemd/systemd/blob/main/src/machine/machine-dbus.c#L732

The important property here is PAMName. I can replicate it with systemd-run.

So In a distrod configued wsl distro, I can execute the following commands to get a shell with systemd user session.

# from powershell start wsl to root user
wsl -d UbuntuMain --user root
# now in ubuntu, inside systemd thanks to distrod
systemd-run --pty --service-type=simple --uid=gittu -p PAMName=login /bin/bash

# now in user session. Can run the followings succesfully
env | grep XDG
systemctl --user status

So can this be added to distrod? I don't know rust but looking at the code of distrod and geine, while geine executes commands like "machinectl daemonize unshare systemd" to do its job, distrod seems to be doing these programatically by api call? Is it a builtin or a rust library to interface with linux systemd / namespace etc... ? Maybe there is a option to add PAMName=login there?

Or you can maybe simply append systemd-run --pty --service-type=simple --uid=USERNAME -p PAMName=login to shell command?

Update:

I've created a small hack in go to run in user session: https://github.com/sarim/gbash

this works for ubuntu kenetic wsl2 windows 11

my original one fails, idk why

Welcome to Ubuntu Kinetic Kudu (development branch) (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

The programs included with the Ubuntu system are free software;

the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

-bash: cannot set terminal process group (28): Inappropriate ioctl for device
-bash: no job control in this shell

$ systemctl status --user
Failed to connect to bus: Permission denied

@mgood7123
Copy link

mgood7123 commented Oct 4, 2022

@nullpo-head How can we add PAMName property when executing $SHELL? Adding that properly creates the shell with systemd user slice/session.

So long story short, I was doing a deep dive on how these systemd stuffs work and how to enable systemd user session. Geine uses this command machinectl shell -q [email protected] /bin/bash to run shell. And it creates systemd user session. After looking through systemd source for how machinectl shell executes it, I found this:

https://github.com/systemd/systemd/blob/main/src/machine/machine-dbus.c#L732

The important property here is PAMName. I can replicate it with systemd-run.

So In a distrod configued wsl distro, I can execute the following commands to get a shell with systemd user session.

# from powershell start wsl to root user
wsl -d UbuntuMain --user root
# now in ubuntu, inside systemd thanks to distrod
systemd-run --pty --service-type=simple --uid=gittu -p PAMName=login /bin/bash

# now in user session. Can run the followings succesfully
env | grep XDG
systemctl --user status

So can this be added to distrod? I don't know rust but looking at the code of distrod and geine, while geine executes commands like "machinectl daemonize unshare systemd" to do its job, distrod seems to be doing these programatically by api call? Is it a builtin or a rust library to interface with linux systemd / namespace etc... ? Maybe there is a option to add PAMName=login there?

Or you can maybe simply append systemd-run --pty --service-type=simple --uid=USERNAME -p PAMName=login to shell command?

Update:

I've created a small hack in go to run in user session: https://github.com/sarim/gbash

combined with this, it works for windows 11 ubuntu kinetic

!!! WORKAROUND !!!

#64

create a /etc/wsl.conf with the contents

[user]
default=root

next create a /etc/profile.d/systemd-fix.sh with the following contents

if [ "$(id -u)" == 0 ]; then

    # put your user name here
    SYSTEMD_ROOT_LOGIN_NAME_DISTROD=USER

    # start distrod if it has not already been started
    /opt/distrod/bin/distrod start

    # wait for systemd to start, systemd is started by distrod
    while [ ! -e /var/run/dbus/system_bus_socket ];
        do
            echo "waiting for systemd to start..."
            sleep 1
    done

    # fix DISPLAY for wslg on windows 11
    export DISPLAY="$(grep nameserver /etc/resolv.conf | sed 's/nameserver //'):0"
    rm -r /tmp/.X11-unix
    ln -s /mnt/wslg/.X11-unix /tmp/.X11-unix


    # login to our user shell, we have no easy way to inherit our parent environment so we must manually specify it
    # use -l to preserve our path, attempting to declare our path manually will fail

    systemd-run --pty --service-type=simple --uid=$SYSTEMD_ROOT_LOGIN_NAME_DISTROD -p PAMName=login --same-dir -E DISPLAY="$DISPLAY" -E WAYLAND_DISPLAY="$WAYLAND_DISPLAY" -E PULSE_SERVER="$PULSE_SERVER" -E WT_PROFILE_ID="$WT_PROFILE_ID" -E WT_SESSION="$WT_SESSION" -E WSLENV="$WSLENV" -E HOSTTYPE="$HOSTTYPE" -E LS_COLORS="$LS_COLORS" -E WSL_INTEROP="$WSL_INTEROP" -E WSL_DISTRO_NAME="$WSL_DISTRO_NAME" -E NAME="$NAME" -E WSL2_GUI_APPS_ENABLED="WSL2_GUI_APPS_ENABLED" /bin/bash -l
    
    # systemd-run above will execute a bash shell, automatically dropping us into our user shell, blocking here
    # we never enter the root unless `$ su` or `$ sudo -i` is used from the user shell
 
    # the following command runs after the user has exited the bash shell
    # by exiting here, we exit the root shell that wsl starts to drop us into our user shell
    # this avoids us having to exit twice when we only entered once:
    # PS C:\Users\small> wsl
    # Waiting for system socket
    # Waiting for system socket
    # Running as unit: run-u8.service
    # Press ^] three times within 1s to disconnect TTY.
    # user@LAPTOP-5PKRTSDE:/$ exit
    # exit
    # root@LAPTOP-5PKRTSDE:/mnt/c/Users/small# exit
    # logout
    # PS C:\Users\small> 

    exit
fi

unfortunately this breaks su

a workaround is sudo bash

PS C:\Users\small> C:\Users\small\Downloads\distrod_wsl_launcher-x86_64\distrod_wsl_launcher-x86_64\distrod_wsl_launcher.exe

        ██████╗ ██╗███████╗████████╗██████╗  ██████╗ ██████╗
        ██╔══██╗██║██╔════╝╚══██╔══╝██╔══██╗██╔═══██╗██╔══██╗
        ██║  ██║██║███████╗   ██║   ██████╔╝██║   ██║██║  ██║
        ██║  ██║██║╚════██║   ██║   ██╔══██╗██║   ██║██║  ██║
        ██████╔╝██║███████║   ██║   ██║  ██║╚██████╔╝██████╔╝
        ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝ ╚═════╝ ╚═════╝
=================================================================================
Thanks for trying Distrod! Choose your distribution to install.
You can install a local .tar.xz, or download an image from linuxcontainers.org.

* linuxcontainers.org is a vendor-neutral project that offers distro images for
  containers, which is not related to Distrod. LXC/LXD is one of its projects.
  BTW, you can run Systemd with distrod, so you can try LXC/LXD with distrod!
=================================================================================
[1] Use a local tar.xz file
[2] Download an image from linuxcontainers.org
[Distrod] Choose the way to get a distro image from the list above.
[Distrod] Type the name or the index of your choice.
[Default: Download an image from linuxcontainers.org]:
[Distrod] Fetching from linuxcontainers.org...
[1] almalinux
[2] alpine
[3] alt
[4] amazonlinux
[5] apertis
[6] archlinux
[7] busybox
[8] centos
[9] debian
[10] devuan
[11] fedora
[12] funtoo
[13] gentoo
[14] kali
[15] mint
[16] opensuse
[17] openwrt
[18] oracle
[19] plamo
[20] pld
[21] rockylinux
[22] springdalelinux
[23] ubuntu
[24] voidlinux
[Distrod] Choose a linuxcontainers.org image from the list above.
[Distrod] Type the name or the index of your choice.
[Default: ubuntu]:
[Distrod] Fetching from linuxcontainers.org...
[1] bionic
[2] focal
[3] xenial
[4] jammy
[5] kinetic
[Distrod] Choose a version from the list above.
[Distrod] Type the name or the index of your choice.
[Default: focal]: 5
[Distrod] Fetching from linuxcontainers.org...
[Distrod] Downloading 'https://images.linuxcontainers.org/images/ubuntu/kinetic/amd64/default/20221003_07:43/rootfs.tar.xz'...
  [00:00:27] [##################################################] 102.64MiB/102.64MiB (3.77MiB/s, 0s)
[Distrod] Download done.
[Distrod] Unpacking and merging the given rootfs to the distrod rootfs. This may take a while...
[Distrod] Now Windows is installing the new distribution. This may take a while...
[Distrod] Distrod is installed in %LocalAppData%\Distrod
[Distrod] Done!
[Distrod] Please input the new Linux user name. This doesn't have to be the same as your Windows user name.
[Distrod] Configuration done.
[Distrod] Installation of Distrod is now complete.
psp@LAPTOP-5PKRTSDE:/mnt/c/Users/small$ sudo -i
[sudo] password for psp:
root@LAPTOP-5PKRTSDE:~# apt install nano
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Suggested packages:
  hunspell
The following NEW packages will be installed:
  nano
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 282 kB of archives.
After this operation, 889 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu kinetic/main amd64 nano amd64 6.4-1 [282 kB]
Fetched 282 kB in 3s (91.4 kB/s)
Selecting previously unselected package nano.
(Reading database ... 16315 files and directories currently installed.)
Preparing to unpack .../archives/nano_6.4-1_amd64.deb ...
Unpacking nano (6.4-1) ...
Setting up nano (6.4-1) ...
update-alternatives: using /bin/nano to provide /usr/bin/editor (editor) in auto mode
update-alternatives: using /bin/nano to provide /usr/bin/pico (pico) in auto mode
root@LAPTOP-5PKRTSDE:~# nano /etc/wsl.conf
root@LAPTOP-5PKRTSDE:~# nano /etc/profile.d/systemd-fix.sh
root@LAPTOP-5PKRTSDE:~# exit
logout
psp@LAPTOP-5PKRTSDE:/mnt/c/Users/small$ exit
logout
[Distrod] Hit enter to exit.

PS C:\Users\small> wsl --shutdown
PS C:\Users\small> wsl
[Distrod][ERROR] There is already a running distro.
waiting for systemd to start...
Running as unit: run-u2.service
Press ^] three times within 1s to disconnect TTY.
PS C:\Users\small> wsl --user psp
psp@LAPTOP-5PKRTSDE:/mnt/c/Users/small$ sudo bash
[sudo] password for psp:
root@LAPTOP-5PKRTSDE:/mnt/c/Users/small# nano /etc/profile.d/systemd-fix.sh # forgot to change user name
root@LAPTOP-5PKRTSDE:/mnt/c/Users/small# exit
exit
psp@LAPTOP-5PKRTSDE:/mnt/c/Users/small$ exit
logout
PS C:\Users\small> wsl --shutdown
PS C:\Users\small> wsl
[Distrod][ERROR] There is already a running distro.
waiting for systemd to start...
Running as unit: run-u2.service
Press ^] three times within 1s to disconnect TTY.
psp@LAPTOP-5PKRTSDE:/$ systemctl status --user
● LAPTOP-5PKRTSDE
    State: running
    Units: 103 loaded (incl. loaded aliases)
     Jobs: 0 queued
   Failed: 0 units
    Since: Tue 2022-10-04 17:07:20 AEST; 9s ago
  systemd: 251.4-1ubuntu6
  Tainted: cgroupsv1
   CGroup: /user.slice/user-1001.slice/[email protected]
           └─init.scope
             ├─140 /lib/systemd/systemd --user
             └─141 "(sd-pam)"
psp@LAPTOP-5PKRTSDE:/$ systemctl status
Failed to dump process list for 'LAPTOP-5PKRTSDE', ignoring: Input/output error
● LAPTOP-5PKRTSDE
    State: running
    Units: 241 loaded (incl. loaded aliases)
     Jobs: 0 queued
   Failed: 0 units
    Since: Tue 2022-10-04 17:07:19 AEST; 16s ago
  systemd: 251.4-1ubuntu6
  Tainted: cgroupsv1
   CGroup: /
psp@LAPTOP-5PKRTSDE:/$

@huangz986
Copy link

I found that enabling user-linger means that the user-session gets launched automatically when WSL boots:
sudo loginctl enable-linger user_name

That might break systemd, not sure

You are right, enable-linger for the user breaks the user's systemd, at least on my machine. You saved my time.

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

No branches or pull requests

8 participants