Here is a patch further cleaning up dummy process startup and the
bootstrap code itself a little.

I've tested it manually giving erroneous input and it behaves in the
same ways as the original.  Of course, it still manages to bootstrap
normally and passes regression tests.

This patches removes a BOOTSTRAP_INCLUDE symbol from tcopprot.h, since
it seems to be useless.  It is about trying to avoid getting prototypes
for functions not needed in bootstrap, presumably because at some point
the bootstrap.c file did not have enough includes to be able to compile
those definitions cleanly, or maybe because it had conflicting
definitions.  But it now works without that.

I also took the liberty of renaming "xlog operation" into "dummy process
type", since that's what really the things are.  I assume it was named
"xlog operation" back when the xlog code was written with the idea of
extending it into different xlog ops.  But we haven't had any.

I think this is as far as I'll go with cleaning up this code in this
round.  Task for some other janitor ...

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: src/backend/bootstrap/bootparse.y
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/bootstrap/bootparse.y,v
retrieving revision 1.86
diff -c -p -r1.86 bootparse.y
*** src/backend/bootstrap/bootparse.y	9 Jan 2007 02:14:11 -0000	1.86
--- src/backend/bootstrap/bootparse.y	16 Feb 2007 04:23:28 -0000
*************** Boot_InsertStmt:
*** 235,244 ****
  						elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
  							 numattr, num_columns_read);
  					if (boot_reldesc == NULL)
! 					{
! 						elog(ERROR, "relation not open");
! 						err_out();
! 					}
  					InsertOneTuple($2);
  					do_end();
  				}
--- 235,241 ----
  						elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
  							 numattr, num_columns_read);
  					if (boot_reldesc == NULL)
! 						elog(FATAL, "relation not open");
  					InsertOneTuple($2);
  					do_end();
  				}
Index: src/backend/bootstrap/bootstrap.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.232
diff -c -p -r1.232 bootstrap.c
*** src/backend/bootstrap/bootstrap.c	16 Feb 2007 02:10:07 -0000	1.232
--- src/backend/bootstrap/bootstrap.c	16 Feb 2007 04:54:30 -0000
***************
*** 20,27 ****
  #include <getopt.h>
  #endif
  
- #define BOOTSTRAP_INCLUDE		/* mask out stuff in tcop/tcopprot.h */
- 
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
--- 20,25 ----
*************** extern char *optarg;
*** 48,53 ****
--- 46,53 ----
  
  #define ALLOC(t, c)		((t *) calloc((unsigned)(c), sizeof(t)))
  
+ static void CheckerModeMain(void);
+ static void BootstrapModeMain(void);
  static void bootstrap_signals(void);
  static void ShutdownDummyProcess(int code, Datum arg);
  static hashnode *AddStr(char *str, int strlength, int mderef);
*************** static Form_pg_attribute AllocateAttribu
*** 55,61 ****
  static int	CompHash(char *str, int len);
  static hashnode *FindStr(char *str, int length, hashnode *mderef);
  static Oid	gettype(char *type);
- static void cleanup(void);
  
  /* ----------------
   *		global variables
--- 55,60 ----
*************** struct typmap
*** 166,172 ****
  static struct typmap **Typ = NULL;
  static struct typmap *Ap = NULL;
  
- static int	Warnings = 0;
  static char Blanks[MAXATTR];
  
  Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */
--- 165,170 ----
*************** static IndexList *ILHead = NULL;
*** 193,215 ****
  
  
  /*
!  *	 The main entry point for running the backend in bootstrap mode
   *
!  *	 The bootstrap mode is used to initialize the template database.
!  *	 The bootstrap backend doesn't speak SQL, but instead expects
!  *	 commands in a special bootstrap language.
   *
!  *	 For historical reasons, BootstrapMain is also used as the control
!  *	 routine for non-backend subprocesses launched by the postmaster,
!  *	 such as startup and shutdown.
   */
