Skip to content

Commit e79e6c4

Browse files
committed
Fix CRC check handling in get_controlfile
The previous patch broke this by returning NULL for a failed CRC check, which pg_controldata would then try to read. Fix by returning the result of the CRC check in a separate argument. Michael Paquier and myself
1 parent 308985b commit e79e6c4

File tree

5 files changed

+32
-38
lines changed

5 files changed

+32
-38
lines changed

src/backend/utils/misc/pg_controldata.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pg_control_system(PG_FUNCTION_ARGS)
3434
TupleDesc tupdesc;
3535
HeapTuple htup;
3636
ControlFileData *ControlFile;
37+
bool crc_ok;
3738

3839
/*
3940
* Construct a tuple descriptor for the result row. This must match this
@@ -51,8 +52,8 @@ pg_control_system(PG_FUNCTION_ARGS)
5152
tupdesc = BlessTupleDesc(tupdesc);
5253

5354
/* read the control file */
54-
ControlFile = get_controlfile(DataDir, NULL);
55-
if (!ControlFile)
55+
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
56+
if (!crc_ok)
5657
ereport(ERROR,
5758
(errmsg("calculated CRC checksum does not match value stored in file")));
5859

@@ -83,6 +84,7 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
8384
ControlFileData *ControlFile;
8485
XLogSegNo segno;
8586
char xlogfilename[MAXFNAMELEN];
87+
bool crc_ok;
8688

8789
/*
8890
* Construct a tuple descriptor for the result row. This must match this
@@ -130,8 +132,8 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
130132
tupdesc = BlessTupleDesc(tupdesc);
131133

132134
/* Read the control file. */
133-
ControlFile = get_controlfile(DataDir, NULL);
134-
if (!ControlFile)
135+
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
136+
if (!crc_ok)
135137
ereport(ERROR,
136138
(errmsg("calculated CRC checksum does not match value stored in file")));
137139

@@ -216,6 +218,7 @@ pg_control_recovery(PG_FUNCTION_ARGS)
216218
TupleDesc tupdesc;
217219
HeapTuple htup;
218220
ControlFileData *ControlFile;
221+
bool crc_ok;
219222

220223
/*
221224
* Construct a tuple descriptor for the result row. This must match this
@@ -235,8 +238,8 @@ pg_control_recovery(PG_FUNCTION_ARGS)
235238
tupdesc = BlessTupleDesc(tupdesc);
236239

237240
/* read the control file */
238-
ControlFile = get_controlfile(DataDir, NULL);
239-
if (!ControlFile)
241+
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
242+
if (!crc_ok)
240243
ereport(ERROR,
241244
(errmsg("calculated CRC checksum does not match value stored in file")));
242245

@@ -268,6 +271,7 @@ pg_control_init(PG_FUNCTION_ARGS)
268271
TupleDesc tupdesc;
269272
HeapTuple htup;
270273
ControlFileData *ControlFile;
274+
bool crc_ok;
271275

272276
/*
273277
* Construct a tuple descriptor for the result row. This must match this
@@ -303,8 +307,8 @@ pg_control_init(PG_FUNCTION_ARGS)
303307
tupdesc = BlessTupleDesc(tupdesc);
304308

305309
/* read the control file */
306-
ControlFile = get_controlfile(DataDir, NULL);
307-
if (!ControlFile)
310+
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
311+
if (!crc_ok)
308312
ereport(ERROR,
309313
(errmsg("calculated CRC checksum does not match value stored in file")));
310314

src/bin/pg_controldata/pg_controldata.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ int
8686
main(int argc, char *argv[])
8787
{
8888
ControlFileData *ControlFile;
89+
bool crc_ok;
8990
char *DataDir = NULL;
9091
time_t time_tmp;
9192
char pgctime_str[128];
@@ -155,8 +156,8 @@ main(int argc, char *argv[])
155156
}
156157

157158
/* get a copy of the control file */
158-
ControlFile = get_controlfile(DataDir, progname);
159-
if (!ControlFile)
159+
ControlFile = get_controlfile(DataDir, progname, &crc_ok);
160+
if (!crc_ok)
160161
printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
161162
"Either the file is corrupt, or it has a different layout than this program\n"
162163
"is expecting. The results below are untrustworthy.\n\n"));

src/bin/pg_ctl/pg_ctl.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,28 +2147,18 @@ static DBState
21472147
get_control_dbstate(void)
21482148
{
21492149
DBState ret;
2150+
bool crc_ok;
2151+
ControlFileData *control_file_data = get_controlfile(pg_data, progname, &crc_ok);
21502152

2151-
for (;;)
2153+
if (!crc_ok)
21522154
{
2153-
ControlFileData *control_file_data = get_controlfile(pg_data, progname);
2154-
2155-
if (control_file_data)
2156-
{
2157-
ret = control_file_data->state;
2158-
pfree(control_file_data);
2159-
return ret;
2160-
}
2161-
2162-
if (wait_seconds > 0)
2163-
{
2164-
pg_usleep(1000000); /* 1 sec */
2165-
wait_seconds--;
2166-
continue;
2167-
}
2168-
21692155
write_stderr(_("%s: control file appears to be corrupt\n"), progname);
21702156
exit(1);
21712157
}
2158+
2159+
ret = control_file_data->state;
2160+
pfree(control_file_data);
2161+
return ret;
21722162
}
21732163

21742164

src/common/controldata_utils.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,24 @@
2929
#include "port/pg_crc32c.h"
3030

3131
/*
32-
* get_controlfile(char *DataDir, const char *progname)
32+
* get_controlfile(char *DataDir, const char *progname, bool *crc_ok_p)
3333
*
34-
* Get controlfile values. The caller is responsible
35-
* for pfreeing the result.
34+
* Get controlfile values. The result is returned as a palloc'd copy of the
35+
* control file data.
3636
*
37-
* Returns NULL if the CRC did not match.
37+
* crc_ok_p can be used by the caller to see whether the CRC of the control
38+
* file data is correct.
3839
*/
3940
ControlFileData *
40-
get_controlfile(const char *DataDir, const char *progname)
41+
get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p)
4142
{
4243
ControlFileData *ControlFile;
4344
int fd;
4445
char ControlFilePath[MAXPGPATH];
4546
pg_crc32c crc;
4647

48+
AssertArg(crc_ok_p);
49+
4750
ControlFile = palloc(sizeof(ControlFileData));
4851
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
4952

@@ -83,11 +86,7 @@ get_controlfile(const char *DataDir, const char *progname)
8386
offsetof(ControlFileData, crc));
8487
FIN_CRC32C(crc);
8588

86-
if (!EQ_CRC32C(crc, ControlFile->crc))
87-
{
88-
pfree(ControlFile);
89-
return NULL;
90-
}
89+
*crc_ok_p = EQ_CRC32C(crc, ControlFile->crc);
9190

9291
/* Make sure the control file is valid byte order. */
9392
if (ControlFile->pg_control_version % 65536 == 0 &&

src/include/common/controldata_utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212

1313
#include "catalog/pg_control.h"
1414

15-
extern ControlFileData *get_controlfile(const char *DataDir, const char *progname);
15+
extern ControlFileData *get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p);
1616

1717
#endif /* COMMON_CONTROLDATA_UTILS_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy