From 9edccd3ba669951b064ba0c6f46a62dd93f5e3f9 Mon Sep 17 00:00:00 2001
From: Imran Zaheer <imran.zhir@gmail.com>
Date: Thu, 4 Jun 2026 17:08:27 +0500
Subject: [PATCH v1] Move system identifier generation to a common helper

The code used to generate a new system identifier is duplicated in
multiple locations, including BootStrapXLOG(), pg_createsubscriber and
pg_resetwal.

Move the implementation to a common GenerateSystemIdentifier() helper
and update existing callers to use it. This allows both backend and
frontend code to share a single implementation of the system identifier
generation algorithm.
---
 src/backend/access/transam/xlog.c           | 20 +-------
 src/bin/pg_basebackup/pg_createsubscriber.c |  9 +---
 src/bin/pg_resetwal/pg_resetwal.c           | 14 ++----
 src/common/Makefile                         |  1 +
 src/common/meson.build                      |  1 +
 src/common/system_identifier.c              | 56 +++++++++++++++++++++
 src/include/common/system_identifier.h      | 19 +++++++
 7 files changed, 84 insertions(+), 36 deletions(-)
 create mode 100644 src/common/system_identifier.c
 create mode 100644 src/include/common/system_identifier.h

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index d69d03b2ef3..0d2a49172e4 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -43,7 +43,6 @@
 #include <time.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <unistd.h>
 
 #include "access/clog.h"
@@ -69,6 +68,7 @@
 #include "catalog/pg_database.h"
 #include "common/controldata_utils.h"
 #include "common/file_utils.h"
+#include "common/system_identifier.h"
 #include "executor/instrument.h"
 #include "miscadmin.h"
 #include "pg_trace.h"
@@ -5460,28 +5460,12 @@ BootStrapXLOG(uint32 data_checksum_version)
 	XLogRecord *record;
 	char	   *recptr;
 	uint64		sysidentifier;
-	struct timeval tv;
 	pg_crc32c	crc;
 
 	/* allow ordinary WAL segment creation, like StartupXLOG() would */
 	SetInstallXLogFileSegmentActive();
 
-	/*
-	 * Select a hopefully-unique system identifier code for this installation.
-	 * We use the result of gettimeofday(), including the fractional seconds
-	 * field, as being about as unique as we can easily get.  (Think not to
-	 * use random(), since it hasn't been seeded and there's no portable way
-	 * to seed it other than the system clock value...)  The upper half of the
-	 * uint64 value is just the tv_sec part, while the lower half contains the
-	 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
-	 * PID for a little extra uniqueness.  A person knowing this encoding can
-	 * determine the initialization time of the installation, which could
-	 * perhaps be useful sometimes.
-	 */
-	gettimeofday(&tv, NULL);
-	sysidentifier = ((uint64) tv.tv_sec) << 32;
-	sysidentifier |= ((uint64) tv.tv_usec) << 12;
-	sysidentifier |= getpid() & 0xFFF;
+	sysidentifier = GenerateSystemIdentifier();
 
 	memset(&buffer, 0, sizeof buffer);
 	page = (XLogPageHeader) &buffer;
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index cb16a608002..2869057e013 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -25,6 +25,7 @@
 #include "common/logging.h"
 #include "common/pg_prng.h"
 #include "common/restricted_token.h"
+#include "common/system_identifier.h"
 #include "datatype/timestamp.h"
 #include "fe_utils/recovery_gen.h"
 #include "fe_utils/simple_list.h"
