From 063c45667ef3ba3c8a23297b07d42edc8653904c Mon Sep 17 00:00:00 2001 From: Matthias van de Meent Date: Wed, 12 Jul 2023 14:08:36 +0200 Subject: [PATCH v5 6/7] Add RM_INVALID, an invalid resource manager The resource manager has ID = 0, thus requiring some special handling in other code. Apart from being generally useful, it is used in future patches to detect the end of wal in lieu of a zero-ed fixed-size xl_tot_len field. --- src/backend/access/transam/xlogreader.c | 13 +++++++++++++ src/bin/pg_waldump/pg_waldump.c | 4 ++-- src/include/access/rmgr.h | 2 +- src/include/access/rmgrlist.h | 1 + src/include/access/xlog_internal.h | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index bebdf1759a..069289847d 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -670,6 +670,19 @@ restart: else { /* XXX: more validation should be done here */ + + /* + * RM_INVALID_ID can be an indication of end-of-WAL, or other signs of + * corruption - that byte should be non-0. + */ + if (record->xl_rmid == RM_INVALID_ID) + { + report_invalid_record(state, + "invalid resource manager id %u at %X/%X", + (uint32) record->xl_rmid, + LSN_FORMAT_ARGS(RecPtr)); + goto err; + } if (total_len < SizeOfXLogRecord) { report_invalid_record(state, diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index fb6a5e76b1..83058d3b47 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -99,7 +99,7 @@ print_rmgr_list(void) { int i; - for (i = 0; i <= RM_MAX_BUILTIN_ID; i++) + for (i = RM_INVALID_ID + 1; i <= RM_MAX_BUILTIN_ID; i++) { printf("%s\n", GetRmgrDesc(i)->rm_name); } @@ -967,7 +967,7 @@ main(int argc, char **argv) else { /* then look for builtin rmgrs */ - for (rmid = 0; rmid <= RM_MAX_BUILTIN_ID; rmid++) + for (rmid = RM_INVALID_ID + 1; rmid <= RM_MAX_BUILTIN_ID; rmid++) { if (pg_strcasecmp(optarg, GetRmgrDesc(rmid)->rm_name) == 0) { diff --git a/src/include/access/rmgr.h b/src/include/access/rmgr.h index 3b6a497e1b..7038ba0833 100644 --- a/src/include/access/rmgr.h +++ b/src/include/access/rmgr.h @@ -41,7 +41,7 @@ typedef enum RmgrIds static inline bool RmgrIdIsBuiltin(int rmid) { - return rmid <= RM_MAX_BUILTIN_ID; + return rmid <= RM_MAX_BUILTIN_ID && rmid != RM_INVALID_ID; } static inline bool diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h index 463bcb67c5..b53d731f56 100644 --- a/src/include/access/rmgrlist.h +++ b/src/include/access/rmgrlist.h @@ -25,6 +25,7 @@ */ /* symbol name, textual name, redo, desc, identify, startup, cleanup, mask, decode */ +PG_RMGR(RM_INVALID_ID, "invalid", NULL, NULL, NULL, NULL, NULL, NULL, NULL) PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, xlog_identify, NULL, NULL, NULL, xlog_decode) PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, xact_identify, NULL, NULL, NULL, xact_decode) PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL, NULL, NULL) diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 9413836a6a..2277b32d05 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD113 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD114 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { -- 2.40.1