mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-03 09:26:51 +02:00
Skip foreign tablespaces when running pg_checksums/pg_verify_checksums
Attempting to use pg_checksums (pg_verify_checksums in 11) on a data folder which includes tablespace paths used across multiple major versions would cause pg_checksums to scan all directories present in pg_tblspc, and not only marked with TABLESPACE_VERSION_DIRECTORY. This could lead to failures when for example running sanity checks on an upgraded instance with --check. Even worse, it was possible to rewrite on-disk pages with --enable for a cluster potentially online. This commit makes pg_checksums skip any directories not named TABLESPACE_VERSION_DIRECTORY, similarly to what is done for base backups. Reported-by: Michael Banck Author: Michael Banck, Bernd Helmle Discussion: https://postgr.es/m/62031974fd8e941dd8351fbc8c7eff60d59c5338.camel@credativ.de backpatch-through: 11
This commit is contained in:
parent
83bd732eb2
commit
8f9aba1874
@ -15,6 +15,7 @@
|
||||
|
||||
#include "catalog/pg_control.h"
|
||||
#include "common/controldata_utils.h"
|
||||
#include "common/relpath.h"
|
||||
#include "getopt_long.h"
|
||||
#include "pg_getopt.h"
|
||||
#include "storage/bufpage.h"
|
||||
@ -238,7 +239,51 @@ scan_directory(const char *basedir, const char *subdir)
|
||||
#else
|
||||
else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn))
|
||||
#endif
|
||||
scan_directory(path, de->d_name);
|
||||
{
|
||||
/*
|
||||
* If going through the entries of pg_tblspc, we assume to operate
|
||||
* on tablespace locations where only TABLESPACE_VERSION_DIRECTORY
|
||||
* is valid, resolving the linked locations and dive into them
|
||||
* directly.
|
||||
*/
|
||||
if (strncmp("pg_tblspc", subdir, strlen("pg_tblspc")) == 0)
|
||||
{
|
||||
char tblspc_path[MAXPGPATH];
|
||||
struct stat tblspc_st;
|
||||
|
||||
/*
|
||||
* Resolve tablespace location path and check whether
|
||||
* TABLESPACE_VERSION_DIRECTORY exists. Not finding a valid
|
||||
* location is unexpected, since there should be no orphaned
|
||||
* links and no links pointing to something else than a
|
||||
* directory.
|
||||
*/
|
||||
snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s/%s",
|
||||
path, de->d_name, TABLESPACE_VERSION_DIRECTORY);
|
||||
|
||||
if (lstat(tblspc_path, &tblspc_st) < 0)
|
||||
{
|
||||
fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
|
||||
progname, tblspc_path, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move backwards once as the scan needs to happen for the
|
||||
* contents of TABLESPACE_VERSION_DIRECTORY.
|
||||
*/
|
||||
snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s",
|
||||
path, de->d_name);
|
||||
|
||||
/* Looks like a valid tablespace location */
|
||||
scan_directory(tblspc_path,
|
||||
TABLESPACE_VERSION_DIRECTORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
scan_directory(path, de->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user