diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-08-03 15:32:06 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-08-03 15:32:06 +0300 |
commit | 0e42397f42b370798461cbf3358185b520329f9f (patch) | |
tree | 177fc0f77ba659163ac64f2778d44296724db31a /src/bin/pg_rewind/filemap.c | |
parent | 69b7a35c9ad8d8a467b5be5ab6ab2db7935e9b28 (diff) | |
download | postgresql-0e42397f42b370798461cbf3358185b520329f9f.tar.gz postgresql-0e42397f42b370798461cbf3358185b520329f9f.zip |
Fix pg_rewind when pg_xlog is a symlink.
pg_xlog is often a symlink, typically to a different filesystem. Don't
get confused and comlain about by that, and just always pretend that it's a
normal directory, even if it's really a symlink.
Also add a test case for this.
Backpatch to 9.5.
Diffstat (limited to 'src/bin/pg_rewind/filemap.c')
-rw-r--r-- | src/bin/pg_rewind/filemap.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c index 05eff68185e..fb26d093160 100644 --- a/src/bin/pg_rewind/filemap.c +++ b/src/bin/pg_rewind/filemap.c @@ -79,6 +79,14 @@ process_source_file(const char *path, file_type_t type, size_t newsize, return; /* + * Pretend that pg_xlog is a directory, even if it's really a symlink. + * We don't want to mess with the symlink itself, nor complain if it's a + * symlink in source but not in target or vice versa. + */ + if (strcmp(path, "pg_xlog") == 0 && type == FILE_TYPE_SYMLINK) + type = FILE_TYPE_DIRECTORY; + + /* * Skip temporary files, .../pgsql_tmp/... and .../pgsql_tmp.* in source. * This has the effect that all temporary files in the destination will be * removed. @@ -112,7 +120,7 @@ process_source_file(const char *path, file_type_t type, size_t newsize, switch (type) { case FILE_TYPE_DIRECTORY: - if (exists && !S_ISDIR(statbuf.st_mode)) + if (exists && !S_ISDIR(statbuf.st_mode) && strcmp(path, "pg_xlog") != 0) { /* it's a directory in source, but not in target. Strange.. */ pg_fatal("\"%s\" is not a directory\n", localpath); @@ -285,6 +293,12 @@ process_target_file(const char *path, file_type_t type, size_t oldsize, strcmp(path, "postmaster.opts") == 0) return; + /* + * Like in process_source_file, pretend that xlog is always a directory. + */ + if (strcmp(path, "pg_xlog") == 0 && type == FILE_TYPE_SYMLINK) + type = FILE_TYPE_DIRECTORY; + key.path = (char *) path; key_ptr = &key; exists = (bsearch(&key_ptr, map->array, map->narray, sizeof(file_entry_t *), |