From be1aaed474578ee5076bf53c939164f507ab62e3 Mon Sep 17 00:00:00 2001
From: Mike Palmiotto <mike.palmiotto@crunchydata.com>
Date: Wed, 4 Mar 2020 03:53:59 +0000
Subject: [PATCH 09/11] Move Backend-specific code down

---
 src/backend/postmaster/postmaster.c | 330 ++++++++++++++--------------
 1 file changed, 165 insertions(+), 165 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index ceb738bf1e..f7a433f3a3 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -516,171 +516,6 @@ HANDLE		PostmasterHandle;
 
 static Port *ConnProcPort = NULL;
 
-/*
- * BackendPrep
- *
- * Do all of the pre-fork setup for a new Backend.
-*/
-int
-BackendPrep(int argc, char *argv[])
-{
-	/*
-	 * Create backend data structure.  Better before the fork() so we can
-	 * handle failure cleanly.
-	 */
-	Backend *bn;
-
-	bn = (Backend *) malloc(sizeof(Backend));
-	if (!bn)
-	{
-		ereport(LOG,
-				(errcode(ERRCODE_OUT_OF_MEMORY),
-				 errmsg("out of memory")));
-	}
-
-	/*
-	 * Compute the cancel key that will be assigned to this backend. The
-	 * backend will have its own copy in the forked-off process' value of
-	 * MyCancelKey, so that it can transmit the key to the frontend.
-	 */
-	if (!RandomCancelKey(&MyCancelKey))
-	{
-		free(bn);
-		ereport(LOG,
-				(errcode(ERRCODE_INTERNAL_ERROR),
-				 errmsg("could not generate random cancel key")));
-	}
-
-	bn->cancel_key = MyCancelKey;
-
-	/* Pass down canAcceptConnections state */
-	ConnProcPort->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
-	bn->dead_end = (ConnProcPort->canAcceptConnections != CAC_OK &&
-						   ConnProcPort->canAcceptConnections != CAC_WAITBACKUP);
-
-	/*
-	 * Unless it's a dead_end child, assign it a child slot number
-	 */
-	if (!bn->dead_end)
-		bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
-	else
-		bn->child_slot = 0;
-
-	/* Hasn't asked to be notified about any bgworkers yet */
-	bn->bgworker_notify = false;
-
-	/*
-	 * Push the Backend to the stack as-is so it can be retreived by the parent
-	 * on the other side of the fork/exec. They will modify this entry in place.
-	 */
-	dlist_push_head(&BackendList, &bn->elem);
-
-	return 0;
-}
-
-/*
- *	 BackendMain
- *
- *	 Child code when forking a Backend.
- */
-void BackendMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
-{
-	/*
-	 * Perform additional initialization and collect startup packet.
-	 *
-	 * We want to do this before InitProcess() for a couple of reasons: 1.
-	 * so that we aren't eating up a PGPROC slot while waiting on the
-	 * client. 2. so that if InitProcess() fails due to being out of
-	 * PGPROC slots, we have already initialized libpq and are able to
-	 * report the error to the client.
-	 */
-	BackendInitialize(ConnProcPort);
-
-	/* And run the backend */
-	BackendRun(ConnProcPort);		/* does not return */
-}
-
-/*
- *	 BackendPostmasterMain
- *
- *	 Parent code when forking a Backend.
- */
-void BackendParentMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
-{
-	dlist_mutable_iter iter;
-
-	/*
-	 * Find our backend node by popping the element with a matching child slot
-	 * off the list. This was pushed to the stack (incomplete) by BackendPrep.
-	 * We need to fix it up and push back.
-	 */
-	dlist_foreach_modify(iter, &BackendList)
-	{
-		Backend *bp = dlist_container(Backend, elem, iter.cur);
-
-		/* MyPMChildSlot is guaranteed to match the child MyPMChildSlot */
-		if (bp->child_slot == MyPMChildSlot)
-		{
-			/*
-			 * Everything's been successful, it's safe to add this backend to our list
-			 * of backends.
-			 */
-			bp->pid = MyChildProcPid;
-			bp->bkend_type = BACKEND_TYPE_NORMAL;	/* Can change later to WALSND */
-
-#ifdef EXEC_BACKEND
-			if (!bp->dead_end)
-				ShmemBackendArrayAdd(bp);
-#endif
-			break;	/* There is only one entry and we've found it */
-		}
-	}
-
-	/* in parent, successful fork */
-	ereport(DEBUG2,
-			(errmsg_internal("forked new backend, pid=%d socket=%d",
-							 (int) MyChildProcPid, (int) MyProcPort->sock)));
-}
-
-/*
- *	 BackendCleanup
- *
- *	 Backend cleanup in case a failure occurs forking a new Backend.
- */
-bool
-BackendCleanup(int child_errno)
-{
-	dlist_mutable_iter iter;
-
-	dlist_foreach_modify(iter, &BackendList)
-	{
-		Backend    *bp = dlist_container(Backend, elem, iter.cur);
-
-		if (bp->child_slot == MyPMChildSlot)
-		{
-			if (!bp->dead_end)
-			{
-				if (!ReleasePostmasterChildSlot(bp->child_slot))
-				{
-					/* Could not release child slot! Panic! */
-					return true;
-				}
-#ifdef EXEC_BACKEND
-				ShmemBackendArrayRemove(bp);
-#endif
-			}
-			dlist_delete(iter.cur);
-			free(bp);
-			break;
-		}
-	}
-
-	report_fork_failure_to_client(MyProcPort, child_errno);
-
-	/* Don't panic */
-	return false;
-}
-
 /*
  * Postmaster main entry point
  */
