Discoveries in the Course of Pushing Limits #144
Replies: 3 comments 4 replies
-
Nice write up. If you are curious as to why we decided to run the system distro as a sort of parent of it's associated user distro, it was two fold. First to allow us to share IPC namespace so we can use shared memory seamlessly (for example for X11 MIT-SHM protocol)... also because the system distro sometime needs to attach to the pid and mountspace of the user distro it's paired with (to find .desktop file, load icon files, etc...). That seemed the nicest and cleanest way to achieve this transparently. |
Beta Was this translation helpful? Give feedback.
-
On Making WSLg and Systemd Play Nicely Together(in genie, anyway; also, credit for a lot of this should go to @diddledan , who figured it out first for his systemd solution) There are three things genie does to play nicely with WSLg: 1. Copy the environment variables.When systemd is started up inside its nice new pid namespace, it doesn't inherit the environment of the user distro namespace; which is what you want, really. Starting a systemd-as-pid-1 is essentially booting a Linux system, so it's starting from a clean slate. For this reason, genie already included mechanisms to clone certain environment variables (WSL_DISTRO_NAME,WSL_INTEROP,WSLENV) and the outside path into the "bottle" to keep essential functions working, so it was as simple as adding the WSLg environment variables (DISPLAY,WAYLAND_DISPLAY,PULSE_SERVER) to the default list to be cloned. 2. Map the /tmp/.X11-unix/X0 socketSystemd, in its default configuration, does a lot of things to initialize the system. Unfortunately for us, one of them is to clean up the /tmp directory, via a unit named systemd-tmpfiles-setup, which blows away the link WSLg has established to the XWayland socket at /mnt/wslg/.X11-unix/X0. (Ordinarily, this is desirable - on a regular Linux system, it would be cleaning up detritus left over from previous boots.) This is a very important link, since X will look for the Unix sockets for local displays in /tmp/.X11-unix and nowhere else. Now, we could just disable that unit, or edit the configuration files for systemd-tmpfiles not to touch that folder, but ideally we would like to make this work without having to modify bits of existing distros, especially bits that are fairly deeply embedded in their startup sequence. So instead, we make and install a couple of systemd units of our own, taking advantage of systemd-socket-proxyd: wslg-xwayland.socket
And wslg-xwayland.service
which arranges for systemd itself to proxy connections to the X server to the proper location for WSLg. 3. Mount the runtime directory in the expected placeWSLg locates the various other sockets and files used to access parts of it under /mnt/wslg/runtime-dir. For most purposes, this is fine, since the environment variables inform clients of that, and everything works. But then you get to things like snaps, or certain apparmor profiles, or other things that expect the user runtime directory to exist under /usr/run/{UID} and will break if it doesn't find it there. To deal with this one, we need the systemd unit that sets up the user runtime directories to instead use the WSLg runtime directory, but only for the primary user . That criterion is because things expect the user runtime directory to be owned by the user it is for, which (for /mnt/wslg/runtime-dir) is UID 1000 (wslg, inside the system distro); conveniently, though, user distros tend to set up the first user created as UID 1000 also, and the /mnt/wslg/runtime-dir will be perceived as owned by this user from inside the user distro. To achieve this, we add an override file to the [email protected], as follows: [email protected]/override.conf
running one of these two scripts: map-user-runtime-dir.sh
map-user-runtime-dir.sh
These don't replace the default [email protected]; it still creates the user runtime directory under /run/user. What they do do is check if WSLg is present on the machine, and then check if the user they are currently creating a runtime directory for is the user who owns the /mnt/wslg/runtime-dir directory (i.e., has UID 1000) If so, they bind mount the WSLg runtime directory over the /run/user/{UID} directory, and then everything is in the right place for the purposes of those apps with expectations about these things. Note: a side-effect of this is that other applications that use the user runtime directory will be creating their sockets, files, etc., under the WSLg runtime directory - for example, my /mnt/wslg/runtime-dir looks like this, with the various other things I run:
I've observed no adverse or indeed non-adverse side-effects from this (and it is, after all, a tmpfs), but it's probably worth noting for reference. I hope this helps you if you're trying to put together your own systemd/WSLg hack. Of course, you could just use mine... 😁 |
Beta Was this translation helpful? Give feedback.
-
The Dbus Status Quo - An Early LookIf you glance again at the process tree up at the start of this thread, you will see that I have four dbus-daemon instances running, between the system and user distros. Let's go through them one by one. First, there is a dbus-daemon running as a direct child of
Apparently a session bus. I have no idea what this one is doing yet, because I can't connect to it even with the help of Second, there is a dbus-daemon running as a child of
This would appear to be a conventional system bus. Looking at the names it knows about --
If my understanding is correct - and I freely admit that my understanding of DBus and associated matters is, at the moment, quite limited - there's nothing actually registered with this one. org.freedesktop.DBus is the service which represents the dbus-daemon itself. That sums up the dbus-daemons found in the system distro. Now, as for the user distro, the only dbus-daemons in there are the ones created by my systemd (using the genie hack), both system and session. I won't bother running through all the details of those when you just as easily can get them from your own distro, but the important point is that everything that uses DBus in the user session is talking to them:
As such, I think - if one is willing to use a systemd hack or other method to get both dbus-daemons running in your user session - I don't think DBus is a locus of problems, at this time, for getting Gnome or other DBus-using applications to work under WSL/WSLg, or at least I have not found such problems yet. Anyone who knows more about DBus and how it is used, please do correct any bad assumptions or errors of fact I have made in this post! TOMORROW: those Gnome bits I have got working, and how; those Gnome bits I have not got working, and wild speculation as to why... |
Beta Was this translation helpful? Give feedback.
-
To expand on that title, I'm Alistair Young ( @cerebrate ), and have spent rather a lot of time since WSL originally shipped pushing it to do things which, shall we say, weren't exactly in the original design specs. (The most prominent fruit of this is genie, a utility which lets you run systemd and all of its associated services inside WSL, officially supported or no.) My habits haven't changed since the advent of WSLg, so this thread is going to serve me as a place to share the things I discover in the course of pushing on WSLg with my fellow hackers and lunatics.
So, let's begin with this one:
What you are looking at here is a process tree taken from inside the WSLg system distribution on my machine, while it is running a single Debian distribution, while it is in turn running genie and systemd. As you can see, namespace transitions are included next to those processes which use them, so you can see what's going on.
If you've been following along with WSL hackery for long, you know that every distro running inside WSL essentially runs inside its own container-style namespace(s), sharing the single kernel instance and VM. This is why, for example, kernel threads don't show up in a
ps aux
, and certain non-namespaced features are shared between distros so that, for example, kernel modules loaded in one distro show up when youlsmod
in a different distro.WSLg appears to complicate this a bit. In the leftmost major column there, you have the processes of the system distribution, but what you will notice, the second major column, is that the processes of the user distribution, my Debian distro, are child processes of the system distro's init. That is to say, the user distro now runs as a mount, pid, and UTS namespace within the system distro.
Under that you can see genie's work (the line containing
unshare
andsystemd
) which creates another mount and pid namespace in order to create an environment in which systemd can own pid 1. While the details of the implementation vary, this much is common to all the hacks which run systemd under WSL. And then beneath it, in turn, you can see all the systemd services (including the user systemd) which it is happy to manage for you.Below it, you can see genie invoking machinectl, which is its way to get systemd-containerd to handle all the work of setting up a login session properly for it.
So, yes, the best way I've found to run everything is in a container inside a container inside a container...
COMING SOON: I talk about getting WSLg to work in this arrangement, dbus and its travails, and the bits of Gnome that you can see working there...
Beta Was this translation helpful? Give feedback.
All reactions