Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+30-18
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

+14-2
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)