1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-02 10:51:20 +03:00

logind: fix serialization/deserialization of user's "display session"

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.
This commit is contained in:
Lennart Poettering 2018-08-03 19:04:35 +02:00
parent 8c29a45709
commit 1c8280fd47
2 changed files with 21 additions and 15 deletions

View 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);

View 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);