Bug 1078789

Summary: RFE: add support for starting X inside a user session for: https://fedoraproject.org/wiki/Changes/XorgWithoutRootRights
Product: [Fedora] Fedora Reporter: Hans de Goede <hdegoede>
Component: gdmAssignee: Ray Strode [halfline] <rstrode>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: grawity, peter.hutterer, rdieter, rstrode, walters
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1179368 (view as bug list) Environment:
Last Closed: 2016-05-20 15:20:53 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On:    
Bug Blocks: 1078902    

Description Hans de Goede 2014-03-20 10:29:28 UTC
Hi,

Please add support for starting X inside a user session, so the Xorg can work without being suid root,
for more details see:

https://fedoraproject.org/wiki/Changes/XorgWithoutRootRights

Thanks & Regards,

Hans

Comment 1 Hans de Goede 2014-03-20 10:39:36 UTC
Note this is sort-off being tracked upstream here:
https://bugzilla.gnome.org/show_bug.cgi?id=726380

Or at least that bug is related, since wayland needs to be started inside the user session too.

Comment 2 Ray Strode [halfline] 2014-04-11 19:06:54 UTC
I've started to hack this up as a proof of concept here:

https://git.gnome.org/browse/gdm/log/?h=wip/xinit-hack

but having worked on this, I think a better approach actually will be:

1) make the X server be socket activated (whether it's Xorg or Xwayland depends on if wayland is running when the socket is activated)
2) make the X server socket go to a well known name automatically in XDG_RUNTIME_DIR (if it's the first X server for the user) so DISPLAY doesn't need to be known ahead of time. 

Land this patch:
https://people.gnome.org/~walters/user-session-patches/xorg-lib-libX11/0001-XOpenDisplay-Use-new-xcb-API-to-instead-of-parsing-D.patch
and this patch
https://people.gnome.org/~walters/user-session-patches/xcb-libxcb/0001-Add-an-API-to-connect-to-a-pre-parsed-display-use-XD.patch
from walters.

3) make GDM stop starting the X server at all instead of persuing the xinit hack above.

I'll look into this more next week.

Comment 3 Hans de Goede 2014-04-11 19:14:24 UTC
Hi Ray,

Thanks for the update, this sounds good. My only worry is that this will only work when using systemd as user session manager. Otherwise we cannot do socket based activation inside a user session.

Regards,

Hans

Comment 4 Ray Strode [halfline] 2014-04-14 14:44:21 UTC
I think we can make this work without making the rest of the session be started by systemd --user.  Right now, the x server calles TakeControl on the session associated with the PID of the X server.  Instead it could call TakeControl on the session of the client that activated it (and failing that fall back to the first graphical session for the user)

