pg_upgrade del/rmdir path fix

Started by Andrew Dunstanover 13 years ago19 messages
#1Andrew Dunstan
andrew@dunslane.net

Here is a patch against 9.2 sources (it applies with offsets to HEAD
too) to fix the problem that pg_upgrade can write paths in arguments for
Windows builtin commands (specifically DEL and RMDIR) with the wrong
path separator style. This should be applied all the way back to 9.0.

cheers

andrew

#2Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#1)
1 attachment(s)
Re: pg_upgrade del/rmdir path fix

On 09/03/2012 02:30 PM, Andrew Dunstan wrote:

Here is a patch against 9.2 sources (it applies with offsets to HEAD
too) to fix the problem that pg_upgrade can write paths in arguments
for Windows builtin commands (specifically DEL and RMDIR) with the
wrong path separator style. This should be applied all the way back to
9.0.

This time with a patch.

cheers

andrew

Attachments:

pg_upgrade_fix_path.patchtext/x-patch; name=pg_upgrade_fix_path.patchDownload
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index aa896b5..32d1e61 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -23,6 +23,36 @@ static void check_for_reg_data_type_usage(ClusterInfo *cluster);
 static void get_bin_version(ClusterInfo *cluster);
 
 
+/*
+ * fix_path
+ * combine two path segements, ignore second if it is NULL.
+ * For Windows convert to using backslashes such as is
+ * suitable for builtin commands like RMDIR and DEL
+ */
+static inline char *fix_path(char *p1, char *p2)
+{
+	char * result;
+	int len = strlen(p1) + (p2 == NULL ? 0 : strlen(p2));
+	int end;
+#ifdef WIN32
+	int i;
+#endif
+
+	result = pg_malloc(len+1);
+	end = strlcpy(result,p1,len+1);
+	if (p2 != NULL)
+		strlcpy(result + end,p2,len + 1 - end);
+
+#ifdef WIN32
+	for (i = 0; i < len; i++)
+		if (result[i] == '/')
+			result[i] = '\\';
+#endif
+	
+	return result;
+}
+
+
 void
 output_check_banner(bool *live_check)
 {
@@ -547,7 +577,7 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 #endif
 
 	/* delete old cluster's default tablespace */
-	fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
+	fprintf(script, RMDIR_CMD " %s\n", fix_path(old_cluster.pgdata, NULL));
 
 	/* delete old cluster's alternate tablespaces */
 	for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
@@ -564,14 +594,17 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 			fprintf(script, "\n");
 			/* remove PG_VERSION? */
 			if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
-				fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
-				 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
+				fprintf(script, RM_CMD " %s%cPG_VERSION\n",
+						fix_path(os_info.tablespaces[tblnum], 
+								 old_cluster.tablespace_suffix),
+						PATH_SEPARATOR);
 
 			for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
 			{
-				fprintf(script, RMDIR_CMD " %s%s/%d\n",
-				  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
-						old_cluster.dbarr.dbs[dbnum].db_oid);
+				fprintf(script, RMDIR_CMD " %s%c%d\n",
+						fix_path(os_info.tablespaces[tblnum], 
+								 old_cluster.tablespace_suffix),
+						PATH_SEPARATOR, old_cluster.dbarr.dbs[dbnum].db_oid);
 			}
 		}
 		else
@@ -580,8 +613,9 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 			 * Simply delete the tablespace directory, which might be ".old"
 			 * or a version-specific subdirectory.
 			 */
-			fprintf(script, RMDIR_CMD " %s%s\n",
-				 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
+			fprintf(script, RMDIR_CMD " %s\n",
+					fix_path(os_info.tablespaces[tblnum], 
+							 old_cluster.tablespace_suffix));
 	}
 
 	fclose(script);
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index 77c7150..4a18497 100644
--- a/contrib/pg_upgrade/pg_upgrade.h
+++ b/contrib/pg_upgrade/pg_upgrade.h
@@ -72,6 +72,7 @@ extern char *output_files[];
 #define pg_copy_file		copy_file
 #define pg_mv_file			rename
 #define pg_link_file		link