@@ -3375,6 +3210,171 @@ reaper(SIGNAL_ARGS)
 	errno = save_errno;
 }
 
+/*
+ * BackendPrep
+ *
+ * Do all of the pre-fork setup for a new Backend.
+*/
+int
+BackendPrep(int argc, char *argv[])
+{
+	/*
+	 * Create backend data structure.  Better before the fork() so we can
+	 * handle failure cleanly.
+	 */
+	Backend *bn;
+
+	bn = (Backend *) malloc(sizeof(Backend));
+	if (!bn)
+	{
+		ereport(LOG,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
+	}
+
+	/*
+	 * Compute the cancel key that will be assigned to this backend. The
+	 * backend will have its own copy in the forked-off process' value of
+	 * MyCancelKey, so that it can transmit the key to the frontend.
+	 */
+	if (!RandomCancelKey(&MyCancelKey))
+	{
+		free(bn);
+		ereport(LOG,
+				(errcode(ERRCODE_INTERNAL_ERROR),
+				 errmsg("could not generate random cancel key")));
+	}
+
+	bn->cancel_key = MyCancelKey;
+
+	/* Pass down canAcceptConnections state */
+	ConnProcPort->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
+	bn->dead_end = (ConnProcPort->canAcceptConnections != CAC_OK &&
+						   ConnProcPort->canAcceptConnections != CAC_WAITBACKUP);
+
+	/*
+	 * Unless it's a dead_end child, assign it a child slot number
+	 */
+	if (!bn->dead_end)
+		bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
+	else
+		bn->child_slot = 0;
+
+	/* Hasn't asked to be notified about any bgworkers yet */
+	bn->bgworker_notify = false;
+
+	/*
+	 * Push the Backend to the stack as-is so it can be retreived by the parent
+	 * on the other side of the fork/exec. They will modify this entry in place.
+	 */
+	dlist_push_head(&BackendList, &bn->elem);
+
+	return 0;
+}
+
+/*
+ *	 BackendMain
+ *
+ *	 Child code when forking a Backend.
+ */
+void BackendMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
+{
+	/*
+	 * Perform additional initialization and collect startup packet.
+	 *
+	 * We want to do this before InitProcess() for a couple of reasons: 1.
+	 * so that we aren't eating up a PGPROC slot while waiting on the
+	 * client. 2. so that if InitProcess() fails due to being out of
+	 * PGPROC slots, we have already initialized libpq and are able to
+	 * report the error to the client.
+	 */
+	BackendInitialize(ConnProcPort);
+
+	/* And run the backend */
+	BackendRun(ConnProcPort);		/* does not return */
+}
+
+/*
+ *	 BackendPostmasterMain
+ *
+ *	 Parent code when forking a Backend.
+ */
+void BackendParentMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
+{
+	dlist_mutable_iter iter;
+
+	/*
+	 * Find our backend node by popping the element with a matching child slot
+	 * off the list. This was pushed to the stack (incomplete) by BackendPrep.
+	 * We need to fix it up and push back.
+	 */
+	dlist_foreach_modify(iter, &BackendList)
+	{
+		Backend *bp = dlist_container(Backend, elem, iter.cur);
+
+		/* MyPMChildSlot is guaranteed to match the child MyPMChildSlot */
+		if (bp->child_slot == MyPMChildSlot)
+		{
+			/*
+			 * Everything's been successful, it's safe to add this backend to our list
+			 * of backends.
+			 */
+			bp->pid = MyChildProcPid;
+			bp->bkend_type = BACKEND_TYPE_NORMAL;	/* Can change later to WALSND */
+
+#ifdef EXEC_BACKEND
+			if (!bp->dead_end)
+				ShmemBackendArrayAdd(bp);
+#endif
+			break;	/* There is only one entry and we've found it */
+		}
+	}
+
+	/* in parent, successful fork */
+	ereport(DEBUG2,
+			(errmsg_internal("forked new backend, pid=%d socket=%d",
+							 (int) MyChildProcPid, (int) MyProcPort->sock)));
+}
+
+/*
+ *	 BackendCleanup
+ *
+ *	 Backend cleanup in case a failure occurs forking a new Backend.
+ */
+bool
+BackendCleanup(int child_errno)
+{
+	dlist_mutable_iter iter;
+
+	dlist_foreach_modify(iter, &BackendList)
+	{
+		Backend    *bp = dlist_container(Backend, elem, iter.cur);
+
+		if (bp->child_slot == MyPMChildSlot)
+		{
+			if (!bp->dead_end)
+			{
+				if (!ReleasePostmasterChildSlot(bp->child_slot))
+				{
+					/* Could not release child slot! Panic! */
+					return true;
+				}
+#ifdef EXEC_BACKEND
+				ShmemBackendArrayRemove(bp);
+#endif
+			}
+			dlist_delete(iter.cur);
+			free(bp);
+			break;
+		}
+	}
+
+	report_fork_failure_to_client(MyProcPort, child_errno);
+
+	/* Don't panic */
+	return false;
+}
+
 /*
  * Scan the bgworkers list and see if the given PID (which has just stopped
  * or crashed) is in it.  Handle its shutdown if so, and return true.  If not a
-- 
2.21.0

