1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-05 00:28:52 +02:00

Add validation for page checksum version in pg_control.

This serves as an additional sanity check to be sure the pg_control format is as expected. The field is useful for being all the way at the end and being four bytes that can only have one of two values. Something more distinctive than 0 and 1 would be better, but this is what we have to work with.

Convert PgControl.pageChecksum to unsigned int and rename to PgControl.pageChecksumVersion and make all downstream changes required for the new datatype.
This commit is contained in:
David Steele
2024-03-10 15:50:10 +13:00
parent 7448fde157
commit 63541b2273
10 changed files with 44 additions and 19 deletions

View File

@ -276,6 +276,14 @@ pgControlFromBuffer(const Buffer *controlFile, const String *const pgVersionForc
// Check the page size
pgPageSizeCheck(result.pageSize);
// Check the checksum version
if (result.pageChecksumVersion != 0 && result.pageChecksumVersion != PG_DATA_CHECKSUM_VERSION)
{
THROW_FMT(
FormatError, "page checksum version is %u but only 0 and " STRINGIFY(PG_DATA_CHECKSUM_VERSION) " are valid",
result.pageChecksumVersion);
}
FUNCTION_LOG_RETURN(PG_CONTROL, result);
}
@ -700,8 +708,8 @@ FN_EXTERN void
pgControlToLog(const PgControl *const pgControl, StringStatic *const debugLog)
{
strStcFmt(
debugLog, "{version: %u, systemId: %" PRIu64 ", walSegmentSize: %u, pageChecksum: %s}", pgControl->version,
pgControl->systemId, pgControl->walSegmentSize, cvtBoolToConstZ(pgControl->pageChecksum));
debugLog, "{version: %u, systemId: %" PRIu64 ", walSegmentSize: %u, pageChecksumVersion: %u}", pgControl->version,
pgControl->systemId, pgControl->walSegmentSize, pgControl->pageChecksumVersion);
}
FN_EXTERN void

View File

@ -109,7 +109,7 @@ typedef struct PgControl
PgPageSize pageSize;
unsigned int walSegmentSize;
bool pageChecksum;
unsigned int pageChecksumVersion; // Page checksum version (0 if no checksum, 1 if checksum)
} PgControl;
/***********************************************************************************************************************************

View File

@ -124,6 +124,14 @@ typedef struct
uint32 xrecoff; /* low bits */
} PageXLogRecPtr;
// PG_DATA_CHECKSUM_VERSION define
// ---------------------------------------------------------------------------------------------------------------------------------
/*
* As of Release 9.3, the checksum version must also be considered when
* handling pages.
*/
#define PG_DATA_CHECKSUM_VERSION 1
// PageHeaderData type
// ---------------------------------------------------------------------------------------------------------------------------------
/*

View File

@ -70,7 +70,7 @@ Read the version specific pg_control into a general data structure
.timeline = ((ControlFileData *)controlFile)->checkPointCopy.ThisTimeLineID, \
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
.pageChecksum = ((ControlFileData *)controlFile)->data_checksum_version != 0, \
.pageChecksumVersion = ((ControlFileData *)controlFile)->data_checksum_version, \
}; \
}