10000 pg_basebackup: Fix cross-platform tablespace relocation. · postgres/postgres@38214da · GitHub
[go: up one dir, main page]

Skip to content

Commit 38214da

Browse files
committed
pg_basebackup: Fix cross-platform tablespace relocation.
Specifically, when pg_basebackup is invoked with -Tx=y, don't error out if x could plausibly be an absolute path either on Windows or on non-Windows systems. We don't know whether the remote system is running the same OS as the local system, so it's not appropriate to assume that our local rule about absolute pathnames is the same as the rule on the remote system. Patch by me, reviewed by Tom Lane, Andrew Dunstan, and Davinder Singh. Discussion: http://postgr.es/m/CA+TgmoY+jC3YiskomvYKDPK3FbrmsDU7_8+wMHt02HOdJeRb0g@mail.gmail.com
1 parent 5c51afe commit 38214da

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,22 @@ tablespace_list_append(const char *arg)
283283
}
284284

285285
/*
286-
* This check isn't absolutely necessary. But all tablespaces are created
287-
* with absolute directories, so specifying a non-absolute path here would
288-
* just never match, possibly confusing users. It's also good to be
289-
* consistent with the new_dir check.
286+
* All tablespaces are created with absolute directories, so specifying a
287+
* non-absolute path here would just never match, possibly confusing users.
288+
* Since we don't know whether the remote side is Windows or not, and it
289+
* might be different than the local side, permit any path that could be
290+
* absolute under either set of rules.
291+
*
292+
* (There is little practical risk of confusion here, because someone
293+
* running entirely on Linux isn't likely to have a relative path that
294+
* begins with a backslash or something that looks like a drive
295+
* specification. If they do, and they also incorrectly believe that
296+
* a relative path is acceptable here, we'll silently fail to warn them
297+
* of their mistake, and the -T option will just not get applied, same
298+
* as if they'd specified -T for a nonexistent tablespace.)
290299
*/
291-
if (!is_absolute_path(cell->old_dir))
300+
if (!is_nonwindows_absolute_path(cell->old_dir) &&
301+
!is_windows_absolute_path(cell->old_dir))
292302
{
293303
fprintf(stderr, _("%s: old directory is not an absolute path in tablespace mapping: %s\n"),
294304
progname, cell->old_dir);

src/include/port.h

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,28 +75,32 @@ extern void get_parent_directory(char *path);
7575
extern char **pgfnames(const char *path);
7676
extern void pgfnames_cleanup(char **filenames);
7777

78-
/*
79-
* is_absolute_path
80-
*
81-
* By making this a macro we avoid needing to include path.c in libpq.
82-
*/
83-
#ifndef WIN32
84-
#define IS_DIR_SEP(ch) ((ch) == '/')
85-
86-
#define is_absolute_path(filename) \
78+
#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/')
79+
#define is_nonwindows_absolute_path(filename) \
8780
( \
88-
IS_DIR_SEP((filename)[0]) \
81+
IS_NONWINDOWS_DIR_SEP((filename)[0]) \
8982
)
90-
#else
91-
#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
9283

84+
#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
9385
/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */
94-
#define is_absolute_path(filename) \
86+
#define is_windows_absolute_path(filename) \
9587
( \
96-
IS_DIR_SEP((filename)[0]) || \
88+
IS_WINDOWS_DIR_SEP((filename)[0]) || \
9789
(isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \
98-
IS_DIR_SEP((filename)[2])) \
90+
IS_WINDOWS_DIR_SEP((filename)[2])) \
9991
)
92+
93+
/*
94+
* is_absolute_path and IS_DIR_SEP
95+
*
96+
* By using macros here we avoid needing to include path.c in libpq.
97+
*/
98+
#ifndef WIN32
99+
#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch)
100+
#define is_absolute_path(filename) is_nonwindows_absolute_path(filename)
101+
#else
102+
#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch)
103+
#define is_absolute_path(filename) is_windows_absolute_path(filename)
100104
#endif
101105

102106
/* Portable locale initialization (in exec.c) */

0 commit comments

Comments
 (0)
0