diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 57ed8c8e29..c9332ba28c 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -101,6 +101,9 @@ static char logrotate_file[MAXPGPATH];
 
 static volatile pid_t postmasterPID = -1;
 
+static char *pre_check_start_script = NULL;	/*added*/
+static char *pre_check_stop_script = NULL;	/*added*/
+
 #ifdef WIN32
 static DWORD pgctl_start_type = SERVICE_AUTO_START;
 static SERVICE_STATUS status;
@@ -922,6 +925,18 @@ do_init(void)
 static void
 do_start(void)
 {
+        /*added*/
+        if (pre_check_start_script)
+        {
+                if (system(pre_check_start_script) != 0)
+                {
+                        write_stderr(_("%s: pre-check for start failed, aborting start\n"), progname);
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
+                        exit(1);
+                }
+        }
+
 	pid_t		old_pid = 0;
 	pid_t		pm_pid;
 
@@ -1014,6 +1029,18 @@ do_start(void)
 static void
 do_stop(void)
 {
+        /*added*/
+        if (pre_check_stop_script)
+        {
+                if (system(pre_check_stop_script) != 0)
+                {
+                        write_stderr(_("%s: pre-check for stop failed, aborting stop\n"), progname);
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
+                        exit(1);
+                }
+        }
+        
 	pid_t		pid;
 
 	pid = get_pgpid(false);
@@ -1082,6 +1109,14 @@ do_restart(void)
 					 progname, pid_file);
 		write_stderr(_("Is server running?\n"));
 		write_stderr(_("trying to start server anyway\n"));
+                /*added*/
+                if (pre_check_start_script && system(pre_check_start_script) != 0)
+                {
+                        write_stderr(_("%s: pre-check script for start failed, aborting start\n"), progname);
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
+                        exit(1);
+                }
 		do_start();
 		return;
 	}
@@ -1100,9 +1135,21 @@ do_restart(void)
 
 	if (postmaster_is_alive(pid))
 	{
+                /*added*/
+                if (pre_check_stop_script && system(pre_check_stop_script) != 0)
+                {
+                        write_stderr(_("%s: pre-check script for stop failed, aborting stop\n"), progname);
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
+                        exit(1);
+                }
+
 		if (kill(pid, sig) != 0)
 		{
 			write_stderr(_("%s: could not send stop signal (PID: %d): %m\n"), progname, (int) pid);
+                        /*added*/
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
 			exit(1);
 		}
 
@@ -1117,6 +1164,9 @@ do_restart(void)
 			if (shutdown_mode == SMART_MODE)
 				write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
 							   "waiting for session-initiated disconnection.\n"));
+                        /*added*/
+                        free(pre_check_start_script);
+                        free(pre_check_stop_script);
 			exit(1);
 		}
 
@@ -1129,6 +1179,14 @@ do_restart(void)
 					 progname, (int) pid);
 		write_stderr(_("starting server anyway\n"));
 	}
+        /*added*/
+        if (pre_check_start_script && system(pre_check_start_script) != 0)
+        {
+                write_stderr(_("%s: pre-check script for start failed, aborting start\n"), progname);
+                free(pre_check_start_script);
+                free(pre_check_stop_script);
+                exit(1);
+        }
 
 	do_start();
 }
@@ -1964,10 +2022,10 @@ do_help(void)
 	printf(_("Usage:\n"));
 	printf(_("  %s init[db]   [-D DATADIR] [-s] [-o OPTIONS]\n"), progname);
 	printf(_("  %s start      [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n"
-			 "                    [-o OPTIONS] [-p PATH] [-c]\n"), progname);
-	printf(_("  %s stop       [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"), progname);
-	printf(_("  %s restart    [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"
-			 "                    [-o OPTIONS] [-c]\n"), progname);
+                         "                    [-o OPTIONS] [-A SCRIPT] [-p PATH] [-c]\n"), progname);                   /*added*/
+        printf(_("  %s stop       [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s] [-Z SCRIPT] \n"), progname);      /*added*/
+        printf(_("  %s restart    [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"
+                         "                    [-o OPTIONS] [-A SCRIPT] [-Z SCRIPT] [-c]\n"), progname);                 /*added*/
 	printf(_("  %s reload     [-D DATADIR] [-s]\n"), progname);
 	printf(_("  %s status     [-D DATADIR]\n"), progname);
 	printf(_("  %s promote    [-D DATADIR] [-W] [-t SECS] [-s]\n"), progname);
@@ -2002,7 +2060,9 @@ do_help(void)
 	printf(_("  -o, --options=OPTIONS  command line options to pass to postgres\n"
 			 "                         (PostgreSQL server executable) or initdb\n"));
 	printf(_("  -p PATH-TO-POSTGRES    normally not necessary\n"));
