diff -r -c postgresql-8.4.orig/src/backend/postmaster/postmaster.c postgresql-8.4/src/backend/postmaster/postmaster.c
*** postgresql-8.4.orig/src/backend/postmaster/postmaster.c	2008-04-01 15:18:52.000000000 +0200
--- postgresql-8.4/src/backend/postmaster/postmaster.c	2008-04-01 15:23:22.000000000 +0200
***************
*** 286,291 ****
--- 286,295 ----
  extern int	optreset;
  #endif
  
+ /* files for online backup */
+ #define BACKUP_LABEL_FILE	"backup_label"
+ #define BACKUP_LABEL_OLD	"backup_label.old"
+ 
  /*
   * postmaster.c - function prototypes
   */
***************
*** 1933,1938 ****
--- 1937,1943 ----
  pmdie(SIGNAL_ARGS)
  {
  	int			save_errno = errno;
+ 	struct stat		statbuf;
  
  	PG_SETMASK(&BlockSig);
  
***************
*** 1955,1960 ****
--- 1960,1975 ----
  			ereport(LOG,
  					(errmsg("received smart shutdown request")));
  
+ 			/* refuse to shut down if "backup_label" exists */
+ 			if (0 == stat(BACKUP_LABEL_FILE, &statbuf))
+ 			{
+ 				ereport(LOG,
+ 					(errmsg("online backup in progress, shutdown refused"),
+ 					errdetail_log("Execute \"pg_stop_backup()\" to leave backup mode before shutting down.")));
+ 				Shutdown = NoShutdown;
+ 				break;
+ 			}
+ 
  			if (pmState == PM_RUN)
  			{
  				/* autovacuum workers are told to shut down immediately */
***************
*** 2011,2016 ****
--- 2026,2047 ----
  			 * PostmasterStateMachine will take the next step.
  			 */
  			PostmasterStateMachine();
+ 
+ 			/*
+ 			 * Rename "backup_label" file if it exists to avoid
+ 			 * recovery after a clean fast shutdown.
+ 			 */
+ 			if (0 == stat(BACKUP_LABEL_FILE, &statbuf))
+ 			{
+ 				unlink(BACKUP_LABEL_OLD);
+ 				if (0 == rename(BACKUP_LABEL_FILE, BACKUP_LABEL_OLD))
+ 				{
+ 					ereport(LOG,
+ 						(errmsg("online backup cancelled, \"%s\" renamed to \"%s\"",
+ 							BACKUP_LABEL_FILE, BACKUP_LABEL_OLD)));
+ 				}
+ 			}
+ 
  			break;
  
  		case SIGQUIT:
Only in postgresql-8.4/src/backend/postmaster: postmaster.c.orig
diff -r -c postgresql-8.4.orig/src/bin/pg_ctl/pg_ctl.c postgresql-8.4/src/bin/pg_ctl/pg_ctl.c
*** postgresql-8.4.orig/src/bin/pg_ctl/pg_ctl.c	2008-04-01 15:18:55.000000000 +0200
--- postgresql-8.4/src/bin/pg_ctl/pg_ctl.c	2008-04-01 15:23:22.000000000 +0200
***************
*** 144,149 ****
--- 144,150 ----
  static char postopts_file[MAXPGPATH];
  static char pid_file[MAXPGPATH];
  static char conf_file[MAXPGPATH];
+ static char backup_file[MAXPGPATH];
  
  #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  static void unlimit_core_size(void);
***************
*** 731,736 ****
--- 732,738 ----
  {
  	int			cnt;
  	pgpid_t		pid;
+ 	struct stat	statbuf;
  
  	pid = get_pgpid();
  
***************
*** 749,754 ****
--- 751,766 ----
  		exit(1);
  	}
  
+ 	if (SMART_MODE == shutdown_mode)
+ 	{
+ 		if (0 == stat(backup_file, &statbuf))
+ 		{
+ 			write_stderr(_("%s: smart shutdown refused, online backup in progress\n"),
+ 				progname);
+ 			exit(1);
+ 		}
+ 	}
+ 
  	if (kill((pid_t) pid, sig) != 0)
  	{
  		write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
***************
*** 799,804 ****
--- 811,817 ----
  {
  	int			cnt;
  	pgpid_t		pid;
+ 	struct stat	statbuf;
  
  	pid = get_pgpid();
  
***************
*** 826,831 ****
--- 839,854 ----
  
  	if (postmaster_is_alive((pid_t) pid))
  	{
+ 		if (SMART_MODE == shutdown_mode)
+ 		{
+ 			if (0 == stat(backup_file, &statbuf))
+ 			{
+ 				write_stderr(_("%s: cannot stop server; online backup in progress\n"),
+ 					progname);
+ 				exit(1);
+ 			}
+ 		}
+ 
  		if (kill((pid_t) pid, sig) != 0)
  		{
  			write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
***************
*** 1883,1888 ****
--- 1906,1912 ----
  		snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
  		snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
  		snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
+ 		snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
  	}
  
  	switch (ctl_command)
