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
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
/*
* Construct a tuple descriptor for the result row. This must match this
/*
* Construct a tuple descriptor for the result row. This must match this
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
- ControlFile = get_controlfile(DataDir, NULL);
- if (!ControlFile)
+ ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
ControlFileData *ControlFile;
XLogSegNo segno;
char xlogfilename[MAXFNAMELEN];
ControlFileData *ControlFile;
XLogSegNo segno;
char xlogfilename[MAXFNAMELEN];
/*
* Construct a tuple descriptor for the result row. This must match this
/*
* Construct a tuple descriptor for the result row. This must match this
tupdesc = BlessTupleDesc(tupdesc);
/* Read the control file. */
tupdesc = BlessTupleDesc(tupdesc);
/* Read the control file. */
- ControlFile = get_controlfile(DataDir, NULL);
- if (!ControlFile)
+ ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
/*
* Construct a tuple descriptor for the result row. This must match this
/*
* Construct a tuple descriptor for the result row. This must match this
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
- ControlFile = get_controlfile(DataDir, NULL);
- if (!ControlFile)
+ ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
TupleDesc tupdesc;
HeapTuple htup;
ControlFileData *ControlFile;
/*
* Construct a tuple descriptor for the result row. This must match this
/*
* Construct a tuple descriptor for the result row. This must match this
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
- ControlFile = get_controlfile(DataDir, NULL);
- if (!ControlFile)
+ ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
main(int argc, char *argv[])
{
ControlFileData *ControlFile;
main(int argc, char *argv[])
{
ControlFileData *ControlFile;
char *DataDir = NULL;
time_t time_tmp;
char pgctime_str[128];
char *DataDir = NULL;
time_t time_tmp;
char pgctime_str[128];
}
/* get a copy of the control file */
}
/* get a copy of the control file */
- ControlFile = get_controlfile(DataDir, progname);
- if (!ControlFile)
+ ControlFile = get_controlfile(DataDir, progname, &crc_ok);
+ if (!crc_ok)
printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
"Either the file is corrupt, or it has a different layout than this program\n"
"is expecting. The results below are untrustworthy.\n\n"));
printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
"Either the file is corrupt, or it has a different layout than this program\n"
"is expecting. The results below are untrustworthy.\n\n"));
get_control_dbstate(void)
{
DBState ret;
get_control_dbstate(void)
{
DBState ret;
+ bool crc_ok;
+ ControlFileData *control_file_data = get_controlfile(pg_data, progname, &crc_ok);
- ControlFileData *control_file_data = get_controlfile(pg_data, progname);
-
- if (control_file_data)
- {
- ret = control_file_data->state;
- pfree(control_file_data);
- return ret;
- }
-
- if (wait_seconds > 0)
- {
- pg_usleep(1000000); /* 1 sec */
- wait_seconds--;
- continue;
- }
-
write_stderr(_("%s: control file appears to be corrupt\n"), progname);
exit(1);
}
write_stderr(_("%s: control file appears to be corrupt\n"), progname);
exit(1);
}
+
+ ret = control_file_data->state;
+ pfree(control_file_data);
+ return ret;
#include "port/pg_crc32c.h"
/*
#include "port/pg_crc32c.h"
/*
- * get_controlfile(char *DataDir, const char *progname)
+ * get_controlfile(char *DataDir, const char *progname, bool *crc_ok_p)
- * Get controlfile values. The caller is responsible
- * for pfreeing the result.
+ * Get controlfile values. The result is returned as a palloc'd copy of the
+ * control file data.
- * Returns NULL if the CRC did not match.
+ * crc_ok_p can be used by the caller to see whether the CRC of the control
+ * file data is correct.
-get_controlfile(const char *DataDir, const char *progname)
+get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p)
{
ControlFileData *ControlFile;
int fd;
char ControlFilePath[MAXPGPATH];
pg_crc32c crc;
{
ControlFileData *ControlFile;
int fd;
char ControlFilePath[MAXPGPATH];
pg_crc32c crc;
ControlFile = palloc(sizeof(ControlFileData));
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
ControlFile = palloc(sizeof(ControlFileData));
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
offsetof(ControlFileData, crc));
FIN_CRC32C(crc);
offsetof(ControlFileData, crc));
FIN_CRC32C(crc);
- if (!EQ_CRC32C(crc, ControlFile->crc))
- {
- pfree(ControlFile);
- return NULL;
- }
+ *crc_ok_p = EQ_CRC32C(crc, ControlFile->crc);
/* Make sure the control file is valid byte order. */
if (ControlFile->pg_control_version % 65536 == 0 &&
/* Make sure the control file is valid byte order. */
if (ControlFile->pg_control_version % 65536 == 0 &&
#include "catalog/pg_control.h"
#include "catalog/pg_control.h"
-extern ControlFileData *get_controlfile(const char *DataDir, const char *progname);
+extern ControlFileData *get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p);
#endif /* COMMON_CONTROLDATA_UTILS_H */
#endif /* COMMON_CONTROLDATA_UTILS_H */