diff -rcN postgresql/doc/src/sgml/backup.sgml postgresql_with_patch/doc/src/sgml/backup.sgml
*** postgresql/doc/src/sgml/backup.sgml	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/doc/src/sgml/backup.sgml	2011-09-13 15:23:49.000000000 +0900
***************
*** 724,734 ****
     <title>Making a Base Backup</title>
  
     <para>
!     The procedure for making a base backup is relatively simple:
    <orderedlist>
     <listitem>
      <para>
!      Ensure that WAL archiving is enabled and working.
      </para>
     </listitem>
     <listitem>
--- 724,736 ----
     <title>Making a Base Backup</title>
  
     <para>
!     The procedure for making a base backup is relatively simple. This can
!     also run on hot standby, the procedure is a little different:
    <orderedlist>
     <listitem>
      <para>
!      Ensure that WAL archiving is enabled and working. On hot standby then
!      this does not need to ensure since there is no WAL archiving originally.
      </para>
     </listitem>
     <listitem>
***************
*** 780,785 ****
--- 782,795 ----
     </listitem>
     <listitem>
      <para>
+      Copy <filename>pg_control</> file to the backup taken by above-procedure.
+      This needs on hot standby. This is performed to recovery with Minimum
+      recovery ending location in <filename>pg_control</> instead of backup end
+      record.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
       Again connect to the database as a superuser, and issue the command:
  <programlisting>
  SELECT pg_stop_backup();
***************
*** 788,793 ****
--- 798,805 ----
       the next WAL segment.  The reason for the switch is to arrange for
       the last WAL segment file written during the backup interval to be
       ready to archive.
+      On hot standby then this terminates the backup mode but does not perform
+      an automatic switch.
      </para>
     </listitem>
     <listitem>
***************
*** 808,813 ****
--- 820,827 ----
       If you wish to place a time limit on the execution of
       <function>pg_stop_backup</>, set an appropriate
       <varname>statement_timeout</varname> value.
+      On hot standby then this does not perform. If WAL archiving is used,
+      ensure to complete archiving as far as <function>pg_stop_backup</> result.
      </para>
     </listitem>
    </orderedlist>
***************
*** 851,856 ****
--- 865,873 ----
      effectively forced on during backup mode.)  You must ensure that these
      steps are carried out in sequence, without any possible
      overlap, or you will invalidate the backup.
+     On hot standby, full_page_writes is not effectively forced because hot
+     standby does not write WAL. you must set 'on' full_page_writes on master
+     during backup mode.
     </para>
  
     <para>
***************
*** 933,938 ****
--- 950,967 ----
      backup dump is which and how far back the associated WAL files go.
      It is generally better to follow the continuous archiving procedure above.
     </para>
+ 
+    <para>
+     <function>pg_stop_backup</> result on hot standby is may be incorrect. But
+     this value is greater than the correct value. If this value is used in
+     recovery then a phenomenon that WAL is not enough does not happen.
+    </para>
+ 
+    <para>
+     When you run in hotstandby <function>pg_start_backup</>, and, if promoted
+     to master when you run the <function>pg_stop_backup</>,
+     <function>pg_stop_backup</> will be failed. Retake the backup then.
+    </para>
    </sect2>
  
    <sect2 id="backup-pitr-recovery">
diff -rcN postgresql/src/backend/access/transam/xlog.c postgresql_with_patch/src/backend/access/transam/xlog.c
*** postgresql/src/backend/access/transam/xlog.c	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/backend/access/transam/xlog.c	2011-09-13 14:55:01.000000000 +0900
***************
*** 664,670 ****
  #endif
  static void pg_start_backup_callback(int code, Datum arg);
  static bool read_backup_label(XLogRecPtr *checkPointLoc,
! 				  bool *backupEndRequired);
  static void rm_redo_error_callback(void *arg);
  static int	get_sync_bit(int method);
  
--- 664,670 ----
  #endif
  static void pg_start_backup_callback(int code, Datum arg);
  static bool read_backup_label(XLogRecPtr *checkPointLoc,
! 				  bool *backupEndRequired, char *backupfromstr);
  static void rm_redo_error_callback(void *arg);
  static int	get_sync_bit(int method);
  
