aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMagnus Hagander <magnus@hagander.net>2016-11-07 14:47:30 +0100
committerMagnus Hagander <magnus@hagander.net>2016-11-07 15:03:56 +0100
commit6d779e05a03d2c06433b71b76f9b0168d47d1a3e (patch)
tree6430e5c893b9efeeb5e89edb47275fa735fb27d2 /src
parentabdc839985a396cb8516a9131e75f602ae277d27 (diff)
downloadpostgresql-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.c48
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.