summaryrefslogtreecommitdiff
path: root/src/login/logind-session.c
AgeCommit message (Collapse)Author
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-09-17Remove six unused variables and add annotationZbigniew Jędrzejewski-Szmek
clang FTW!
2013-09-17logind: fix build for ARM with sizeof(dev_t) > sizeof(void*)David Herrmann
Unfortunately on ARM-32 systems dev_t can be 64bit and thus we cannot store it easily in void* keys for hashtables. Fix that by passing a pointer to the dev_t variable instead.
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 session_activate(vtnr = 0)David Herrmann
VT numbers start with 1. If a session has vtnr == 0, we must not assume it is running on a VT. Note that this could trigger the assert() below as CreateSession() sets vtnr to 0, not <0.
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: make Session.Activate() lazyDavid Herrmann
Currently, Activate() calls chvt(), which does an ioctl(VT_ACTIVATE) and immediately calls seat_set_active(). However, VTs are allowed to prevent being deactivated. Therefore, logind cannot be sure the VT_ACTIVATE call was actually successful. Furthermore, compositors often need to clean up their devices before they acknowledge the VT switch. The immediate call to seat_set_active() may modify underlying ACLs, though. Thus, some compositors may fail cleaning up their stuff. Moreover, the compositor being switched to (if listening to logind instead of VTs) will not be able to activate its devices if the old VT still has them active. We could simply add an VT_WAITACTIVE call, which blocks until the given VT is active. However, this can block forever if the compositor hangs. So to fix this, we make Activate() lazy. That is, it only schedules a session-switch but does not wait for it to complete. The caller can no longer rely on it being immediate. Instead, a caller is required to wait for the PropertiesChanged signal and read the "Active" field. We could make Activate() wait asynchronously for the session-switch to complete and then send the return-message afterwards. However, this would add a lot of state-tracking with no real gain: 1) Sessions normally don't care whether Activate() was actually successful as they currently _must_ wait for the VT activation to do anything for real. 2) Error messages for failed session switches can be printed by logind instead of the session issuing Activate(). 3) Sessions that require synchronous Activate() calls can simply issue the call and then wait for "Active" properties to change. This also allows them to implement their own timeout. This change prepares for multi-session on seats without VTs. Forced VT switches are always bad as compositors cannot perform any cleanup. This isn't strictly required, but may lead to loss of information and ambiguous error messages. So for multi-session on seats without VTs, we must wait for the current session to clean-up before finalizing the session-switch. This requires Activate() to be lazy as we cannot block here. Note that we can always implement a timeout which allows us to guarantee the session switch to happen. Nevertheless, this calls for a lazy Activate().
2013-09-17logind: add session controllersDavid Herrmann
A session usually has only a single compositor or other application that controls graphics and input devices on it. To avoid multiple applications from hijacking each other's devices or even using the devices in parallel, we add session controllers. A session controller is an application that manages a session. Specific API calls may be limited to controllers to avoid others from getting unprivileged access to restricted resources. A session becomes a controller by calling the RequestControl() dbus API call. It can drop it via ReleaseControl(). logind tracks bus-names to release the controller once an application closes the bus. We use the new bus-name tracking to do that. Note that during ReleaseControl() we need to check whether some other session also tracks the name before we remove it from the bus-name tracking list. Currently, we only allow one controller at a time. However, the public API does not enforce this restriction. So if it makes sense, we can allow multiple controllers in parallel later. Or we can add a "scope" parameter, which allows a different controller for graphics-devices, sound-devices and whatever you want. Note that currently you get -EBUSY if there is already a controller. You can force the RequestControl() call (root-only) to drop the current controller and recover the session during an emergency. To recover a seat, this is not needed, though. You can simply create a new session or force-activate it. To become a session controller, a dbus caller must either be root or the same user as the user of the session. This allows us to run a session compositor as user and we no longer need any CAP_SYS_ADMIN.
2013-09-16Verify validity of session name when received from outsideZbigniew Jędrzejewski-Szmek
Only ASCII letters and digits are allowed.
2013-08-28logind-session.c: use _cleanup_Zbigniew Jędrzejewski-Szmek
2013-08-28logind: be more verbose on errorsZbigniew Jędrzejewski-Szmek
2013-08-13logind: restore logic to kill user processes when session endsLennart Poettering
2013-07-10user-sessions: rely on PID 1 to kill sessionsLennart Poettering
As we want to centralized cgroup access we should stop killing the user sessions directly from the systemd-user-sessions service. Instead, rely on PID 1 doing this by adding the right ordering dependencies to the session scope units.
2013-07-10logind: when creating the scope job fails, return this immediately to the ↵Lennart Poettering
client that wants to register the session Otherwise we'll hanging for the job to finish without any job existing. Similar, for machined.
2013-07-02logind: after deserializatio readd systemd units to unit-to-object hashmap ↵Lennart Poettering
correctly
2013-07-02libsystemd-logind: fix detection of session/user/machine of a PIDLennart Poettering
2013-07-02logind: port over to use scopes+slices for all cgroup stuffLennart Poettering
In order to prepare things for the single-writer cgroup scheme, let's make logind use systemd's own primitives for cgroup management. Every login user now gets his own private slice unit, in which his sessions live in a scope unit each. Also, add user@$UID.service to the same slice, and implicitly start it on first login.
2013-06-27core: general cgroup reworkLennart Poettering
Replace the very generic cgroup hookup with a much simpler one. With this change only the high-level cgroup settings remain, the ability to set arbitrary cgroup attributes is removed, so is support for adding units to arbitrary cgroup controllers or setting arbitrary paths for them (especially paths that are different for the various controllers). This also introduces a new -.slice root slice, that is the parent of system.slice and friends. This enables easy admin configuration of root-level cgrouo properties. This replaces DeviceDeny= by DevicePolicy=, and implicitly adds in /dev/null, /dev/zero and friends if DeviceAllow= is used (unless this is turned off by DevicePolicy=).
2013-06-20logind: add infrastructure to keep track of machines, and move to slicesLennart Poettering
- This changes all logind cgroup objects to use slice objects rather than fixed croup locations. - logind can now collect minimal information about running VMs/containers. As fixed cgroup locations can no longer be used we need an entity that keeps track of machine cgroups in whatever slice they might be located. Since logind already keeps track of users, sessions and seats this is a trivial addition. - nspawn will now register with logind and pass various bits of metadata along. A new option "--slice=" has been added to place the container in a specific slice. - loginctl gained commands to list, introspect and terminate machines. - user.slice and machine.slice will now be pulled in by logind.service, since only logind.service requires this slice.
2013-06-10Use stdint.h macros instead of casts to print uint64_t valuesZbigniew Jędrzejewski-Szmek
Casts are visually heavy, and can obscure unwanted truncations.
2013-04-22cgroup: make sure all our cgroup objects have a suffix and are properly escapedLennart Poettering
Session objects will now get the .session suffix, user objects the .user suffix, nspawn containers the .nspawn suffix. This also changes the user cgroups to be named after the numeric UID rather than the username, since this allows us the parse these paths standalone without requiring access to the cgroup file system. This also changes the mapping of instanced units to cgroups. Instead of mapping foo@bar.service to the cgroup path /user/foo@.service/bar we will now map it to /user/foo@.service/foo@bar.service, in order to ensure that all our objects are properly suffixed in the tree.
2013-04-16nspawn: introduce the new /machine/ tree in the cgroup tree and move ↵Lennart Poettering
containers there Containers will now carry a label (normally derived from the root directory name, but configurable by the user), and the container's root cgroup is /machine/<label>. This label is called "machine name", and can cover both containers and VMs (as soon as libvirt also makes use of /machine/). libsystemd-login can be used to query the machine name from a process. This patch also includes numerous clean-ups for the cgroup code.
2013-04-15core: always create /user and /machine top-level cgroup dirsLennart Poettering
This allows clients to put inotify watches on these trees to watch for state changes, without having to wait until these dirs are created. This introduces the new top-level /machine cgroup dir as canonical location where OS containers and VMs shall be located (as discussed with the libvirt folks).
2013-04-10logind: avoid creating stale session state filesFedora systemd team
There were old session state files accumulating in /run/systemd/session. They confused e.g. "reboot", which thought there were still users logged in. The files got created like this: session_stop(Session *s) -> ... unlink(s->state_file); ... seat_set_active(s->seat, NULL) -> session_save(...); /* re-creates the state file we just unlinked */ Fix it simply by clearing the s->started flag earlier to prevent any further writes of the state file (session_save() checks the flag).
2013-04-09logind: introduce an explicit session class for cronjobs and similarLennart Poettering
cronjobs are neither interactive user session, nor lock screens, nor login screens, hence they should get their own class.
2013-04-05Use initalization instead of explicit zeroingZbigniew Jędrzejewski-Szmek
Before, we would initialize many fields twice: first by filling the structure with zeros, and then a second time with the real values. We can let the compiler do the job for us, avoiding one copy. A downside of this patch is that text gets slightly bigger. This is because all zero() calls are effectively inlined: $ size build/.libs/systemd text data bss dec hex filename before 897737 107300 2560 1007597 f5fed build/.libs/systemd after 897873 107300 2560 1007733 f6075 build/.libs/systemd … actually less than 1‰. A few asserts that the parameter is not null had to be removed. I don't think this changes much, because first, it is quite unlikely for the assert to fail, and second, an immediate SEGV is almost as good as an assert.
2013-02-14honor SELinux labels, when creating and writing config filesHarald Hoyer
Also split out some fileio functions to fileio.c and provide a SELinux aware pendant in fileio-label.c see https://bugzilla.redhat.com/show_bug.cgi?id=881577
2013-01-15logind: remove unused variableMichal Sekletar
2012-12-24logind: add support for automatic suspend/hibernate/shutdown on idleLennart Poettering
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-21logind: check return value, log warning on errorVáclav Pavlín
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: Ensure the user, seat and session files are updated when the session ↵Colin Guthrie
is closing.
2012-09-03journal: generate structured journal messages for a number of eventsLennart Poettering
2012-07-26log.h: new log_oom() -> int -ENOMEM, use itShawn Landden
also a number of minor fixups and bug fixes: spelling, oom errors that didn't print errors, not properly forwarding error codes, few more consistency issues, et cetera
2012-07-25use "Out of memory." consistantly (or with "\n")Shawn Landden
glibc/glib both use "out of memory" consistantly so maybe we should consider that instead of this. Eliminates one string out of a number of binaries. Also fixes extra newline in udev/scsi_id
2012-07-22logind: fix operation precedence mix-upZbigniew Jędrzejewski-Szmek
Since + has higher precedence than ?:, and u+b is unlikely to be exactly zero, the timestamp would usually be set to IDLE_THRESHOLD_USEC. Fix it by returning either 'last activity', or 'last activity+IDLE_THRESHOLD_USEC'.
2012-06-21logind: introduce a state for session, being one of online, active, closingLennart Poettering
online = logged in active = logged in and session is in the fg closing = nominally logged out but some left-over processes still around Related to: https://bugzilla.gnome.org/show_bug.cgi?id=677556
2012-05-31logind: properly clean up user cgroups when they run emptyLennart Poettering
2012-05-31mkdir: append _label to all mkdir() calls that explicitly set the selinux ↵Kay Sievers
context
2012-05-30logind: optionally handle power, sleep and lid switch eventsLennart Poettering
This takes handling of chassis power and sleep keys as well as the lid switch over from acpid. This logic is enabled by default for power and sleep keys, but not for the lid switch. If a graphical session is in the foreground no action is taken under the assumption that the graphical session does this.
2012-05-21login: minor typo fixLennart Poettering
2012-05-08util: split-out path-util.[ch]Kay Sievers
2012-05-07logind: fix memory leakFrederic Crozat
2012-04-16logind: add shutdown/suspend/idle inhibition frameworkLennart Poettering
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-03-22logind: extend comment about X11 socket symlinkLennart Poettering