diff options
author | Magnus Hagander <magnus@hagander.net> | 2016-11-07 14:47:30 +0100 |
---|---|---|
committer | Magnus Hagander <magnus@hagander.net> | 2016-11-07 15:03:56 +0100 |
commit | 6d779e05a03d2c06433b71b76f9b0168d47d1a3e (patch) | |
tree | 6430e5c893b9efeeb5e89edb47275fa735fb27d2 /src | |
parent | abdc839985a396cb8516a9131e75f602ae277d27 (diff) | |
download | postgresql-6d779e05a03d2c06433b71b76f9b0168d47d1a3e.tar.gz postgresql-6d779e05a03d2c06433b71b76f9b0168d47d1a3e.zip |
Fix handling of symlinked pg_stat_tmp and pg_replslot
This was already fixed in HEAD as part of 6ad8ac60 but was not
backpatched.
Also change the way pg_xlog is handled to be the same as the other
directories.
Patch from me with pg_xlog addition from Michael Paquier, test updates
from David Steele.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/replication/basebackup.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 6120c8f6db3..901a65c51ca 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -57,6 +57,8 @@ static bool sendFile(char *readfilename, char *tarfilename, static void sendFileWithContent(const char *filename, const char *content); static void _tarWriteHeader(const char *filename, const char *linktarget, struct stat * statbuf); +static int64 _tarWriteDir(const char *pathbuf, int basepathlen, struct stat * statbuf, + bool sizeonly); static void send_int8_string(StringInfoData *buf, int64 intval); static void SendBackupHeader(List *tablespaces); static void base_backup_cleanup(int code, Datum arg); @@ -966,9 +968,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces, if ((statrelpath != NULL && strcmp(pathbuf, statrelpath) == 0) || strncmp(de->d_name, PG_STAT_TMP_DIR, strlen(PG_STAT_TMP_DIR)) == 0) { - if (!sizeonly) - _tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf); - size += 512; + size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly); continue; } @@ -978,9 +978,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces, */ if (strcmp(de->d_name, "pg_replslot") == 0) { - if (!sizeonly) - _tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf); - size += 512; /* Size of the header just added */ + size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly); continue; } @@ -991,18 +989,8 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces, */ if (strcmp(pathbuf, "./pg_xlog") == 0) { - if (!sizeonly) - { - /* If pg_xlog is a symlink, write it as a directory anyway */ -#ifndef WIN32 - if (S_ISLNK(statbuf.st_mode)) -#else - if (pgwin32_is_junction(pathbuf)) -#endif - statbuf.st_mode = S_IFDIR | S_IRWXU; - _tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf); - } - size += 512; /* Size of the header just added */ + /* If pg_xlog is a symlink, write it as a directory anyway */ + size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly); /* * Also send archive_status directory (by hackishly reusing @@ -1245,6 +1233,30 @@ _tarWriteHeader(const char *filename, const char *linktarget, } /* + * Write tar header for a directory. If the entry in statbuf is a link then + * write it as a directory anyway. + */ +static int64 +_tarWriteDir(const char *pathbuf, int basepathlen, struct stat * statbuf, + bool sizeonly) +{ + if (sizeonly) + /* Directory headers are always 512 bytes */ + return 512; + + /* If symlink, write it as a directory anyway */ +#ifndef WIN32 + if (S_ISLNK(statbuf->st_mode)) +#else + if (pgwin32_is_junction(pathbuf)) +#endif + statbuf->st_mode = S_IFDIR | S_IRWXU; + + _tarWriteHeader(pathbuf + basepathlen + 1, NULL, statbuf); + return 512; +} + +/* * Increment the network transfer counter by the given number of bytes, * and sleep if necessary to comply with the requested network transfer * rate. |