*
* src/bin/pg_verify_checksums/pg_verify_checksums.c
*/
+#include "postgres_fe.h"
-#define FRONTEND 1
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
-#include "postgres.h"
#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "getopt_long.h"
+#include "pg_getopt.h"
#include "storage/bufpage.h"
#include "storage/checksum.h"
#include "storage/checksum_impl.h"
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-
-#include "pg_getopt.h"
-
static int64 files = 0;
static int64 blocks = 0;
static const char *progname;
static void
-usage()
+usage(void)
{
printf(_("%s verifies data checksums in a PostgreSQL database cluster.\n\n"), progname);
printf(_("Usage:\n"));
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
}
-static const char *skip[] = {
+static const char *const skip[] = {
"pg_control",
"pg_filenode.map",
"pg_internal.init",
};
static bool
-skipfile(char *fn)
+skipfile(const char *fn)
{
- const char **f;
+ const char *const *f;
if (strcmp(fn, ".") == 0 ||
strcmp(fn, "..") == 0)
}
static void
-scan_file(char *fn, int segmentno)
+scan_file(const char *fn, BlockNumber segmentno)
{
char buf[BLCKSZ];
PageHeader header = (PageHeader) buf;
int f;
- int blockno;
+ BlockNumber blockno;
f = open(fn, O_RDONLY | PG_BINARY);
if (f < 0)
break;
if (r != BLCKSZ)
{
- fprintf(stderr, _("%s: short read of block %d in file \"%s\", got only %d bytes\n"),
+ fprintf(stderr, _("%s: short read of block %u in file \"%s\", got only %d bytes\n"),
progname, blockno, fn, r);
exit(1);
}
blocks++;
/* New pages have no checksum yet */
- if (PageIsNew(buf))
+ if (PageIsNew(header))
continue;
csum = pg_checksum_page(buf, blockno + segmentno * RELSEG_SIZE);
if (csum != header->pd_checksum)
{
if (ControlFile->data_checksum_version == PG_DATA_CHECKSUM_VERSION)
- fprintf(stderr, _("%s: checksum verification failed in file \"%s\", block %d: calculated checksum %X but expected %X\n"),
+ fprintf(stderr, _("%s: checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X\n"),
progname, fn, blockno, csum, header->pd_checksum);
badblocks++;
}
}
static void
-scan_directory(char *basedir, char *subdir)
+scan_directory(const char *basedir, const char *subdir)
{
char path[MAXPGPATH];
DIR *dir;
}
while ((de = readdir(dir)) != NULL)
{
- char fn[MAXPGPATH + 1];
+ char fn[MAXPGPATH];
struct stat st;
if (skipfile(de->d_name))
}
if (S_ISREG(st.st_mode))
{
+ char fnonly[MAXPGPATH];
char *forkpath,
*segmentpath;
- int segmentno = 0;
+ BlockNumber segmentno = 0;
/*
* Cut off at the segment boundary (".") to get the segment number
* fork boundary, to get the relfilenode the file belongs to for
* filtering.
*/
- segmentpath = strchr(de->d_name, '.');
+ strlcpy(fnonly, de->d_name, sizeof(fnonly));
+ segmentpath = strchr(fnonly, '.');
if (segmentpath != NULL)
{
*segmentpath++ = '\0';
}
}
- forkpath = strchr(de->d_name, '_');
+ forkpath = strchr(fnonly, '_');
if (forkpath != NULL)
*forkpath++ = '\0';
- if (only_relfilenode && strcmp(only_relfilenode, de->d_name) != 0)
+ if (only_relfilenode && strcmp(only_relfilenode, fnonly) != 0)
/* Relfilenode not to be included */
continue;
DataDir = optarg;
break;
case 'r':
- if (atoi(optarg) <= 0)
+ if (atoi(optarg) == 0)
{
fprintf(stderr, _("%s: invalid relfilenode specification, must be numeric: %s\n"), progname, optarg);
exit(1);