7
7
*
8
8
* src/bin/pg_verify_checksums/pg_verify_checksums.c
9
9
*/
10
+ #include "postgres_fe.h"
10
11
11
- #define FRONTEND 1
12
+ #include <dirent.h>
13
+ #include <sys/stat.h>
14
+ #include <unistd.h>
12
15
13
- #include "postgres.h"
14
16
#include "catalog/pg_control.h"
15
17
#include "common/controldata_utils.h"
16
18
#include "getopt_long.h"
19
+ #include "pg_getopt.h"
17
20
#include "storage/bufpage.h"
18
21
#include "storage/checksum.h"
19
22
#include "storage/checksum_impl.h"
20
23
21
- #include <sys/stat.h>
22
- #include <dirent.h>
23
- #include <unistd.h>
24
-
25
- #include "pg_getopt.h"
26
-
27
24
28
25
static int64 files = 0 ;
29
26
static int64 blocks = 0 ;
@@ -36,7 +33,7 @@ static bool verbose = false;
36
33
static const char * progname ;
37
34
38
35
static void
39
- usage ()
36
+ usage (void )
40
37
{
41
38
printf (_ ("%s verifies data checksums in a PostgreSQL database cluster.\n\n" ), progname );
42
39
printf (_ ("Usage:\n" ));
@@ -52,7 +49,7 @@ usage()
52
49
printf (_ ("Report bugs to <pgsql-bugs@postgresql.org>.\n" ));
53
50
}
54
51
55
- static const char * skip [] = {
52
+ static const char * const skip [] = {
56
53
"pg_control" ,
57
54
"pg_filenode.map" ,
58
55
"pg_internal.init" ,
@@ -61,9 +58,9 @@ static const char *skip[] = {
61
58
};
62
59
63
60
static bool
64
- skipfile (char * fn )
61
+ skipfile (const char * fn )
65
62
{
66
- const char * * f ;
63
+ const char * const * f ;
67
64
68
65
if (strcmp (fn , "." ) == 0 ||
69
66
strcmp (fn , ".." ) == 0 )
@@ -76,12 +73,12 @@ skipfile(char *fn)
76
73
}
77
74
78
75
static void
79
- scan_file (char * fn , int segmentno )
76
+ scan_file (const char * fn , BlockNumber segmentno )
80
77
{
81
78
char buf [BLCKSZ ];
82
79
PageHeader header = (PageHeader ) buf ;
83
80
int f ;
84
- int blockno ;
81
+ BlockNumber blockno ;
85
82
86
83
f = open (fn , O_RDONLY | PG_BINARY );
87
84
if (f < 0 )
@@ -102,21 +99,21 @@ scan_file(char *fn, int segmentno)
102
99
break ;
103
100
if (r != BLCKSZ )
104
101
{
105
- fprintf (stderr , _ ("%s: short read of block %d in file \"%s\", got only %d bytes\n" ),
102
+ fprintf (stderr , _ ("%s: short read of block %u in file \"%s\", got only %d bytes\n" ),
106
103
progname , blockno , fn , r );
107
104
exit (1 );
108
105
}
109
106
blocks ++ ;
110
107
111
108
/* New pages have no checksum yet */
112
- if (PageIsNew (buf ))
109
+ if (PageIsNew (header ))
113
110
continue ;
114
111
115
112
csum = pg_checksum_page (buf , blockno + segmentno * RELSEG_SIZE );
116
113
if (csum != header -> pd_checksum )
117
114
{
118
115
if (ControlFile -> data_checksum_version == PG_DATA_CHECKSUM_VERSION )
119
- fprintf (stderr , _ ("%s: checksum verification failed in file \"%s\", block %d : calculated checksum %X but expected %X\n" ),
116
+ fprintf (stderr , _ ("%s: checksum verification failed in file \"%s\", block %u : calculated checksum %X but block contains %X\n" ),
120
117
progname , fn , blockno , csum , header -> pd_checksum );
121
118
badblocks ++ ;
122
119
}
@@ -130,7 +127,7 @@ scan_file(char *fn, int segmentno)
130
127
}
131
128
132
129
static void
133
- scan_directory (char * basedir , char * subdir )
130
+ scan_directory (const char * basedir , const char * subdir )
134
131
{
135
132
char path [MAXPGPATH ];
136
133
DIR * dir ;
@@ -146,7 +143,7 @@ scan_directory(char *basedir, char *subdir)
146
143
}
147
144
while ((de = readdir (dir )) != NULL )
148
145
{
149
- char fn [MAXPGPATH + 1 ];
146
+ char fn [MAXPGPATH ];
150
147
struct stat st ;
151
148
152
149
if (skipfile (de -> d_name ))
@@ -161,17 +158,19 @@ scan_directory(char *basedir, char *subdir)
161
158
}
162
159
if (S_ISREG (st .st_mode ))
163
160
{
161
+ char fnonly [MAXPGPATH ];
164
162
char * forkpath ,
165
163
* segmentpath ;
166
- int segmentno = 0 ;
164
+ BlockNumber segmentno = 0 ;
167
165
168
166
/*
169
167
* Cut off at the segment boundary (".") to get the segment number
170
168
* in order to mix it into the checksum. Then also cut off at the
171
169
* fork boundary, to get the relfilenode the file belongs to for
172
170
* filtering.
173
171
*/
174
- segmentpath = strchr (de -> d_name , '.' );
172
+ strlcpy (fnonly , de -> d_name , sizeof (fnonly ));
173
+ segmentpath = strchr (fnonly , '.' );
175
174
if (segmentpath != NULL )
176
175
{
177
176
* segmentpath ++ = '\0' ;
@@ -184,11 +183,11 @@ scan_directory(char *basedir, char *subdir)
184
183
}
185
184
}
186
185
187
- forkpath = strchr (de -> d_name , '_' );
186
+ forkpath = strchr (fnonly , '_' );
188
187
if (forkpath != NULL )
189
188
* forkpath ++ = '\0' ;
190
189
191
- if (only_relfilenode && strcmp (only_relfilenode , de -> d_name ) != 0 )
190
+ if (only_relfilenode && strcmp (only_relfilenode , fnonly ) != 0 )
192
191
/* Relfilenode not to be included */
193
192
continue ;
194
193
@@ -247,7 +246,7 @@ main(int argc, char *argv[])
247
246
DataDir = optarg ;
248
247
break ;
249
248
case 'r' :
250
- if (atoi (optarg ) < = 0 )
249
+ if (atoi (optarg ) = = 0 )
251
250
{
252
251
fprintf (stderr , _ ("%s: invalid relfilenode specification, must be numeric: %s\n" ), progname , optarg );
253
252
exit (1 );
0 commit comments