Skip to content

Commit 6d779e0

Browse files
committed
Fix handling of symlinked pg_stat_tmp and pg_replslot
This was already fixed in HEAD as part of 6ad8ac6 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.
1 parent abdc839 commit 6d779e0

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/backend/replication/basebackup.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static bool sendFile(char *readfilename, char *tarfilename,
5757
static void sendFileWithContent(const char *filename, const char *content);
5858
static void _tarWriteHeader(const char *filename, const char *linktarget,
5959
struct stat * statbuf);
60+
static int64 _tarWriteDir(const char *pathbuf, int basepathlen, struct stat * statbuf,
61+
bool sizeonly);
6062
static void send_int8_string(StringInfoData *buf, int64 intval);
6163
static void SendBackupHeader(List *tablespaces);
6264
static void base_backup_cleanup(int code, Datum arg);
@@ -966,9 +968,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
966968
if ((statrelpath != NULL && strcmp(pathbuf, statrelpath) == 0) ||
967969
strncmp(de->d_name, PG_STAT_TMP_DIR, strlen(PG_STAT_TMP_DIR)) == 0)
968970
{
969-
if (!sizeonly)
970-
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
971-
size += 512;
971+
size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
972972
continue;
973973
}
974974

@@ -978,9 +978,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
978978
*/
979979
if (strcmp(de->d_name, "pg_replslot") == 0)
980980
{
981-
if (!sizeonly)
982-
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
983-
size += 512; /* Size of the header just added */
981+
size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
984982
continue;
985983
}
986984

@@ -991,18 +989,8 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
991989
*/
992990
if (strcmp(pathbuf, "./pg_xlog") == 0)
993991
{
994-
if (!sizeonly)
995-
{
996-
/* If pg_xlog is a symlink, write it as a directory anyway */
997-
#ifndef WIN32
998-
if (S_ISLNK(statbuf.st_mode))
999-
#else
1000-
if (pgwin32_is_junction(pathbuf))
1001-
#endif
1002-
statbuf.st_mode = S_IFDIR | S_IRWXU;
1003-
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
1004-
}
1005-
size += 512; /* Size of the header just added */
992+
/* If pg_xlog is a symlink, write it as a directory anyway */
993+
size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
1006994

1007995
/*
1008996
* Also send archive_status directory (by hackishly reusing
@@ -1244,6 +1232,30 @@ _tarWriteHeader(const char *filename, const char *linktarget,
12441232
pq_putmessage('d', h, 512);
12451233
}
12461234

1235+
/*
1236+
* Write tar header for a directory. If the entry in statbuf is a link then
1237+
* write it as a directory anyway.
1238+
*/
1239+
static int64
1240+
_tarWriteDir(const char *pathbuf, int basepathlen, struct stat * statbuf,
1241+
bool sizeonly)
1242+
{
1243+
if (sizeonly)
1244+
/* Directory headers are always 512 bytes */
1245+
return 512;
1246+
1247+
/* If symlink, write it as a directory anyway */
1248+
#ifndef WIN32
1249+
if (S_ISLNK(statbuf->st_mode))
1250+
#else
1251+
if (pgwin32_is_junction(pathbuf))
1252+
#endif
1253+
statbuf->st_mode = S_IFDIR | S_IRWXU;
1254+
1255+
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, statbuf);
1256+
return 512;
1257+
}
1258+
12471259
/*
12481260
* Increment the network transfer counter by the given number of bytes,
12491261
* and sleep if necessary to comply with the requested network transfer

0 commit comments

Comments
 (0)