***************
*** 6023,6028 ****
--- 6023,6029 ----
  	uint32		freespace;
  	TransactionId oldestActiveXID;
  	bool		backupEndRequired = false;
+ 	char		backupfromstr[10];
  
  	/*
  	 * Read control file and check XLOG status looks valid.
***************
*** 6061,6067 ****
  				(errmsg("database system was interrupted while in recovery at log time %s",
  						str_time(ControlFile->checkPointCopy.time)),
  				 errhint("If this has occurred more than once some data might be corrupted"
! 			  " and you might need to choose an earlier recovery target.")));
  	else if (ControlFile->state == DB_IN_PRODUCTION)
  		ereport(LOG,
  			  (errmsg("database system was interrupted; last known up at %s",
--- 6062,6069 ----
  				(errmsg("database system was interrupted while in recovery at log time %s",
  						str_time(ControlFile->checkPointCopy.time)),
  				 errhint("If this has occurred more than once some data might be corrupted"
! 			  " and does not take online backup from hot standby"
! 			  " then you might need to choose an earlier recovery target.")));
  	else if (ControlFile->state == DB_IN_PRODUCTION)
  		ereport(LOG,
  			  (errmsg("database system was interrupted; last known up at %s",
***************
*** 6156,6162 ****
  	if (StandbyMode)
  		OwnLatch(&XLogCtl->recoveryWakeupLatch);
  
! 	if (read_backup_label(&checkPointLoc, &backupEndRequired))
  	{
  		/*
  		 * When a backup_label file is present, we want to roll forward from
--- 6158,6164 ----
  	if (StandbyMode)
  		OwnLatch(&XLogCtl->recoveryWakeupLatch);
  
! 	if (read_backup_label(&checkPointLoc, &backupEndRequired, backupfromstr))
  	{
  		/*
  		 * When a backup_label file is present, we want to roll forward from
***************
*** 6307,6312 ****
--- 6309,6328 ----
  		volatile XLogCtlData *xlogctl = XLogCtl;
  
  		/*
+ 		 * set backupEndPoint at the start if we take online backup from
+ 		 * hot standby. backupEndPoint is used to distinguish whether the
+ 		 * backup is taken from master or hot stanby. If backupStartPoint
+ 		 * and backupEndPoint is invalid then this is meaning the first
+ 		 * recovery.
+ 		 */
+ 		if (XLogRecPtrIsInvalid(ControlFile->backupStartPoint) &&
+ 		    XLogRecPtrIsInvalid(ControlFile->backupEndPoint))
+ 		{
+ 			if (!XLogRecPtrIsInvalid(ControlFile->minRecoveryPoint))
+ 				ControlFile->backupEndPoint = ControlFile->minRecoveryPoint;
+ 		}
+ 
+ 		/*
  		 * Update pg_control to show that we are recovering and to show the
  		 * selected checkpoint as the place we are starting from. We also mark
  		 * pg_control with any minimum recovery stop point obtained from a
***************
*** 6618,6623 ****
--- 6634,6660 ----
  				error_context_stack = errcontext.previous;
  
  				/*
+ 				 * Check whether redo reaches minRecoveryPoint if we take online
+ 				 * backup from hot standby. Because we can not write backup end
+ 				 * record when we execute pg_stop_backup under the situation.
+ 				 */
+ 				if (!XLogRecPtrIsInvalid(ControlFile->backupEndPoint))
+ 				{
+ 					if (XLByteLE(ControlFile->backupEndPoint, EndRecPtr))
+ 					{
+ 						elog(DEBUG1, "end of backup reached in the control file");
+ 
+ 						LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ 
+ 						MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
+ 						MemSet(&ControlFile->backupEndPoint, 0, sizeof(XLogRecPtr));
+ 						UpdateControlFile();
+ 
+ 						LWLockRelease(ControlFileLock);
+ 					}
+ 				}
+ 
+ 				/*
  				 * Update shared recoveryLastRecPtr after this record has been
  				 * replayed.
  				 */
