Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shutdown conundrum with Plasma #664

Open
hsitter opened this issue Aug 9, 2016 · 6 comments
Open

shutdown conundrum with Plasma #664

hsitter opened this issue Aug 9, 2016 · 6 comments

Comments

@hsitter
Copy link
Collaborator

hsitter commented Aug 9, 2016

Plasma systems have problems shutting down properly with system.

This is fairly complicated...

Plasma presently doesn't fully clean up its session (as in: doesn't kill everything before yielding to SDDM or systemd).
Upon logout Plasma returns to sddm, which gets restarted, which implicitly kills most if not everything in standard situations.
BUT on shutdown and reboot Plasma yields to systemd. Systemd then will want to TERM (and later KILL) all user session scopes. This however has a dependency ordering problem with sddm.

sddm.service has After=systemd-user-sessions.service this doesn't actually help since the use of this service is "Permit user logins after boot, prohibit user logins at shutdown". It does not actually communicate anything about session state itself.

So what happens is:

  • plasma tells systemd to reboot
  • login gets disabled as per systemd-user-sessions
  • recent logind will send TERM to all processes of all user session
  • systemd-user-sessions is now swiftly switching to stopped
  • sddm.service can now be stoppped
  • sddm.service gets TERM
  • sddm terminates, X is now dead
  • user session TERM might still be going on!
  • X is now gone, so any and all apps that are still doing TERM and entering non-safe codepaths (such as ones that expect X is stull running) will get SIGSEVS or other crap, possibly triggering crashhandlers that hold things up with fetching coredumps or attaching gdb or whatever other nonesense might be going on in handlers.
  • these processes are now stuck until logind calls it quits and sends KILL

Now the problem with this is that SDDM shouldn't pull X from under a sessions feet, that is poor dep ordering as it were. The tricky thing is doing this correctly for which there are multiple options:

  1. before sddm exits, it sends TERM or maybe even KILL to all processes of the session it started (this seems a bit repetitive since systemd already implements that functionality)
  2. sddm.service could use After=user.slice to make sure sddm gets ordered after user session killing, I am not sure if this has any adverse effects, but it seems to solve the problem

sddm-greater stuck

On my system sddm-greeter actually get stuck in closing (using plasma's breeze theme)

         Service: sddm-greeter; type x11; class greeter
           State: closing
            Unit: session-1.scope
                  ├─3610 dbus-launch --autolaunch a4c8250cb9ad40cd8cbc60c5e8e9967c --binary-syntax --close-stderr
                  └─3618 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
@hsitter
Copy link
Collaborator Author

hsitter commented Aug 10, 2016

So, actually After=user.slice makes no sense because technically we would have to have user.slice shut down before sddm, albeit for start up we need user.slice to start before sddm (or actually we need systemd-user-sessions and don't care about user.slice at all). Which is something that apparently can't be expressed via systemd, or maybe I am just not finding a config. I am now thinking that this needs to be somewhat more involved.

sddm.service should be changed to killmode=mixed which will give sddm itself TERM upon stop but leave the cgroup untouched for starters. Sddm should then block it's own termination until all sddm-started user sessions are fully closed. To that end sddm maybe could send TERM to everything. Alternatively it could simply not do anything but wait, in which case logind would be expected to do the TERM emission, sddm would simply wait for all sessions to close. If sddm's TERM times out, in mixed the entire cgroup will get KILL (that includes Xorg) next, bringing us to the situation we have now. The difference however is that while sddm's TERM was timing out logind would have also sent TERM to the user sessions, so their KILL is imminent anyway, whether or not they get XIOs or whatever from X or an actual KILL from systemd at this point makes no difference anymore.

Best case scenario shutdown:

  1. systemd stop sddm
  2. sddm blocks term while sessions-not-closed
  3. logind terms sessions
  4. sddm unblocks and stops
  5. system shuts down

Worst case scenario shutdown (session app is unresponsive to TERM within timeout):

  1. systemd stops sddm
  2. sddm blocks term while sessions-not-closed
  3. logind terms sessions
  4. an application 'foobar' decides to not react to term
  5. configured timeout is reached for sddm
  6. systemd kills sddm, sddm-greeter, Xorg and whatever else was forked
  7. configured timeout is reached for logind
  8. logind kills sessions
  9. 'foobar' gets killed
  10. system shuts down

It's still not very elegant but TBH the default expectation here is that desktops actually manage to clean up their session before invoking reboot/poweroff I should think, so what I am suggesting is basically fallback behavior I guess.

@plfiorini
Copy link
Member

plfiorini commented Aug 20, 2016

sddm.service could use After=user.slice to make sure sddm gets ordered after user session killing, I am not sure if this has any adverse effects, but it seems to solve the problem

the greeter logins in as sddm - perhaps when the sddm user session will be stopped there be problems there

@plfiorini
Copy link
Member

@apachelogger before doing something so complex on sddm please try to fix plasma first.

@plfiorini
Copy link
Member

@apachelogger would xorg with user privileges help here? in that case plasma and sddm would have two different servers

@eatdust
Copy link

eatdust commented Nov 17, 2016

Hi there,
I can confirm the same behaviour on Mageia and on all other window-managers. I am using a very small one, fvwm2 and also the systemd session get stuck in "closing state":

loginctl session-status c1
c1 - sddm (958)
Since: Thu 2016-11-17 10:58:34 CET; 7h ago
Leader: 9973
Seat: seat0; vc1
Display: :0
Service: sddm-greeter; type x11; class greeter
State: closing
Unit: session-c1.scope
├─9996 dbus-launch --autolaunch dacb524af88b4fb6821f6a8a1a765167 --binary-syntax --close-stderr
└─9997 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

We have a bug report opened there, seems to be generated by this dbus --autolaunch.

https://bugs.mageia.org/show_bug.cgi?id=18942

Cheers.

@LRitzdorf
Copy link

Just as a heads-up, this seems to have been fixed by Plasma, in https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/1177.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants