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-06-30 10:04:48.000000000 +0900
--- postgresql_with_patch/src/backend/access/transam/xlog.c	2011-07-11 18:46:45.000000000 +0900
***************
*** 6284,6289 ****
--- 6284,6303 ----
  		/* use volatile pointer to prevent code rearrangement */
  		volatile XLogCtlData *xlogctl = XLogCtl;
  
+ 		/* 
+ 		 * get minRecoveryPoint before the value is changed for 
+ 		 * getting backup on standby server.
+ 		 * check the result, set to pg_control.
+ 		 */
+ 		XLogRecPtr prevminRecoveryPoint = ControlFile->minRecoveryPoint;
+ 		if (!ControlFile->backupserver)
+ 		{
+ 			if (prevminRecoveryPoint.xlogid == 0 && prevminRecoveryPoint.xrecoff == 0)
+ 				ControlFile->backupserver = BACKUPSERVER_MASTER;
+ 			else
+ 				ControlFile->backupserver = BACKUPSERVER_SLAVE;
+ 		}
+ 
  		/*
  		 * 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
***************
*** 6592,6597 ****
--- 6606,6631 ----
  				/* Pop the error context stack */
  				error_context_stack = errcontext.previous;
  
+ 				/* 
+ 				 * Check whether to reach minRecoveryPoint when getting backup 
+ 				 * on standby server.
+ 				 */
+ 				if (ControlFile->backupserver == BACKUPSERVER_SLAVE)
+ 				{
+ 					if (XLByteLE(prevminRecoveryPoint, EndRecPtr))
+ 					{
+ 						elog(DEBUG1, "end of backup reached in the control file");
+ 
+ 						LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ 
+ 						MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
+ 						ControlFile->backupserver = BACKUPSERVER_NONE;
+ 						UpdateControlFile();
+ 
+ 						LWLockRelease(ControlFileLock);
+ 					}
+ 				}
+ 
  				/*
  				 * Update shared recoveryLastRecPtr after this record has been
  				 * replayed.
***************
*** 8512,8517 ****
--- 8546,8552 ----
  			if (XLByteLT(ControlFile->minRecoveryPoint, lsn))
  				ControlFile->minRecoveryPoint = lsn;
  			MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
+ 			ControlFile->backupserver = BACKUPSERVER_NONE;
  			UpdateControlFile();
  
  			LWLockRelease(ControlFileLock);
***************
*** 8845,8850 ****
--- 8880,8886 ----
  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;
***************
*** 8862,8871 ****
  		   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,
--- 8898,8904 ----
  		   errmsg("must be superuser or replication role to run a backup")));
  
  	if (RecoveryInProgress())
! 		duringrecovery = true;
  
  	if (!XLogIsNeeded())
  		ereport(ERROR,
***************
*** 8890,8896 ****
  	 * 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
--- 8923,8930 ----
  	 * 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
***************
*** 8924,8930 ****
  	}
  	else
  		XLogCtl->Insert.nonExclusiveBackups++;
! 	XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
  	/* Ensure we release forcePageWrites if fail below */
--- 8958,8965 ----
  	}
  	else
  		XLogCtl->Insert.nonExclusiveBackups++;
! 	if (!duringrecovery)
! 		XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
  	/* Ensure we release forcePageWrites if fail below */
***************
*** 9112,9117 ****
--- 9147,9153 ----
  do_pg_stop_backup(char *labelfile, bool waitforarchive)
  {
  	bool		exclusive = (labelfile == NULL);
+ 	bool		duringrecovery = false;
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
  	XLogRecData rdata;
***************
*** 9138,9147 ****
  		 (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,
--- 9174,9180 ----
  		 (errmsg("must be superuser or replication role to run a backup"))));
  
  	if (RecoveryInProgress())
! 		duringrecovery = true;
  
  	if (!XLogIsNeeded())
  		ereport(ERROR,
***************
*** 9168,9174 ****
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
--- 9201,9208 ----
  	}
  
  	if (!XLogCtl->Insert.exclusiveBackup &&
! 		XLogCtl->Insert.nonExclusiveBackups == 0 &&
! 	    !duringrecovery)
  	{
  		XLogCtl->Insert.forcePageWrites = false;
  	}
***************
*** 9222,9227 ****
--- 9256,9268 ----
  	}
  
  	/*
+ 	 * 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).
  	 */
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-06-30 10:04:48.000000000 +0900
--- postgresql_with_patch/src/bin/pg_controldata/pg_controldata.c	2011-07-07 18:23:22.000000000 +0900
***************
*** 86,91 ****
--- 86,105 ----
  	return _("unrecognized wal_level");
  }
  
+ static const char *
+ backupserver_str(BackupServer backupserver)
+ {
+ 	switch (backupserver)
+ 	{
+ 		case BACKUPSERVER_NONE:
+ 			return "none";
+ 		case BACKUPSERVER_MASTER:
+ 			return "master";
+ 		case BACKUPSERVER_SLAVE:
+ 			return "slave";
+ 	}
+ 	return _("unrecognized backupserver");
+ }
  
  int
  main(int argc, char *argv[])
***************
*** 232,237 ****
--- 246,253 ----
  	printf(_("Backup start location:                %X/%X\n"),
  		   ControlFile.backupStartPoint.xlogid,
  		   ControlFile.backupStartPoint.xrecoff);
+ 	printf(_("Backup from:                          %s\n"),
+ 		   backupserver_str(ControlFile.backupserver));
  	printf(_("Current wal_level setting:            %s\n"),
  		   wal_level_str(ControlFile.wal_level));
  	printf(_("Current max_connections setting:      %d\n"),
diff -rcN postgresql/src/include/access/xlog.h postgresql_with_patch/src/include/access/xlog.h
*** postgresql/src/include/access/xlog.h	2011-06-30 10:04:48.000000000 +0900
--- postgresql_with_patch/src/include/access/xlog.h	2011-07-07 15:32:57.000000000 +0900
***************
*** 209,214 ****
--- 209,222 ----
  } WalLevel;
  extern int	wal_level;
  
+ /* where to get backup */
+ typedef enum BackupServer
+ {
+ 	BACKUPSERVER_NONE = 0,
+ 	BACKUPSERVER_MASTER,
+ 	BACKUPSERVER_SLAVE,
+ } BackupServer;
+ 
  #define XLogArchivingActive()	(XLogArchiveMode && wal_level >= WAL_LEVEL_ARCHIVE)
  #define XLogArchiveCommandSet() (XLogArchiveCommand[0] != '\0')
  
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-06-30 10:04:48.000000000 +0900
--- postgresql_with_patch/src/include/catalog/pg_control.h	2011-07-11 14:34:09.000000000 +0900
***************
*** 142,147 ****
--- 142,156 ----
  	XLogRecPtr	backupStartPoint;
  
  	/*
+ 	 * backupserver is used while postgresql is in recovery mode to
+ 	 * store the location of where the backup comes from.
+ 	 * When Postgres starts recovery operations
+ 	 * it is set to "none". During recovery it is updated to either "master", or "slave".
+ 	 * When recovery operations finish it is updated back to "none".
+ 	 */
+ 	int			backupserver;
+ 
+ 	/*
  	 * Parameter settings that determine if the WAL can be used for archival
  	 * or hot standby.
  	 */
