From b3ca1502ede271f68d7db8e8273bee355ce7e0f1 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Wed, 26 Oct 2022 18:25:08 +1100
Subject: [PATCH v5] GUC C variable sanity check

Added a function to perform a sanity-check comparison of the C variable initial
value with the compiled-in default (boot_val). The purpose of this is to prevent
anybody reading those C declarations from being fooled by mismatched values.

Also fixed some existing mismatching values.
---
 src/backend/access/transam/xact.c   |  2 +-
 src/backend/access/transam/xlog.c   |  2 +-
 src/backend/libpq/be-secure.c       |  4 +--
 src/backend/postmaster/postmaster.c |  2 +-
 src/backend/storage/buffer/bufmgr.c | 20 ++++++++---
 src/backend/storage/ipc/dsm_impl.c  |  2 +-
 src/backend/utils/adt/xml.c         |  4 +--
 src/backend/utils/cache/plancache.c |  2 +-
 src/backend/utils/error/elog.c      |  2 +-
 src/backend/utils/init/globals.c    |  4 +--
 src/backend/utils/misc/guc.c        | 72 +++++++++++++++++++++++++++++++++++++
 src/backend/utils/misc/guc_tables.c | 19 ++++++++--
 src/backend/utils/misc/ps_status.c  |  8 ++++-
 13 files changed, 122 insertions(+), 21 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index fd5103a..f45c95f 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -75,7 +75,7 @@
  *	User-tweakable parameters
  */
 int			DefaultXactIsoLevel = XACT_READ_COMMITTED;
-int			XactIsoLevel;
+int			XactIsoLevel = XACT_READ_COMMITTED;
 
 bool		DefaultXactReadOnly = false;
 bool		XactReadOnly;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8f10eff..be54c23 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -131,7 +131,7 @@ bool		wal_init_zero = true;
 bool		wal_recycle = true;
 bool		log_checkpoints = true;
 int			sync_method = DEFAULT_SYNC_METHOD;
-int			wal_level = WAL_LEVEL_MINIMAL;
+int			wal_level = WAL_LEVEL_REPLICA;
 int			CommitDelay = 0;	/* precommit delay in microseconds */
 int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
 int			wal_retrieve_retry_interval = 5000;
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index e3e5471..c896357 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -58,8 +58,8 @@ char	   *SSLECDHCurve;
 /* GUC variable: if false, prefer client ciphers */
 bool		SSLPreferServerCiphers;
 
-int			ssl_min_protocol_version;
-int			ssl_max_protocol_version;
+int			ssl_min_protocol_version = PG_TLS1_2_VERSION;
+int			ssl_max_protocol_version = PG_TLS_ANY;
 
 /* ------------------------------------------------------------ */
 /*			 Procedures common to all secure sessions			*/
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 30fb576..0b637ba 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -196,7 +196,7 @@ BackgroundWorker *MyBgworkerEntry = NULL;
 
 
 /* The socket number we are listening for connections on */
-int			PostPortNumber;
+int			PostPortNumber = DEF_PGPORT;
 
 /* The directory names for Unix socket(s) */
 char	   *Unix_socket_directories;
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 6b95381..e5d31e8 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -142,22 +142,32 @@ bool		track_io_timing = false;
  * for buffers not belonging to tablespaces that have their
  * effective_io_concurrency parameter set.
  */
-int			effective_io_concurrency = 0;
+int			effective_io_concurrency =
+#ifdef USE_PREFETCH
+		1;
+#else
+		0;
+#endif
 
 /*
  * Like effective_io_concurrency, but used by maintenance code paths that might
  * benefit from a higher setting because they work on behalf of many sessions.
  * Overridden by the tablespace setting of the same name.
  */
-int			maintenance_io_concurrency = 0;
+int			maintenance_io_concurrency =
+#ifdef USE_PREFETCH
+		10;
+#else
+		0;
+#endif
 
 /*
  * GUC variables about triggering kernel writeback for buffers written; OS
  * dependent defaults are set via the GUC mechanism.
  */
-int			checkpoint_flush_after = 0;
-int			bgwriter_flush_after = 0;
-int			backend_flush_after = 0;
+int			checkpoint_flush_after = DEFAULT_CHECKPOINT_FLUSH_AFTER;
+int			bgwriter_flush_after = DEFAULT_BGWRITER_FLUSH_AFTER;
+int			backend_flush_after = DEFAULT_BACKEND_FLUSH_AFTER;
 
 /* local state for StartBufferIO and related functions */
 static BufferDesc *InProgressBuf = NULL;
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index e1b90c5..6ddd46a 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -109,7 +109,7 @@ const struct config_enum_entry dynamic_shared_memory_options[] = {
 };
 
 /* Implementation selector. */
-int			dynamic_shared_memory_type;
+int			dynamic_shared_memory_type = DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE;
 
 /* Amount of space reserved for DSM segments in the main area. */
 int			min_dynamic_shared_memory;
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index d32cb11..8cd5262 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -94,8 +94,8 @@
 
 
 /* GUC variables */
-int			xmlbinary;
-int			xmloption;
+int			xmlbinary = XMLBINARY_BASE64;
+int			xmloption = XMLOPTION_CONTENT;
 
 #ifdef USE_LIBXML
 
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 0d6a295..cc94320 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -116,7 +116,7 @@ static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue);
 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
 
 /* GUC parameter */
-int			plan_cache_mode;
+int			plan_cache_mode = PLAN_CACHE_MODE_AUTO;
 
 /*
  * InitPlanCache: initialize module during InitPostgres.
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 6e0a66c..2585e24 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -107,7 +107,7 @@ extern bool redirection_done;
 emit_log_hook_type emit_log_hook = NULL;
 
 /* GUC parameters */
