From 9e649e32ee68d9a7145a35d02c59bdc03442d165 Mon Sep 17 00:00:00 2001
From: Mike Palmiotto <mike.palmiotto@crunchydata.com>
Date: Tue, 10 Mar 2020 22:29:44 +0000
Subject: [PATCH v2 03/12] Add AutoVacLauncherType to subprocess struct

---
 src/backend/postmaster/autovacuum.c | 66 ++---------------------------
 src/backend/postmaster/postmaster.c | 36 +++++++++-------
 src/backend/postmaster/subprocess.c |  8 ++++
 src/include/postmaster/autovacuum.h |  3 +-
 src/include/postmaster/subprocess.h |  1 +
 5 files changed, 34 insertions(+), 80 deletions(-)

diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index da75e755f0..d0fdb7e5ee 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -95,6 +95,7 @@
 #include "storage/procsignal.h"
 #include "storage/sinvaladt.h"
 #include "storage/smgr.h"
+#include "postmaster/subprocess.h"
 #include "tcop/tcopprot.h"
 #include "utils/fmgroids.h"
 #include "utils/fmgrprotos.h"
@@ -303,11 +304,9 @@ static WorkerInfo MyWorkerInfo = NULL;
 int			AutovacuumLauncherPid = 0;
 
 #ifdef EXEC_BACKEND
-static pid_t avlauncher_forkexec(void);
 static pid_t avworker_forkexec(void);
 #endif
 NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();
-NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
 
 static Oid	do_start_worker(void);
 static void HandleAutoVacLauncherInterrupts(void);
@@ -353,26 +352,6 @@ static void autovac_refresh_stats(void);
  ********************************************************************/
 
 #ifdef EXEC_BACKEND
-/*
- * forkexec routine for the autovacuum launcher process.
- *
- * Format up the arglist, then fork and exec.
- */
-static pid_t
-avlauncher_forkexec(void)
-{
-	char	   *av[10];
-	int			ac = 0;
-
-	av[ac++] = "postgres";
-	av[ac++] = "--forkavlauncher";
-	av[ac++] = NULL;			/* filled in by postmaster_forkexec */
-	av[ac] = NULL;
-
-	Assert(ac < lengthof(av));
-
-	return postmaster_forkexec(ac, av);
-}
 
 /*
  * We need this set from the outside, before InitProcess is called
@@ -384,50 +363,11 @@ AutovacuumLauncherIAm(void)
 }
 #endif
 
-/*
- * Main entry point for autovacuum launcher process, to be called from the
- * postmaster.
- */
-int
-StartAutoVacLauncher(void)
-{
-	pid_t		AutoVacPID;
-
-#ifdef EXEC_BACKEND
-	switch ((AutoVacPID = avlauncher_forkexec()))
-#else
-	switch ((AutoVacPID = fork_process()))
-#endif
-	{
-		case -1:
-			ereport(LOG,
-					(errmsg("could not fork autovacuum launcher process: %m")));
-			return 0;
-
-#ifndef EXEC_BACKEND
-		case 0:
-			/* in postmaster child ... */
-			InitPostmasterChild();
-
-			/* Close the postmaster's sockets */
-			ClosePostmasterPorts(false);
-
-			AutoVacLauncherMain(0, NULL);
-			break;
-#endif
-		default:
-			return (int) AutoVacPID;
-	}
-
-	/* shouldn't get here */
-	return 0;
-}
-
 /*
  * Main loop for the autovacuum launcher process.
  */
-NON_EXEC_STATIC void
-AutoVacLauncherMain(int argc, char *argv[])
+void
+AutoVacLauncherMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
 {
 	sigjmp_buf	local_sigjmp_buf;
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 4b86aeec2d..2251303589 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1773,7 +1773,7 @@ ServerLoop(void)
 			(AutoVacuumingActive() || start_autovac_launcher) &&
 			pmState == PM_RUN)
 		{
-			AutoVacPID = StartAutoVacLauncher();
+			AutoVacPID = StartSubprocess(AutoVacuumLauncherType);
 			if (AutoVacPID != 0)
 				start_autovac_launcher = false; /* signal processed */
 		}
@@ -3053,7 +3053,7 @@ reaper(SIGNAL_ARGS)
 			 * situation, some of them may be alive already.
 			 */
 			if (!IsBinaryUpgrade && AutoVacuumingActive() && AutoVacPID == 0)
