From 8edd8c77c88e75822334ccb8376d2c151d6e5615 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 24 Jan 2025 17:00:10 -0500 Subject: [PATCH] postmaster: Move code to switch into FatalError state into function There are two places switching to FatalError mode, behaving somewhat differently. An upcoming commit will introduce a third. That doesn't seem seem like a good idea. This commit just moves the FatalError related code from HandleChildCrash() into its own function, a subsequent commit will evolve the state machine change to be suitable for other callers. Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/kgng5nrvnlv335evmsuvpnh354rw7qyazl73kdysev2cr2v5zu@m3cfzxicm5kp --- src/backend/postmaster/postmaster.c | 74 ++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a24c0385fe6..a92fe4240b2 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -2674,40 +2674,35 @@ CleanupBackend(PMChild *bp, } /* - * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, - * walwriter, autovacuum, archiver, slot sync worker, or background worker. + * Transition into FatalError state, in response to something bad having + * happened. Commonly the caller will have logged the reason for entering + * FatalError state. * - * The objectives here are to clean up our local state about the child - * process, and to signal all other remaining children to quickdie. - * - * The caller has already released its PMChild slot. + * This should only be called when not already in FatalError or + * ImmediateShutdown state. */ static void -HandleChildCrash(int pid, int exitstatus, const char *procname) +HandleFatalError(QuitSignalReason reason, bool consider_sigabrt) { - /* - * We only log messages and send signals if this is the first process - * crash and we're not doing an immediate shutdown; otherwise, we're only - * here to update postmaster's idea of live processes. If we have already - * signaled children, nonzero exit status is to be expected, so don't - * clutter log. - */ - if (FatalError || Shutdown == ImmediateShutdown) - return; + int sigtosend; - LogChildExit(LOG, procname, pid, exitstatus); - ereport(LOG, - (errmsg("terminating any other active server processes"))); - SetQuitSignalReason(PMQUIT_FOR_CRASH); + Assert(!FatalError); + Assert(Shutdown != ImmediateShutdown); + + SetQuitSignalReason(reason); + + if (consider_sigabrt && send_abort_for_crash) + sigtosend = SIGABRT; + else + sigtosend = SIGQUIT; /* - * Signal all other child processes to exit. The crashed process has - * already been removed from ActiveChildList. + * Signal all other child processes to exit. * * We could exclude dead-end children here, but at least when sending * SIGABRT it seems better to include them. */ - TerminateChildren(send_abort_for_crash ? SIGABRT : SIGQUIT); + TerminateChildren(sigtosend); FatalError = true; @@ -2727,6 +2722,39 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) AbortStartTime = time(NULL); } +/* + * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, + * walwriter, autovacuum, archiver, slot sync worker, or background worker. + * + * The objectives here are to clean up our local state about the child + * process, and to signal all other remaining children to quickdie. + * + * The caller has already released its PMChild slot. + */ +static void +HandleChildCrash(int pid, int exitstatus, const char *procname) +{ + /* + * We only log messages and send signals if this is the first process + * crash and we're not doing an immediate shutdown; otherwise, we're only + * here to update postmaster's idea of live processes. If we have already + * signaled children, nonzero exit status is to be expected, so don't + * clutter log. + */ + if (FatalError || Shutdown == ImmediateShutdown) + return; + + LogChildExit(LOG, procname, pid, exitstatus); + ereport(LOG, + (errmsg("terminating any other active server processes"))); + + /* + * Switch into error state. The crashed process has already been removed + * from ActiveChildList. + */ + HandleFatalError(PMQUIT_FOR_CRASH, true); +} + /* * Log the death of a child process. */ -- 2.30.2