From 4605d1c98b305567a7addb22643a9cc7519315e9 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 3 Jan 2009 20:03:08 +0000
Subject: [PATCH] Allow loadable modules to create PGC_POSTMASTER GUC
 variables, but only when loaded via shared_preload_libraries.  Needed for
 support of pg_stat_statements, or pretty much anything else that wants a GUC
 to control size of a shared memory allocation.

---
 src/backend/utils/init/miscinit.c |  7 ++++++-
 src/backend/utils/misc/guc.c      | 23 +++++++++++++++++++++--
 src/include/miscadmin.h           |  3 ++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 8e449487cc5..461918ed309 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.170 2009/01/01 17:23:51 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.171 2009/01/03 20:03:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1131,6 +1131,9 @@ ValidatePgVersion(const char *path)
 char	   *shared_preload_libraries_string = NULL;
 char	   *local_preload_libraries_string = NULL;
 
+/* Flag telling that we are loading shared_preload_libraries */
+bool		process_shared_preload_libraries_in_progress = false;
+
 /*
  * load the shared libraries listed in 'libraries'
  *
@@ -1197,9 +1200,11 @@ load_libraries(const char *libraries, const char *gucname, bool restricted)
 void
 process_shared_preload_libraries(void)
 {
+	process_shared_preload_libraries_in_progress = true;
 	load_libraries(shared_preload_libraries_string,
 				   "shared_preload_libraries",
 				   false);
+	process_shared_preload_libraries_in_progress = false;
 }
 
 /*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 1290af8dee0..303329167a8 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.487 2009/01/02 10:33:20 mha Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.488 2009/01/03 20:03:08 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -5625,6 +5625,17 @@ init_custom_variable(const char *name,
 {
 	struct config_generic *gen;
 
+	/*
+	 * Only allow custom PGC_POSTMASTER variables to be created during
+	 * shared library preload; any later than that, we can't ensure that
+	 * the value doesn't change after startup.  This is a fatal elog if it
+	 * happens; just erroring out isn't safe because we don't know what
+	 * the calling loadable module might already have hooked into.
+	 */
+	if (context == PGC_POSTMASTER &&
+		!process_shared_preload_libraries_in_progress)
+		elog(FATAL, "cannot create PGC_POSTMASTER variables after startup");
+
 	gen = (struct config_generic *) guc_malloc(ERROR, sz);
 	memset(gen, 0, sz);
 
@@ -5707,7 +5718,15 @@ define_custom_variable(struct config_generic * variable)
 		case PGC_S_ENV_VAR:
 		case PGC_S_FILE:
 		case PGC_S_ARGV:
-			phcontext = PGC_SIGHUP;
+			/*
+			 * If we got past the check in init_custom_variable, we can
+			 * safely assume that any existing value for a PGC_POSTMASTER
+			 * variable was set in postmaster context.
+			 */
+			if (variable->context == PGC_POSTMASTER)
+				phcontext = PGC_POSTMASTER;
+			else
+				phcontext = PGC_SIGHUP;
 			break;
 		case PGC_S_DATABASE:
 		case PGC_S_USER:
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index ccef61f1bab..e1c1042d681 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.207 2009/01/01 17:23:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.208 2009/01/03 20:03:08 tgl Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to other files.
@@ -328,6 +328,7 @@ extern void BaseInit(void);
 
 /* in utils/init/miscinit.c */
 extern bool IgnoreSystemIndexes;
+extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
 extern char *shared_preload_libraries_string;
 extern char *local_preload_libraries_string;
 
-- 
GitLab