Allow loadable modules to create PGC_POSTMASTER GUC variables, but only
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 3 Jan 2009 20:03:08 +0000 (20:03 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 3 Jan 2009 20:03:08 +0000 (20:03 +0000)
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
src/backend/utils/misc/guc.c
src/include/miscadmin.h

index 3c1f00fef9824c85d1dea30238f5764ae0d78f25..74b4078254ef5bd038b26e6e7171dbd252b32051 100644 (file)
@@ -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;
 }
 
 /*
index 137077e104282e14412d9ee31f0a8d2fbb50b355..b524c3c87831552278f8190351eda8e43c243799 100644 (file)
@@ -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:
index 2b1382c0ab2d7175648d418166bb5412db65585c..9753d2f71ccf966b87901449a1450de2311cd5e9 100644 (file)
@@ -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;