diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 883dbd42f7d7c44713d51bfb4325f4e4b17d75a2..98c610dcadd5a021f0f906b6b3af162198ce86f1 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.257 2006/11/21 20:59:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258 2006/11/30 18:29:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4651,8 +4651,6 @@ StartupXLOG(void)
 	uint32		freespace;
 	TransactionId oldestActiveXID;
 
-	CritSectionCount++;
-
 	/*
 	 * Read control file and check XLOG status looks valid.
 	 *
@@ -5188,7 +5186,6 @@ StartupXLOG(void)
 
 	ereport(LOG,
 			(errmsg("database system is ready")));
-	CritSectionCount--;
 
 	/* Shut down readFile facility, free space */
 	if (readFile >= 0)
@@ -5426,12 +5423,10 @@ ShutdownXLOG(int code, Datum arg)
 	ereport(LOG,
 			(errmsg("shutting down")));
 
-	CritSectionCount++;
 	CreateCheckPoint(true, true);
 	ShutdownCLOG();
 	ShutdownSUBTRANS();
 	ShutdownMultiXact();
-	CritSectionCount--;
 
 	ereport(LOG,
 			(errmsg("database system is shut down")));
@@ -5605,10 +5600,7 @@ CreateCheckPoint(bool shutdown, bool force)
 	 *
 	 * This I/O could fail for various reasons.  If so, we will fail to
 	 * complete the checkpoint, but there is no reason to force a system
-	 * panic. Accordingly, exit critical section while doing it.  (If we are
-	 * doing a shutdown checkpoint, we probably *should* panic --- but that
-	 * will happen anyway because we'll still be inside the critical section
-	 * established by ShutdownXLOG.)
+	 * panic. Accordingly, exit critical section while doing it.
 	 */
 	END_CRIT_SECTION();
 
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 5aa378ae70dea837344a023d268f901855e5cd5e..4d5c1d1cca86cfda6c5fb450263ff09195302be1 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.31 2006/11/21 20:59:52 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.32 2006/11/30 18:29:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,6 +350,12 @@ BackgroundWriterMain(void)
 		}
 		if (shutdown_requested)
 		{
+			/*
+			 * From here on, elog(ERROR) should end with exit(1), not send
+			 * control back to the sigsetjmp block above
+			 */
+			ExitOnAnyError = true;
+			/* Close down the database */
 			ShutdownXLOG(0, 0);
 			DumpFreeSpaceMap(0, 0);
 			/* Normal exit from the bgwriter is here */
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 907a08bb23e32a838993fe7cf1dc58a1b5bf776b..dbe835f3d0953d2a3d52241276926fdde8d7fa88 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.504 2006/11/28 12:54:41 petere Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.505 2006/11/30 18:29:12 tgl Exp $
  *
  * NOTES
  *
@@ -1934,8 +1934,13 @@ pmdie(SIGNAL_ARGS)
 			 * Note: if we previously got SIGTERM then we may send SIGUSR2 to
 			 * the bgwriter a second time here.  This should be harmless.
 			 */
-			if (StartupPID != 0 || FatalError)
-				break;			/* let reaper() handle this */
+			if (StartupPID != 0)
+			{
+				signal_child(StartupPID, SIGTERM);
+				break;			/* let reaper() do the rest */
+			}
+			if (FatalError)
+				break;			/* let reaper() handle this case */
 			/* Start the bgwriter if not running */
 			if (BgWriterPID == 0)
 				BgWriterPID = StartBackgroundWriter();
@@ -2108,6 +2113,21 @@ reaper(SIGNAL_ARGS)
 			 */
 			HandleChildCrash(pid, exitstatus,
 							 _("background writer process"));
+
+			/*
+			 * If the bgwriter crashed while trying to write the shutdown
+			 * checkpoint, we may as well just stop here; any recovery
+			 * required will happen on next postmaster start.
+			 */
+			if (Shutdown > NoShutdown &&
+				!DLGetHead(BackendList) && AutoVacPID == 0)
+			{
+				ereport(LOG,
+						(errmsg("abnormal database system shutdown")));
+				ExitPostmaster(1);
+			}
+
+			/* Else, proceed as in normal crash recovery */
 			continue;
 		}