Pass CAC as an argument to the 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 commit, which moves 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
This commit is contained in:
Heikki Linnakangas 2024-03-12 13:42:36 +02:00
parent 73f7fb2a4c
commit d162c3a73b
2 changed files with 32 additions and 24 deletions

View File

@ -418,7 +418,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);
@ -477,7 +489,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 */
@ -4087,6 +4099,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
@ -4118,8 +4131,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
@ -4133,7 +4146,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 */
@ -4145,7 +4158,7 @@ BackendStartup(Port *port)
ClosePostmasterPorts(false);
/* Perform additional initialization and collect startup packet */
BackendInitialize(port);
BackendInitialize(port, cac);
/* And run the backend */
BackendRun(port);
@ -4232,7 +4245,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;
@ -4367,7 +4380,7 @@ BackendInitialize(Port *port)
*/
if (status == STATUS_OK)
{
switch (port->canAcceptConnections)
switch (cac)
{
case CAC_STARTUP:
ereport(FATAL,
@ -4506,15 +4519,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));
@ -4921,7 +4938,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
@ -4955,7 +4975,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);

View File

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