***************
*** 8414,8423 ****
  		/*
  		 * If we see a shutdown checkpoint while waiting for an end-of-backup
  		 * record, the backup was canceled and the end-of-backup record will
! 		 * never arrive.
  		 */
  		if (InArchiveRecovery &&
! 			!XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
  			ereport(ERROR,
  					(errmsg("online backup was canceled, recovery cannot continue")));
  
--- 8451,8463 ----
  		/*
  		 * If we see a shutdown checkpoint while waiting for an end-of-backup
  		 * record, the backup was canceled and the end-of-backup record will
! 		 * never arrive. If the backup is taken from hot standby then this
! 		 * error is not output because there is a case of shutdown on master
! 		 * during taking online backup from hot standby.
  		 */
  		if (InArchiveRecovery &&
! 			!XLogRecPtrIsInvalid(ControlFile->backupStartPoint) &&
! 			XLogRecPtrIsInvalid(ControlFile->backupEndPoint))
  			ereport(ERROR,
  					(errmsg("online backup was canceled, recovery cannot continue")));
  
***************
*** 8880,8885 ****
--- 8920,8926 ----
  do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile)
  {
  	bool		exclusive = (labelfile == NULL);
+ 	bool		duringrecovery = false;
  	XLogRecPtr	checkpointloc;
  	XLogRecPtr	startpoint;
  	pg_time_t	stamp_time;
***************
*** 8890,8908 ****
  	struct stat stat_buf;
  	FILE	   *fp;
  	StringInfoData labelfbuf;
  
  	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  		   errmsg("must be superuser or replication role to run a backup")));
  
  	if (RecoveryInProgress())
! 		ereport(ERROR,
! 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 				 errmsg("recovery is in progress"),
! 				 errhint("WAL control functions cannot be executed during recovery.")));
  
! 	if (!XLogIsNeeded())
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  			  errmsg("WAL level not sufficient for making an online backup"),
--- 8931,8956 ----
  	struct stat stat_buf;
  	FILE	   *fp;
  	StringInfoData labelfbuf;
+ 	char	   *backupfromstr = BACKUP_FROM_MASTER;
  
  	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  		   errmsg("must be superuser or replication role to run a backup")));
  
+ 	/*
+ 	 * check whether during recovery, and determine a string on backup_label.
+ 	 * If duringrecovery is true here then the subsequent process on WAL (check
+ 	 * wal_level, RequestXLogSwitch, forcePageWrites and gotUniqueStartpoint
+ 	 * by RequestCheckpoint) is skipped because hot standby can not write a wal.
+ 	 */
  	if (RecoveryInProgress())
! 	{
! 		duringrecovery = true;
! 		backupfromstr = BACKUP_FROM_SLAVE;
! 	}
  
! 	if (!XLogIsNeeded() && !duringrecovery)
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  			  errmsg("WAL level not sufficient for making an online backup"),
***************
*** 8925,8931 ****
  	 * directory was not included in the base backup and the WAL archive was
  	 * cleared too before starting the backup.
  	 */
! 	RequestXLogSwitch();
  
  	/*
  	 * Mark backup active in shared memory.  We must do full-page WAL writes
--- 8973,8980 ----
  	 * directory was not included in the base backup and the WAL archive was
  	 * cleared too before starting the backup.
  	 */
! 	if (!duringrecovery)
! 		RequestXLogSwitch();
  
  	/*
  	 * Mark backup active in shared memory.  We must do full-page WAL writes
***************
*** 8959,8965 ****
  	}
  	else
  		XLogCtl->Insert.nonExclusiveBackups++;
! 	XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
  	/* Ensure we release forcePageWrites if fail below */
--- 9008,9015 ----
  	}
  	else
  		XLogCtl->Insert.nonExclusiveBackups++;
! 	if (!duringrecovery)
! 		XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
  	/* Ensure we release forcePageWrites if fail below */
***************
*** 9010,9016 ****
  				gotUniqueStartpoint = true;
  			}
  			LWLockRelease(WALInsertLock);
! 		} while (!gotUniqueStartpoint);
  
  		XLByteToSeg(startpoint, _logId, _logSeg);
  		XLogFileName(xlogfilename, ThisTimeLineID, _logId, _logSeg);