! int
! BootstrapMain(int argc, char *argv[])
  {
  	char	   *progname = argv[0];
- 	int			i;
  	int			flag;
! 	int			xlogop = BS_XLOG_NOP;
  	char	   *userDoption = NULL;
  
  	/*
--- 191,209 ----
  
  
  /*
!  *	 DummyProcessMain
   *
!  *	 The main entry point for dummy (non-backend) processes, such as the
!  *	 bgwriter, bootstrapper and the shared memory checker code.
   *
!  *	 This code is here just because of historical reasons.
   */
! void
! DummyProcessMain(int argc, char *argv[])
  {
  	char	   *progname = argv[0];
  	int			flag;
! 	DummyProcType	dummyType = CheckerProcess;
  	char	   *userDoption = NULL;
  
  	/*
*************** BootstrapMain(int argc, char *argv[])
*** 278,284 ****
  				strlcpy(OutputFileName, optarg, MAXPGPATH);
  				break;
  			case 'x':
! 				xlogop = atoi(optarg);
  				break;
  			case 'c':
  			case '-':
--- 272,278 ----
  				strlcpy(OutputFileName, optarg, MAXPGPATH);
  				break;
  			case 'x':
! 				dummyType = atoi(optarg);
  				break;
  			case 'c':
  			case '-':
*************** BootstrapMain(int argc, char *argv[])
*** 328,339 ****
  	{
  		const char *statmsg;
  
! 		switch (xlogop)
  		{
! 			case BS_XLOG_STARTUP:
  				statmsg = "startup process";
  				break;
! 			case BS_XLOG_BGWRITER:
  				statmsg = "writer process";
  				break;
  			default:
--- 322,333 ----
  	{
  		const char *statmsg;
  
! 		switch (dummyType)
  		{
! 			case StartupProcess:
  				statmsg = "startup process";
  				break;
! 			case BgWriterProcess:
  				statmsg = "writer process";
  				break;
  			default:
*************** BootstrapMain(int argc, char *argv[])
*** 398,433 ****
  	 */
  	SetProcessingMode(NormalProcessing);
  
! 	switch (xlogop)
  	{
! 		case BS_XLOG_NOP:
  			bootstrap_signals();
! 			break;
  
! 		case BS_XLOG_BOOTSTRAP:
  			bootstrap_signals();
  			BootStrapXLOG();
  			StartupXLOG();
! 			break;
  
! 		case BS_XLOG_STARTUP:
  			bootstrap_signals();
  			StartupXLOG();
  			LoadFreeSpaceMap();
  			BuildFlatFiles(false);
  			proc_exit(0);		/* startup done */
  
! 		case BS_XLOG_BGWRITER:
  			/* don't set signals, bgwriter has its own agenda */
  			InitXLOGAccess();
  			BackgroundWriterMain();
  			proc_exit(1);		/* should never return */
- 
- 		default:
- 			elog(PANIC, "unrecognized XLOG op: %d", xlogop);
- 			proc_exit(1);
  	}
  
  	/*
  	 * We must be getting invoked for bootstrap mode
  	 */
--- 392,434 ----
  	 */
  	SetProcessingMode(NormalProcessing);
  
! 	switch (dummyType)
  	{
! 		case CheckerProcess:
  			bootstrap_signals();
! 			CheckerModeMain();
! 			proc_exit(0);
  
! 		case BootstrapProcess:
  			bootstrap_signals();
  			BootStrapXLOG();
  			StartupXLOG();
! 			BootstrapModeMain();
! 			proc_exit(1);		/* should never return */
  
! 		case StartupProcess:
  			bootstrap_signals();
  			StartupXLOG();
  			LoadFreeSpaceMap();
  			BuildFlatFiles(false);
  			proc_exit(0);		/* startup done */
  
! 		case BgWriterProcess:
  			/* don't set signals, bgwriter has its own agenda */
  			InitXLOGAccess();
  			BackgroundWriterMain();
  			proc_exit(1);		/* should never return */
  	}
+ }
  
+ /*
+  * In shared memory checker mode, all we really want to do is create shared
+  * memory and semaphores (just to prove we can do it with the current GUC
+  * settings).
+  */
+ static void
+ CheckerModeMain(void)
+ {
  	/*
  	 * We must be getting invoked for bootstrap mode
  	 */
*************** BootstrapMain(int argc, char *argv[])
*** 439,453 ****
  	 * Do backend-like initialization for bootstrap mode
  	 */
  	InitProcess();
! 	(void) InitPostgres(NULL, InvalidOid, NULL, NULL);
  
  	/*
! 	 * In NOP mode, all we really want to do is create shared memory and
! 	 * semaphores (just to prove we can do it with the current GUC settings).
! 	 * So, quit now.
  	 */
! 	if (xlogop == BS_XLOG_NOP)
! 		proc_exit(0);
  
  	/* Initialize stuff for bootstrap-file processing */
  	for (i = 0; i < MAXATTR; i++)
--- 440,469 ----
  	 * Do backend-like initialization for bootstrap mode
  	 */
  	InitProcess();
! 	InitPostgres(NULL, InvalidOid, NULL, NULL);
! }
! 
! /*
!  *	 The main entry point for running the backend in bootstrap mode
!  *
!  *	 The bootstrap mode is used to initialize the template database.
!  *	 The bootstrap backend doesn't speak SQL, but instead expects
!  *	 commands in a special bootstrap language.
!  */
! static void
! BootstrapModeMain(void)
! {
! 	int			i;
! 
! 	Assert(!IsUnderPostmaster);
! 
! 	SetProcessingMode(BootstrapProcessing);
  
  	/*
! 	 * Do backend-like initialization for bootstrap mode
  	 */
! 	InitProcess();
! 	InitPostgres(NULL, InvalidOid, NULL, NULL);
  
  	/* Initialize stuff for bootstrap-file processing */
  	for (i = 0; i < MAXATTR; i++)
*************** BootstrapMain(int argc, char *argv[])
*** 468,481 ****
  	/* Perform a checkpoint to ensure everything's down to disk */
  	SetProcessingMode(NormalProcessing);
  	CreateCheckPoint(true, true);
- 	SetProcessingMode(BootstrapProcessing);
  
  	/* Clean up and exit */
! 	StartTransactionCommand();
! 	cleanup();
  
! 	/* not reached, here to make compiler happy */
! 	return 0;
  }
  
  
--- 484,495 ----
  	/* Perform a checkpoint to ensure everything's down to disk */
  	SetProcessingMode(NormalProcessing);
  	CreateCheckPoint(true, true);
  
  	/* Clean up and exit */
! 	if (boot_reldesc != NULL)
! 		closerel(NULL);
  
! 	proc_exit(0);
  }
  
  
