Use the existing user D-Bus session bus instead of spawning dbus-launch - #212
Open
Fantu wants to merge 3 commits into
Open
Use the existing user D-Bus session bus instead of spawning dbus-launch#212Fantu wants to merge 3 commits into
Fantu wants to merge 3 commits into
Conversation
…bus-launch. require_dbus_session() only looked at DBUS_SESSION_BUS_ADDRESS, so with the variable unset it re-exec'd the session under `dbus-launch --exit-with-session` even when the user already had a session bus running on the well-known socket at $XDG_RUNTIME_DIR/bus (the default on systemd, and on elogind setups with dbus configured for the user bus). That starts a second bus, splitting activatable services and portals across the two, and on systems that ship no dbus-launch binary (Debian with only dbus-user-session installed) the session does not start at all. X11 logins usually escape this because the display manager wraps the session in a script that exports DBUS_SESSION_BUS_ADDRESS, but the Wayland session does not go through those wrappers, so it depends on the display manager. Ask GDBus for the session bus address first: it looks for the socket at $XDG_RUNTIME_DIR/bus, and we export the address so every child of the session ends up on the same bus. The dbus-launch fallback stays for setups without a user bus, so nothing changes there. This is what gnome-session does in leader-main.c. Closes: linuxmint#210 Assisted-by: Claude Code:claude-opus-5
The declared minimum, 2.37.3, has not matched the code for a long time: g_settings_schema_list_keys() in csm-autostart-app.c needs 2.46, g_strv_contains() and the g_autoptr/g_autofree macros need 2.44, and the GSubprocess and GVariantDict API need 2.40. Ask for 2.50 rather than 2.46: that is the version where g_dbus_address_get_for_bus_sync() started falling back to the well-known socket at $XDG_RUNTIME_DIR/bus, which is what lets the previous commit pick up the user session bus instead of spawning dbus-launch. Assisted-by: Claude Code:claude-opus-5
execvp() returns only when it failed, and then it always returns -1, so `if (!execvp (...))` was never true: the g_set_error() branch was dead code. Instead of failing with "No session bus and could not exec dbus-launch", require_dbus_session() fell through to the `return TRUE` marked "Should not be reached" and the session kept going with no session bus at all, silently, until something else broke further down. Call execvp() and treat its return as the failure it is. This is easier to hit than it looks on systems that ship no dbus-launch binary, and the previous commit does not change that: it only makes the fallback rarer, not the failure mode better. Assisted-by: Claude Code:claude-opus-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #210.
require_dbus_session()only looks atDBUS_SESSION_BUS_ADDRESS. When that variable is unset it re-execs the whole session underdbus-launch --exit-with-session, even when the user already has a session bus running on the well-known socket at$XDG_RUNTIME_DIR/bus— the default under systemd, and also the case on elogind setups with dbus configured for the user bus.Two things go wrong:
dbus-launchbinary (a Debian install with onlydbus-user-session, nodbus-x11) that fallback cannot work at all.X11 logins usually escape this because the display manager wraps the session in a script that exports
DBUS_SESSION_BUS_ADDRESS; the Wayland session does not go through those wrappers, so it depends on the display manager.What the branch does
main.c: Use the existing user D-Bus session bus instead of spawning dbus-launch.dbus-launchfallback stays for setups without a user bus. This is what gnome-session does inleader-main.c.build: Require GLib 2.50.g_settings_schema_list_keys()needs 2.46,g_strv_contains()and theg_autoptr/g_autofreemacros need 2.44, GSubprocess and GVariantDict need 2.40). 2.50 is the version whereg_dbus_address_get_for_bus_sync()gained the fallback to$XDG_RUNTIME_DIR/busthat the first commit relies on.main.c: Report the failure when dbus-launch cannot be executed.execvp()returns only when it failed, and then always returns-1, soif (!execvp (...))was never true and theg_set_error()branch was dead code: instead of failing with "No session bus and could not exec dbus-launch", the function fell through to thereturn TRUEmarked "Should not be reached" and the session carried on with no session bus at all, silently. Found while testing this branch.Testing
Tested against 6.6.4 on Debian sid —
require_dbus_session()is identical there and on master, so the change applies unmodified. Both a package build (sbuild, sid chroot) and a real desktop session (KVM VM, lightdm + Cinnamon, X11 and Wayland) were used.Behaviour of
require_dbus_session(), checked withstrace -f -e trace=execveoncinnamon-session --version, which runs before option parsing:$XDG_RUNTIME_DIR/bus, variable unsetdbus-launch, which forks a seconddbus-daemon --sessiondbus-launchexec at all, address taken from the running user busdbus-launchavailabledbus-launchdbus-launchUnable to start session: No session bus and could not exec dbus-launch: No such file or directory, session abortsReal session, lightdm autologin into Cinnamon:
org.cinnamon.*services plus the gtk/xapp portals on it,systemctl --user show-environmentconsistent, no seconddbus-daemon --session.Exec=env -u DBUS_SESSION_BUS_ADDRESS cinnamon-session-cinnamon --wayland), which is what a display manager that does not export it looks like. With the branch, the session starts and its children inheritDBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus. Without it, and withdbus-x11installed, the session dies at startup —Unable to start session: Lost name on bus: org.gnome.SessionManager— and lightdm falls back to the greeter.Two notes for whoever reviews this, since they explain why the bug is rarely seen:
pam_systemditself that exportsDBUS_SESSION_BUS_ADDRESS(checked on systemd 261: the string is inpam_systemd.so, and without PAM the variable is absent). So every PAM session — X11, Wayland,su -, ssh — already has it, and thedbus-launchpath is unreachable there. The change matters for setups that do not get it from PAM, elogind among them.dbus-launchinstalled, the session still comes up today, because every GIO client falls back to$XDG_RUNTIME_DIR/buson its own; the children just never see the variable. The visible breakage needsdbus-launchto be present.Related Debian bug: https://bugs.debian.org/835846