]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: handle session leader termination during deserialization more gracefully 39607/head
authorMike Yuan <me@yhndnzj.com>
Tue, 4 Nov 2025 20:13:49 +0000 (21:13 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 6 Nov 2025 19:53:49 +0000 (20:53 +0100)
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

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

index 027906277c15ab03c9d87ccf263f076bf6034ce0..d0c36f1b41edcdd5b1c5d36c3278fb9657b54312 100644 (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));
index e643189338282481089b941f1dfbe4ba252ee489..5cdfc2a00dc8e3980c3a400f06c6995873e9ce2e 100644 (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));
         }