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
This commit is contained in:
Mike Yuan
2025-11-04 21:13:49 +01:00
parent c54112bdee
commit a6590235df
2 changed files with 10 additions and 8 deletions

View File

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

View File

@@ -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));
}