--- 9060,9066 ----
  				gotUniqueStartpoint = true;
  			}
  			LWLockRelease(WALInsertLock);
! 		} while (!gotUniqueStartpoint && !duringrecovery);
  
  		XLByteToSeg(startpoint, _logId, _logSeg);
  		XLogFileName(xlogfilename, ThisTimeLineID, _logId, _logSeg);
***************
*** 9033,9038 ****
--- 9083,9089 ----
  						 exclusive ? "pg_start_backup" : "streamed");
  		appendStringInfo(&labelfbuf, "START TIME: %s\n", strfbuf);
  		appendStringInfo(&labelfbuf, "LABEL: %s\n", backupidstr);
+ 		appendStringInfo(&labelfbuf, "FROM: %s\n", backupfromstr);
  
  		/*
  		 * Okay, write the file, or return its contents to caller.
***************
*** 9105,9111 ****
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
--- 9156,9163 ----
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0 &&
! 		!RecoveryInProgress())
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
***************
*** 9149,9154 ****
--- 9201,9207 ----
  do_pg_stop_backup(char *labelfile, bool waitforarchive)
  {
  	bool		exclusive = (labelfile == NULL);
+ 	bool		duringrecovery = false;
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
  	XLogRecData rdata;
***************
*** 9168,9192 ****
  	int			waits = 0;
  	bool		reported_waiting = false;
  	char	   *remaining;
  
  	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  		 (errmsg("must be superuser or replication role to run a backup"))));
  
  	if (RecoveryInProgress())
! 		ereport(ERROR,
! 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 				 errmsg("recovery is in progress"),
! 				 errhint("WAL control functions cannot be executed during recovery.")));
  
! 	if (!XLogIsNeeded())
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  			  errmsg("WAL level not sufficient for making an online backup"),
  				 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
  
  	/*
  	 * OK to update backup counters and forcePageWrites
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
--- 9221,9277 ----
  	int			waits = 0;
  	bool		reported_waiting = false;
  	char	   *remaining;
+ 	XLogRecPtr	checkPointLoc;
+ 	bool		backupEndRequired = false;
+ 	char		backupfromstr[10];
  
  	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  		 (errmsg("must be superuser or replication role to run a backup"))));
  
+ 	/*
+ 	 * check whether during recovery. If duringrecovery is true here then the
+ 	 * subsequent process on WAL (check wal_level, forcePageWrites, XLogInsert,
+ 	 * RequestXLogSwitch, write the backup history file and XLogArchivingActive)
+ 	 * is skipped because hot standby can not write a wal.
+ 	 */
  	if (RecoveryInProgress())
! 		duringrecovery = true;
  
! 	if (!XLogIsNeeded() && !duringrecovery)
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  			  errmsg("WAL level not sufficient for making an online backup"),
  				 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
  
  	/*
+ 	 * backupfromstr is taken from backup_label, which is where we
+ 	 * execute pg_start_backup on. check whether this state is equals it.
+ 	 * If read_backup_label function returns error, this function is
+ 	 * failed by error handling after this.
+ 	 */
+ 	if (read_backup_label(&checkPointLoc, &backupEndRequired, backupfromstr))
+ 	{
+ 		if (duringrecovery == false)
+ 		{
+ 			if (strcmp(backupfromstr, BACKUP_FROM_MASTER) != 0 ||
+ 				ControlFile->state != DB_IN_PRODUCTION)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ 						 errmsg("different state than when pg_start_backup is executed")));
+ 		}
+ 		else
+ 		{
+ 			if (strcmp(backupfromstr, BACKUP_FROM_SLAVE) != 0 ||
+ 				ControlFile->state != DB_IN_ARCHIVE_RECOVERY)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ 						 errmsg("different state than when pg_start_backup is executed")));
+ 		}
+ 	}
+ 
+ 	/*
  	 * OK to update backup counters and forcePageWrites
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
***************
*** 9205,9211 ****
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
--- 9290,9297 ----
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0 &&
! 	    !duringrecovery)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
***************
*** 9259,9264 ****
--- 9345,9357 ----
  	}
  
  	/*
+ 	 * When pg_stop_backup is excuted on hot standby server, the result
+ 	 * is minRecoveryPoint in the control file.
+ 	 */
+ 	if (duringrecovery)
+ 		return ControlFile->minRecoveryPoint;
+ 
+ 	/*
  	 * Read and parse the START WAL LOCATION line (this code is pretty crude,
  	 * but we are not expecting any variability in the file format).
  	 */
***************
*** 9416,9422 ****
  	XLogCtl->Insert.nonExclusiveBackups--;
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
--- 9509,9516 ----
  	XLogCtl->Insert.nonExclusiveBackups--;
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0 &&
! 		!RecoveryInProgress())
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
***************
*** 9790,9802 ****
   * streamed backup, *backupEndRequired is set to TRUE.
   */
  static bool
! read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired)
  {
  	char		startxlogfilename[MAXFNAMELEN];
  	TimeLineID	tli;
  	FILE	   *lfp;
  	char		ch;
  	char		backuptype[20];
  
  	*backupEndRequired = false;
  
--- 9884,9897 ----
   * streamed backup, *backupEndRequired is set to TRUE.
   */
  static bool
! read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, char *backupfromstr)
  {
  	char		startxlogfilename[MAXFNAMELEN];
  	TimeLineID	tli;
  	FILE	   *lfp;
  	char		ch;
  	char		backuptype[20];
+ 	char		strbuff[256];
  
  	*backupEndRequired = false;
  
***************
*** 9842,9847 ****
--- 9937,9957 ----
  			*backupEndRequired = true;
  	}
  
+ 	fgets(strbuff, sizeof(strbuff), lfp);  /* skip one line */
+ 	fgets(strbuff, sizeof(strbuff), lfp);  /* skip one line */
+ 	fgets(strbuff, sizeof(strbuff), lfp);  /* skip one line */
+ 
+ 	/*
+ 	 * Read and parse the FROM line. If not read then output WARNING message
+ 	 * and set BACKUP_FROM_MASTER.
+ 	 *
+ 	 */
+ 	strcpy(backupfromstr, BACKUP_FROM_MASTER);
+ 	if (fscanf(lfp, "FROM: %s%c", backupfromstr, &ch) != 2 || ch != '\n')
+ 		ereport(WARNING,
+ 				(errmsg("loaded old file \"%s\", set backup from \"%s\"",
+ 						BACKUP_LABEL_FILE, BACKUP_FROM_MASTER)));
+ 
  	if (ferror(lfp) || FreeFile(lfp))
  		ereport(FATAL,
  				(errcode_for_file_access(),
diff -rcN postgresql/src/backend/postmaster/postmaster.c postgresql_with_patch/src/backend/postmaster/postmaster.c
*** postgresql/src/backend/postmaster/postmaster.c	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/backend/postmaster/postmaster.c	2011-09-12 05:24:42.000000000 +0900
***************
*** 287,292 ****
--- 287,295 ----
  static PMState pmState = PM_INIT;
  
  static bool ReachedNormalRunning = false;		/* T if we've reached PM_RUN */
+ static bool ReachedHotStandbyRunning = false;	/* T if we've reached PM_HOT_STANDBY */
+ static bool WaitBackupForHotStandby = false;	/* T if we've moved from PM_WAIT_READONLY
+ 												 * to PM_WAIT_BACKUP */
  
  bool		ClientAuthInProgress = false;		/* T during new-client
  												 * authentication */
***************
*** 2825,2831 ****
  		 * PM_WAIT_BACKUP state ends when online backup mode is not active.
  		 */
  		if (!BackupInProgress())
! 			pmState = PM_WAIT_BACKENDS;
  	}
  
  	if (pmState == PM_WAIT_READONLY)
--- 2828,2845 ----
  		 * PM_WAIT_BACKUP state ends when online backup mode is not active.
  		 */
  		if (!BackupInProgress())
! 		{
! 			/*
! 			 * WaitBackupForHotStandby, this flag is if we execute
! 			 * smart shutdown during takeing online backup from hot standby.
! 			 * If the flag is true then we need to change PM_WAIT_BACKENDS
! 			 * at the root of PM_WAIT_READONLY.
! 			 */
! 			if (!WaitBackupForHotStandby)
! 				pmState = PM_WAIT_BACKENDS;
! 			else
! 				pmState = PM_WAIT_READONLY;
! 		}
  	}
  
  	if (pmState == PM_WAIT_READONLY)
