diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index d3565a5..0e15562 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -137,7 +137,7 @@ ProcessConfigFile(GucContext context)
 	/* Parse the file into a list of option names and values */
 	head = tail = NULL;
 
-	if (!ParseConfigFile(ConfigFileName, NULL, true, 0, elevel, &head, &tail))
+	if (!ParseConfigFile(ConfigFileName, NULL, true, true, 0, elevel, &head, &tail))
 	{
 		/* Syntax error(s) detected in the file, so bail out */
 		error = true;
@@ -145,6 +145,40 @@ ProcessConfigFile(GucContext context)
 	}
 
 	/*
+	 * If DataDir is now set, search for a recovery.conf file so we can
+	 * read any parameters from that as well. If DataDir isn't set by now,
+	 * we can ignore it, since it will error out at next level up.
+	 *
+	 * This step is the same as saying "include_if_exists recovery.conf"
+	 * as the last line of the postgresql.conf
+	 *
+	 * recovery.conf is renamed to recovery.done at the end of recovery.
+	 * Note that this means the contents of recovery.conf will not be
+	 * reread when we SIGHUP after the end of recovery, so that all
+	 * recovery parameters will end up at their boot values.
+	 *
+	 * Note also that this means that we use the setting of data_directory
+	 * as it exists now for the purposes of reading recovery.conf.
+	 * Some will note that setting data_directory inside recovery.conf
+	 * could change the final value of that. If anybody thinks that is
+	 * even remotely likely, we can put specific trap against that occurring
+	 * easily enough.
+	 */
+#define RECOVERY_COMMAND_FILE "recovery.conf"
+	if (DataDir)
+	{
+		char   RecoveryConfFileName[MAXPGPATH];
+
+		snprintf(RecoveryConfFileName, MAXPGPATH, "%s/%s", DataDir, RECOVERY_COMMAND_FILE);
+		if (!ParseConfigFile(RecoveryConfFileName, NULL, false, false, 0, elevel, &head, &tail))
+		{
+			/* Syntax error(s) detected in the file, so bail out */
+			error = true;
+			goto cleanup_list;
+		}
+	}
+
+	/*
 	 * Mark all extant GUC variables as not present in the config file.
 	 * We need this so that we can tell below which ones have been removed
 	 * from the file since we last processed it.
@@ -404,7 +438,8 @@ AbsoluteConfigLocation(const char *location, const char *calling_file)
  * and absolute-ifying the path name if necessary.
  */
 bool
-ParseConfigFile(const char *config_file, const char *calling_file, bool strict,
+ParseConfigFile(const char *config_file, const char *calling_file,
+				bool strict, bool log,
 				int depth, int elevel,
 				ConfigVariable **head_p,
 				ConfigVariable **tail_p)
@@ -439,7 +474,8 @@ ParseConfigFile(const char *config_file, const char *calling_file, bool strict,
 			return false;
 		}
 
-		ereport(LOG,
+		if (log)
+			ereport(LOG,
 				(errmsg("skipping missing configuration file \"%s\"",
 						config_file)));
 		return OK;
@@ -592,7 +628,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
 			 * An include_if_exists directive isn't a variable and should be
 			 * processed immediately.
 			 */
-			if (!ParseConfigFile(opt_value, config_file, false,
+			if (!ParseConfigFile(opt_value, config_file, false, true,
 								 depth + 1, elevel,
 								 head_p, tail_p))
 				OK = false;
@@ -606,7 +642,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
 			 * An include directive isn't a variable and should be processed
 			 * immediately.
 			 */
-			if (!ParseConfigFile(opt_value, config_file, true,
+			if (!ParseConfigFile(opt_value, config_file, true, true,
 								 depth + 1, elevel,
 								 head_p, tail_p))
 				OK = false;
@@ -614,6 +650,10 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
 			pfree(opt_name);
 			pfree(opt_value);
 		}
+		else if (guc_name_compare(opt_name, "data_directory") == 0)
+		{
+			SetDataDir(opt_value);
+		}
 		else
 		{
 			/* ordinary variable, append to list */
@@ -779,7 +819,7 @@ ParseConfigDirectory(const char *includedir,
 		qsort(filenames, num_filenames, sizeof(char *), pg_qsort_strcmp);
 		for (i = 0; i < num_filenames; i++)
 		{
-			if (!ParseConfigFile(filenames[i], NULL, true,
+			if (!ParseConfigFile(filenames[i], NULL, true, true,
 								 depth, elevel, head_p, tail_p))
 			{
 				status = false;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f9fb264..96f6727 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4120,6 +4120,13 @@ SelectConfigFiles(const char *userDoption, const char *progname)
 		configdir = make_absolute_path(getenv("PGDATA"));
 
 	/*
+	 * Set our initial value of DataDir from the configdir.
+	 * This may be overidden later if data_directory parameter is set.
+	 */
+	if (configdir)
+		SetDataDir(configdir);
+
+	/*
 	 * Find the configuration file: if config_file was specified on the
 	 * command line, use it, else use configdir/postgresql.conf.  In any case
 	 * ensure the result is an absolute path, so that it will be interpreted
@@ -4165,15 +4172,8 @@ SelectConfigFiles(const char *userDoption, const char *progname)
 	/*
 	 * If the data_directory GUC variable has been set, use that as DataDir;
 	 * otherwise use configdir if set; else punt.
-	 *
-	 * Note: SetDataDir will copy and absolute-ize its argument, so we don't
-	 * have to.
 	 */
-	if (data_directory)
-		SetDataDir(data_directory);
-	else if (configdir)
-		SetDataDir(configdir);
-	else
+	if (!DataDir)
 	{
 		write_stderr("%s does not know where to find the database system data.\n"
 					 "This can be specified as \"data_directory\" in \"%s\", "
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 42428cb..16130e2 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -112,7 +112,7 @@ typedef struct ConfigVariable
 } ConfigVariable;
 
 extern bool ParseConfigFile(const char *config_file, const char *calling_file,
-				bool strict, int depth, int elevel,
+				bool strict, bool log, int depth, int elevel,
 				ConfigVariable **head_p, ConfigVariable **tail_p);
 extern bool ParseConfigFp(FILE *fp, const char *config_file,
 			  int depth, int elevel,
