Merge lp:~pitti/lightdm/cleanup-session into lp:lightdm

Proposed by Martin Pitt
Status: Merged
Merged at revision: 2437
Proposed branch: lp:~pitti/lightdm/cleanup-session
Merge into: lp:lightdm
Diff against target: 72 lines (+40/-0)
3 files modified
src/login1.c (+33/-0)
src/login1.h (+2/-0)
src/session.c (+5/-0)
To merge this branch: bzr merge lp:~pitti/lightdm/cleanup-session
Reviewer Review Type Date Requested Status
Robert Ancell Needs Fixing
Review via email: mp+310758@code.launchpad.net

Description of the change

Fix bug 1637758 in a central/generic way instead of chasing every session (like unity-greeter) to clean up after itself.

This was not previously necessary with session D-Bus, as upstart killed that, and nm-applet/unity-settings-daemon went down with it. But now it's the other way around, nothing in e. g. unity-greeter stops nm-applet when the session closes, so that and the user bus and the whole lightdm logind session stay lingering.

To post a comment you must log in.
Revision history for this message
Martin Pitt (pitti) wrote :

I uploaded this to zesty as debian/patch/, as too many people complain about the weird behaviour (duplicate settings-daemon etc.)

Revision history for this message
Robert Ancell (robert-ancell) wrote :

Oops, I overwrote you change with the 1.21 upload. Sorry. In the future please directly commit any packaging changes to lp:lightdm - these are more important to be in sync with what is in Ubuntu than blocking on a review (changes outside debian/ should still go through review).

Revision history for this message
Robert Ancell (robert-ancell) wrote :

I was under the impression that the logind PAM module would clean up the session but it appears that it only calls ReleaseSession which doesn't kill the processes like TerminateSession does. So if that's the case, then we do need to call TerminateSession at some point (for misbehaving greeter sessions).

However, we should do it after we send SIGTERM to the greeter - it should have a chance to shutdown cleanly. So I think the correct behaviour is to:

1. Send SIGTERM to the greeter
2. Wait for the greeter to stop (session_watch_cb)
3. Call TerminateSession to clean up anything the greeter missed.
4. Wait for the logind session to close (to avoid a race)

There should also be tests to confirm the TerminateSession call is made.

It's probably best to resurrect that distro patch and get that into zesty then fix it properly on this branch.

Revision history for this message
Robert Ancell (robert-ancell) :
review: Needs Fixing
Revision history for this message
Martin Pitt (pitti) wrote :

lp:lightdm had a lot of commits and a newer upstream release than zesty, that's why I didn't just upload that directly.

> it appears that it only calls ReleaseSession which doesn't kill the processes like TerminateSession does.

Correct. logind *can* kill sessions on logout (KillUserProcesses=yes in logind.conf), but we don't do that by default as this would also kill e. g. "screen".

> we should do it after we send SIGTERM to the greeter - it should have a chance to shutdown cleanly.

We could use KillSession with SIGTERM first and wait -- but I don't see why we should bother. The "clean shutdown" part should already have happened from the greeter session itself (and e. g. unity-greeter actually does partially clean itself up), so this would just introduce another round of waiting and thus increase the time for login.

> 4. Wait for the logind session to close (to avoid a race)

I don't think that's necessary -- that can happen asynchronously in the background. The point is to make sure that things like settings-daemon disappear before starting the real user session; if the session itself is still "closing" (but without processes inside any more) for a few msecs that doesn't hurt at all.

Revision history for this message
Robert Ancell (robert-ancell) wrote :

> > 4. Wait for the logind session to close (to avoid a race)
>
> I don't think that's necessary -- that can happen asynchronously in the
> background. The point is to make sure that things like settings-daemon
> disappear before starting the real user session; if the session itself is
> still "closing" (but without processes inside any more) for a few msecs that
> doesn't hurt at all.

Can we assume all processes are gone by the time TerminateSession() is called?

Revision history for this message
Robert Ancell (robert-ancell) wrote :

"Perfect is the enemy of good". Works well enough so I've committed with a regression test.

Revision history for this message
Martin Pitt (pitti) wrote :

> Can we assume all processes are gone by the time TerminateSession() is called?

Not synchronously, it'll still take some time for the processes to react and shut down. But so far this seems to be "good enough" to fix the login issues.

But indeed this is a good point, this should be improved, like waiting for the session-XX.scope unit to actually disappear.

Thanks for adding a test!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/login1.c'
2--- src/login1.c 2015-10-16 10:04:18 +0000
3+++ src/login1.c 2016-11-14 11:05:19 +0000
4@@ -437,6 +437,39 @@
5 }
6 }
7
8+void
9+login1_service_terminate_session (Login1Service *service, const gchar *session_id)
10+{
11+ GError *error = NULL;
12+
13+ g_return_if_fail (service != NULL);
14+ g_return_if_fail (session_id != NULL);
15+
16+ g_debug ("Terminating login1 session %s", session_id);
17+
18+ if (session_id)
19+ {
20+ GVariant *result;
21+
22+ result = g_dbus_connection_call_sync (service->priv->connection,
23+ LOGIN1_SERVICE_NAME,
24+ LOGIN1_OBJECT_NAME,
25+ LOGIN1_MANAGER_INTERFACE_NAME,
26+ "TerminateSession",
27+ g_variant_new ("(s)", session_id),
28+ G_VARIANT_TYPE ("()"),
29+ G_DBUS_CALL_FLAGS_NONE,
30+ -1,
31+ NULL,
32+ &error);
33+ if (error)
34+ g_warning ("Error terminating login1 session: %s", error->message);
35+ g_clear_error (&error);
36+ if (result)
37+ g_variant_unref (result);
38+ }
39+}
40+
41 static void
42 login1_service_init (Login1Service *service)
43 {
44
45=== modified file 'src/login1.h'
46--- src/login1.h 2014-12-16 22:48:40 +0000
47+++ src/login1.h 2016-11-14 11:05:19 +0000
48@@ -78,6 +78,8 @@
49
50 void login1_service_activate_session (Login1Service *service, const gchar *session_id);
51
52+void login1_service_terminate_session (Login1Service *service, const gchar *session_id);
53+
54 const gchar *login1_seat_get_id (Login1Seat *seat);
55
56 gboolean login1_seat_get_can_graphical (Login1Seat *seat);
57
58=== modified file 'src/session.c'
59--- src/session.c 2016-07-11 21:51:14 +0000
60+++ src/session.c 2016-11-14 11:05:19 +0000
61@@ -913,6 +913,11 @@
62 {
63 g_return_if_fail (session != NULL);
64
65+ /* Kill remaining processes in our logind session to avoid them leaking
66+ * to the user session (they share the same $DISPLAY) */
67+ if (getuid () == 0 && session->priv->login1_session_id)
68+ login1_service_terminate_session (login1_service_get_instance (), session->priv->login1_session_id);
69+
70 /* If can cleanly stop then do that */
71 if (session_get_is_authenticated (session) && !session->priv->command_run)
72 {

Subscribers

People subscribed via source and target branches