WSL 2 GUI trouble - Can't open Synaptic nor pluma with using the sudo command
I installed WSL 2 and the Mate Desktop Environment. I can log in via xrdp. I can browse the system and the internet but I'm missing some features like opening synaptic or open an editor with the sudo command. Also some settings from within the control center does not open and I'm not able to change the desktop language. Is there a workaround with installing some needed packages to get that managed? Or by editing some files and rights?
Thanks a lot
Summary
The question is a bit light in details, but I think I can reproduce much (if not all) of it. There are likely two problems that are causing the issues listed in the question:
- WSL's current lack of Systemd support
- The root user needs a link to
.Xauthority
Installation
Ok, let's start with the installation process to make sure we are on the same page. In a new WSL/Ubuntu 20.04 instance, I did the following:
sudo apt update && sudo apt upgrade
sudo apt install ubuntu-mate-desktop xrdp synaptic
# Selected lightdm for login during install, but I don't think it matters
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini
echo "mate-session" > ~/.xsession
Created ~/.xsessionrc
with:
export XDG_SESSION_DESKTOP=mate
export XDG_CURRENT_DESKTOP=ubuntu:mate
export XDG_DATA_DIRS=/usr/share/mate:/usr/local/share:/usr/share:/var/lib/snapd/desktop
export XDG_CONFIG_DIRS=/etc/xdg/xdg-mate:/etc/xdg
And then started xrdp
via:
sudo service xrdp start
Initial startup
At that point, I was able to use Windows Remote Desktop Connection on localhost:3390
to connect to the MATE desktop.
I immediately received an error with blueman-applet
crashing. No real surprise here, since WSL doesn't have Bluetooth support, but I probably wouldn't expect a crash. Running blueman-applet
from the terminal shows more info, culminating in:
__bus = Gio.bus_get_sync(Gio.BusType.SYSTEM)
gi.repository.GLib.Error: g-io-error-quark: Could not connect: No such file or directory (1)
Hmm. Sounds like a bus problem. Let's come back to that one ...
A few moments later, I get another crash from update-manager
. Again, running from the terminal shows me:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.FileNotFound: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
Okay, we definitely have some issues. You may not even be noticing these at this point since those errors seem to be suppressed after the first occurrence.
sudo issues
> sudo pluma does_this_work.txt
No protocol specified
Cannot open display:
Run 'pluma --help' to see a full list of available command line options.
A similar problem occurs with Synaptic.
This is fairly easily solved via this answer:
sudo ln -s $HOME/.Xauthority /root
Now sudo synaptic
and sudo pluma
work correctly.
Can't change language and other settings problems
Attempting to open Language Settings from the Control Center results in the window attempting to display but then crashing immediately. Again, let's look at the terminal output of gnome-language-selector
:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.FileNotFound: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
Hey, I'm sensing a pattern here ...
The root cause and (hopefully) solution
Gnome requires Systemd. WSL does not use Systemd, but instead uses its own /init
as PID1. See my answer here for some details on what it does. Most importantly for this discussion, note that it appends the Windows path to the Linux/WSL path and handles Interop so that you can launch Windows .exe
cutables.
It is possible to make Ubuntu in WSL think that Systemd is in control, and we need to do that in order for Gnome to work properly.
I'm going to give you the simplest possible solution. It is not necessarily the best solution. Because it is "barebones", you will lose the ability to run Windows .exe
cutables. You will also lose the Windows path, but since that's really only useful for running Windows programs anyway, we'll consider that part of the same limitation.
If you want a more complex solution that attempts to solve this, look to some of the answers in this SO question, specifically Genie or WSL2 Hacks.
But all of these are just more complex versions of this:
sudo -b unshare --pid --fork --mount-proc /lib/systemd/systemd --system-unit=multi-user.target
This starts Systemd in a new namespace with its own PID mapping. Inside that namespace, Systemd will be PID1 (as it must, to function properly) and own all other processes. However, the "real" PID mapping still exists outside that namespace.
Wait a few seconds, run ps -ef
. If you see a number of /lib/systemd/systemd-udevd
processes, then Systemd is still starting up. Give it a moment and try again.
Note that systemd
is not yet PID1. That's because we have created the namespace, but we haven't entered it yet.
When the process list "settles down", Systemd is ready to go. On my system, that's really only 5 seconds or so. At that point, enter the namespace with:
sudo -E nsenter --all --wd="$PWD" -t $(pgrep -xo systemd) runuser -P -l $USER -c "exec $SHELL"
Doing a ps -ef
at this point will show systemd
as PID1, along with all of the other services that it brings up.
Best practice is to disable any Systemd units that you don't need, but it's not necessary to get things from MATE running better.
Now that we are in the Systemd namespace:
sudo systemctl start xrdp
sudo systemctl status xrdp
And then try connecting via RDP.
At this point, things are working about as well as I think you could ask:
- You can change your language (takes effect after logging out of MATE and reconnecting via RDP)
- You can access the Users & Groups settings, Disk settings, etc.
- You cannot access Bluetooth, since there is no hardware support, but at least it gives the proper message now, rather than crashes.
- You should not do any network or firewall configuration, as WSL still needs to manage this
Note
Once you have started Systemd in an instance, it "takes over". At startup, it creates numerous files and starts processes. If you were to start another WSL Ubuntu session at the same time, you will likely face issues if you don't enter the namespace. For instance:
> sudo service xrdp status
Failed to retrieve unit state: Connection reset by peer
Failed to get properties: Connection reset by peer
This is because the service
command detects that certain files in /var/run
have been created by Systemd and attempts to use Systemd if so.
If you want to return to a "normal" WSL working environment, where Interop works (e.g. you can run Visual Studio Code), then you must (from PowerShell or CMD) wsl --terminate <distroname>
(distroname is likely Ubuntu
) and then restart WSL.