Comment 5 Hans de Goede 2014-04-14 14:51:24 UTC
(In reply to Ray Strode [halfline] from comment #4)
> I think we can make this work without making the rest of the session be
> started by systemd --user.  Right now, the x server calles TakeControl on
> the session associated with the PID of the X server.  Instead it could call
> TakeControl on the session of the client that activated it (and failing that
> fall back to the first graphical session for the user)

This is not about deciding which session to call TakeControl on, in order to be allowed to TakeControl the server needs to be running as the user who owns that session, how are we going to tell the system level  systemd about that (assuming you want to use the system-level systemd to start the server in absence of a user session systemd). And the Xorg process needs to have the tty it is going to run on as owning tty to make vt-switching work without root rights, how is the system level systemd going to do that ?

Note I'm not saying this cannot be done, I'm happy with any solution you can come up with.

Comment 6 Ray Strode [halfline] 2014-04-14 15:19:58 UTC
Note, even today systemd --user is running when you log into your session.  It's automatically done when the logind session is registered.  It's just nothing is started from it.  We should be able make Xorg get started via socket activation for the systemd --user, without forcing the rest of the session to use systemd --user.  Of course, I think we should have a full blown systemd user session for GNOME, anyway, but I assumed your concern was about maintaining backward compatibility for other desktops.

Comment 7 Hans de Goede 2014-04-14 15:29:54 UTC
Hi,

(In reply to Ray Strode [halfline] from comment #6)
> Note, even today systemd --user is running when you log into your session. 
> It's automatically done when the logind session is registered.  It's just
> nothing is started from it.  We should be able make Xorg get started via
> socket activation for the systemd --user, without forcing the rest of the
> session to use systemd --user.

Ah yes, I did not know systemd --user was already running, but yes if it is then that using that sounds like a good idea. We would simply need to generate a unit for the socket activation on the fly in the user systemd unit dir before starting systemd (we need to do it on the fly as the display number and the vt need to be in there and those are both dynamic).

> Of course, I think we should have a full
> blown systemd user session for GNOME, anyway, but I assumed your concern was
> about maintaining backward compatibility for other desktops.

My main concern was this not working at all. But indeed getting other desktops to work when they are started from gdm is important too. Maybe we can just always start systemd --user for other desktops too, with only the X unit file ?

Regards,

Hans

Comment 8 Ray Strode [halfline] 2014-04-14 15:46:15 UTC
(In reply to Hans de Goede from comment #7)
> Ah yes, I did not know systemd --user was already running, but yes if it is
> then that using that sounds like a good idea. We would simply need to
> generate a unit for the socket activation on the fly in the user systemd
> unit dir before starting systemd (we need to do it on the fly as the display
> number and the vt need to be in there and those are both dynamic).
Well my proposal was that DISPLAY would be unset and we would make unset DISPLAY mean "connect to $XDG_RUNTIME_DIR/X11-socket".  So we shouldn't need to guess an available DISPLAY number ahead of time.

I'm hoping we can get away with a static configuration, but if we need to use a generator or something, that's probably okay I guess.

> My main concern was this not working at all. But indeed getting other
> desktops to work when they are started from gdm is important too. Maybe we
> can just always start systemd --user for other desktops too, with only the X
> unit file ?
Right, all desktops from all display managers at the moment get an empty systemd --user right now, since it's started from pam_systemd at log in time.

Comment 9 Ray Strode [halfline] 2014-04-16 20:04:08 UTC
(In reply to Ray Strode [halfline] from comment #4)
> Instead it could call TakeControl on the session of the client that activated
> it (and failing that fall back to the first graphical session for the user)

I started to look into this today and ran into a problem: the peer credentials of the received socket are associated with the systemd process, not with the X client initiating the activation.  Still investigating...

Comment 10 Ray Strode [halfline] 2014-04-21 21:41:40 UTC
just another status update...

I've gotten socket activation to work somewhat okay from GDM, but still have more to do.  The first bit needed is a patch here:

http://cgit.freedesktop.org/~halfline/libxcb/commit/?id=ca093dca194e88df619bb4397b4ea979686da537

to make xcb support connecting to an absolute filename for its socket.  I also needed this commit:

http://cgit.freedesktop.org/~halfline/xserver/commit/?h=logind-integration&id=a1593e3afeb5072264b9a846ac4074b9eba73d12

to find the appropriate session to take control of.  That commit's going to break startx with non-setuid Xorg, so it needs some work.

These are systemd unit files:

http://cgit.freedesktop.org/~halfline/xserver/commit/?h=logind-integration&id=30d39766484033b159e244bc4b2a9432fcd05498

One oddity, is the -displayfd 256.  That's just a hack to prevent the X server from requiring a display number (which we don't need or care about).  I'll have to come up with a better answer for this, especially since there's a patch floating around xorg-devel list now that makes -displayfd require a valid fd.

and a gdm change here:

https://git.gnome.org/browse/gdm/commit/?h=wip/systemd-activation&id=451a7223ca2bfb786b8e12aa3fd8a1e1bfb14d3c

to unconditionally force GDM to treat X sessions has handled outside of GDM.

and these changes:

https://git.gnome.org/browse/gdm/commit/?h=wip/systemd-activation&id=ef0122010dd68e15da889b43fbd20b835ef1cfa9

to force DISPLAY to the socket path, and hide the tty fd from bash (which is run by Xsession) so it doesn't try to make the X clients have control of the tty instead of the X server, and chown call to the tty to make it readable by the user.  I think we should be able to leverage the PAM stack to do this for us instead, in the same it's handled for text logins.

Anyway, all of those changes are just to get me to proof-of-concept stage. They aren't landable yet as is.  Will have more info once I get a little further.

Comment 11 Hans de Goede 2014-04-22 07:16:04 UTC
Hi Ray,

Thanks for the status update. I'm afraid I'm a bit burried with other work atm. Part of which is the xorg-rebase for rawhide, which should make testing this all easier.

Let me know if you've any specific questions you would like me to answer. As for the libxcb / xserver patches I suggest you post those directly to the xorg-devel mailinglist.

Thanks,

Hans

Comment 12 Ray Strode [halfline] 2014-04-22 11:35:56 UTC
No questions at the moment. I'm just using this bug report as a landing page for the work since it's linked from the tracker bug linked on the wiki page about the change.

I'll make sure to send the patches upstream when they're a little more baked. At this point they're just at a proof-of-concept level.

Comment 13 Ray Strode [halfline] 2014-04-25 12:14:54 UTC
one more status update... I've fleshed out the X server patches more now:

http://cgit.freedesktop.org/~halfline/xserver/commit/?h=logind-integration

but there's some annoying lifecycle issues that still need to be resolved. Normally the X server's life cycle is determined by one of these command line options: 

1) -terminate  "die when the last client connection goes away"
2) -noreset  "don't died until killed by another process"
3) -reset  "flush all state stop and start back up again when the last client goes away"

The problem with -terminate is there are a number of small transient X connections during login, so you end up with the X server dying and restarting a bunch of times during login.  The problem with -noreset is since the X server isn't managed by GDM anymore, there's nothing around to kill it. Likewise for -reset.

Of course we know the lifecycle of the session now, it's defined by logind.  So I did a patch to make the X server quit when the session goes away.  This ran into an immediate problem: the dbus-daemon goes away when its X connection goes away, and the X server doesn't go away until everything in the session goes away (including the dbus-daemon, and all the things tied to it). 

Of course in a kdbus world the dbus-daemon isn't going to be around, and we need to fix all the things tied to it anyway, but that's neither here nor there. 

In the meantime, I changed the patch to the X server to quit as soon as the session goes to the "closing" state (which it goes to when gnome-session dies) instead of quitting when the session dies.  This doesn't quite work, because something (some evolution process I think) immediately tries to connect to the X server as soon as it dies, so it gets reactivated (and fails since the session is closing) right after dying.

So I changed the logic one more time, to kill all clients when going to closing, and only die later when the session goes away.  This doesn't work either, because pulseaudio stays around keeping the session open while in it's in the closing state.  I think pulseaudio would be a good candidate process to move to a systemd --user service.

Thinking about it more, I shouldn't be tying the X server to the session lifetime.  I'm going to look into making the X server reset when going to the closing state and only ever die when systemd --user goes away.  That should hopefully address all problems. (so actually not too different than 3 at the start of this comment)

Comment 14 Rex Dieter 2016-05-20 15:20:53 UTC
I'm pretty sure gdm supports this feature for awhile and can be closed (holler or re-open if you feel that to be in error)