*************** ShutdownDummyProcess(int code, Datum arg
*** 550,567 ****
  	LWLockReleaseAll();
  }
  
- /* ----------------
-  *		error handling / abort routines
-  * ----------------
-  */
- void
- err_out(void)
- {
- 	Warnings++;
- 	cleanup();
- }
- 
- 
  /* ----------------------------------------------------------------
   *				MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS
   * ----------------------------------------------------------------
--- 564,569 ----
*************** InsertOneValue(char *value, int i)
*** 815,829 ****
  
  	elog(DEBUG4, "inserting column %d value \"%s\"", i, value);
  
! 	if (Typ != NULL)
! 	{
! 		typoid = boot_reldesc->rd_att->attrs[i]->atttypid;
! 	}
! 	else
! 	{
! 		/* XXX why is typoid determined differently in this case? */
! 		typoid = attrtypes[i]->atttypid;
! 	}
  
  	boot_get_type_io_data(typoid,
  						  &typlen, &typbyval, &typalign,
--- 817,823 ----
  
  	elog(DEBUG4, "inserting column %d value \"%s\"", i, value);
  
! 	typoid = boot_reldesc->rd_att->attrs[i]->atttypid;
  
  	boot_get_type_io_data(typoid,
  						  &typlen, &typbyval, &typalign,
*************** InsertOneNull(int i)
*** 850,877 ****
  }
  
  /* ----------------
-  *		cleanup
-  * ----------------
-  */
- static void
- cleanup(void)
- {
- 	static int	beenhere = 0;
- 
- 	if (!beenhere)
- 		beenhere = 1;
- 	else
- 	{
- 		elog(FATAL, "cleanup called twice");
- 		proc_exit(1);
- 	}
- 	if (boot_reldesc != NULL)
- 		closerel(NULL);
- 	CommitTransactionCommand();
- 	proc_exit(Warnings ? 1 : 0);
- }
- 
- /* ----------------
   *		gettype
   *
   * NB: this is really ugly; it will return an integer index into TypInfo[],
--- 844,849 ----
*************** gettype(char *type)
*** 934,940 ****
  		return gettype(type);
  	}
  	elog(ERROR, "unrecognized type \"%s\"", type);
- 	err_out();
  	/* not reached, here to make compiler happy */
  	return 0;
  }
--- 906,911 ----
Index: src/backend/main/main.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/main/main.c,v
retrieving revision 1.107
diff -c -p -r1.107 main.c
*** src/backend/main/main.c	5 Jan 2007 22:19:29 -0000	1.107
--- src/backend/main/main.c	16 Feb 2007 03:35:28 -0000
*************** main(int argc, char *argv[])
*** 177,183 ****
  #endif
  
  	if (argc > 1 && strcmp(argv[1], "--boot") == 0)
! 		exit(BootstrapMain(argc, argv));
  
  	if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
  		exit(GucInfoMain());
--- 177,183 ----
  #endif
  
  	if (argc > 1 && strcmp(argv[1], "--boot") == 0)
