Skip to content

Commit b6a323a

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 3af8467 commit b6a323a

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
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);
@@ -969,9 +971,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
969971
if ((statrelpath != NULL && strcmp(pathbuf, statrelpath) == 0) ||
970972
strncmp(de->d_name, PG_STAT_TMP_DIR, strlen(PG_STAT_TMP_DIR)) == 0)
971973
{
972-
if (!sizeonly)
973-
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
974-
size += 512;
974+
size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
975975
continue;
976976
}
977977

@@ -981,9 +981,7 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
981981
*/
982982
if (strcmp(de->d_name, "pg_replslot") == 0)
983983
{
984-
if (!sizeonly)
985-
_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
986-
size += 512; /* Size of the header just added */
984+
size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
987985
continue;
988986
}
989987

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

1010998
/*
1011999
* Also send archive_status directory (by hackishly reusing
@@ -1247,6 +1235,30 @@ _tarWriteHeader(const char *filename, const char *linktarget,
12471235
pq_putmessage('d', h, 512);
12481236
}
12491237

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

src/bin/pg_basebackup/t/010_pg_basebackup.pl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use Config;
55
use PostgresNode;
66
use TestLib;
7-
use Test::More tests => 51;
7+
use Test::More tests => 52;
88

99
program_help_ok('pg_basebackup');
1010
program_version_ok('pg_basebackup');
@@ -102,7 +102,17 @@
102102
# skip on Windows.
103103
SKIP:
104104
{
105-
skip "symlinks not supported on Windows", 10 if ($windows_os);
105+
skip "symlinks not supported on Windows", 11 if ($windows_os);
106+
107+
# Move pg_replslot out of $pgdata and create a symlink to it.
108+
$node->stop;
109+
110+
rename("$pgdata/pg_replslot", "$tempdir/pg_replslot")
111+
or BAIL_OUT "could not move $pgdata/pg_replslot";
112+
symlink("$tempdir/pg_replslot", "$pgdata/pg_replslot")
113+
or BAIL_OUT "could not symlink to $pgdata/pg_replslot";
114+
115+
$node->start;
106116

107117
# Create a temporary directory in the system location and symlink it
108118
# to our physical temp location. That way we can use shorter names
@@ -140,6 +150,8 @@
140150
"tablespace symlink was updated");
141151
closedir $dh;
142152

153+
ok(-d "$tempdir/backup1/pg_replslot", 'pg_replslot symlink copied as directory');
154+
143155
mkdir "$tempdir/tbl=spc2";
144156
$node->safe_psql('postgres', "DROP TABLE test1;");
145157
$node->safe_psql('postgres', "DROP TABLESPACE tblspc1;");

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy