*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 41,46 ****
--- 41,47 ----
  #include "miscadmin.h"
  #include "pgstat.h"
  #include "postmaster/bgwriter.h"
+ #include "postmaster/startup.h"
  #include "replication/walreceiver.h"
  #include "replication/walsender.h"
  #include "storage/bufmgr.h"
***************
*** 584,602 **** typedef struct xl_restore_point
  	char		rp_name[MAXFNAMELEN];
  } xl_restore_point;
  
- /*
-  * Flags set by interrupt handlers for later service in the redo loop.
-  */
- static volatile sig_atomic_t got_SIGHUP = false;
- static volatile sig_atomic_t shutdown_requested = false;
- static volatile sig_atomic_t promote_triggered = false;
- 
- /*
-  * Flag set when executing a restore command, to tell SIGTERM signal handler
-  * that it's safe to just proc_exit.
-  */
- static volatile sig_atomic_t in_restore_command = false;
- 
  
  static void XLogArchiveNotify(const char *xlog);
  static void XLogArchiveNotifySeg(uint32 log, uint32 seg);
--- 585,590 ----
***************
*** 3068,3088 **** RestoreArchivedFile(char *path, const char *xlogfname,
  							 xlogRestoreCmd)));
  
  	/*
! 	 * Set in_restore_command to tell the signal handler that we should exit
! 	 * right away on SIGTERM. We know that we're at a safe point to do that.
! 	 * Check if we had already received the signal, so that we don't miss a
! 	 * shutdown request received just before this.
  	 */
! 	in_restore_command = true;
! 	if (shutdown_requested)
! 		proc_exit(1);
  
  	/*
  	 * Copy xlog from archival storage to XLOGDIR
  	 */
  	rc = system(xlogRestoreCmd);
  
! 	in_restore_command = false;
  
  	if (rc == 0)
  	{
--- 3056,3071 ----
  							 xlogRestoreCmd)));
  
  	/*
! 	 * Check signals before restore command and reset afterwards.
  	 */
! 	PreRestoreCommand();
  
  	/*
  	 * Copy xlog from archival storage to XLOGDIR
  	 */
  	rc = system(xlogRestoreCmd);
  
! 	PostRestoreCommand();
  
  	if (rc == 0)
  	{
***************
*** 9931,10107 **** CancelBackup(void)
  	}
  }
  
- /* ------------------------------------------------------
-  *	Startup Process main entry point and signal handlers
-  * ------------------------------------------------------
-  */
- 
- /*
-  * startupproc_quickdie() occurs when signalled SIGQUIT by the postmaster.
-  *
-  * Some backend has bought the farm,
-  * so we need to stop what we're doing and exit.
-  */
- static void
- startupproc_quickdie(SIGNAL_ARGS)
- {
- 	PG_SETMASK(&BlockSig);
- 
- 	/*
- 	 * We DO NOT want to run proc_exit() callbacks -- we're here because
- 	 * shared memory may be corrupted, so we don't want to try to clean up our
- 	 * transaction.  Just nail the windows shut and get out of town.  Now that
- 	 * there's an atexit callback to prevent third-party code from breaking
- 	 * things by calling exit() directly, we have to reset the callbacks
- 	 * explicitly to make this work as intended.
- 	 */
- 	on_exit_reset();
- 
- 	/*
- 	 * Note we do exit(2) not exit(0).	This is to force the postmaster into a
- 	 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
- 	 * backend.  This is necessary precisely because we don't clean up our
- 	 * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
- 	 * should ensure the postmaster sees this as a crash, too, but no harm in
- 	 * being doubly sure.)
- 	 */
- 	exit(2);
- }
- 
- 
- /* SIGUSR1: let latch facility handle the signal */
- static void
- StartupProcSigUsr1Handler(SIGNAL_ARGS)
- {
- 	int			save_errno = errno;
- 
- 	latch_sigusr1_handler();
- 
- 	errno = save_errno;
- }
- 
- /* SIGUSR2: set flag to finish recovery */
- static void
- StartupProcTriggerHandler(SIGNAL_ARGS)
- {
- 	int			save_errno = errno;
- 
- 	promote_triggered = true;
- 	WakeupRecovery();
- 
- 	errno = save_errno;
- }
- 
- /* SIGHUP: set flag to re-read config file at next convenient time */
- static void
- StartupProcSigHupHandler(SIGNAL_ARGS)
- {
- 	int			save_errno = errno;
- 
- 	got_SIGHUP = true;
- 	WakeupRecovery();
- 
- 	errno = save_errno;
- }
- 
- /* SIGTERM: set flag to abort redo and exit */
- static void
- StartupProcShutdownHandler(SIGNAL_ARGS)
- {
- 	int			save_errno = errno;
- 
- 	if (in_restore_command)
- 		proc_exit(1);
- 	else
- 		shutdown_requested = true;
- 	WakeupRecovery();
- 
- 	errno = save_errno;
- }
- 
- /* Handle SIGHUP and SIGTERM signals of startup process */
- void
- HandleStartupProcInterrupts(void)
- {
- 	/*
- 	 * Check if we were requested to re-read config file.
- 	 */
- 	if (got_SIGHUP)
- 	{
- 		got_SIGHUP = false;
- 		ProcessConfigFile(PGC_SIGHUP);
- 	}
- 
- 	/*
- 	 * Check if we were requested to exit without finishing recovery.
- 	 */
- 	if (shutdown_requested)
- 		proc_exit(1);
- 
- 	/*
- 	 * Emergency bailout if postmaster has died.  This is to avoid the
- 	 * necessity for manual cleanup of all postmaster children.
- 	 */
- 	if (IsUnderPostmaster && !PostmasterIsAlive())
- 		exit(1);
- }
- 
- /* Main entry point for startup process */
- void
- StartupProcessMain(void)
- {
- 	/*
- 	 * If possible, make this process a group leader, so that the postmaster
- 	 * can signal any child processes too.
- 	 */
- #ifdef HAVE_SETSID
- 	if (setsid() < 0)
- 		elog(FATAL, "setsid() failed: %m");
- #endif
- 
- 	/*
- 	 * Properly accept or ignore signals the postmaster might send us.
- 	 *
- 	 * Note: ideally we'd not enable handle_standby_sig_alarm unless actually
- 	 * doing hot standby, but we don't know that yet.  Rely on it to not do
- 	 * anything if it shouldn't.
- 	 */
- 	pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
- 	pqsignal(SIGINT, SIG_IGN);	/* ignore query cancel */
- 	pqsignal(SIGTERM, StartupProcShutdownHandler);		/* request shutdown */
- 	pqsignal(SIGQUIT, startupproc_quickdie);	/* hard crash time */
- 	if (EnableHotStandby)
- 		pqsignal(SIGALRM, handle_standby_sig_alarm);	/* ignored unless
- 														 * InHotStandby */
- 	else
- 		pqsignal(SIGALRM, SIG_IGN);
- 	pqsignal(SIGPIPE, SIG_IGN);
- 	pqsignal(SIGUSR1, StartupProcSigUsr1Handler);
- 	pqsignal(SIGUSR2, StartupProcTriggerHandler);
- 
- 	/*
- 	 * Reset some signals that are accepted by postmaster but not here
- 	 */
- 	pqsignal(SIGCHLD, SIG_DFL);
- 	pqsignal(SIGTTIN, SIG_DFL);
- 	pqsignal(SIGTTOU, SIG_DFL);
- 	pqsignal(SIGCONT, SIG_DFL);
- 	pqsignal(SIGWINCH, SIG_DFL);
- 
- 	/*
- 	 * Unblock signals (they were blocked when the postmaster forked us)
- 	 */
- 	PG_SETMASK(&UnBlockSig);
- 
- 	StartupXLOG();
- 
- 	/*
- 	 * Exit normally. Exit code 0 tells postmaster that we completed recovery
- 	 * successfully.
- 	 */
- 	proc_exit(0);
- }
- 
  /*
   * Read the XLOG page containing RecPtr into readBuf (if not read already).
   * Returns true if the page is read successfully.
--- 9914,9919 ----
***************
*** 10549,10560 **** CheckForStandbyTrigger(void)
  	if (triggered)
  		return true;
  
! 	if (promote_triggered)
  	{
  		ereport(LOG,
  				(errmsg("received promote request")));
  		ShutdownWalRcv();
! 		promote_triggered = false;
  		triggered = true;
  		return true;
  	}
--- 10361,10372 ----
  	if (triggered)
  		return true;
  
! 	if (IsPromoteTriggered())
  	{
  		ereport(LOG,
  				(errmsg("received promote request")));
  		ShutdownWalRcv();
! 		ResetPromoteTriggered();
  		triggered = true;
  		return true;
  	}
*** a/src/backend/bootstrap/bootstrap.c
--- b/src/backend/bootstrap/bootstrap.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
  #include "postmaster/bgwriter.h"
+ #include "postmaster/startup.h"
  #include "postmaster/walwriter.h"
  #include "replication/walreceiver.h"
  #include "storage/bufmgr.h"
*** a/src/backend/postmaster/Makefile
--- b/src/backend/postmaster/Makefile
***************
*** 13,18 **** top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
  OBJS = autovacuum.o bgwriter.o fork_process.o pgarch.o pgstat.o postmaster.o \
! 	syslogger.o walwriter.o checkpointer.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 13,18 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = autovacuum.o bgwriter.o fork_process.o pgarch.o pgstat.o postmaster.o \
! 	startup.o syslogger.o walwriter.o checkpointer.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/postmaster/startup.c
***************
*** 0 ****
--- 1,261 ----
+ /*-------------------------------------------------------------------------
+  *
+  * startup.c
+  *
+  * The Startup process initialises the server and performs any recovery
+  * actions that have been specified. Notice that there is no "main loop"
+  * since the Startup process ends as soon as initialisation is complete.
+  *
+  *
+  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+  *
+  *
+  * IDENTIFICATION
+  *	  src/backend/postmaster/startup.c
+  *
+  *-------------------------------------------------------------------------
+  */
+ #include "postgres.h"
+ 
+ #include <signal.h>
+ #include <unistd.h>
+ 
+ #include "libpq/pqsignal.h"
+ #include "miscadmin.h"
+ #include "postmaster/startup.h"
+ #include "storage/ipc.h"
+ #include "storage/latch.h"
+ #include "storage/pmsignal.h"
+ #include "storage/proc.h"
+ #include "utils/guc.h"
+ 
+ 
+ /*
+  * Flags set by interrupt handlers for later service in the redo loop.
+  */
+ static volatile sig_atomic_t got_SIGHUP = false;
+ static volatile sig_atomic_t shutdown_requested = false;
+ static volatile sig_atomic_t promote_triggered = false;
+ 
+ /*
+  * Flag set when executing a restore command, to tell SIGTERM signal handler
+  * that it's safe to just proc_exit.
+  */
+ static volatile sig_atomic_t in_restore_command = false;
+ 
+ /* Signal handlers */
+ static void startupproc_quickdie(SIGNAL_ARGS);
+ static void StartupProcSigUsr1Handler(SIGNAL_ARGS);
+ static void StartupProcTriggerHandler(SIGNAL_ARGS);
+ static void StartupProcSigHupHandler(SIGNAL_ARGS);
+ 
+ 
+ /* --------------------------------
+  *		signal handler routines
+  * --------------------------------
+  */
+ 
+ /*
+  * startupproc_quickdie() occurs when signalled SIGQUIT by the postmaster.
+  *
+  * Some backend has bought the farm,
+  * so we need to stop what we're doing and exit.
+  */
+ static void
+ startupproc_quickdie(SIGNAL_ARGS)
+ {
+ 	PG_SETMASK(&BlockSig);
+ 
+ 	/*
+ 	 * We DO NOT want to run proc_exit() callbacks -- we're here because
+ 	 * shared memory may be corrupted, so we don't want to try to clean up our
+ 	 * transaction.  Just nail the windows shut and get out of town.  Now that
+ 	 * there's an atexit callback to prevent third-party code from breaking
+ 	 * things by calling exit() directly, we have to reset the callbacks
+ 	 * explicitly to make this work as intended.
+ 	 */
+ 	on_exit_reset();
+ 
+ 	/*
+ 	 * Note we do exit(2) not exit(0).	This is to force the postmaster into a
+ 	 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
+ 	 * backend.  This is necessary precisely because we don't clean up our
+ 	 * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
+ 	 * should ensure the postmaster sees this as a crash, too, but no harm in
+ 	 * being doubly sure.)
+ 	 */
+ 	exit(2);
+ }
+ 
+ 
+ /* SIGUSR1: let latch facility handle the signal */
+ static void
+ StartupProcSigUsr1Handler(SIGNAL_ARGS)
+ {
+ 	int			save_errno = errno;
+ 
+ 	latch_sigusr1_handler();
+ 
+ 	errno = save_errno;
+ }
+ 
+ /* SIGUSR2: set flag to finish recovery */
+ static void
+ StartupProcTriggerHandler(SIGNAL_ARGS)
+ {
+ 	int			save_errno = errno;
+ 
+ 	promote_triggered = true;
+ 	WakeupRecovery();
+ 
+ 	errno = save_errno;
+ }
+ 
+ /* SIGHUP: set flag to re-read config file at next convenient time */
+ static void
+ StartupProcSigHupHandler(SIGNAL_ARGS)
+ {
+ 	int			save_errno = errno;
+ 
+ 	got_SIGHUP = true;
+ 	WakeupRecovery();
+ 
+ 	errno = save_errno;
+ }
+ 
+ /* SIGTERM: set flag to abort redo and exit */
+ static void
+ StartupProcShutdownHandler(SIGNAL_ARGS)
+ {
+ 	int			save_errno = errno;
+ 
+ 	if (in_restore_command)
+ 		proc_exit(1);
+ 	else
+ 		shutdown_requested = true;
+ 	WakeupRecovery();
+ 
+ 	errno = save_errno;
+ }
+ 
+ /* Handle SIGHUP and SIGTERM signals of startup process */
+ void
+ HandleStartupProcInterrupts(void)
+ {
+ 	/*
+ 	 * Check if we were requested to re-read config file.
+ 	 */
+ 	if (got_SIGHUP)
+ 	{
+ 		got_SIGHUP = false;
+ 		ProcessConfigFile(PGC_SIGHUP);
+ 	}
+ 
+ 	/*
+ 	 * Check if we were requested to exit without finishing recovery.
+ 	 */
+ 	if (shutdown_requested)
+ 		proc_exit(1);
+ 
+ 	/*
+ 	 * Emergency bailout if postmaster has died.  This is to avoid the
+ 	 * necessity for manual cleanup of all postmaster children.
+ 	 */
+ 	if (IsUnderPostmaster && !PostmasterIsAlive())
+ 		exit(1);
+ }
+ 
+ 
+ /* ----------------------------------
+  *	Startup Process main entry point
+  * ----------------------------------
+  */
+ void
+ StartupProcessMain(void)
+ {
+ 	/*
+ 	 * If possible, make this process a group leader, so that the postmaster
+ 	 * can signal any child processes too.
+ 	 */
+ #ifdef HAVE_SETSID
+ 	if (setsid() < 0)
+ 		elog(FATAL, "setsid() failed: %m");
+ #endif
+ 
+ 	/*
+ 	 * Properly accept or ignore signals the postmaster might send us.
+ 	 *
+ 	 * Note: ideally we'd not enable handle_standby_sig_alarm unless actually
+ 	 * doing hot standby, but we don't know that yet.  Rely on it to not do
+ 	 * anything if it shouldn't.
+ 	 */
+ 	pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
+ 	pqsignal(SIGINT, SIG_IGN);	/* ignore query cancel */
+ 	pqsignal(SIGTERM, StartupProcShutdownHandler);		/* request shutdown */
+ 	pqsignal(SIGQUIT, startupproc_quickdie);	/* hard crash time */
+ 	if (EnableHotStandby)
+ 		pqsignal(SIGALRM, handle_standby_sig_alarm);	/* ignored unless
+ 														 * InHotStandby */
+ 	else
+ 		pqsignal(SIGALRM, SIG_IGN);
+ 	pqsignal(SIGPIPE, SIG_IGN);
+ 	pqsignal(SIGUSR1, StartupProcSigUsr1Handler);
+ 	pqsignal(SIGUSR2, StartupProcTriggerHandler);
+ 
+ 	/*
+ 	 * Reset some signals that are accepted by postmaster but not here
+ 	 */
+ 	pqsignal(SIGCHLD, SIG_DFL);
+ 	pqsignal(SIGTTIN, SIG_DFL);
+ 	pqsignal(SIGTTOU, SIG_DFL);
+ 	pqsignal(SIGCONT, SIG_DFL);
+ 	pqsignal(SIGWINCH, SIG_DFL);
+ 
+ 	/*
+ 	 * Unblock signals (they were blocked when the postmaster forked us)
+ 	 */
+ 	PG_SETMASK(&UnBlockSig);
+ 
+ 	StartupXLOG();
+ 
+ 	/*
+ 	 * Exit normally. Exit code 0 tells postmaster that we completed recovery
+ 	 * successfully.
+ 	 */
+ 	proc_exit(0);
+ }
+ 
+ void
+ PreRestoreCommand(void)
+ {
+ 	/*
+ 	 * Set in_restore_command to tell the signal handler that we should exit
+ 	 * right away on SIGTERM. We know that we're at a safe point to do that.
+ 	 * Check if we had already received the signal, so that we don't miss a
+ 	 * shutdown request received just before this.
+ 	 */
+ 	in_restore_command = true;
+ 	if (shutdown_requested)
+ 		proc_exit(1);
+ }
+ 
+ void
+ PostRestoreCommand(void)
+ {
+ 	in_restore_command = false;
+ }
+ 
+ bool
+ IsPromoteTriggered(void)
+ {
+ 	if (promote_triggered)
+ 		return true;
+ 	else
+ 		return false;
+ }
+ 
+ void
+ ResetPromoteTriggered(void)
+ {
+ 	promote_triggered = false;
+ }
*** a/src/backend/replication/walreceiverfuncs.c
--- b/src/backend/replication/walreceiverfuncs.c
***************
*** 24,29 ****
--- 24,30 ----
  #include <signal.h>
  
  #include "access/xlog_internal.h"
+ #include "postmaster/startup.h"
  #include "replication/walreceiver.h"
  #include "storage/pmsignal.h"
  #include "storage/shmem.h"
***************
*** 110,115 **** WalRcvInProgress(void)
--- 111,117 ----
  
  /*
   * Stop walreceiver (if running) and wait for it to die.
+  * Executed by the Startup process.
   */
  void
  ShutdownWalRcv(void)
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
***************
*** 312,319 **** extern XLogRecPtr GetFlushRecPtr(void);
  extern void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch);
  extern TimeLineID GetRecoveryTargetTLI(void);
  
- extern void HandleStartupProcInterrupts(void);
- extern void StartupProcessMain(void);
  extern bool CheckPromoteSignal(void);
  extern void WakeupRecovery(void);
  
--- 312,317 ----
*** /dev/null
--- b/src/include/postmaster/startup.h
***************
*** 0 ****
--- 1,26 ----
+ /*-------------------------------------------------------------------------
+  *
+  * startup.h
+  *	  Exports from postmaster/startup.c.
+  *
+  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+  *
+  * src/include/postmaster/startup.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef _STARTUP_H
+ #define _STARTUP_H
+ 
+ extern void HandleStartupProcInterrupts(void);
+ extern void StartupProcessMain(void);
+ extern void PreRestoreCommand(void);
+ extern void PostRestoreCommand(void);
+ extern bool IsPromoteTriggered(void);
+ extern void ResetPromoteTriggered(void);
+ 
+ /* in xlog.c */
+ extern void WakeupRecovery(void);
+ extern void StartupXLOG(void);
+ 
+ #endif   /* _STARTUP_H */