***************
*** 2840,2850 ****
  		 */
  		if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
  		{
! 			if (StartupPID != 0)
! 				signal_child(StartupPID, SIGTERM);
! 			if (WalReceiverPID != 0)
! 				signal_child(WalReceiverPID, SIGTERM);
! 			pmState = PM_WAIT_BACKENDS;
  		}
  	}
  
--- 2854,2878 ----
  		 */
  		if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
  		{
! 			if (!BackupInProgress())
! 			{
! 				if (StartupPID != 0)
! 					signal_child(StartupPID, SIGTERM);
! 				if (WalReceiverPID != 0)
! 					signal_child(WalReceiverPID, SIGTERM);
! 				pmState = PM_WAIT_BACKENDS;
! 			}
! 			else
! 			{
! 				/*
! 				 * This is meaning that we execute smart shutdown during
! 				 * online backup from hot standby. we need to allow the
! 				 * connection to the backend by changing PM_WAIT_BACKUP
! 				 * to execute pg_stop_backup.
! 				 */
! 				WaitBackupForHotStandby = true;
! 				pmState = PM_WAIT_BACKUP;
! 			}
  		}
  	}
  
***************
*** 2993,3006 ****
  		{
  			/*
  			 * Terminate backup mode to avoid recovery after a clean fast
! 			 * shutdown.  Since a backup can only be taken during normal
! 			 * running (and not, for example, while running under Hot Standby)
! 			 * it only makes sense to do this if we reached normal running. If
! 			 * we're still in recovery, the backup file is one we're
! 			 * recovering *from*, and we must keep it around so that recovery
! 			 * restarts from the right place.
  			 */
! 			if (ReachedNormalRunning)
  				CancelBackup();
  
  			/* Normal exit from the postmaster is here */
--- 3021,3029 ----
  		{
  			/*
  			 * Terminate backup mode to avoid recovery after a clean fast
! 			 * shutdown if we reached normal running or hot standby.
  			 */
! 			if (ReachedNormalRunning || ReachedHotStandbyRunning)
  				CancelBackup();
  
  			/* Normal exit from the postmaster is here */
***************
*** 4157,4162 ****
--- 4180,4186 ----
  		ereport(LOG,
  		(errmsg("database system is ready to accept read only connections")));
  
+ 		ReachedHotStandbyRunning = true;
  		pmState = PM_HOT_STANDBY;
  	}
  
diff -rcN postgresql/src/bin/pg_controldata/pg_controldata.c postgresql_with_patch/src/bin/pg_controldata/pg_controldata.c
*** postgresql/src/bin/pg_controldata/pg_controldata.c	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/bin/pg_controldata/pg_controldata.c	2011-09-12 05:24:42.000000000 +0900
***************
*** 234,239 ****
--- 234,242 ----
  		   ControlFile.backupStartPoint.xrecoff);
  	printf(_("End-of-backup record required:        %s\n"),
  		   ControlFile.backupEndRequired ? _("yes") : _("no"));
