698723
From 0314e68fe961cec941b1b0eb1cbcca4546cfdfdb Mon Sep 17 00:00:00 2001
698723
From: Lennart Poettering <lennart@poettering.net>
698723
Date: Fri, 3 Aug 2018 19:04:35 +0200
698723
Subject: [PATCH] logind: fix serialization/deserialization of user's "display
698723
 session"
698723
698723
Previously this was serialized as part of the user object. This didn't
698723
work however, as we load users first, and sessions seconds and hence
698723
referencing a session from the user load logic cannot work.
698723
698723
Fix this by storing an IS_DISPLAY property along with each session, and
698723
make the session with this set display session when it is loaded.
698723
698723
(cherry picked from commit 1c8280fd47b6561d35b15b3b6d49bdeacf891bfd)
698723
698723
Related: #1642460
698723
---
698723
 src/login/logind-session.c | 18 +++++++++++++++++-
698723
 src/login/logind-user.c    | 18 ++++--------------
698723
 2 files changed, 21 insertions(+), 15 deletions(-)
698723
698723
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
698723
index 5621d59a41..0afb065b2b 100644
698723
--- a/src/login/logind-session.c
698723
+++ b/src/login/logind-session.c
698723
@@ -184,11 +184,13 @@ int session_save(Session *s) {
698723
                 "UID="UID_FMT"\n"
698723
                 "USER=%s\n"
698723
                 "ACTIVE=%i\n"
698723
+                "IS_DISPLAY=%i\n"
698723
                 "STATE=%s\n"
698723
                 "REMOTE=%i\n",
698723
                 s->user->uid,
698723
                 s->user->name,
698723
                 session_is_active(s),
698723
+                s->user->display == s,
698723
                 session_state_to_string(session_get_state(s)),
698723
                 s->remote);
698723
 
698723
@@ -359,7 +361,8 @@ int session_load(Session *s) {
698723
                 *monotonic = NULL,
698723
                 *controller = NULL,
698723
                 *active = NULL,
698723
-                *devices = NULL;
698723
+                *devices = NULL,
698723
+                *is_display = NULL;
698723
 
698723
         int k, r;
698723
 
698723
@@ -389,6 +392,7 @@ int session_load(Session *s) {
698723
                            "CONTROLLER",     &controller,
698723
                            "ACTIVE",         &active,
698723
                            "DEVICES",        &devices,
698723
+                           "IS_DISPLAY",     &is_display,
698723
                            NULL);
698723
 
698723
         if (r < 0)
698723
@@ -496,6 +500,18 @@ int session_load(Session *s) {
698723
                         s->was_active = k;
698723
         }
698723
 
698723
+        if (is_display) {
698723
+                /* Note that when enumerating users are loaded before sessions, hence the display session to use is
698723
+                 * something we have to store along with the session and not the user, as in that case we couldn't
698723
+                 * apply it at the time we load the user. */
698723
+
698723
+                k = parse_boolean(is_display);
698723
+                if (k < 0)
698723
+                        log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m");
698723
+                else if (k > 0)
698723
+                        s->user->display = s;
698723
+        }
698723
+
698723
         if (controller) {
698723
                 if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
698723
                         session_set_controller(s, controller, false, false);
698723
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
698723
index 60ccd62abb..17ed361411 100644
698723
--- a/src/login/logind-user.c
698723
+++ b/src/login/logind-user.c
698723
@@ -277,8 +277,7 @@ int user_save(User *u) {
698723
 }
698723
 
698723
 int user_load(User *u) {
698723
-        _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
698723
-        Session *s = NULL;
698723
+        _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
698723
         int r;
698723
 
698723
         assert(u);
698723
@@ -286,22 +285,13 @@ int user_load(User *u) {
698723
         r = parse_env_file(NULL, u->state_file, NEWLINE,
698723
                            "SERVICE_JOB", &u->service_job,
698723
                            "SLICE_JOB",   &u->slice_job,
698723
-                           "DISPLAY",     &display,
698723
                            "REALTIME",    &realtime,
698723
                            "MONOTONIC",   &monotonic,
698723
                            NULL);
698723
-        if (r < 0) {
698723
-                if (r == -ENOENT)
698723
-                        return 0;
698723
-
698723
+        if (r == -ENOENT)
698723
+                return 0;
698723
+        if (r < 0)
698723
                 return log_error_errno(r, "Failed to read %s: %m", u->state_file);
698723
-        }
698723
-
698723
-        if (display)
698723
-                s = hashmap_get(u->manager->sessions, display);
698723
-
698723
-        if (s && s->display && display_is_local(s->display))
698723
-                u->display = s;
698723
 
698723
         if (realtime)
698723
                 timestamp_deserialize(realtime, &u->timestamp.realtime);