From 85036308dc5871b1d41e4292fa089d3809963252 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 30 Nov 2018 10:15:06 +0900 Subject: [PATCH] Switch pg_verify_checksums back to a blacklist This basically reverts commit d55241af705667d4503638e3f77d3689fd6be31, leaving around a portion of the regression tests still adapted with empty relation files, and corrupted cases. This is also proving to be failing to check properly relation files located in a non-default tablespace path. Per discussion with various folks, including Stephen Frost, David Steele, Andres Freund, Michael Banck and myself. Reported-by: Michael Banck Discussion: https://postgr.es/m/20181021134206.GA14282@paquier.xyz Backpatch-through: 11 --- .../pg_verify_checksums/pg_verify_checksums.c | 79 +++++-------------- 1 file changed, 18 insertions(+), 61 deletions(-) diff --git a/src/bin/pg_verify_checksums/pg_verify_checksums.c b/src/bin/pg_verify_checksums/pg_verify_checksums.c index 36d11ab563..589a3cc589 100644 --- a/src/bin/pg_verify_checksums/pg_verify_checksums.c +++ b/src/bin/pg_verify_checksums/pg_verify_checksums.c @@ -15,7 +15,6 @@ #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" @@ -50,69 +49,27 @@ usage(void) printf(_("Report bugs to .\n")); } -/* - * isRelFileName - * - * Check if the given file name is authorized for checksum verification. - */ +static const char *const skip[] = { + "pg_control", + "pg_filenode.map", + "pg_internal.init", + "PG_VERSION", + NULL, +}; + static bool -isRelFileName(const char *fn) +skipfile(const char *fn) { - int pos; - - /*---------- - * Only files including data checksums are authorized for verification. - * This is guessed based on the file name by reverse-engineering - * GetRelationPath() so make sure to update both code paths if any - * updates are done. The following file name formats are allowed: - * - * . - * _ - * _. - * - * Note that temporary files, beginning with 't', are also skipped. - * - *---------- - */ - - /* A non-empty string of digits should follow */ - for (pos = 0; isdigit((unsigned char) fn[pos]); ++pos) - ; - /* leave if no digits */ - if (pos == 0) - return false; - /* good to go if only digits */ - if (fn[pos] == '\0') - return true; - - /* Authorized fork files can be scanned */ - if (fn[pos] == '_') - { - int forkchar = forkname_chars(&fn[pos + 1], NULL); - - if (forkchar <= 0) - return false; + const char *const *f; - pos += forkchar + 1; - } - - /* Check for an optional segment number */ - if (fn[pos] == '.') - { - int segchar; - - for (segchar = 1; isdigit((unsigned char) fn[pos + segchar]); ++segchar) - ; - - if (segchar <= 1) - return false; - pos += segchar; - } + if (strcmp(fn, ".") == 0 || + strcmp(fn, "..") == 0) + return true; - /* Now this should be the end */ - if (fn[pos] != '\0') - return false; - return true; + for (f = skip; *f; f++) + if (strcmp(*f, fn) == 0) + return true; + return false; } static void @@ -189,7 +146,7 @@ scan_directory(const char *basedir, const char *subdir) char fn[MAXPGPATH]; struct stat st; - if (!isRelFileName(de->d_name)) + if (skipfile(de->d_name)) continue; snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name); -- 2.40.0