dvdhrm / kmscon

Linux KMS/DRM based virtual Console Emulator
http://www.freedesktop.org/wiki/Software/kmscon
Other
436 stars 81 forks source link

Set XDG_VTNR for sessions running on real VTs #92

Closed tchebb closed 11 years ago

tchebb commented 11 years ago

Currently, logind maintains a one-to-one mapping of sessions and VTs. It uses the active VT to determine which session should be marked as active and given ACLs for hardware access. pam_systemd normally determines the VT a session is on using the name of the TTY it is connected to. This works for getty, but not for kmscon because the session is actually running on a pts. Because of this, the logind session is never marked as active and access to many hardware devices is limited.

I understand that the aim of kmscon is to enable CONFIG_VT to be disabled altogether. For session activation to work in that case, significant changes to logind itself would have to be made. But for the most common current configuration (running on a real VT), all that has to be done to make session activation work is to set the XDG_VTNR environment variable to the VT number kmscon is running on, which overrides pam_systemd's VT autodetection.

dvdhrm commented 11 years ago

Eventually, we need some "external session integration" in systemd-logind so something like "uvtd" can work properly. However, I won't have time to implement it until October or later so I will try to discuss this with Lennard and co. during Linux-Plumbers-Conf in September.

I did look into the pam-systemd module and it didn't parse XDG_VTNR the last time I checked. This was when I asked Lennard to parse XDG_SEAT so we can pass the seat-name. But this might have changed so I will check later whether setting XDG_VTNR fixes all this. The src/pty.c file already passes some other environ-variables so it is a simple patch.

Thanks for the report! I will try to fix this tomorrow. Regards David

tchebb commented 11 years ago

pam_systemd does appear to parse XDG_VTNR now (I'm not sure since when). When I run kmscon with --no-reset-env in a wrapper which sets XDG_VTNR properly, everything works beautifully.

dvdhrm commented 11 years ago

Please see 35eb595863af94a9b89cf00fecec21490fe0ffd7 and the two related commits I just pushed.

Note that this won't work if the new session is started from within an existing session. pam will overwrite XDG_VTNR then. So always use the systemd-units to start the session.

Thanks for the report! David

tchebb commented 11 years ago

Thanks for such a quick fix!

If you don't mind me asking, what are your thoughts on changes that will need to be made to logind for "external session integration"? Would the current VT syscalls need to be replaced with some sort of interface to a userspace daemon?

dvdhrm commented 11 years ago

@tchebb You're welcome!

The idea is to provide a multi-session capability for seats other than the default seat (seat0) (or even the default seat if VTs are disabled). The kmscon repository already contains a uvtd binary which implements the VT API in user-space via CUSE/FUSE. It's experimental and the ultimate goal is to drop the VT API entirely and use something more appropriate (like a system-compositor). But the uvtd application is an example how to keep backwards-compatibility to applications that require the VT API.

This, however, means we need to rewrite the communication between logind and the session-manager. If we have something like uvtd, we have to make logind provide a dbus-interface that is used by uvtd to notify logind about new sessions, session-switches and so on. The interface hasn't been fully fledged, but my idea is something like this:

logind provides: RegisterSessionAgent(agent, seat) and UnregisterSessionAgent(agent). uvtd can register itself on the seat it is running on. The "agent" object then provides a dbus-interface that is used by logind. It basically provides the same as VTs: A signal on session-switch (maybe optionally synchronous?), a notification on new/gone sessions and a query API to let logind query uvtd for information.

Ideas welcome!

tchebb commented 11 years ago

@dvdhrm I've been thinking about this more. For simply emulating logind's current behavior with uvtd, having one "session agent" for a seat seems like the obvious solution. But what about applications such as a Wayland system compositor or kmscon in multi-session mode, which multiplex between multiple sessions all on a single "VT"? Ideally, logind should be aware of which multiplexed sessions are active and should be able to switch between them when it receives an "Activate" dbus message, just like it can using real VTs now. Adding this functionality would require a new API for multiplexers to use; one very similar to the one you're proposing for uvtd.

I think an elegant solution to both problems would be to allow not just one, but a hierarchy of session multiplexers on any given seat. For example, an instance of uvtd could be the "root" multiplexer on a seat and have a Wayland system compositor as one child and a kmscon instance as another. If the kmscon session was active and logind received an activate message for one of the Wayland sessions hosted by the system compositor, it would use the multiplexer dbus API to send session switch messages to both uvtd and the system compositor in order to get the correct session on-screen.

A potential problem I can see is a multiplexer having to know the session IDs of its clients. Currently, sessions are registered through PAM after the client has been spawned. Without something like VTNR or the VT determination code currently in use, a client would have to communicate its session ID in an out-of-band way to the multiplexer hosting it so the multiplexer could accurately report session switches to logind. Correct me if I'm wrong, but I don't believe that the legacy VT API that uvtd implements supports this. Would the session agent API you outlined have this problem or is there something I'm missing about it?

If I have time this summer, I may take a stab at implementing this functionality in logind, so I'd love to hear any thoughts or suggestions you may have.

dvdhrm commented 11 years ago

@tchebb I don't think we should make logind the central place here. In my opinion it is responsible for state-tracking, not policy. So my proposal (which afaik achieves the same as you suggest) is the following:

We have only one central system-compositor, uvtd, .. etc. I call this application uvtd for now, but this can also be a wayland-system-compositor. uvtd is responsible to manage session-interaction and device-association. It provides an API for applications to register/unregister sessions. This is done either via the legacy VT API or via an wayland-extension for system-compositors. If we use the VT API, a session gets the default attributes as this API is pretty limited. However, if an application uses the wayland-extension, it can also tell uvtd whether it's a boot-splash, a user-session, a screen-saver, ... uvtd is then responsible of showing the correct session and dispatching between them.

A normal gnome-session would register its compositor as user-session on uvtd (or use the legacy VT API which corresponds to user-sessions). uvtd notices that and probably stops the boot-splash-screen and shows the gnome-session. On system-shortcuts (like ctrl+alt+FX) it switches between user-sessions. Or a user-session might notify uvtd to switch to another session.

The thing is, I don't want all this in logind as it can get pretty huge. Dealing with KMS/DRM, input devices and so on can get pretty complex and shouldn't be a requirement for logind. Therefore, I want an independent API in logind which allows one single external session-manager. If a seat has real legacy VTs, then this API will be blocked as the kernel VTs are the session-manager in that case. In all other cases, you can choose your session-manager and start it. Some users might want plain uvtd, others might want a full wayland system-compositor.

Also take into account that the system-compositor isn't a real compositor. That is, I have wayland-extensions here which allow the system-compositor to pass DRM-access to user-session-compositors. So the system-compositor isn't actually involved in any graphics access. However, it may support standard wayland compositing so for instance a boot-splash could use the standard wayland-interface and not deal with raw hardware access.

Does that make sense to you? If not, I am open for suggestions. But a recursive-multiplexer API shouldn't be part of logind IMO. Instead, we should move it to a separate daemon to avoid unnecessary complexities in systemd.