From: Mike Yuan Date: Tue, 4 Nov 2025 20:13:49 +0000 (+0100) Subject: logind: handle session leader termination during deserialization more gracefully X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a6590235dfffc8a676a75b373d97f1db2ebf7079;p=thirdparty%2Fsystemd.git logind: handle session leader termination during deserialization more gracefully We track session leaders by pidfd precisely to make restarts reliable, as leader exiting before deserialization is somewhat expected. Such case is already handled gracefully (we'd GC sessions without leader before kicking off the new cycle), but let's also tweak the log message a bit to reduce annoyance. Closes #39556 --- diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 027906277c1..d0c36f1b41e 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -423,6 +423,8 @@ static int session_load_leader(Session *s, uint64_t pidfdid) { return 0; r = pidref_set_pid(&pidref, s->deserialized_pid); + if (r == -ESRCH) + return log_warning_errno(r, "Leader of session '%s' is gone while deserializing.", s->id); if (r < 0) return log_error_errno(r, "Failed to deserialize leader PID for session '%s': %m", s->id); if (pidref.fd < 0) @@ -437,9 +439,9 @@ static int session_load_leader(Session *s, uint64_t pidfdid) { pidref.pid); if (pidref.fd_id != pidfdid) - return log_error_errno(SYNTHETIC_ERRNO(ESRCH), - "Deserialized pidfd id for process " PID_FMT " (%" PRIu64 ") doesn't match with the current one (%" PRIu64 "), refusing.", - pidref.pid, pidfdid, pidref.fd_id); + return log_warning_errno(SYNTHETIC_ERRNO(ESRCH), + "Deserialized pidfd id for process " PID_FMT " (%" PRIu64 ") doesn't match the current one (%" PRIu64 "). PID recycled while deserializing?", + pidref.pid, pidfdid, pidref.fd_id); } r = session_set_leader_consume(s, TAKE_PIDREF(pidref)); diff --git a/src/login/logind.c b/src/login/logind.c index e6431893382..5cdfc2a00dc 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -473,10 +473,10 @@ static int deliver_session_leader_fd_consume(Session *s, const char *fdname, int r = pidref_set_pidfd_take(&leader_fdstore, fd); if (r < 0) { - if (r == -ESRCH) - log_debug_errno(r, "Leader of session '%s' is gone while deserializing.", s->id); - else - log_warning_errno(r, "Failed to create reference to leader of session '%s': %m", s->id); + log_warning_errno(r, + r == -ESRCH ? "Leader of session '%s' is gone while deserializing." + : "Failed to create reference to leader of session '%s': %m", + s->id); goto fail_close; } TAKE_FD(fd); @@ -566,7 +566,7 @@ static int manager_enumerate_sessions(Manager *m) { session_add_to_gc_queue(s); k = session_load(s); - if (k < 0) + if (k < 0 && k != -ESRCH) RET_GATHER(r, log_warning_errno(k, "Failed to deserialize session '%s', ignoring: %m", s->id)); }