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