! 		DummyProcessMain(argc, argv);	/* does not return */
  
  	if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
  		exit(GucInfoMain());
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.523
diff -c -p -r1.523 postmaster.c
*** src/backend/postmaster/postmaster.c	16 Feb 2007 02:10:07 -0000	1.523
--- src/backend/postmaster/postmaster.c	16 Feb 2007 03:58:01 -0000
*************** static void SignalChildren(int signal);
*** 275,281 ****
  static void SignalSomeChildren(int signal, bool only_autovac);
  static int	CountChildren(void);
  static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
! static pid_t StartChildProcess(int xlop);
  static void StartAutovacuumWorker(void);
  
  #ifdef EXEC_BACKEND
--- 275,281 ----
  static void SignalSomeChildren(int signal, bool only_autovac);
  static int	CountChildren(void);
  static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
! static pid_t StartChildProcess(DummyProcType type);
  static void StartAutovacuumWorker(void);
  
  #ifdef EXEC_BACKEND
*************** static void ShmemBackendArrayAdd(Backend
*** 360,367 ****
  static void ShmemBackendArrayRemove(pid_t pid);
  #endif   /* EXEC_BACKEND */
  
! #define StartupDataBase()		StartChildProcess(BS_XLOG_STARTUP)
! #define StartBackgroundWriter() StartChildProcess(BS_XLOG_BGWRITER)
  
  /* Macros to check exit status of a child process */
  #define EXIT_STATUS_0(st)  ((st) == 0)
--- 360,367 ----
  static void ShmemBackendArrayRemove(pid_t pid);
  #endif   /* EXEC_BACKEND */
  
! #define StartupDataBase()		StartChildProcess(StartupProcess)
! #define StartBackgroundWriter() StartChildProcess(BgWriterProcess)
  
  /* Macros to check exit status of a child process */
  #define EXIT_STATUS_0(st)  ((st) == 0)
*************** SubPostmasterMain(int argc, char *argv[]
*** 3438,3444 ****
  		/* Attach process to shared data structures */
  		CreateSharedMemoryAndSemaphores(false, 0);
  
! 		BootstrapMain(argc - 2, argv + 2);
  		proc_exit(0);
  	}
  	if (strcmp(argv[1], "--forkavlauncher") == 0)
--- 3438,3444 ----
  		/* Attach process to shared data structures */
  		CreateSharedMemoryAndSemaphores(false, 0);
  
! 		DummyProcessMain(argc - 2, argv + 2);
  		proc_exit(0);
  	}
  	if (strcmp(argv[1], "--forkavlauncher") == 0)
*************** CountChildren(void)
*** 3703,3720 ****
   * StartChildProcess -- start a non-backend child process for the postmaster
   *
   * xlop determines what kind of child will be started.	All child types
!  * initially go to BootstrapMain, which will handle common setup.
   *
   * Return value of StartChildProcess is subprocess' PID, or 0 if failed
   * to start subprocess.
   */
  static pid_t
! StartChildProcess(int xlop)
  {
  	pid_t		pid;
  	char	   *av[10];
  	int			ac = 0;
! 	char		xlbuf[32];
  
  	/*
  	 * Set up command-line arguments for subprocess
--- 3703,3720 ----
   * StartChildProcess -- start a non-backend child process for the postmaster
   *
   * xlop determines what kind of child will be started.	All child types
!  * initially go to DummyProcessMain, which will handle common setup.
   *
   * Return value of StartChildProcess is subprocess' PID, or 0 if failed
   * to start subprocess.
   */
  static pid_t
! StartChildProcess(DummyProcType type)
  {
  	pid_t		pid;
  	char	   *av[10];
  	int			ac = 0;
! 	char		typebuf[32];
  
  	/*
  	 * Set up command-line arguments for subprocess
*************** StartChildProcess(int xlop)
*** 3726,3733 ****
  	av[ac++] = NULL;			/* filled in by postmaster_forkexec */
  #endif
  
! 	snprintf(xlbuf, sizeof(xlbuf), "-x%d", xlop);
! 	av[ac++] = xlbuf;
  
  	av[ac] = NULL;
  	Assert(ac < lengthof(av));
--- 3726,3733 ----
  	av[ac++] = NULL;			/* filled in by postmaster_forkexec */
  #endif
  
! 	snprintf(typebuf, sizeof(typebuf), "-x%d", type);
! 	av[ac++] = typebuf;
  
  	av[ac] = NULL;
  	Assert(ac < lengthof(av));
*************** StartChildProcess(int xlop)
*** 3752,3758 ****
  		MemoryContextDelete(PostmasterContext);
  		PostmasterContext = NULL;
  
! 		BootstrapMain(ac, av);
  		ExitPostmaster(0);
  	}
  #endif   /* EXEC_BACKEND */
--- 3752,3758 ----
  		MemoryContextDelete(PostmasterContext);
  		PostmasterContext = NULL;
  
! 		DummyProcessMain(ac, av);
  		ExitPostmaster(0);
  	}
  #endif   /* EXEC_BACKEND */
