summaryrefslogtreecommitdiff
path: root/src/login/logind-seat.c
AgeCommit message (Collapse)Author
2014-03-04logind: small simplificationsZbigniew Jędrzejewski-Szmek
2014-02-25login: set pos-slot to fallback on pos-evictionDavid Herrmann
If we evict a session position, we open the position slot for future sessions. However, there might already be another session on the same position if both were started on the same VT. This is currently done if gdm spawns the session on its own Xserver. Hence, look for such a session on pos-eviction and claim the new slot immediately.
2014-02-25login: fix pos-array allocationDavid Herrmann
GREEDY_REALLOC takes a pointer to the real size, not the array-width as argument. Therefore, our array is currently way to small to keep the seat positions. Introduce GREEDY_REALLOC0_T() as typed version of GREEDY_REALLOC and store the array-width instead of array-size.
2014-02-11logind: always kill session when termination is requestedZbigniew Jędrzejewski-Szmek
KillUserProcesses=yes/no should be ignored when termination is explicitly requested.
2014-02-05Update some message formatsZbigniew Jędrzejewski-Szmek
Use PID_FMT/USEC_FMT/... in more places. Also update logind error messages to print the full path to a file that failed. This should make debugging easier for people who do not know off the top of their head where logind stores it state.
2014-01-20logind: introduce session "positions"David Herrmann
logind has no concept of session ordering. Sessions have a unique name, some attributes about the capabilities and that's already it. There is currently no stable+total order on sessions. If we use the logind API to switch between sessions, we are faced with an unordered list of sessions we have no clue of. This used to be no problem on seats with VTs or on seats with only a single active session. However, with the introduction of multi-session capability for seats without VTs, we need to find a way to order sessions in a stable way. This patch introduces session "positions". A position is a simple integer assigned to a session which is never changed implicitly (currently, we also don't change it explicitly, but that may be changed someday). For seats with VTs, we force the position to be the same as the VTnr. Without VTs, we simply find the lowest unassigned number and use it as position. If position-assignment fails or if, for any reason, we decide to not assign a position to a session, the position is set to 0 (which is treated as invalid position). During session_load() or if two sessions have the same VTnr, we may end up with two sessions with the same position (this shouldn't happen, but lets be fail-safe in case some other part of the stack fails). This case is dealt with gracefully by ignoring any session but the first session assigned to the position. Thus, session->pos is a hint, seat->positions[i] is the definite position-assignment. Always verify both match in case you need to modify them! Additionally, we introduce SwitchTo(unsigned int) on the seat-dbus-API. You can call it with any integer value != 0 and logind will try to switch to the request position. If you implement a compositor or any other session-controller, you simply watch for ctrl+alt+F1 to F12 and call SwitchTo(Fx). logind will figure a way out deal with this number. For convenience, we also introduce SwitchToNext/Previous(). It should be called on ctrl+alt+Left/Right (like the kernel-console used to support). Note that the public API (SwitchTo*()) is *not* bound to the underlying logic that is implemented now. We don't export "session-positions" on the dbus/C API! They are an implementation detail. Instead, the SwitchTo*() API is supposed to be a hint to let logind choose the session-switching logic. Any foreground session-controller is free to enumerate/order existing sessions according to their needs and call Session.Activate() manually. But the SwitchTo*() API provides a uniform behavior across session-controllers. Background: Session-switching keys depend on the active keymap. The XKB specification provides the XKB_KEY_XF86Switch_VT_1-12 key-symbols which have to be mapped by all keymaps to allow session-switching. It is usually bound to ctrl+alt+Fx but may be set differently. A compositor passes any keyboard input to XKB before passing it to clients. In case a key-press invokes the XKB_KEY_XF86Switch_VT_x action, the keypress is *not* forwarded to clients, but instead a session-switch is scheduled. This actually prevents us from handling these keys outside of the session. If an active compositor has a keymap with a different mapping of these keys, and logind itself tries to catch these combinations, we end up with the key-press sent to the compositor's clients *and* handled by logind. This is *bad* and we must avoid this. The only situation where a background process is allowed to handle key-presses is debugging and emergency-keys. In these cases, we don't care for keymap mismatches and accept the double-event. Another exception is unmapped keys like PowerOff/Suspend (even though this one is controversial).
2013-12-06Get rid of our reimplementation of basenameZbigniew Jędrzejewski-Szmek
The only problem is that libgen.h #defines basename to point to it's own broken implementation instead of the GNU one. This can be fixed by #undefining basename.
2013-11-28logind: require VTs on seat0 and forbid elsewhereDavid Herrmann
Sessions on seat0 must pass us a vtnr, otherwise, you shouldn't try attaching it to seat0. For seats without VTs, we do the exact opposite: we forbid VTs. There can be odd situations if the session-files contain invalid combinations. However, we try to keep sessions alive and restore state as good as possible.
2013-11-28logind: make VT numbers unsignedDavid Herrmann
Fix the whole code to use "unsigned int" for vtnr. 0 is an invalid vtnr so we don't need negative numbers at all. Note that most code already assumes it's unsigned so in case there's a negative vtnr, our code may, under special circumstances, silently break. So this patch makes sure all sources of vtnrs verify the validity. Also note that the dbus api already uses unsigned ints.
2013-11-28login: revert lazy session-activation on non-VT seatsDavid Herrmann
Existing applications like gdm already depend on new sessions to get immediately activated on seats without VTs. Fixes a bug reported as: [systemd-devel] systemd 208:trouble with inactive user sessions at non-seat0 seats This patch restores the original behavior. We either need to add a new flag for session-creation or some other heuristic to avoid activating new sessions in the future.
2013-11-05logind: port logind to libsystemd-busLennart Poettering
2013-10-14list: make our list macros a bit easier to use by not requring type spec on ↵Lennart Poettering
each invocation We can determine the list entry type via the typeof() gcc construct, and so we should to make the macros much shorter to use.
2013-10-01logind: send PropertyChanged during deactivationDavid Herrmann
We only send the PropertyChanged signal for the to-be-activated session but not for the to-be-deactivated one. Fix that so both listeners get notified about the new state.
2013-09-17logind: implement generic multi-sessionDavid Herrmann
This enables the multi-session capability for seats that don't have VTs. For legacy seats with VTs, everything stays the same. However, all other seats now also get the multi-session capability. The only feature that was missing was session-switching. As logind can force a session-switch and signal that via the "Active" property, we only need a way to allow synchronized/delayed session switches. Compositors need to cleanup some devices before acknowledging the session switch. Therefore, we use the session-devices to give compositors a chance to block a session-switch until they cleaned everything up. If you activate a session on a seat without VTs, we send a PauseDevice signal to the active session for every active device. Only once the session acknowledged all these with a PauseDeviceComplete() call, we perform the final session switch. One important note is that delayed session-switching is meant for backwards compatibility. New compositors or other sessions should really try to deal correctly with forced session switches! They only need to handle EACCES/EPERM from syscalls and treat them as "PauseDevice" signal. Following logind patches will add a timeout to session-switches which forces the switch if the active session does not react in a timely fashion. Moreover, explicit ForceActivate() calls might also be supported. Hence, sessions must not crash if their devices get paused.
2013-09-17logind: introduce session-devicesDavid Herrmann
A session-device is a device that is bound to a seat and used by a session-controller to run the session. This currently includes DRM, fbdev and evdev devices. A session-device can be created via RequestDevice() on the dbus API of the session. You can drop it via ReleaseDevice() again. Once the session is destroyed or you drop control of the session, all session-devices are automatically destroyed. Session devices follow the session "active" state. A device can be active/running or inactive/paused. Whenever a session is not the active session, no session-device of it can be active. That is, if a session is not in foreground, all session-devices are paused. Whenever a session becomes active, all devices are resumed/activated by logind. If it fails, a device may stay paused. With every session-device you request, you also get a file-descriptor back. logind keeps a copy of this fd and uses kernel specific calls to pause/resume the file-descriptors. For example, a DRM fd is muted by logind as long as a given session is not active. Hence, the fd of the application is also muted. Once the session gets active, logind unmutes the fd and the application will get DRM access again. This, however, requires kernel support. DRM devices provide DRM-Master for synchronization, evdev devices have EVIOCREVOKE (pending on linux-input-ML). fbdev devices do not provide such synchronization methods (and never will). Note that for evdev devices, we call EVIOCREVOKE once a session gets inactive. However, this cannot be undone (the fd is still valid but mostly unusable). So we reopen a new fd once the session is activated and send it together with the ResumeDevice() signal. With this infrastructure in place, compositors can now run without CAP_SYS_ADMIN (that is, without being root). They use RequestControl() to acquire a session and listen for devices via udev_monitor. For every device they want to open, they call RequestDevice() on logind. This returns a fd which they can use now. They no longer have to open the devices themselves or call any privileged ioctls. This is all done by logind. Session-switches are still bound to VTs. Hence, compositors will get notified via the usual VT mechanisms and can cleanup their state. Once the VT switch is acknowledged as usual, logind will get notified via sysfs and pause the old-session's devices and resume the devices of the new session. To allow using this infrastructure with systems without VTs, we provide notification signals. logind sends PauseDevice("force") dbus signals to the current session controller for every device that it pauses. And it sends ResumeDevice signals for every device that it resumes. For seats with VTs this is sent _after_ the VT switch is acknowledged. Because the compositor already acknowledged that it cleaned-up all devices. However, for seats without VTs, this is used to notify the active compositor that the session is about to be deactivated. That is, logind sends PauseDevice("force") for each active device and then performs the session-switch. The session-switch changes the "Active" property of the session which can be monitored by the compositor. The new session is activated and the ResumeDevice events are sent. For seats without VTs, this is a forced session-switch. As this is not backwards-compatible (xserver actually crashes, weston drops the related devices, ..) we also provide an acknowledged session-switch. Note that this is never used for sessions with VTs. You use the acknowledged VT-switch on these seats. An acknowledged session switch sends PauseDevice("pause") instead of PauseDevice("force") to the active session. It schedules a short timeout and waits for the session to acknowledge each of them with PauseDeviceComplete(). Once all are acknowledged, or the session ran out of time, a PauseDevice("force") is sent for all remaining active devices and the session switch is performed. Note that this is only partially implemented, yet, as we don't allow multi-session without VTs, yet. A follow up commit will hook it up and implemented the acknowledgements+timeout. The implementation is quite simple. We use major/minor exclusively to identify devices on the bus. On RequestDevice() we retrieve the udev_device from the major/minor and search for an existing "Device" object. If no exists, we create it. This guarantees us that we are notified whenever the device changes seats or is removed. We create a new SessionDevice object and link it to the related Session and Device. Session->devices is a hashtable to lookup SessionDevice objects via major/minor. Device->session_devices is a linked list so we can release all linked session-devices once a device vanishes. Now we only have to hook this up in seat_set_active() so we correctly change device states during session-switches. As mentioned earlier, these are forced state-changes as VTs are currently used exclusively for multi-session implementations. Everything else are hooks to release all session-devices once the controller changes or a session is closed or removed.
2013-09-17logind: extract has_vts() from can_multi_session()David Herrmann
We currently use seat_can_multi_session() to test for two things: * whether the seat can handle session-switching * whether the seat has VTs As both are currently logically equivalent, we didn't care. However, we want to allow session-switching on seats without VTs, so split this helper into: * seat_can_multi_session(): whether session-switching is supported * seat_has_vts(): whether the seat has VTs Note that only one seat on a system can have VTs. There is only one set of them. We automatically assign them to seat0 as usual. With this patch in place, we can easily add new session-switching/tracking methods without breaking any VT code as it is now protected by has_vts(), no longer by can_multi_session().
2013-09-17logind: fix seat_can_tty() to check for VTsDavid Herrmann
A seat provides text-logins if it has VTs. This is always limited to seat0 so the seat_is_seat0() check is correct. However, if VTs are disabled, no seat provides text-logins so we also need to check for the console-fd. This was previously: return seat_is_vtconsole(); It looked right, but was functionally equivalent to seat_is_seat0(). The rename of this helper made it more obvious that it is missing the VT test.
2013-09-17logind: rename vtconsole to seat0David Herrmann
The seat->vtconsole member always points to the default seat seat0. Even if VTs are disabled, it's used as default seat. Therefore, rename it to seat0 to correctly state what it is. This also changes the seat files in /run from IS_VTCONSOLE to IS_SEAT0. It wasn't used by any code, yet, so this seems fine. While we are at it, we also remove every "if (s->vtconsole)" as this pointer is always valid!
2013-09-17logind: listen actively for session devicesDavid Herrmann
Session compositors need access to fbdev, DRM and evdev devices if they control a session. To make logind pass them to sessions, we need to listen for them actively. However, we avoid creating new seats for non master-of-seat devices. Only once a seat is created, we start remembering all other session devices. If the last master-device is removed (even if there are other non-master devices still available), we destroy the seat. This is the current behavior, but we need to explicitly implement it now as there may be non-master devices in the seat->devices list. Unlike master devices, we don't care whether our list of non-master devices is complete. We don't export this list but use it only as cache if sessions request these devices. Hence, if a session requests a device that is not in the list, we will simply look it up. However, once a session requested a device, we must be notified of "remove" udev events. So we must link the devices somehow into the device-list. Regarding the implementation, we now sort the device list by the "master" flag. This guarantees that master devices are at the front and non-master devices at the tail of the list. Thus, we can easily test whether a seat has a master device attached.
2012-10-13log: introduce a macro to format message idZbigniew Jędrzejewski-Szmek
The MESSAGE_ID=... stanza will appear in countless number of places. It is just too long to write it out in full each time. Incidentally, this also fixes a typo of MESSSAGE is three places.
2012-09-16logind: redefine idleness to start at last activityZbigniew Jędrzejewski-Szmek
Before, after the timeout, a session would be timestamped as idle since 'last activity' + 'idle timeout'. Now, it is timestamped as idle since 'last activity'. Before, after all sessions were idle, the seat would be marked with as idle with the timestamp of the oldest idle session. Now it is marked with the timestamp of the youngest idle session. Both changes seem to me to be closer to natural understanding of idleness: the time since last activity counts.
2012-09-12logind: Avoid unnecesary rewrite of user file when switching sessions of the ↵Colin Guthrie
same user.
2012-09-03journal: generate structured journal messages for a number of eventsLennart Poettering
2012-06-21logind: expose CanGraphical and CanTTY properties on seat objectsLennart Poettering
Since we boot so fast now that gdm might get started before the graphics drivers are properly loaded and probed we might end up announcing seat0 to gdm before it has graphics capabilities. Which will cause gdm/X11 cause to fail later on. To fix this race, let's expose CanGraphical and CanTTY fields on all seats, which clarify whether a seat is suitable for gdm resp, suitable for text logins. gdm then needs to watch CanGraphical and spawn X11 on it only if it is true. This way: USB graphics seats will expose CanGraphical=yes, CanTTY=no Machines with no graphics drivers at all, but a text console: CanGraphical=no, CanTTY=yes Machines with CONFIG_VT turned off: CanGraphical=yes, CanTTY=no And the most important case: seat0 where the graphics driver has not been probed yet boot up with CanGraphical=no, CanTTY=yes first, which then changes to CanGraphical=yes as soon as the probing is complete.
2012-05-31mkdir: append _label to all mkdir() calls that explicitly set the selinux ↵Kay Sievers
context
2012-05-08util: split-out path-util.[ch]Kay Sievers
2012-04-12relicense to LGPLv2.1 (with exceptions)Lennart Poettering
We finally got the OK from all contributors with non-trivial commits to relicense systemd from GPL2+ to LGPL2.1+. Some udev bits continue to be GPL2+ for now, but we are looking into relicensing them too, to allow free copy/paste of all code within systemd. The bits that used to be MIT continue to be MIT. The big benefit of the relicensing is that closed source code may now link against libsystemd-login.so and friends.
2012-04-10rename basic.la to shared.la and put selinux deps in shared-selinx.laKay Sievers
Only 34 of 74 tools need libselinux linked, and libselinux is a pain with its unconditional library constructor.
2012-01-18logind: allow to create multiple sessions on non-multi-session seats to deal ↵Lennart Poettering
with left-over sessions
2012-01-03logind: if we can't open /dev/tty0, assume there is no VT subsystem and ↵Lennart Poettering
don't pretend we could do VT switching
2011-12-31logind: move logind into its own subdirectoryLennart Poettering