+#define PATH_SEPARATOR      '/'
 #define RM_CMD				"rm -f"
 #define RMDIR_CMD			"rm -rf"
 #define SCRIPT_EXT			"sh"
@@ -81,6 +82,7 @@ extern char *output_files[];
 #define pg_mv_file			pgrename
 #define pg_link_file		win32_pghardlink
 #define sleep(x)			Sleep(x * 1000)
+#define PATH_SEPARATOR      '\\'
 #define RM_CMD				"DEL /q"
 #define RMDIR_CMD			"RMDIR /s/q"
 #define SCRIPT_EXT			"bat"
#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#2)
Re: pg_upgrade del/rmdir path fix

Andrew Dunstan <andrew@dunslane.net> writes:

This time with a patch.

Nitpicky gripe: "fix_path" is a mighty generic name. How about
"fix_path_for_windows" or something like that? I don't think I'd
mark it inline, either.

More generally, the behavior of combining two (maybe) filename segments
seems overcomplicated and unnecessary. Why not just have it take *one*
argument and back-slashify that, without the concatenation behavior?
Then you'd have two calls instead of one at some of the call sites,
but that doesn't seem like much of a loss. The malloc'd strings are
getting leaked anyway. The function itself would reduce to pg_strdup
and a backslashification loop. Also, you could turn it into a complete
no-op (not even pg_strdup) on non-Windows.

regards, tom lane

#4Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#3)
1 attachment(s)
Re: pg_upgrade del/rmdir path fix

On 09/03/2012 03:22 PM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

This time with a patch.

Nitpicky gripe: "fix_path" is a mighty generic name. How about
"fix_path_for_windows" or something like that? I don't think I'd
mark it inline, either.

More generally, the behavior of combining two (maybe) filename segments
seems overcomplicated and unnecessary. Why not just have it take *one*
argument and back-slashify that, without the concatenation behavior?
Then you'd have two calls instead of one at some of the call sites,
but that doesn't seem like much of a loss. The malloc'd strings are
getting leaked anyway. The function itself would reduce to pg_strdup
and a backslashification loop. Also, you could turn it into a complete
no-op (not even pg_strdup) on non-Windows.

OK, revised patch attached.

cheers

andrew

Attachments:

pg_upgrade_fix_path_separator.patchtext/x-patch; name=pg_upgrade_fix_path_separator.patchDownload
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index efb080b..d965fa8 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -23,6 +23,35 @@ static void check_for_reg_data_type_usage(ClusterInfo *cluster);
 static void get_bin_version(ClusterInfo *cluster);
 
 
+/*
+ * fix_path_separator
+ * For non-Windows, just return the argument.
+ * For Windows convert any forward slash to a backslash
+ * such as is suitable for arguments to builtin commands 
+ * like RMDIR and DEL.
+ */
+static char *fix_path_separator(char *path)
+{
+#ifdef WIN32
+
+	char *result;
+	char *c;
+
+	result = pg_strdup(path);
+
+	for (c = result; *c != '\0'; c++)
+		if (*c == '/')
+			*c = '\\';
+
+	return result;
+
+#else
+
+	return path;
+
+#endif
+}
+
 void
 output_check_banner(bool *live_check)
 {
@@ -544,7 +573,7 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 #endif
 
 	/* delete old cluster's default tablespace */
-	fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
+	fprintf(script, RMDIR_CMD " %s\n", fix_path_separator(old_cluster.pgdata));
 
 	/* delete old cluster's alternate tablespaces */
 	for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
@@ -561,14 +590,17 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 			fprintf(script, "\n");
 			/* remove PG_VERSION? */
 			if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
-				fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
-				 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
+				fprintf(script, RM_CMD " %s%s%cPG_VERSION\n",
+						fix_path_separator(os_info.tablespaces[tblnum]), 
+						fix_path_separator(old_cluster.tablespace_suffix),
+						PATH_SEPARATOR);
 
 			for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
 			{
-				fprintf(script, RMDIR_CMD " %s%s/%d\n",
-				  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
-						old_cluster.dbarr.dbs[dbnum].db_oid);
+				fprintf(script, RMDIR_CMD " %s%s%c%d\n",
+						fix_path_separator(os_info.tablespaces[tblnum]),
+						fix_path_separator(old_cluster.tablespace_suffix),
+						PATH_SEPARATOR, old_cluster.dbarr.dbs[dbnum].db_oid);
 			}
 		}
 		else
@@ -578,7 +610,8 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 			 * or a version-specific subdirectory.
 			 */
 			fprintf(script, RMDIR_CMD " %s%s\n",
-				 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
+					fix_path_separator(os_info.tablespaces[tblnum]), 
+					fix_path_separator(old_cluster.tablespace_suffix));
 	}
 
 	fclose(script);
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index 7b19d91..b57da53 100644
--- a/contrib/pg_upgrade/pg_upgrade.h
+++ b/contrib/pg_upgrade/pg_upgrade.h
@@ -72,6 +72,7 @@ extern char *output_files[];
 #define pg_copy_file		copy_file
 #define pg_mv_file			rename
 #define pg_link_file		link
+#define PATH_SEPARATOR      '/'
 #define RM_CMD				"rm -f"
 #define RMDIR_CMD			"rm -rf"
 #define SCRIPT_EXT			"sh"
@@ -81,6 +82,7 @@ extern char *output_files[];
 #define pg_mv_file			pgrename
 #define pg_link_file		win32_pghardlink
 #define sleep(x)			Sleep(x * 1000)
+#define PATH_SEPARATOR      '\\'
 #define RM_CMD				"DEL /q"
 #define RMDIR_CMD			"RMDIR /s/q"
 #define SCRIPT_EXT			"bat"
#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#4)
Re: pg_upgrade del/rmdir path fix

Andrew Dunstan <andrew@dunslane.net> writes:

OK, revised patch attached.

Looks good to me.

regards, tom lane

#6Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#5)
Re: pg_upgrade del/rmdir path fix

On 09/03/2012 04:32 PM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

OK, revised patch attached.

Looks good to me.

OK. I will try to get the test script wrapped up tonight or tomorrow,
that's the only thing left.

cheers

andrew

#7Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#1)
Re: pg_upgrade del/rmdir path fix

On Mon, Sep 3, 2012 at 02:30:18PM -0400, Andrew Dunstan wrote:

Here is a patch against 9.2 sources (it applies with offsets to HEAD
too) to fix the problem that pg_upgrade can write paths in arguments
for Windows builtin commands (specifically DEL and RMDIR) with the
wrong path separator style. This should be applied all the way back
to 9.0.

Wow, my guess is that no one ever ran those auto-generated scripts on
Windows. Thanks.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#8Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#7)
Re: pg_upgrade del/rmdir path fix

On 09/03/2012 10:41 PM, Bruce Momjian wrote:

On Mon, Sep 3, 2012 at 02:30:18PM -0400, Andrew Dunstan wrote:

Here is a patch against 9.2 sources (it applies with offsets to HEAD
too) to fix the problem that pg_upgrade can write paths in arguments
for Windows builtin commands (specifically DEL and RMDIR) with the
wrong path separator style. This should be applied all the way back
to 9.0.

Wow, my guess is that no one ever ran those auto-generated scripts on
Windows. Thanks.

Lucky for us the test script does or I'd never have noticed either.

cheers

andrew

#9Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#8)
Re: pg_upgrade del/rmdir path fix

On 09/03/2012 11:05 PM, Andrew Dunstan wrote:

On 09/03/2012 10:41 PM, Bruce Momjian wrote:

On Mon, Sep 3, 2012 at 02:30:18PM -0400, Andrew Dunstan wrote:

Here is a patch against 9.2 sources (it applies with offsets to HEAD
too) to fix the problem that pg_upgrade can write paths in arguments
for Windows builtin commands (specifically DEL and RMDIR) with the
wrong path separator style. This should be applied all the way back
to 9.0.

Wow, my guess is that no one ever ran those auto-generated scripts on
Windows. Thanks.

Lucky for us the test script does or I'd never have noticed either.

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

cheers

andrew

#10Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andrew Dunstan (#9)
Re: pg_upgrade del/rmdir path fix

Excerpts from Andrew Dunstan's message of mar sep 04 01:16:39 -0300 2012:

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

Great, thanks.

Who's going to work now on porting the shell script to Perl? ;-)

Somehow the verbose reporting of user relation files being copied does
not seem exceedingly useful; and I don't remember seeing that on Linux.

Should this be tweaked to avoid outputting the status message?

c:\mingw\msys\1.0\home\pgrunner\bf\root\HEAD\pgsql.7020\contrib\pg_upgrade>echo
ECHO is on.

--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#11Bruce Momjian
bruce@momjian.us
In reply to: Alvaro Herrera (#10)
Re: pg_upgrade del/rmdir path fix

On Tue, Sep 4, 2012 at 11:42:58AM -0300, Alvaro Herrera wrote:

Excerpts from Andrew Dunstan's message of mar sep 04 01:16:39 -0300 2012:

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

Great, thanks.

Who's going to work now on porting the shell script to Perl? ;-)

Well, we require Perl for development, but not for usage, at least not
yet. There was talk of needing Perl for doing standby pg_upgrade, but
there were too many concerns about that idea.

Somehow the verbose reporting of user relation files being copied does
not seem exceedingly useful; and I don't remember seeing that on Linux.

Should this be tweaked to avoid outputting the status message?

c:\mingw\msys\1.0\home\pgrunner\bf\root\HEAD\pgsql.7020\contrib\pg_upgrade>echo
ECHO is on.

Probably.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#11)
Re: pg_upgrade del/rmdir path fix

Bruce Momjian <bruce@momjian.us> writes:

On Tue, Sep 4, 2012 at 11:42:58AM -0300, Alvaro Herrera wrote:

Who's going to work now on porting the shell script to Perl? ;-)

Well, we require Perl for development, but not for usage, at least not
yet.

This is a regression-test script, so that complaint doesn't seem to me
to have a lot of force ... especially not when set against the fact that
the shell script is useless on non-mingw Windows.

regards, tom lane

#13Andrew Dunstan
andrew@dunslane.net
In reply to: Alvaro Herrera (#10)
Re: pg_upgrade del/rmdir path fix

On 09/04/2012 10:42 AM, Alvaro Herrera wrote:

Excerpts from Andrew Dunstan's message of mar sep 04 01:16:39 -0300 2012:

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

Great, thanks.

Who's going to work now on porting the shell script to Perl? ;-)

Probably me, one day ...

Somehow the verbose reporting of user relation files being copied does
not seem exceedingly useful; and I don't remember seeing that on Linux.

Yes, it's a pain. Not sure what causes it.

Should this be tweaked to avoid outputting the status message?

c:\mingw\msys\1.0\home\pgrunner\bf\root\HEAD\pgsql.7020\contrib\pg_upgrade>echo
ECHO is on.

Already fixed.

cheers

andrew

#14Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#11)
Re: pg_upgrade del/rmdir path fix

On 09/04/2012 10:49 AM, Bruce Momjian wrote:

On Tue, Sep 4, 2012 at 11:42:58AM -0300, Alvaro Herrera wrote:

Excerpts from Andrew Dunstan's message of mar sep 04 01:16:39 -0300 2012:

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

Great, thanks.

Who's going to work now on porting the shell script to Perl? ;-)

Well, we require Perl for development, but not for usage, at least not
yet. There was talk of needing Perl for doing standby pg_upgrade, but
there were too many concerns about that idea.

This is a test script, not what you should use in production. I don't
see any reason why we shouldn't require Perl for running the standard test.

cheers

andrew

#15Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#14)
Re: pg_upgrade del/rmdir path fix

On Tue, Sep 4, 2012 at 11:12:52AM -0400, Andrew Dunstan wrote:

On 09/04/2012 10:49 AM, Bruce Momjian wrote:

On Tue, Sep 4, 2012 at 11:42:58AM -0300, Alvaro Herrera wrote:

Excerpts from Andrew Dunstan's message of mar sep 04 01:16:39 -0300 2012:

And here's the first Windows buildfarm check of pg_upgrade.
<http://www.pgbuildfarm.org/cgi-bin/show_stage_log.pl?nm=pitta&amp;dt=2012-09-04%2003%3A00%3A05&amp;stg=check-pg_upgrade&gt;

Great, thanks.

Who's going to work now on porting the shell script to Perl? ;-)

Well, we require Perl for development, but not for usage, at least not
yet. There was talk of needing Perl for doing standby pg_upgrade, but
there were too many concerns about that idea.

This is a test script, not what you should use in production. I
don't see any reason why we shouldn't require Perl for running the
standard test.

Oh, I thought he was talking about the scripts pg_upgrade creates for
users to run. Sorry.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#14)
Re: pg_upgrade del/rmdir path fix

Andrew Dunstan <andrew@dunslane.net> writes:

This is a test script, not what you should use in production. I don't
see any reason why we shouldn't require Perl for running the standard test.

But on the third hand ... we've taken pains to ensure that you don't
*have* to have Perl to build from a tarball, and I think it is not
unreasonable that "build" should include being able to do "make check".

Maybe we have to carry both this shell script and a Perl equivalent
for Windows.

regards, tom lane

#17Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#16)
Re: pg_upgrade del/rmdir path fix

On 09/04/2012 11:21 AM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

This is a test script, not what you should use in production. I don't
see any reason why we shouldn't require Perl for running the standard test.

But on the third hand ... we've taken pains to ensure that you don't
*have* to have Perl to build from a tarball, and I think it is not
unreasonable that "build" should include being able to do "make check".

Maybe we have to carry both this shell script and a Perl equivalent
for Windows.

Yeah. I think it will just be another target in vcregress.pl

cheers

andrew

#18Andrew Dunstan
andrew@dunslane.net
In reply to: Alvaro Herrera (#10)
Re: pg_upgrade del/rmdir path fix

On 09/04/2012 10:42 AM, Alvaro Herrera wrote:

Somehow the verbose reporting of user relation files being copied does
not seem exceedingly useful; and I don't remember seeing that on Linux.

Yeah, and it does something odd anyway when it's not writing to a
terminal. Can we get rid of it, or make it only work in verbose mode?

cheers

andrew

#19Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#18)
1 attachment(s)
Re: pg_upgrade del/rmdir path fix

On 09/04/2012 02:25 PM, Andrew Dunstan wrote:

On 09/04/2012 10:42 AM, Alvaro Herrera wrote:

Somehow the verbose reporting of user relation files being copied does
not seem exceedingly useful; and I don't remember seeing that on Linux.

Yeah, and it does something odd anyway when it's not writing to a
terminal. Can we get rid of it, or make it only work in verbose mode?

The attached is an attempt to fix this. I think it handles most of
what's wrong with this. (The patch is bigger because the code currently
uses a variable called "fileno" - not a good idea.)

cheers

andrew

Attachments:

pg_upgrade_relfilenode_log.patchtext/x-patch; name=pg_upgrade_relfilenode_log.patchDownload
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
index 33a867f..0a579d5 100644
--- a/contrib/pg_upgrade/relfilenode.c
+++ b/contrib/pg_upgrade/relfilenode.c
@@ -14,7 +14,6 @@
 #include "catalog/pg_class.h"
 #include "access/transam.h"
 
-
 static void transfer_single_new_db(pageCnvCtx *pageConverter,
 					   FileNameMap *maps, int size);
 static void transfer_relfile(pageCnvCtx *pageConverter,
@@ -136,7 +135,7 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 	char		**namelist = NULL;
 	int			numFiles = 0;
 	int			mapnum;
-	int			fileno;
+	int			file_no;
 	bool		vm_crashsafe_change = false;
 
 	old_dir[0] = '\0';
@@ -156,8 +155,8 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 		{
 			if (numFiles > 0)
 			{
-				for (fileno = 0; fileno < numFiles; fileno++)
-					pg_free(namelist[fileno]);
+				for (file_no = 0; file_no < numFiles; file_no++)
+					pg_free(namelist[file_no]);
 				pg_free(namelist);
 			}
 
@@ -171,7 +170,34 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 				 maps[mapnum].old_relfilenode);
 		snprintf(new_file, sizeof(new_file), "%s/%u", maps[mapnum].new_dir,
 				 maps[mapnum].new_relfilenode);
-		pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_file);
+		if (!isatty(fileno(stdout)))
+		{
+			/* don't try to be cute if we're not interactive */
+			pg_log(PG_REPORT, "  %s\n", old_file);
+		}
+		else
+		{
+			/* 
+			 * print the largest rightmost part of the name that can fit
+			 * within the message width.
+			 */
+			int remove = strlen(old_file) - atoi(MESSAGE_WIDTH);
+			char *start = old_file;
+			char *sep;
+
+			if ( remove > 0 )	
+			{
+				/*
+				 * If it's a partial path. move past the
+				 * first file path separator we find, so we don't
+				 * print a partial path segment.
+				 */
+				start += remove;
+				if ((sep = strpbrk(start,"/\\")) != NULL)
+					start = sep + 1;
+			}				
+			pg_log(PG_REPORT, OVERWRITE_MESSAGE, start);
+		}
 
 		/*
 		 * Copy/link the relation's primary file (segment 0 of main fork)
@@ -190,23 +216,23 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 			snprintf(file_pattern, sizeof(file_pattern), "%u_",
 					 maps[mapnum].old_relfilenode);
 
-			for (fileno = 0; fileno < numFiles; fileno++)
+			for (file_no = 0; file_no < numFiles; file_no++)
 			{
-				char	   *vm_offset = strstr(namelist[fileno], "_vm");
+				char	   *vm_offset = strstr(namelist[file_no], "_vm");
 				bool		is_vm_file = false;
 
 				/* Is a visibility map file? (name ends with _vm) */
 				if (vm_offset && strlen(vm_offset) == strlen("_vm"))
 					is_vm_file = true;
 
-				if (strncmp(namelist[fileno], file_pattern,
+				if (strncmp(namelist[file_no], file_pattern,
 							strlen(file_pattern)) == 0 &&
 					(!is_vm_file || !vm_crashsafe_change))
 				{
 					snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
-							 namelist[fileno]);
+							 namelist[file_no]);
 					snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
-							 maps[mapnum].new_relfilenode, strchr(namelist[fileno], '_'));
+							 maps[mapnum].new_relfilenode, strchr(namelist[file_no], '_'));
 
 					unlink(new_file);
 					transfer_relfile(pageConverter, old_file, new_file,
@@ -225,15 +251,15 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 		snprintf(file_pattern, sizeof(file_pattern), "%u.",
 				 maps[mapnum].old_relfilenode);
 
-		for (fileno = 0; fileno < numFiles; fileno++)
+		for (file_no = 0; file_no < numFiles; file_no++)
 		{
-			if (strncmp(namelist[fileno], file_pattern,
+			if (strncmp(namelist[file_no], file_pattern,
 						strlen(file_pattern)) == 0)
 			{
 				snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
-						 namelist[fileno]);
+						 namelist[file_no]);
 				snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
-						 maps[mapnum].new_relfilenode, strchr(namelist[fileno], '.'));
+						 maps[mapnum].new_relfilenode, strchr(namelist[file_no], '.'));
 
 				unlink(new_file);
 				transfer_relfile(pageConverter, old_file, new_file,
@@ -244,8 +270,8 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 
 	if (numFiles > 0)
 	{
-		for (fileno = 0; fileno < numFiles; fileno++)
-			pg_free(namelist[fileno]);
+		for (file_no = 0; file_no < numFiles; file_no++)
+			pg_free(namelist[file_no]);
 		pg_free(namelist);
 	}
 }