-				AutoVacPID = StartAutoVacLauncher();
+				AutoVacPID = StartSubprocess(AutoVacuumLauncherType);
 			if (PgArchStartupAllowed() && PgArchPID == 0)
 				PgArchPID = pgarch_start();
 			if (PgStatPID == 0)
@@ -5041,19 +5041,6 @@ SubPostmasterMain(int argc, char *argv[])
 		/* And run the backend */
 		BackendRun(&port);		/* does not return */
 	}
-	if (strcmp(argv[1], "--forkavlauncher") == 0)
-	{
-		/* Restore basic shared memory pointers */
-		InitShmemAccess(UsedShmemSegAddr);
-
-		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
-		InitProcess();
-
-		/* Attach process to shared data structures */
-		CreateSharedMemoryAndSemaphores();
-
-		AutoVacLauncherMain(argc - 2, argv + 2);	/* does not return */
-	}
 	if (strcmp(argv[1], "--forkavworker") == 0)
 	{
 		/* Restore basic shared memory pointers */
@@ -5121,6 +5108,19 @@ SubPostmasterMain(int argc, char *argv[])
 
 		AuxiliaryProcessMain(argc - 2, argv + 2);	/* does not return */
 	}
+	else
+	{
+		/* Restore basic shared memory pointers */
+		InitShmemAccess(UsedShmemSegAddr);
+
+		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
+		InitProcess();
+
+		/* Attach process to shared data structures */
+		CreateSharedMemoryAndSemaphores();
+
+		MySubprocess->entrypoint(argc - 2, argv + 2);
+	}
 
 	abort();					/* shouldn't get here */
 }
@@ -5488,7 +5488,11 @@ StartSubprocess(SubprocessType type)
 		MemoryContextDelete(PostmasterContext);
 		PostmasterContext = NULL;
 
-		AuxiliaryProcessMain(argc, argv);
+		if (MySubprocess->needs_aux_proc)
+			AuxiliaryProcessMain(argc, argv);
+		else
+			MySubprocess->entrypoint(argc, argv);
+
 		ExitPostmaster(0);
 	}
 #endif							/* EXEC_BACKEND */
diff --git a/src/backend/postmaster/subprocess.c b/src/backend/postmaster/subprocess.c
index 7e96678dfb..9aa60cc93e 100644
--- a/src/backend/postmaster/subprocess.c
+++ b/src/backend/postmaster/subprocess.c
@@ -12,6 +12,7 @@
  */
 #include "postgres.h"
 #include "bootstrap/bootstrap.h"
+#include "postmaster/autovacuum.h"
 #include "postmaster/bgwriter.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/startup.h"
@@ -71,6 +72,13 @@ static PgSubprocess process_types[] = {
 		.needs_aux_proc = true,
 		.entrypoint = WalReceiverMain,
 		.fork_failure = NULL
+	},
+	{
+		.name = "avlauncher",
+		.desc = "autovacuum launcher",
+		.needs_aux_proc = false,
+		.entrypoint = AutoVacLauncherMain,
+		.fork_failure = NULL
 	}
 };
 
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index d40ed55531..08050cd81c 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -58,6 +58,8 @@ extern void autovac_init(void);
 extern int	StartAutoVacLauncher(void);
 extern int	StartAutoVacWorker(void);
 
+extern void AutoVacLauncherMain(int argc, char *argv[]);
+
 /* called from postmaster when a worker could not be forked */
 extern void AutoVacWorkerFailed(void);
 
@@ -65,7 +67,6 @@ extern void AutoVacWorkerFailed(void);
 extern void AutoVacuumUpdateDelay(void);
 
 #ifdef EXEC_BACKEND
-extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
 extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();
 extern void AutovacuumWorkerIAm(void);
 extern void AutovacuumLauncherIAm(void);
diff --git a/src/include/postmaster/subprocess.h b/src/include/postmaster/subprocess.h
index 33f6a7ab04..9e3c743333 100644
--- a/src/include/postmaster/subprocess.h
+++ b/src/include/postmaster/subprocess.h
@@ -23,6 +23,7 @@ typedef enum
 	CheckpointerType,
 	WalWriterType,
 	WalReceiverType,	/* end of Auxiliary Process Forks */
+	AutoVacuumLauncherType,
 
 	NUMSUBPROCESSTYPES			/* Must be last! */
 } SubprocessType;
-- 
2.17.0