*************** StartChildProcess(int xlop)
*** 3763,3775 ****
  		int			save_errno = errno;
  
  		errno = save_errno;
! 		switch (xlop)
  		{
! 			case BS_XLOG_STARTUP:
  				ereport(LOG,
  						(errmsg("could not fork startup process: %m")));
  				break;
! 			case BS_XLOG_BGWRITER:
  				ereport(LOG,
  				   (errmsg("could not fork background writer process: %m")));
  				break;
--- 3763,3775 ----
  		int			save_errno = errno;
  
  		errno = save_errno;
! 		switch (type)
  		{
! 			case StartupProcess:
  				ereport(LOG,
  						(errmsg("could not fork startup process: %m")));
  				break;
! 			case BgWriterProcess:
  				ereport(LOG,
  				   (errmsg("could not fork background writer process: %m")));
  				break;
*************** StartChildProcess(int xlop)
*** 3783,3789 ****
  		 * fork failure is fatal during startup, but there's no need to choke
  		 * immediately if starting other child types fails.
  		 */
! 		if (xlop == BS_XLOG_STARTUP)
  			ExitPostmaster(1);
  		return 0;
  	}
--- 3783,3789 ----
  		 * fork failure is fatal during startup, but there's no need to choke
  		 * immediately if starting other child types fails.
  		 */
! 		if (type == StartupProcess)
  			ExitPostmaster(1);
  		return 0;
  	}
Index: src/include/bootstrap/bootstrap.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/bootstrap/bootstrap.h,v
retrieving revision 1.45
diff -c -p -r1.45 bootstrap.h
*** src/include/bootstrap/bootstrap.h	5 Jan 2007 22:19:51 -0000	1.45
--- src/include/bootstrap/bootstrap.h	16 Feb 2007 03:47:51 -0000
*************** typedef struct hashnode
*** 32,38 ****
  extern Relation boot_reldesc;
  extern Form_pg_attribute attrtypes[MAXATTR];
  extern int	numattr;
! extern int	BootstrapMain(int argc, char *argv[]);
  
  extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo);
  
--- 32,38 ----
  extern Relation boot_reldesc;
  extern Form_pg_attribute attrtypes[MAXATTR];
  extern int	numattr;
! extern void	DummyProcessMain(int argc, char *argv[]);
  
  extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo);
  
*************** extern int	boot_yyparse(void);
*** 64,72 ****
  extern int	boot_yylex(void);
  extern void boot_yyerror(const char *str);
  
! #define BS_XLOG_NOP			0
! #define BS_XLOG_BOOTSTRAP	1
! #define BS_XLOG_STARTUP		2
! #define BS_XLOG_BGWRITER	3
  
  #endif   /* BOOTSTRAP_H */
--- 64,75 ----
  extern int	boot_yylex(void);
  extern void boot_yyerror(const char *str);
  
! typedef enum
! {
! 	CheckerProcess,
! 	BootstrapProcess,
! 	StartupProcess,
! 	BgWriterProcess
! } DummyProcType;
  
  #endif   /* BOOTSTRAP_H */
Index: src/include/tcop/tcopprot.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/tcop/tcopprot.h,v
retrieving revision 1.86
diff -c -p -r1.86 tcopprot.h
*** src/include/tcop/tcopprot.h	5 Jan 2007 22:19:58 -0000	1.86
--- src/include/tcop/tcopprot.h	16 Feb 2007 04:05:08 -0000
*************** typedef enum
*** 43,50 ****
  
  extern LogStmtLevel log_statement;
  
- #ifndef BOOTSTRAP_INCLUDE
- 
  extern List *pg_parse_and_rewrite(const char *query_string,
  					 Oid *paramTypes, int numParams);
  extern List *pg_parse_query(const char *query_string);
--- 43,48 ----
*************** extern List *pg_plan_queries(List *query
*** 55,61 ****
  				bool needSnapshot);
  
  extern bool assign_max_stack_depth(int newval, bool doit, GucSource source);
- #endif   /* BOOTSTRAP_INCLUDE */
  
  extern void die(SIGNAL_ARGS);
  extern void quickdie(SIGNAL_ARGS);
--- 53,58 ----
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at

                http://www.postgresql.org/about/donate

Reply via email to