From 49d65d0b063f1bdca9276caa511c177fef5953fd Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Tue, 20 Oct 2026 20:01:11 +0900 Subject: [PATCH v4 4/4] Use pg_parse_lsn() for reading backup label read_backup_label() parsed several WAL positions on the label file with fscanf("%X/%08X"). This commit convert to use the common LSN parser. --- src/backend/access/transam/xlogrecovery.c | 23 ++++++++++++++--------- src/backend/utils/adt/pg_lsn.c | 2 -- src/include/common/pg_parse_lsn.h | 2 ++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index 20be788da78..7c9c6acf1d2 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -44,6 +44,7 @@ #include "catalog/pg_control.h" #include "commands/tablespace.h" #include "common/file_utils.h" +#include "common/pg_parse_lsn.h" #include "miscadmin.h" #include "nodes/miscnodes.h" #include "pgstat.h" @@ -1190,8 +1191,7 @@ read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI, char backupfrom[20]; char backuplabel[MAXPGPATH]; char backuptime[128]; - uint32 hi, - lo; + char lsn[MAXPG_LSNLEN + 1]; /* suppress possible uninitialized-variable warnings */ *checkPointLoc = InvalidXLogRecPtr; @@ -1218,19 +1218,23 @@ read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI, * is pretty crude, but we are not expecting any variability in the file * format). */ - if (fscanf(lfp, "START WAL LOCATION: %X/%08X (file %08X%16s)%c", - &hi, &lo, &tli_from_walseg, startxlogfilename, &ch) != 5 || ch != '\n') + if (fscanf(lfp, + "START WAL LOCATION: %" CppAsString2(MAXPG_LSNLEN) "s (file %08X%16s)%c", + lsn, &tli_from_walseg, startxlogfilename, &ch) != 4 || + ch != '\n' || + !pg_parse_lsn(lsn, &RedoStartLSN)) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); - RedoStartLSN = ((uint64) hi) << 32 | lo; RedoStartTLI = tli_from_walseg; - if (fscanf(lfp, "CHECKPOINT LOCATION: %X/%08X%c", - &hi, &lo, &ch) != 3 || ch != '\n') + if (fscanf(lfp, + "CHECKPOINT LOCATION: %" CppAsString2(MAXPG_LSNLEN) "s%c", lsn, + &ch) != 2 || + ch != '\n' || + !pg_parse_lsn(lsn, checkPointLoc)) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); - *checkPointLoc = ((uint64) hi) << 32 | lo; *backupLabelTLI = tli_from_walseg; /* @@ -1297,7 +1301,8 @@ read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI, tli_from_file, BACKUP_LABEL_FILE))); } - if (fscanf(lfp, "INCREMENTAL FROM LSN: %X/%08X\n", &hi, &lo) > 0) + if (fscanf(lfp, "INCREMENTAL FROM LSN: %" CppAsString2(MAXPG_LSNLEN) "s\n", + lsn) > 0) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("this is an incremental backup, not a data directory"), diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index 7886e9b83e8..3ec2c2b650e 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -19,8 +19,6 @@ #include "utils/numeric.h" #include "utils/pg_lsn.h" -#define MAXPG_LSNLEN 17 - /*---------------------------------------------------------- * Formatting and conversion routines. *---------------------------------------------------------*/ diff --git a/src/include/common/pg_parse_lsn.h b/src/include/common/pg_parse_lsn.h index 0a80785a4e9..85cda67bce9 100644 --- a/src/include/common/pg_parse_lsn.h +++ b/src/include/common/pg_parse_lsn.h @@ -15,6 +15,8 @@ #include "access/xlogdefs.h" +#define MAXPG_LSNLEN 17 + extern bool pg_parse_lsn(const char *str, XLogRecPtr *result); #endif /* PG_PARSE_LSN_H */ -- 2.52.0