-int			Log_error_verbosity = PGERROR_VERBOSE;
+int			Log_error_verbosity = PGERROR_DEFAULT;
 char	   *Log_line_prefix = NULL; /* format for extra log line info */
 int			Log_destination = LOG_DESTINATION_STDERR;
 char	   *Log_destination_string = NULL;
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 1a5d29a..00bceec 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -133,8 +133,8 @@ int			max_parallel_maintenance_workers = 2;
  * MaxBackends is computed by PostmasterMain after modules have had a chance to
  * register background workers.
  */
-int			NBuffers = 1000;
-int			MaxConnections = 90;
+int			NBuffers = 16384;
+int			MaxConnections = 100;
 int			max_worker_processes = 8;
 int			max_parallel_workers = 8;
 int			MaxBackends = 0;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 6f21752..7c9c4be 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1382,6 +1382,77 @@ check_GUC_name_for_parameter_acl(const char *name)
 	return false;
 }
 
+/*
+ * A GUC C variable can be declared with an initial value, but the GUC mechanism
+ * will overwrite that using the compiled-in default (boot_val) as per
+ * guc_tables.c.
+ *
+ * This function performs a sanity-check comparison of the C variable initial
+ * value with the boot_val, to prevent anybody reading those C declarations
+ * from being fooled by mismatched values.
+ *
+ * GUC C variable validation rules:
+ * bool - can be false, otherwise must be same as the boot_val
+ * int  - can be 0, otherwise must be same as the boot_val
+ * real - can be 0.0, otherwise must be same as the boot_val
+ * string - can be NULL, otherwise must be strcmp equal to the boot_val
+ * enum - must be same as the boot_val
+ */
+static void
+sanity_check_GUC_C_var(struct config_generic *gconf)
+{
+#ifdef USE_ASSERT_CHECKING
+
+	switch (gconf->vartype)
+	{
+		case PGC_BOOL:
+			{
+				struct config_bool *conf = (struct config_bool *) gconf;
+
+				if (*conf->variable && !conf->boot_val)
+					elog(FATAL, "GUC (PGC_BOOL) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_INT:
+			{
+				struct config_int *conf = (struct config_int *) gconf;
+
+				if (*conf->variable != 0 && *conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_INT) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_REAL:
+			{
+				struct config_real *conf = (struct config_real *) gconf;
+
+				if (*conf->variable != 0.0 && *conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_REAL) %s, boot_val=%g, C-var=%g",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_STRING:
+			{
+				struct config_string *conf = (struct config_string *) gconf;
+
+				if (*conf->variable != NULL && strcmp(*conf->variable, conf->boot_val) != 0)
+					elog(FATAL, "GUC (PGC_STRING) %s, boot_val=%s, C-var=%s",
+						 conf->gen.name, conf->boot_val ? conf->boot_val : "<null>", *conf->variable);
+				break;
+			}
+		case PGC_ENUM:
+			{
+				struct config_enum *conf = (struct config_enum *) gconf;
+
+				if (*conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_ENUM) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+	}
+#endif
+}
 
 /*
  * Initialize GUC options during program startup.
@@ -1413,6 +1484,7 @@ InitializeGUCOptions(void)
 	hash_seq_init(&status, guc_hashtab);
 	while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
 	{
+		sanity_check_GUC_C_var(hentry->gucvar);
 		InitializeOneGUCOption(hentry->gucvar);
 	}
 
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 05ab087..da387f1 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -526,13 +526,16 @@ int			ssl_renegotiation_limit;
  * This really belongs in pg_shmem.c, but is defined here so that it doesn't
  * need to be duplicated in all the different implementations of pg_shmem.c.
  */
-int			huge_pages;
+int			huge_pages = HUGE_PAGES_TRY;
 int			huge_page_size;
 
 /*
  * These variables are all dummies that don't do anything, except in some
  * cases provide the value for SHOW to display.  The real state is elsewhere
  * and is kept in sync by assign_hooks.
+ *
+ * Declaration assignments here are for keeping the GUC C var sanity-checker
+ * happy.
  */
 static char *syslog_ident_str;
 static double phony_random_seed;
@@ -543,7 +546,12 @@ static char *locale_ctype;
 static char *server_encoding_string;
 static char *server_version_string;
 static int	server_version_num;
-static int	syslog_facility;
+static int	syslog_facility =
+#ifdef HAVE_SYSLOG
+		LOG_LOCAL0;
+#else
+		0;
+#endif
 static char *timezone_string;
 static char *log_timezone_string;
 static char *timezone_abbreviations_string;
@@ -559,7 +567,12 @@ static int	shared_memory_size_in_huge_pages;
 static int	wal_block_size;
 static bool data_checksums;
 static bool integer_datetimes;
-static bool assert_enabled;
+static bool assert_enabled =
+#ifdef USE_ASSERT_CHECKING
+		true;
+#else
+		false;
+#endif
 static char *recovery_target_timeline_string;
 static char *recovery_target_string;
 static char *recovery_target_xid_string;
diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index 8520ce7..46ade41 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -30,8 +30,14 @@
 #include "utils/ps_status.h"
 
 extern char **environ;
-bool		update_process_title = true;
 
+/* GUC variable */
+bool		update_process_title =
+#ifdef WIN32
+		false;
+#else
+		true;
+#endif
 
 /*
  * Alternative ways of updating ps display:
-- 
1.8.3.1