@@ -709,7 +710,6 @@ modify_subscriber_sysid(const struct CreateSubscriberOptions *opt)
 {
 	ControlFileData *cf;
 	bool		crc_ok;
-	struct timeval tv;
 
 	char	   *out_file;
 	char	   *cmd_str;
@@ -722,13 +722,8 @@ modify_subscriber_sysid(const struct CreateSubscriberOptions *opt)
 
 	/*
 	 * Select a new system identifier.
-	 *
-	 * XXX this code was extracted from BootStrapXLOG().
 	 */
-	gettimeofday(&tv, NULL);
-	cf->system_identifier = ((uint64) tv.tv_sec) << 32;
-	cf->system_identifier |= ((uint64) tv.tv_usec) << 12;
-	cf->system_identifier |= getpid() & 0xFFF;
+	cf->system_identifier = GenerateSystemIdentifier();
 
 	if (dry_run)
 		pg_log_info("dry-run: would set system identifier to %" PRIu64 " on subscriber",
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index f8d25afed9d..c5a755e4ea9 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -39,7 +39,6 @@
 #include <dirent.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -54,6 +53,7 @@
 #include "common/logging.h"
 #include "common/restricted_token.h"
 #include "common/string.h"
+#include "common/system_identifier.h"
 #include "fe_utils/option_utils.h"
 #include "fe_utils/version.h"
 #include "getopt_long.h"
@@ -669,9 +669,6 @@ read_controlfile(void)
 static void
 GuessControlValues(void)
 {
-	uint64		sysidentifier;
-	struct timeval tv;
-
 	/*
 	 * Set up a completely default set of pg_control values.
 	 */
@@ -683,14 +680,9 @@ GuessControlValues(void)
 
 	/*
 	 * Create a new unique installation identifier, since we can no longer use
-	 * any old XLOG records.  See notes in xlog.c about the algorithm.
+	 * any old XLOG records.
 	 */
-	gettimeofday(&tv, NULL);
-	sysidentifier = ((uint64) tv.tv_sec) << 32;
-	sysidentifier |= ((uint64) tv.tv_usec) << 12;
-	sysidentifier |= getpid() & 0xFFF;
-
-	ControlFile.system_identifier = sysidentifier;
+	ControlFile.system_identifier = GenerateSystemIdentifier();
 
 	ControlFile.checkPointCopy.redo = SizeOfXLogLongPHD;
 	ControlFile.checkPointCopy.ThisTimeLineID = 1;
diff --git a/src/common/Makefile b/src/common/Makefile
index 1a2fbbe887f..4299090c107 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -77,6 +77,7 @@ OBJS_COMMON = \
 	rmtree.o \
 	saslprep.o \
 	scram-common.o \
+	system_identifier.o \
 	string.o \
 	stringinfo.o \
 	unicode_case.o \
diff --git a/src/common/meson.build b/src/common/meson.build
index 9bd55cda95b..65cf160f144 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -31,6 +31,7 @@ common_sources = files(
   'rmtree.c',
   'saslprep.c',
   'scram-common.c',
+  'system_identifier.c',
   'string.c',
   'stringinfo.c',
   'unicode_case.c',
diff --git a/src/common/system_identifier.c b/src/common/system_identifier.c
new file mode 100644
index 00000000000..acb07f3834c
--- /dev/null
+++ b/src/common/system_identifier.c
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------
+ *
+ * system_identifier.c
+ *		Implementation of system identifier generation
+ *
+ * Portions Copyright (c) 2026, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ *	  src/common/system_identifier.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "common/system_identifier.h"
+
+/*
+ * GenerateSystemIdentifier
+ *
+ * Creates a reasonably unique 64-bit identifier using:
+ *  - current time (seconds + microseconds)
+ *  - process ID
+ */
+uint64
+GenerateSystemIdentifier(void)
+{
+	struct	timeval tv;
+	uint64	sysidentifier;
+
+	/*
+	 * Select a hopefully-unique system identifier code for this installation.
+	 * We use the result of gettimeofday(), including the fractional seconds
+	 * field, as being about as unique as we can easily get.  (Think not to
+	 * use random(), since it hasn't been seeded and there's no portable way
+	 * to seed it other than the system clock value...)  The upper half of the
+	 * uint64 value is just the tv_sec part, while the lower half contains the
+	 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
+	 * PID for a little extra uniqueness.  A person knowing this encoding can
+	 * determine the initialization time of the installation, which could
+	 * perhaps be useful sometimes.
+	 */
+	gettimeofday(&tv, NULL);
+	sysidentifier = ((uint64) tv.tv_sec) << 32;
+	sysidentifier |= ((uint64) tv.tv_usec) << 12;
+	sysidentifier |= getpid() & 0xFFF;
+
+	return sysidentifier;
+}
\ No newline at end of file
diff --git a/src/include/common/system_identifier.h b/src/include/common/system_identifier.h
new file mode 100644
index 00000000000..5ef7600c80d
--- /dev/null
+++ b/src/include/common/system_identifier.h
@@ -0,0 +1,19 @@
+/*-------------------------------------------------------------------------
+ *
+ * system_identifier.h
+ *    Common utility to generate a system identifier
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef SYSTEM_IDENTIFIER_H
+#define SYSTEM_IDENTIFIER_H
+
+#include <stdint.h>
+
+/*
+ * Generate a new system identifier.
+ */
+extern uint64 GenerateSystemIdentifier(void);
+
+#endif		/* SYSTEM_IDENTIFIER_H */
\ No newline at end of file
-- 
2.34.1

