1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-05-22 10:15:16 +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
@@ -53,7 +53,7 @@ Create a pg_control file
}, \
.blcksz = pgControl.pageSize, \
.xlog_seg_size = pgControl.walSegmentSize, \
.data_checksum_version = pgControl.pageChecksum, \
.data_checksum_version = pgControl.pageChecksumVersion, \
}; \
\
((ControlFileData *)buffer)->crc = \
+8 -7
View File
@@ -1570,7 +1570,7 @@ testRun(void)
TEST_TITLE("ok if cluster checksums are enabled and checksum-page is any value");
// Create pg_control with page checksums
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_94, .pageChecksum = true);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_94, .pageChecksumVersion = 1);
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
@@ -2700,7 +2700,7 @@ testRun(void)
{
// Update pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksum = true, .walSegmentSize = 1024 * 1024);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksumVersion = 1, .walSegmentSize = 1024 * 1024);
// Update version
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, PG_VERSION_11_Z, .timeModified = backupTimeStart);
@@ -3025,7 +3025,7 @@ testRun(void)
// Create pg_control with unexpected catalog and control version
HRN_PG_CONTROL_OVERRIDE_VERSION_PUT(
storagePgWrite(), PG_VERSION_11, 1501, .catalogVersion = 202211110, .pageChecksum = true,
storagePgWrite(), PG_VERSION_11, 1501, .catalogVersion = 202211110, .pageChecksumVersion = 1,
.walSegmentSize = 1024 * 1024);
// Set to a smaller values than the defaults allow
@@ -3123,7 +3123,7 @@ testRun(void)
HRN_STORAGE_REMOVE(storageTest, "pg1");
// Update pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksum = false, .walSegmentSize = 2 * 1024 * 1024);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .walSegmentSize = 2 * 1024 * 1024);
// Update version
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, PG_VERSION_11_Z, .timeModified = backupTimeStart);
@@ -3193,7 +3193,7 @@ testRun(void)
HRN_STORAGE_PATH_REMOVE(storageTest, "pg1", .recurse = true);
// Update pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksum = false, .walSegmentSize = 2 * 1024 * 1024);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksumVersion = 0, .walSegmentSize = 2 * 1024 * 1024);
// Update version
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, PG_VERSION_11_Z, .timeModified = backupTimeStart);
@@ -3276,7 +3276,7 @@ testRun(void)
"P00 INFO: check archive for segment 0000000105DBF06000000000\n"
"P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-grow (24KB, [PCT]) checksum [SHA1]");
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .pageChecksum = false, .walSegmentSize = 2 * 1024 * 1024);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_11, .walSegmentSize = 2 * 1024 * 1024);
// Run backup
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .walSwitch = true);
@@ -3663,7 +3663,8 @@ testRun(void)
// Update pg_control
HRN_PG_CONTROL_PUT(
storagePgWrite(), PG_VERSION_11, .pageChecksum = true, .walSegmentSize = 2 * 1024 * 1024, .pageSize = pgPageSize4);
storagePgWrite(), PG_VERSION_11, .pageChecksumVersion = 1, .walSegmentSize = 2 * 1024 * 1024,
.pageSize = pgPageSize4);
// Update version
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, PG_VERSION_11_Z, .timeModified = backupTimeStart);
+1 -1
View File
@@ -73,7 +73,7 @@ testRun(void)
HRN_CFG_LOAD(cfgCmdStanzaCreate, argList);
// Create pg_control and run stanza-create
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_95, .pageChecksum = false);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_95);
TEST_RESULT_VOID(cmdStanzaCreate(), "stanza create");
}
+1 -1
View File
@@ -3138,7 +3138,7 @@ testRun(void)
const String *repoPath = STRDEF(TEST_PATH "/repo");
// Created pg_control and PG_VERSION
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_15, .pageChecksum = false);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_15);
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, PG_VERSION_15_Z);
// Create encrypted stanza
+11 -3
View File
@@ -134,6 +134,12 @@ testRun(void)
pgControlFromFile(storageTest, NULL), FormatError,
"page size is 65536 but only 1024, 2048, 4096, 8192, 16384, and 32768 are supported");
// -------------------------------------------------------------------------------------------------------------------------
HRN_PG_CONTROL_PUT(storageTest, PG_VERSION_11, .pageChecksumVersion = 2);
TEST_ERROR(
pgControlFromFile(storageTest, NULL), FormatError, "page checksum version is 2 but only 0 and 1 are valid");
// -------------------------------------------------------------------------------------------------------------------------
HRN_PG_CONTROL_PUT(
storageTest, PG_VERSION_94, .systemId = 0xEFEFEFEFEF, .catalogVersion = hrnPgCatalogVersion(PG_VERSION_94),
@@ -146,11 +152,12 @@ testRun(void)
TEST_RESULT_UINT(info.checkpoint, 0xAABBAABBEEFFEEFF, "check checkpoint");
TEST_RESULT_UINT(info.timeline, 88, "check timeline");
TEST_RESULT_UINT(info.pageSize, pgPageSize8, "check page size");
TEST_RESULT_UINT(info.pageChecksumVersion, 0, "check page checksum");
// -------------------------------------------------------------------------------------------------------------------------
HRN_PG_CONTROL_PUT(
storageTest, PG_VERSION_16, .systemId = 0xEFEFEFEFEF, .catalogVersion = hrnPgCatalogVersion(PG_VERSION_16),
.checkpoint = 0xAABBAABBEEFFEEFF, .timeline = 88, .pageSize = pgPageSize1);
.checkpoint = 0xAABBAABBEEFFEEFF, .timeline = 88, .pageSize = pgPageSize1, .pageChecksumVersion = 1);
TEST_ASSIGN(info, pgControlFromFile(storageTest, NULL), "get control info v90");
TEST_RESULT_UINT(info.systemId, 0xEFEFEFEFEF, " check system id");
@@ -159,6 +166,7 @@ testRun(void)
TEST_RESULT_UINT(info.checkpoint, 0xAABBAABBEEFFEEFF, "check checkpoint");
TEST_RESULT_UINT(info.timeline, 88, "check timeline");
TEST_RESULT_UINT(info.pageSize, pgPageSize1, "check page size");
TEST_RESULT_UINT(info.pageChecksumVersion, 1, "check page checksum");
// -------------------------------------------------------------------------------------------------------------------------
HRN_PG_CONTROL_PUT(
@@ -473,12 +481,12 @@ testRun(void)
.version = PG_VERSION_11,
.systemId = 0xEFEFEFEFEF,
.walSegmentSize = 16 * 1024 * 1024,
.pageChecksum = true
.pageChecksumVersion = 1,
};
TEST_RESULT_VOID(FUNCTION_LOG_OBJECT_FORMAT(&pgControl, pgControlToLog, logBuf, sizeof(logBuf)), "pgControlToLog");
TEST_RESULT_Z(
logBuf, "{version: 110000, systemId: 1030522662895, walSegmentSize: 16777216, pageChecksum: true}", "check log");
logBuf, "{version: 110000, systemId: 1030522662895, walSegmentSize: 16777216, pageChecksumVersion: 1}", "check log");
}
// *****************************************************************************************************************************