Plasma5 user sessions

Max Harmathy max.harmathy at web.de
Thu Feb 1 14:14:39 UTC 2018


Am 15.01.2018 um 14:32 schrieb Max Harmathy:
> Greetings from Munich's LiMux developers team.
> 
> short story:
> 
> * during user session initialisation notifications get displayed as windows
> * if one user requests a shutdown (reboot, poweroff) all sessions get killed
> 
> long story:
> 
> We are currently in development of our next (final?) release. Our
> current release is based on Ubuntu 14.04 trust, whereas our next release
> will be based on Ubuntu 18.04 bionic.
> 
> Thus we switch from
> * upstart to systemd
> * ConsoleKit to logind
> * KDM to SDDM
> * Plasma 4.x to Plasma 5.x
> 
> We have to execute some tasks for every user who logs into a computer.
> This includes configuring start menu applications, configuring printers,
> mounting network shares and synchronise the users home directory with a
> filer (downsync). We also provide slots where administrators can run
> scripts in the user context.
> 
> Up until now we hooked into the user session by putting some files into
> /etc/X11/Xsession.d which is as far as we understand executed by the
> display-manager when a x11 user session gets initialised.
> 
> During these configuration steps there are some notifications we want to
> be displayed after the desktop is ready. Therefore we collect such
> messages. The a script in /etc/xdg/autostart displays them after the
> plasma session started as normal desktop notifications. Therefore the
> script sends them through the DBus session bus via
> org.freedesktop.Notifications. However on our development release those
> messages get displayed as windows instead of the usual bubbles. It seems
> that the notification handling is not ready when the autostarts are running.
> 
> When the user ends the session we also run code to synchronise the home
> directory (upsync), umnount network shares etc. This works as expected
> if the user does a simple logout. However if the user requests a
> shutdown (reboot, poweroff) then the session and other user sessions are
> killed and the computer shuts down. The KSMServer
> (plasma-workspace/ksmserver/server.cpp, void KSMServer::cleanUp()) uses
> a KDisplayManager (plasma-workspace/libkworkspace/kdisplaymanager.cpp)
> which sends a "Reboot" or "PowerOff" through the system bus to logind.
> This results in an immediate shutdown and neither our code nor parts of
> the startkde script is executed.
> 
> Comments in kdisplaymanager.cpp state that there should be a policykit
> dialog preventing a shutdown if other sessions are running, which is not
> displayed in our case. But also without other sessions running, the
> logout should finish in a clean way(wait for startkde to terminate).
> 
> We found out, that running a process with a systemd inhibitor as root e.g
>> # systemd-inhibit --what=shutdown --mode=block sleep 365d
> prevents the system from killing the session and a clean logout is
> conducted. However in this case also the shutdown request is silently
> ignored.
> 
> There are some questions we where not able to find answers by ourselves:
> 
> Is there a definition when xdg-autostart applications are started?
> 
> Is there a way to make sure that the session is ready to display
> notifications?
> 
> It seems that sending dbus messages to logind in kdisplaymanager.cpp is
> too early. Could this be a general issue? Should this not be the last
> part of startkde?
> 
> Could this be a misconfiguration of policykit?
> 
> Could it be that the behaviour of logind changed recently?
> 
> It looks like there are currently some weak spots with plasma5 sessions.
> We hope that we can work together to make the users session handling
> more robust.
> 


I want to give a report about what we have implemented in the last few
days. It will work for us, but this is not a general solution for the
underling problem, which is a in my opinion a fundamental design issue
with graphical user sessions on modern linux desktop systems.

We patched the library "libkworkspace" in plasma-workspace not to send
shutdown requests via DBus to logind. Instead we write the request to
"/run/user/$UID/shutdown_request". I put a mirror with the patch applied
to 5.12 branch to github [1].

We have the framework [3] for configuring the session start a little
program [2] after logout, deconfiguring and profile synchronisation. The
program checks for the file and then sends the DBus message to logind.
We also integrated a dialog for the case when other users are still
logged in and a interface to shutdown the system through an agent.

We know that this solution is a hack. But that is the best we could come
up within a few days. However the underling issue goes deeper, I think:

There is no real consensus what defines a graphical user session and how
to handle it.

There is the Posix point of view. There is the setsid() system call
which enables a process to start a new session. But this is not only for
initiating a user session in the sense of a graphical session, but
basically any program can group subprocesses into such a session.

There is also the classical X11 session where an X-Server is running on
a certain display. This session is in many ways orthogonal to the above
concept. Either the user starts a X11 session via xinit (startx) from
the console, then the user session is already there when X-Server starts
and possibly a desktop environment. Or there is already an X-Server with
a display manager running. Then the display manager will start a new
user session reusing the very same X-Server. To start a desktop
environment the display manager will execute a script commonly known as
"Xsession". When the user session ends the control goes back to the
display manager and the X11 session continues to live on. (Sidenote:
With Wayland sessions around this whole concept does not work anymore in
general.)

Then there is logind (and ConsoleKit) which more or less adds another
concept or specialises the Posix concept. A logind user session is
spawned by the pam_systemd.so module [4]. This will also get called when
a user authenticates in a display manager greeter. With SDDM there is a
sddm_helper process which does that. That process then will be the lead
process of the user session. You can check that with "loginctl". Logind
will then run all systemd user units and also watch all process spawned
by in the session even if they daemonize. Independently the display
manager (sddm_helper) will execute the Xsession script. The session
eventually ends when the lead process terminates. Then there is the
possibility to request a shutdown with logind. If the user is allowed to
shutdown then systemd will shutdown on system level terminating all user
sessions without waiting for them to terminate (see function
"execute_shutdown_or_sleep" in [5]). There is only polkit (see finction
"verify_shutdown_creds" in [5]) between the Dbus call and the shutdown.

I figured out what Gnome does in this case: There is a binary
gnome-session which is directly referenced in the session desktop file
in "/usr/share/sessions" and "/usr/share/wayland-sessions". When the
user request a shutdown then the DBus call is the very last thing the
gnome-session binary does. There no code whatsoever after that.

For now we have a solution which works for us. And the code in
"startkde" which won't be executed probably don't matter for an average
linux desktop use case. But I guess we should come up with a better and
clean solution in the long run.


> [1] https://github.com/harmathy/plasma-workspace
> [2] https://github.com/harmathy/lisslo
> [3] https://github.com/harmathy/goto-usersession
> [4] https://www.freedesktop.org/software/systemd/man/pam_systemd.html
> [5] https://github.com/systemd/systemd/blob/master/src/login/logind-dbus.c


I will be at FOSDEM this weekend and would be pleased to discuss this
topic.


Max



























More information about the Enterprise mailing list