From: Nathan Bossart <nathandbossart@gmail.com>
To: Andres Freund <andres@anarazel.de>
Cc: Thomas Munro <thomas.munro@gmail.com>
Cc: Michael Paquier <michael@paquier.xyz>
Cc: Robert Haas <robertmhaas@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Fujii Masao <fujii@postgresql.org>
Cc: Postgres hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: stopgap fix for signal handling during restore_command
Date: Sat, 25 Feb 2023 11:39:29 -0800
Message-ID: <20230225193929.GA919073@nathanxps13> (raw)
In-Reply-To: <20230225192825.GA868928@nathanxps13>
References: <20230223231503.GA743455@nathanxps13>
<CA+hUKG+d+u2BZu=N4q15EbR7s52KugSQeQ8eUXE8iuEBe108ng@mail.gmail.com>
<20230224043323.GA821522@nathanxps13>
<20230225190742.lfopue3nkrvxxoie@awork3.anarazel.de>
<20230225192825.GA868928@nathanxps13>
On Sat, Feb 25, 2023 at 11:28:25AM -0800, Nathan Bossart wrote:
> On Sat, Feb 25, 2023 at 11:07:42AM -0800, Andres Freund wrote:
>> I think the much more interesting assertion here would be to check that
>> MyProc->pid equals the current pid.
>
> I don't mind changing this, but why is this a more interesting assertion?
Here is a new patch set with this change.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.comAttachments:
[text/x-diff] v8-0001-Move-extra-code-out-of-the-Pre-PostRestoreCommand.patch (2.0K, ../20230225193929.GA919073@nathanxps13/2-v8-0001-Move-extra-code-out-of-the-Pre-PostRestoreCommand.patch)
download | inline diff:
From 575b959d5e2980454c7ebe10794fff7c5aaf68ed Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Thu, 23 Feb 2023 14:27:48 -0800
Subject: [PATCH v8 1/2] Move extra code out of the Pre/PostRestoreCommand()
block.
If SIGTERM is received within this block, the startup process will
immediately proc_exit() in the signal handler, so it is inadvisable
to include any more code than is required in this section. This
change moves the code recently added to this block (see 1b06d7b and
7fed801) to outside of the block. This ensures that only system()
is called while proc_exit() might be called in the SIGTERM handler,
which is how this code worked from v8.4 to v14.
---
src/backend/access/transam/xlogarchive.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.cindex fcc87ff44f..41684418b6 100644--- a/src/backend/access/transam/xlogarchive.c+++ b/src/backend/access/transam/xlogarchive.c@@ -159,20 +159,27 @@ RestoreArchivedFile(char *path, const char *xlogfname,
(errmsg_internal("executing restore command \"%s\"",
xlogRestoreCmd)));
+ fflush(NULL);+ pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);+
/*
- * Check signals before restore command and reset afterwards.+ * PreRestoreCommand() informs the SIGTERM handler for the startup process+ * that it should proc_exit() right away. This is done for the duration of+ * the system() call because there isn't a good way to break out while it+ * is executing. Since we might call proc_exit() in a signal handler, it+ * is best to put any additional logic before or after the+ * PreRestoreCommand()/PostRestoreCommand() section.
*/
PreRestoreCommand();
/*
* Copy xlog from archival storage to XLOGDIR
*/
- fflush(NULL);- pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
rc = system(xlogRestoreCmd);
- pgstat_report_wait_end();
PostRestoreCommand();
++ pgstat_report_wait_end();
pfree(xlogRestoreCmd);
if (rc == 0)
--
2.25.1
[text/x-diff] v8-0002-Don-t-proc_exit-in-startup-s-SIGTERM-handler-if-f.patch (2.8K, ../20230225193929.GA919073@nathanxps13/3-v8-0002-Don-t-proc_exit-in-startup-s-SIGTERM-handler-if-f.patch)
download | inline diff:
From 42a9760cd34e9aafa6ffe30b0e28e2c893ae6a2c Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Tue, 14 Feb 2023 09:44:53 -0800
Subject: [PATCH v8 2/2] Don't proc_exit() in startup's SIGTERM handler if
forked by system().
Instead, emit a message to STDERR and _exit() in this case. This
change also adds assertions to proc_exit(), ProcKill(), and
AuxiliaryProcKill() to verify that these functions are not called
by a process forked by system(), etc.
---
src/backend/postmaster/startup.c | 20 +++++++++++++++++++-
src/backend/storage/ipc/ipc.c | 3 +++
src/backend/storage/lmgr/proc.c | 2 ++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.cindex efc2580536..bace915881 100644--- a/src/backend/postmaster/startup.c+++ b/src/backend/postmaster/startup.c@@ -19,6 +19,8 @@
*/
#include "postgres.h"
+#include <unistd.h>+
#include "access/xlog.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
@@ -121,7 +123,23 @@ StartupProcShutdownHandler(SIGNAL_ARGS)
int save_errno = errno;
if (in_restore_command)
- proc_exit(1);+ {+ /*+ * If we are in a child process (e.g., forked by system() in+ * RestoreArchivedFile()), we don't want to call any exit callbacks.+ * The parent will take care of that.+ */+ if (MyProcPid == (int) getpid())+ proc_exit(1);+ else+ {+ const char msg[] = "StartupProcShutdownHandler() called in child process\n";+ int rc pg_attribute_unused();++ rc = write(STDERR_FILENO, msg, sizeof(msg));+ _exit(1);+ }+ }
else
shutdown_requested = true;
WakeupRecovery();
diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.cindex 1904d21795..d5097dc008 100644--- a/src/backend/storage/ipc/ipc.c+++ b/src/backend/storage/ipc/ipc.c@@ -103,6 +103,9 @@ static int on_proc_exit_index,
void
proc_exit(int code)
{
+ /* proc_exit() is not safe in forked processes from system(), etc. */+ Assert(MyProcPid == (int) getpid());+
/* Clean up everything that must be cleaned up */
proc_exit_prepare(code);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.cindex 22b4278610..b9e2c3aafe 100644--- a/src/backend/storage/lmgr/proc.c+++ b/src/backend/storage/lmgr/proc.c@@ -805,6 +805,7 @@ ProcKill(int code, Datum arg)
dlist_head *procgloballist;
Assert(MyProc != NULL);
+ Assert(MyProc->pid == (int) getpid()); /* not safe if forked by system(), etc. */
/* Make sure we're out of the sync rep lists */
SyncRepCleanupAtProcExit();
@@ -925,6 +926,7 @@ AuxiliaryProcKill(int code, Datum arg)
PGPROC *proc;
Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
+ Assert(MyProc->pid == (int) getpid()); /* not safe if forked by system(), etc. */
auxproc = &AuxiliaryProcs[proctype];
--
2.25.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: nathandbossart@gmail.com, andres@anarazel.de, thomas.munro@gmail.com, michael@paquier.xyz, robertmhaas@gmail.com, tgl@sss.pgh.pa.us, fujii@postgresql.org, pgsql-hackers@lists.postgresql.org
Subject: Re: stopgap fix for signal handling during restore_command
In-Reply-To: <20230225193929.GA919073@nathanxps13>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox