Blob Blame History Raw
From 72ca16c8c256e9b5f3fdf81163d5ef90b9c170b2 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 30 Aug 2018 13:06:54 -0400
Subject: [PATCH 23/48] common: don't bail if session disappears out from under
 us

It's entirely possible for a session returned by
sd_seat_get_sessions to disappear immediately after the
sd_seat_get_sessions call returns.  This is especially
likely at logout time where the session will briefly be
in the "closing" state before getting reaped.

If that happens when we're looking for a greeter session, we
stop looking for a greeter session and bail out all confused.

This commit fixes the confusion by gracefully handling the
session disappearing by just proceeding to the next session
in the list.

This commit is very similar to commit 155ee7eca which got
accidentally reverted during code consolidation. The main
difference is this commit checks the correct error code
of -ENXIO instead of -ENOENT, so it might actually fix
what it's ostensibly supposed to fix.
---
 common/gdm-common.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/common/gdm-common.c b/common/gdm-common.c
index c909aceee..59b8dfc44 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -391,90 +391,96 @@ gdm_activate_session_by_id (GDBusConnection *connection,
         return TRUE;
 }
 
 gboolean
 gdm_get_login_window_session_id (const char  *seat_id,
 		                 char       **session_id)
 {
         gboolean   ret;
         int        res, i;
         char     **sessions;
         char      *service_id;
         char      *service_class;
         char      *state;
 
         res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
         if (res < 0) {
                 g_debug ("Failed to determine sessions: %s", strerror (-res));
                 return FALSE;
         }
 
         if (sessions == NULL || sessions[0] == NULL) {
                 *session_id = NULL;
                 ret = FALSE;
                 goto out;
         }
 
         for (i = 0; sessions[i]; i ++) {
 
                 res = sd_session_get_class (sessions[i], &service_class);
                 if (res < 0) {
-                        if (res == -ENOENT)
+                        if (res == -ENXIO)
                                 continue;
 
                         g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
                         ret = FALSE;
                         goto out;
                 }
 
                 if (strcmp (service_class, "greeter") != 0) {
                         free (service_class);
                         continue;
                 }
 
                 free (service_class);
 
                 ret = sd_session_get_state (sessions[i], &state);
                 if (ret < 0) {
+                        if (res == -ENXIO)
+                                continue;
+
                         g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res));
                         ret = FALSE;
                         goto out;
                 }
 
                 if (g_strcmp0 (state, "closing") == 0) {
                         free (state);
                         continue;
                 }
                 free (state);
 
                 res = sd_session_get_service (sessions[i], &service_id);
                 if (res < 0) {
+                        if (res == -ENXIO)
+                                continue;
+
                         g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
                         ret = FALSE;
                         goto out;
                 }
 
                 if (strcmp (service_id, "gdm-launch-environment") == 0) {
                         *session_id = g_strdup (sessions[i]);
                         ret = TRUE;
 
                         free (service_id);
                         goto out;
                 }
 
                 free (service_id);
         }
 
         *session_id = NULL;
         ret = FALSE;
 
 out:
         if (sessions) {
                 for (i = 0; sessions[i]; i ++) {
                         free (sessions[i]);
                 }
 
                 free (sessions);
         }
 
         return ret;
 }
-- 
2.26.0