+ 	printf(_("Backup end location:                  %X/%X\n"),
+ 		   ControlFile.backupEndPoint.xlogid,
+ 		   ControlFile.backupEndPoint.xrecoff);
  	printf(_("Current wal_level setting:            %s\n"),
  		   wal_level_str(ControlFile.wal_level));
  	printf(_("Current max_connections setting:      %d\n"),
diff -rcN postgresql/src/bin/pg_ctl/pg_ctl.c postgresql_with_patch/src/bin/pg_ctl/pg_ctl.c
*** postgresql/src/bin/pg_ctl/pg_ctl.c	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/bin/pg_ctl/pg_ctl.c	2011-09-12 05:24:42.000000000 +0900
***************
*** 882,894 ****
  	{
  		/*
  		 * If backup_label exists, an online backup is running. Warn the user
! 		 * that smart shutdown will wait for it to finish. However, if
! 		 * recovery.conf is also present, we're recovering from an online
! 		 * backup instead of performing one.
  		 */
  		if (shutdown_mode == SMART_MODE &&
! 			stat(backup_file, &statbuf) == 0 &&
! 			stat(recovery_file, &statbuf) != 0)
  		{
  			print_msg(_("WARNING: online backup mode is active\n"
  						"Shutdown will not complete until pg_stop_backup() is called.\n\n"));
--- 882,891 ----
  	{
  		/*
  		 * If backup_label exists, an online backup is running. Warn the user
! 		 * that smart shutdown will wait for it to finish.
  		 */
  		if (shutdown_mode == SMART_MODE &&
! 			stat(backup_file, &statbuf) == 0)
  		{
  			print_msg(_("WARNING: online backup mode is active\n"
  						"Shutdown will not complete until pg_stop_backup() is called.\n\n"));
diff -rcN postgresql/src/bin/pg_resetxlog/pg_resetxlog.c postgresql_with_patch/src/bin/pg_resetxlog/pg_resetxlog.c
*** postgresql/src/bin/pg_resetxlog/pg_resetxlog.c	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/bin/pg_resetxlog/pg_resetxlog.c	2011-09-12 05:24:42.000000000 +0900
***************
*** 503,509 ****
  	ControlFile.time = (pg_time_t) time(NULL);
  	ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
  
! 	/* minRecoveryPoint and backupStartPoint can be left zero */
  
  	ControlFile.wal_level = WAL_LEVEL_MINIMAL;
  	ControlFile.MaxConnections = 100;
--- 503,509 ----
  	ControlFile.time = (pg_time_t) time(NULL);
  	ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
  
! 	/* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
  
  	ControlFile.wal_level = WAL_LEVEL_MINIMAL;
  	ControlFile.MaxConnections = 100;
***************
*** 638,643 ****
--- 638,645 ----
  	ControlFile.backupStartPoint.xlogid = 0;
  	ControlFile.backupStartPoint.xrecoff = 0;
  	ControlFile.backupEndRequired = false;
+ 	ControlFile.backupEndPoint.xlogid = 0;
+ 	ControlFile.backupEndPoint.xrecoff = 0;
  
  	/*
  	 * Force the defaults for max_* settings. The values don't really matter
diff -rcN postgresql/src/include/access/xlog.h postgresql_with_patch/src/include/access/xlog.h
*** postgresql/src/include/access/xlog.h	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/include/access/xlog.h	2011-09-12 05:24:42.000000000 +0900
***************
*** 328,331 ****
--- 328,335 ----
  #define BACKUP_LABEL_FILE		"backup_label"
  #define BACKUP_LABEL_OLD		"backup_label.old"
  
+ /* These are written in backup label file */
+ #define BACKUP_FROM_MASTER		"master"
+ #define BACKUP_FROM_SLAVE		"slave"
+ 
  #endif   /* XLOG_H */
diff -rcN postgresql/src/include/catalog/pg_control.h postgresql_with_patch/src/include/catalog/pg_control.h
*** postgresql/src/include/catalog/pg_control.h	2011-09-12 05:19:14.000000000 +0900
--- postgresql_with_patch/src/include/catalog/pg_control.h	2011-09-12 05:24:42.000000000 +0900
***************
*** 143,152 ****
--- 143,158 ----
  	 * start up. If it's false, but backupStartPoint is set, a backup_label
  	 * file was found at startup but it may have been a leftover from a stray
  	 * pg_start_backup() call, not accompanied by pg_stop_backup().
+ 	 *
+ 	 * backupEndPoint is set a same value as minRecoveryPoint at the first
+ 	 * recovery if the backup is taken from hot standby. It is unset if we
+ 	 * reach the end of backup. It is not set if the backup is taken from
+ 	 * normal running.
  	 */
  	XLogRecPtr	minRecoveryPoint;
  	XLogRecPtr	backupStartPoint;
  	bool		backupEndRequired;
+ 	XLogRecPtr	backupEndPoint;
  
  	/*
  	 * Parameter settings that determine if the WAL can be used for archival
