v12-0001-Pass-CAC-as-argument-to-backend-process.patch

text/x-patch

Filename: v12-0001-Pass-CAC-as-argument-to-backend-process.patch
Type: text/x-patch
Part: 0
Message: Re: Refactoring backend fork+exec code

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v12-0001
Subject: Pass CAC as argument to backend process
File+
src/backend/postmaster/postmaster.c 32 12
src/include/libpq/libpq-be.h 0 12
From 7920cdf03b2fe9102d324eda7858a8a569feaf7b Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 30 Nov 2023 00:04:22 +0200
Subject: [PATCH v12 1/8] Pass CAC as argument to backend process

We used to smuggle it to the child process in the Port struct, but it
seems better to pass it down as a separate argument. This paves the
way for the next commits, in which we move the initialization of the
Port struct to the backend process, after forking.

Reviewed-by: Tristan Partin, Andres Freund
Discussion: https://www.postgresql.org/message-id/7a59b073-5b5b-151e-7ed3-8b01ff7ce9ef@iki.fi
---
 src/backend/postmaster/postmaster.c | 44 +++++++++++++++++++++--------
 src/include/libpq/libpq-be.h        | 12 --------
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 59318067460..851828077b1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -420,7 +420,19 @@ static void HandleChildCrash(int pid, int exitstatus, const char *procname);
 static void LogChildExit(int lev, const char *procname,
 						 int pid, int exitstatus);
 static void PostmasterStateMachine(void);
-static void BackendInitialize(Port *port);
+
+/* Return value of canAcceptConnections() */
+typedef enum CAC_state
+{
+	CAC_OK,
+	CAC_STARTUP,
+	CAC_SHUTDOWN,
+	CAC_RECOVERY,
+	CAC_NOTCONSISTENT,
+	CAC_TOOMANY,
+} CAC_state;
+
+static void BackendInitialize(Port *port, CAC_state cac);
 static void BackendRun(Port *port) pg_attribute_noreturn();
 static void ExitPostmaster(int status) pg_attribute_noreturn();
 static int	ServerLoop(void);
@@ -479,7 +491,7 @@ typedef struct
 } win32_deadchild_waitinfo;
 #endif							/* WIN32 */
 
-static pid_t backend_forkexec(Port *port);
+static pid_t backend_forkexec(Port *port, CAC_state cac);
 static pid_t internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker);
 
 /* Type for a socket that can be inherited to a client process */
@@ -4089,6 +4101,7 @@ BackendStartup(Port *port)
 {
 	Backend    *bn;				/* for backend cleanup */
 	pid_t		pid;
+	CAC_state	cac;
 
 	/*
 	 * Create backend data structure.  Better before the fork() so we can
@@ -4120,8 +4133,8 @@ BackendStartup(Port *port)
 	bn->cancel_key = MyCancelKey;
 
 	/* Pass down canAcceptConnections state */
-	port->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
-	bn->dead_end = (port->canAcceptConnections != CAC_OK);
+	cac = canAcceptConnections(BACKEND_TYPE_NORMAL);
+	bn->dead_end = (cac != CAC_OK);
 
 	/*
 	 * Unless it's a dead_end child, assign it a child slot number
@@ -4135,7 +4148,7 @@ BackendStartup(Port *port)
 	bn->bgworker_notify = false;
 
 #ifdef EXEC_BACKEND
-	pid = backend_forkexec(port);
+	pid = backend_forkexec(port, cac);
 #else							/* !EXEC_BACKEND */
 	pid = fork_process();
 	if (pid == 0)				/* child */
@@ -4147,7 +4160,7 @@ BackendStartup(Port *port)
 		ClosePostmasterPorts(false);
 
 		/* Perform additional initialization and collect startup packet */
-		BackendInitialize(port);
+		BackendInitialize(port, cac);
 
 		/* And run the backend */
 		BackendRun(port);
@@ -4234,7 +4247,7 @@ report_fork_failure_to_client(Port *port, int errnum)
  * but have not yet set up most of our local pointers to shmem structures.
  */
 static void
-BackendInitialize(Port *port)
+BackendInitialize(Port *port, CAC_state cac)
 {
 	int			status;
 	int			ret;
@@ -4369,7 +4382,7 @@ BackendInitialize(Port *port)
 	 */
 	if (status == STATUS_OK)
 	{
-		switch (port->canAcceptConnections)
+		switch (cac)
 		{
 			case CAC_STARTUP:
 				ereport(FATAL,
@@ -4508,15 +4521,19 @@ postmaster_forkexec(int argc, char *argv[])
  * returns the pid of the fork/exec'd process, or -1 on failure
  */
 static pid_t
-backend_forkexec(Port *port)
+backend_forkexec(Port *port, CAC_state cac)
 {
-	char	   *av[4];
+	char	   *av[5];
 	int			ac = 0;
+	char		cacbuf[10];
 
 	av[ac++] = "postgres";
 	av[ac++] = "--forkbackend";
 	av[ac++] = NULL;			/* filled in by internal_forkexec */
 
+	snprintf(cacbuf, sizeof(cacbuf), "%d", (int) cac);
+	av[ac++] = cacbuf;
+
 	av[ac] = NULL;
 	Assert(ac < lengthof(av));
 
@@ -4923,7 +4940,10 @@ SubPostmasterMain(int argc, char *argv[])
 	/* Run backend or appropriate child */
 	if (strcmp(argv[1], "--forkbackend") == 0)
 	{
-		Assert(argc == 3);		/* shouldn't be any more args */
+		CAC_state	cac;
+
+		Assert(argc == 4);
+		cac = (CAC_state) atoi(argv[3]);
 
 		/*
 		 * Need to reinitialize the SSL library in the backend, since the
@@ -4957,7 +4977,7 @@ SubPostmasterMain(int argc, char *argv[])
 		 * PGPROC slots, we have already initialized libpq and are able to
 		 * report the error to the client.
 		 */
-		BackendInitialize(port);
+		BackendInitialize(port, cac);
 
 		/* Restore basic shared memory pointers */
 		InitShmemAccess(UsedShmemSegAddr);
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 47d66d55241..59c2a1d874f 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -58,17 +58,6 @@ typedef struct
 #include "libpq/pqcomm.h"
 
 
-typedef enum CAC_state
-{
-	CAC_OK,
-	CAC_STARTUP,
-	CAC_SHUTDOWN,
-	CAC_RECOVERY,
-	CAC_NOTCONSISTENT,
-	CAC_TOOMANY,
-} CAC_state;
-
-
 /*
  * GSSAPI specific state information
  */
@@ -156,7 +145,6 @@ typedef struct Port
 	int			remote_hostname_resolv; /* see above */
 	int			remote_hostname_errcode;	/* see above */
 	char	   *remote_port;	/* text rep of remote port */
-	CAC_state	canAcceptConnections;	/* postmaster connection status */
 
 	/*
 	 * Information that needs to be saved from the startup packet and passed
-- 
2.39.2