-	printf(_("\nOptions for stop or restart:\n"));
+        printf(_("  -A, --pre-check-start=SCRIPT        pre-cehck user script for start\n"));                   /*added*/
+        printf(_("\nOptions for stop or restart:\n"));
+        printf(_("  -Z, --pre-check-stop=SCRIPT        pre-cehck user script for stop\n"));                     /*added*/
 	printf(_("  -m, --mode=MODE        MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
 
 	printf(_("\nShutdown modes are:\n"));
@@ -2201,6 +2261,8 @@ main(int argc, char **argv)
 		{"core-files", no_argument, NULL, 'c'},
 		{"wait", no_argument, NULL, 'w'},
 		{"no-wait", no_argument, NULL, 'W'},
+                {"pre-check-start", required_argument, NULL, 'A'},		/*added*/
+                {"pre-check-stop", required_argument, NULL, 'Z'},		/*added*/
 		{NULL, 0, NULL, 0}
 	};
 
@@ -2341,6 +2403,12 @@ main(int argc, char **argv)
 			case 'c':
 				allow_core_files = true;
 				break;
+                        case 'A': /*added*/
+                                pre_check_start_script = strdup(optarg);
+                                break;
+                        case 'Z': /*added*/
+                                pre_check_stop_script = strdup(optarg);
+                                break;
 			default:
 				/* getopt_long already issued a suitable error message */
 				do_advice();
@@ -2499,6 +2567,8 @@ main(int argc, char **argv)
 		default:
 			break;
 	}
+        free(pre_check_start_script);           /*added*/
+        free(pre_check_stop_script);            /*added*/
 
 	exit(0);
 }
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 6a5ef00743..4bc62e456c 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -40,11 +40,29 @@ else
 	print $conf "listen_addresses = '127.0.0.1'\n";
 }
 close $conf;
+
+# Set up scripts for pre-check
+my $pre_check_start_script = "$tempdir/pre_check_start.sh";
+my $pre_check_stop_script = "$tempdir/pre_check_stop.sh";
++
+# Create pre_check_start_script
+open(my $fh, '>', $pre_check_start_script) or die "Could not open file '$pre_check_start_script' $!";
+print $fh "#!/bin/sh\nexit 0\n";
+close $fh;
+chmod 0755, $pre_check_start_script;
++
+# Create pre_check_stop_script
+open($fh, '>', $pre_check_stop_script) or die "Could not open file '$pre_check_stop_script' $!";
+print $fh "#!/bin/sh\nexit 0\n";
+close $fh;
+chmod 0755, $pre_check_stop_script;
+
 my $ctlcmd = [
 	'pg_ctl', 'start', '-D', "$tempdir/data", '-l',
-	"$PostgreSQL::Test::Utils::log_path/001_start_stop_server.log"
+	"$PostgreSQL::Test::Utils::log_path/001_start_stop_server.log",
+        '-A', $pre_check_start_script, '-Z', $pre_check_stop_script
 ];
-command_like($ctlcmd, qr/done.*server started/s, 'pg_ctl start');
+command_like($ctlcmd, qr/done.*server started/s, 'pg_ctl start with pre-check scripts');
 
 # sleep here is because Windows builds can't check postmaster.pid exactly,
 # so they may mistake a pre-existing postmaster.pid for one created by the
@@ -53,7 +71,7 @@ command_like($ctlcmd, qr/done.*server started/s, 'pg_ctl start');
 sleep 3 if ($windows_os);
 command_fails([ 'pg_ctl', 'start', '-D', "$tempdir/data" ],
 	'second pg_ctl start fails');
-command_ok([ 'pg_ctl', 'stop', '-D', "$tempdir/data" ], 'pg_ctl stop');
+command_ok([ 'pg_ctl', 'stop', '-D', "$tempdir/data", '-Z', $pre_check_stop_script ], 'pg_ctl stop with pre-check script');
 command_fails([ 'pg_ctl', 'stop', '-D', "$tempdir/data" ],
 	'second pg_ctl stop fails');
 
@@ -61,8 +79,8 @@ command_fails([ 'pg_ctl', 'stop', '-D', "$tempdir/data" ],
 # Windows but we still want to do the restart test.
 my $logFileName = "$tempdir/data/perm-test-600.log";
 
-command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-l', $logFileName ],
-	'pg_ctl restart with server not running');
+command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-l', $logFileName, '-A', $pre_check_start_script, '-Z', $pre_check_stop_script ],
+        'pg_ctl restart with server not running and pre-check scripts');
 
 # Permissions on log file should be default
 SKIP:
@@ -89,16 +107,16 @@ SKIP:
 	chmod_recursive("$tempdir/data", 0750, 0640);
 
 	command_ok(
-		[ 'pg_ctl', 'start', '-D', "$tempdir/data", '-l', $logFileName ],
+                [ 'pg_ctl', 'start', '-D', "$tempdir/data", '-l', $logFileName, '-A', $pre_check_start_script, '-Z', $pre_check_stop_script ],
 		'start server to check group permissions');
 
 	ok(-f $logFileName);
 	ok(check_mode_recursive("$tempdir/data", 0750, 0640));
 }
 
-command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data" ],
-	'pg_ctl restart with server running');
+command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-A', $pre_check_start_script, '-Z', $pre_check_stop_script ],
+        'pg_ctl restart with server running and pre-check scripts');
 
-system_or_bail 'pg_ctl', 'stop', '-D', "$tempdir/data";
+system_or_bail 'pg_ctl', 'stop', '-D', "$tempdir/data", '-Z', $pre_check_stop_script;
 
 done_testing();
