]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: fix serialization/deserialization of user's "display session"
authorLennart Poettering <lennart@poettering.net>
Fri, 3 Aug 2018 17:04:35 +0000 (19:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 13 Oct 2018 10:59:29 +0000 (12:59 +0200)
Previously this was serialized as part of the user object. This didn't
work however, as we load users first, and sessions seconds and hence
referencing a session from the user load logic cannot work.

Fix this by storing an IS_DISPLAY property along with each session, and
make the session with this set display session when it is loaded.

src/login/logind-session.c
src/login/logind-user.c

index f59e62837eaaf73c1cf6282daa89cc5d3d171546..6c447f5534298a07a6d55f9cad54102c9a76d286 100644 (file)
@@ -184,11 +184,13 @@ int session_save(Session *s) {
                 "UID="UID_FMT"\n"
                 "USER=%s\n"
                 "ACTIVE=%i\n"
+                "IS_DISPLAY=%i\n"
                 "STATE=%s\n"
                 "REMOTE=%i\n",
                 s->user->uid,
                 s->user->name,
                 session_is_active(s),
+                s->user->display == s,
                 session_state_to_string(session_get_state(s)),
                 s->remote);
 
@@ -359,7 +361,8 @@ int session_load(Session *s) {
                 *monotonic = NULL,
                 *controller = NULL,
                 *active = NULL,
-                *devices = NULL;
+                *devices = NULL,
+                *is_display = NULL;
 
         int k, r;
 
@@ -389,6 +392,7 @@ int session_load(Session *s) {
                            "CONTROLLER",     &controller,
                            "ACTIVE",         &active,
                            "DEVICES",        &devices,
+                           "IS_DISPLAY",     &is_display,
                            NULL);
 
         if (r < 0)
@@ -496,6 +500,18 @@ int session_load(Session *s) {
                         s->was_active = k;
         }
 
+        if (is_display) {
+                /* Note that when enumerating users are loaded before sessions, hence the display session to use is
+                 * something we have to store along with the session and not the user, as in that case we couldn't
+                 * apply it at the time we load the user. */
+
+                k = parse_boolean(is_display);
+                if (k < 0)
+                        log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m");
+                else if (k > 0)
+                        s->user->display = s;
+        }
+
         if (controller) {
                 if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
                         session_set_controller(s, controller, false, false);
index ad6349944c48e75be90ff69543e9a0ccc8ac6d31..302d3b08e681b14858c39cea54d996eb7384b167 100644 (file)
@@ -277,8 +277,7 @@ int user_save(User *u) {
 }
 
 int user_load(User *u) {
-        _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
-        Session *s = NULL;
+        _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
         int r;
 
         assert(u);
@@ -286,22 +285,13 @@ int user_load(User *u) {
         r = parse_env_file(NULL, u->state_file, NEWLINE,
                            "SERVICE_JOB", &u->service_job,
                            "SLICE_JOB",   &u->slice_job,
-                           "DISPLAY",     &display,
                            "REALTIME",    &realtime,
                            "MONOTONIC",   &monotonic,
                            NULL);
-        if (r < 0) {
-                if (r == -ENOENT)
-                        return 0;
-
+        if (r == -ENOENT)
+                return 0;
+        if (r < 0)
                 return log_error_errno(r, "Failed to read %s: %m", u->state_file);
-        }
-
-        if (display)
-                s = hashmap_get(u->manager->sessions, display);
-
-        if (s && s->display && display_is_local(s->display))
-                u->display = s;
 
         if (realtime)
                 timestamp_deserialize(realtime, &u->timestamp.realtime);