Обсуждение: new Configuration patch, implements 'include'

Поиск
Список
Период
Сортировка

new Configuration patch, implements 'include'

От
mlw
Дата:
This is a patch that allows PostgreSQL to use a configuration
file that is outside the main database directory.

It adds one more command line parameter, "-C" which
specifies the location of the postgres configuration file.

A patched version of PostgreSQL will function as:

postmaster -C /etc/postgres/postgresql.conf

This will direct the postmaster program to use the
configuration file "/etc/postgres/postgresql.conf"

Within this file are four  additional parameters: include,
hba_conf,ident_conf, and data_dir.

They are used as:
include = '/etc/postgres/debug.conf'
data_dir = '/vol01/postgres'
hba_conf = '/etc/postgres/pg_hba_conf'
ident_conf = '/etc/postgres/pg_ident.conf'

The "-D" option on the command line overrides the "data_dir"
in the configuration file.

If no hba_conf and/or ident_conf setting is specified, the default
$PGDATA/pg_hba.conf and/or $PGDATA/pg_ident.conf will be used.

This patch is intended to move the PostgreSQL configuration out of the
data directory so that it can be modified and backed up.

This patch is also useful for running multiple servers with the same
parameters:

postmaster -C /etc/postgres/postgresql.conf -D /VOL01/postgres -p 5432
postmaster -C /etc/postgres/postgresql.conf -D /VOL02/postgres -p 5433

To apply the patch, enter your PostreSQL source directory, and run:

cat pgec-PGVERSON.patch | patch -p 1
diff -u -r postgresql-7.3.2/src/backend/libpq/hba.c postgresql-7.3.2.ec/src/backend/libpq/hba.c
--- postgresql-7.3.2/src/backend/libpq/hba.c    Sat Dec 14 13:49:43 2002
+++ postgresql-7.3.2.ec/src/backend/libpq/hba.c    Mon Feb 17 09:30:15 2003
@@ -35,6 +35,7 @@
 #include "miscadmin.h"
 #include "nodes/pg_list.h"
 #include "storage/fd.h"
+#include "utils/guc.h"


 #define IDENT_USERNAME_MAX 512
@@ -837,10 +838,20 @@
     if (hba_lines)
         free_lines(&hba_lines);

-    /* Put together the full pathname to the config file. */
-    bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char);
-    conf_file = (char *) palloc(bufsize);
-    snprintf(conf_file, bufsize, "%s/%s", DataDir, CONF_FILE);
+    /* Explicit HBA in config file */
+    if(explicit_hbafile && strlen(explicit_hbafile))
+    {
+        bufsize = strlen(explicit_hbafile)+1;
+        conf_file = (char *) palloc(bufsize);
+        strcpy(conf_file, explicit_hbafile);
+    }
+    else
+    {
+        /* put together the full pathname to the config file */
+        bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char);
+        conf_file = (char *) palloc(bufsize);
+        snprintf(conf_file, bufsize, "%s/%s", DataDir, CONF_FILE);
+    }

     file = AllocateFile(conf_file, "r");
     if (file == NULL)
@@ -979,10 +990,20 @@
     if (ident_lines)
         free_lines(&ident_lines);

-    /* put together the full pathname to the map file */
-    bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char);
-    map_file = (char *) palloc(bufsize);
-    snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_FILE);
+    /* Explicit IDENT in config file */
+    if(explicit_identfile && strlen(explicit_identfile))
+    {
+        bufsize = strlen(explicit_identfile)+1;
+        map_file = (char *) palloc(bufsize);
+        strcpy(map_file, explicit_identfile);
+    }
+    else
+    {
+        /* put together the full pathname to the map file */
+        bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char);
+        map_file = (char *) palloc(bufsize);
+        snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_FILE);
+    }

     file = AllocateFile(map_file, "r");
     if (file == NULL)
diff -u -r postgresql-7.3.2/src/backend/postmaster/postmaster.c postgresql-7.3.2.ec/src/backend/postmaster/postmaster.c
--- postgresql-7.3.2/src/backend/postmaster/postmaster.c    Wed Jan 15 19:27:17 2003
+++ postgresql-7.3.2.ec/src/backend/postmaster/postmaster.c    Mon Feb 17 09:30:15 2003
@@ -421,7 +421,7 @@

     opterr = 1;

-    while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)
+    while ((opt = getopt(argc, argv, "A:a:B:b:C:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)
     {
         switch (opt)
         {
@@ -441,6 +441,9 @@
             case 'b':
                 /* Can no longer set the backend executable file to use. */
                 break;
+            case 'C': // MLW
+                explicit_pgconfig = optarg;
+                break;
             case 'D':
                 potential_DataDir = optarg;
                 break;
@@ -564,13 +567,23 @@
         ExitPostmaster(1);
     }

-    /*
-     * Now we can set the data directory, and then read postgresql.conf.
-     */
-    checkDataDir(potential_DataDir);    /* issues error messages */
-    SetDataDir(potential_DataDir);
-
-    ProcessConfigFile(PGC_POSTMASTER);
+    if(explicit_pgconfig)
+    {
+        ProcessConfigFile(PGC_POSTMASTER);
+        if(!potential_DataDir && pgdatadir)
+            potential_DataDir = pgdatadir;
+        checkDataDir(potential_DataDir);    /* issues error messages */
+        SetDataDir(potential_DataDir);
+    }
+    else
+    {
+        /*
+         * Now we can set the data directory, and then read postgresql.conf.
+         */
+        checkDataDir(potential_DataDir);    /* issues error messages */
+        SetDataDir(potential_DataDir);
+        ProcessConfigFile(PGC_POSTMASTER);
+    }

     /*
      * Check for invalid combinations of GUC settings.
diff -u -r postgresql-7.3.2/src/backend/utils/misc/guc-file.l postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.l
--- postgresql-7.3.2/src/backend/utils/misc/guc-file.l    Tue Jul 30 12:33:08 2002
+++ postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.l    Mon Feb 17 12:05:35 2003
@@ -116,51 +116,27 @@
     }
 }

+#define ELEVEL_FROM_CONTEXT(ctx)    (ctx == PGC_SIGHUP) ? DEBUG3 : ERROR

-/*
- * Official function to read and process the configuration file. The
- * parameter indicates in what context the file is being read
- * (postmaster startup, backend startup, or SIGHUP). All options
- * mentioned in the configuration file are set to new values. This
- * function does not return if an error occurs. If an error occurs, no
- * values will be changed.
- */
-void
-ProcessConfigFile(GucContext context)
+static void
+ReadConfigFile(char *filename, GucContext context)
 {
     int token, parse_state;
     char *opt_name, *opt_value;
-    char *filename;
     struct name_value_pair *item, *head, *tail;
-    int elevel;
-    FILE * fp;
-
-    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND
-        || context == PGC_SIGHUP);
-    Assert(DataDir);
-    elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
+    FILE *fp;
+    int elevel = ELEVEL_FROM_CONTEXT(context);

-    /*
-     * Open file
-     */
-    filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
-    if (filename == NULL)
-    {
-        elog(elevel, "out of memory");
-        return;
-    }
-    sprintf(filename, "%s/" CONFIG_FILENAME, DataDir);
-
-    fp = AllocateFile(filename, "r");
-    if (!fp)
-    {
+        fp = AllocateFile(filename, "r");
+    if (!fp)
+        {
+            /* File not found is fine */
+            if (errno != ENOENT)
+                    elog(elevel, "could not read configuration file %s: %s",
+                filename, strerror(errno));
         free(filename);
-        /* File not found is fine */
-        if (errno != ENOENT)
-            elog(elevel, "could not read configuration file `" CONFIG_FILENAME "': %s", strerror(errno));
         return;
-    }
-
+        }
     /*
      * Parse
      */
@@ -189,7 +165,8 @@
                     token = yylex();

                 if (token != GUC_ID && token != GUC_STRING &&
-                    token != GUC_INTEGER && token != GUC_REAL &&
+                    token != GUC_INTEGER &&
+                    token != GUC_REAL &&
                     token != GUC_UNQUOTED_STRING)
                     goto parse_error;
                 opt_value = strdup(yytext);
@@ -233,7 +210,6 @@
         }

     FreeFile(fp);
-    free(filename);

     /*
      * Check if all options are valid
@@ -256,7 +232,6 @@

  parse_error:
     FreeFile(fp);
-    free(filename);
     free_name_value_list(head);
     elog(elevel, CONFIG_FILENAME ":%u: syntax error, token=\"%s\"",
         ConfigFileLineno,yytext);
@@ -264,12 +239,54 @@

  out_of_memory:
     FreeFile(fp);
-    free(filename);
     free_name_value_list(head);
     elog(elevel, "out of memory");
     return;
 }
+/*
+ * Official function to read and process the configuration file. The
+ * parameter indicates in what context the file is being read
+ * (postmaster startup, backend startup, or SIGHUP). All options
+ * mentioned in the configuration file are set to new values. This
+ * function does not return if an error occurs. If an error occurs, no
+ * values will be changed.
+ */
+void
+ProcessConfigFile(GucContext context)
+{
+    char *filename;

+    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND
+        || context == PGC_SIGHUP);
+
+    /* Added for explicit config file */
+    if(explicit_pgconfig)
+    {
+        /*
+         * Use explicit file
+         */
+        filename = strdup(explicit_pgconfig);
+    }
+    else
+    {
+        /*
+         * Use environmental config
+         */
+        filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
+        sprintf(filename, "%s/" CONFIG_FILENAME, DataDir);
+    }
+
+    if (filename == NULL)
+    {
+        int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
+        elog(elevel, "out of memory");
+        return;
+    }
+
+    ReadConfigFile(filename, context);
+
+    free(filename);
+}


 /* ----------------
diff -u -r postgresql-7.3.2/src/backend/utils/misc/guc.c postgresql-7.3.2.ec/src/backend/utils/misc/guc.c
--- postgresql-7.3.2/src/backend/utils/misc/guc.c    Tue Jan 28 13:04:13 2003
+++ postgresql-7.3.2.ec/src/backend/utils/misc/guc.c    Mon Feb 17 12:07:47 2003
@@ -51,6 +51,11 @@
 #include "utils/pg_locale.h"
 #include "pgstat.h"

+/* Added for config file only startup MLW */
+char *explicit_pgconfig = NULL;
+char *explicit_hbafile = NULL;
+char *explicit_identfile = NULL;
+char *pgdatadir = NULL;

 /* XXX these should be in other modules' header files */
 extern bool Log_connections;
@@ -113,6 +118,7 @@
 char       *client_min_messages_str = NULL;
 const char    client_min_messages_str_default[] = "notice";

+static void ReadConfigFile(char *filename, GucContext context);

 #ifndef PG_KRB_SRVTAB
 #define PG_KRB_SRVTAB ""
@@ -146,7 +152,8 @@
     PGC_BOOL,
     PGC_INT,
     PGC_REAL,
-    PGC_STRING
+    PGC_STRING,
+    PGC_FUNCTION
 };

 /* Generic fields applicable to all types of variables */
@@ -239,6 +246,13 @@
     char       *tentative_val;
 };

+struct config_function
+{
+    struct config_generic gen;
+    void (*function)(char *param, GucContext context);
+};
+
+
 /* Macros for freeing malloc'd pointers only if appropriate to do so */
 /* Some of these tests are probably redundant, but be safe ... */
 #define SET_STRING_VARIABLE(rec, newval) \
@@ -853,10 +867,32 @@
     },

     {
+        {"data_dir", PGC_POSTMASTER}, &pgdatadir,
+        "", NULL, NULL
+    },
+
+    {
+        {"hba_conf", PGC_POSTMASTER}, &explicit_hbafile,
+        "", NULL, NULL
+    },
+
+    {
+        {"ident_conf", PGC_POSTMASTER}, &explicit_identfile,
+        "", NULL, NULL
+    },
+
+    {
         {NULL, 0}, NULL, NULL, NULL, NULL
     }
 };

+
+static struct config_function ConfigureFunctions[] =
+{
+    { {"include", PGC_POSTMASTER}, ReadConfigFile},
+    { {NULL,0}, NULL}
+};
+
 /******** end of options list ********/


@@ -919,6 +955,12 @@
         conf->gen.vartype = PGC_STRING;
         num_vars++;
     }
+    for(i = 0; ConfigureFunctions[i].gen.name; i++)
+    {
+        struct config_function *conf = &ConfigureFunctions[i];
+        conf->gen.vartype = PGC_FUNCTION;
+        num_vars++;
+    }

     guc_vars = (struct config_generic **)
         malloc(num_vars * sizeof(struct config_generic *));
@@ -939,6 +981,9 @@
     for (i = 0; ConfigureNamesString[i].gen.name; i++)
         guc_vars[num_vars++] = &ConfigureNamesString[i].gen;

+    for (i = 0; ConfigureFunctions[i].gen.name; i++)
+        guc_vars[num_vars++] = &ConfigureFunctions[i].gen;
+
     qsort((void *) guc_vars, num_vars, sizeof(struct config_generic *),
           guc_var_compare);

@@ -1135,6 +1180,8 @@
                     conf->session_val = str;
                     break;
                 }
+            case PGC_FUNCTION: /* Nothing to do */
+                break;
         }
     }

@@ -1280,6 +1327,8 @@
                     guc_dirty = true;
                     break;
                 }
+            case PGC_FUNCTION: /* Nothing to do */
+                break;
         }
     }
 }
@@ -1421,6 +1470,8 @@
                     conf->gen.status = 0;
                     break;
                 }
+            case    PGC_FUNCTION: /* Nothing to do */
+                break;
         }
     }

@@ -1684,6 +1735,17 @@
      */
     switch (record->vartype)
     {
+        case PGC_FUNCTION:
+            if(!DoIt)
+            {
+                /* During the "checking" stage of configuration
+                 * read, run functions
+                 */
+                struct config_function *fn =
+                    (struct config_function *)record;
+                fn->function((char *)value, context);
+            }
+            break;
         case PGC_BOOL:
             {
                 struct config_bool *conf = (struct config_bool *) record;
@@ -2063,6 +2125,9 @@

         case PGC_STRING:
             return *((struct config_string *) record)->variable;
+        case PGC_FUNCTION:
+            /* Should never really happen */
+            return NULL;
     }
     return NULL;
 }
@@ -2097,6 +2162,9 @@

         case PGC_STRING:
             return ((struct config_string *) record)->reset_val;
+        case PGC_FUNCTION:
+            /* Should never really happen */
+            return NULL;
     }
     return NULL;
 }
diff -u -r postgresql-7.3.2/src/backend/utils/misc/postgresql.conf.sample
postgresql-7.3.2.ec/src/backend/utils/misc/postgresql.conf.sample
--- postgresql-7.3.2/src/backend/utils/misc/postgresql.conf.sample    Mon Jan 27 22:44:09 2003
+++ postgresql-7.3.2.ec/src/backend/utils/misc/postgresql.conf.sample    Mon Feb 17 12:04:44 2003
@@ -23,6 +23,21 @@

 #========================================================================

+# Allows PostgreSQL to include another file
+# include = '/somedir/pgdefs.conf'
+
+# Allows PostgreSQL to use a pg_hba.conf file
+# which is not in the database directory.
+# hba_conf = '/etc/postgres/pg_hba.conf'
+
+# Allows PostgreSQL to use a pg_ident.conf file
+# which is not in the database directory.
+# ident_conf = '/etc/postgres/pg_ident.conf'
+
+# Allows Postgres to find its data directory
+# from this configuration file.
+# data_dir = '/RAID0/postgres'
+

 #
 #    Connection Parameters
diff -u -r postgresql-7.3.2/src/include/utils/guc.h postgresql-7.3.2.ec/src/include/utils/guc.h
--- postgresql-7.3.2/src/include/utils/guc.h    Mon Oct 21 14:57:35 2002
+++ postgresql-7.3.2.ec/src/include/utils/guc.h    Mon Feb 17 11:41:13 2003
@@ -137,5 +137,10 @@
 extern char *client_min_messages_str;

 extern const char client_min_messages_str_default[];
+/* Added MLW */
+extern char *explicit_pgconfig;
+extern char *explicit_hbafile;
+extern char *explicit_identfile;
+extern char *pgdatadir;

 #endif   /* GUC_H */

Re: new Configuration patch, implements 'include'

От
Tom Lane
Дата:
mlw <pgsql@mohawksoft.com> writes:
> If no hba_conf and/or ident_conf setting is specified, the default
> $PGDATA/pg_hba.conf and/or $PGDATA/pg_ident.conf will be used.

Doesn't anybody see the (a) inconsistency and (b) uselessness of this?
If you are trying to keep your config files out of the data directory,
it's hardly sensible to default to finding two out of three there.

We should have a -C that specifies a *directory*, and all three config
files should be sought therein.  The argument that that somehow forces
people to use symlinks doesn't convince me at all.

But I've grown tired of arguing, because it's clear that I'm making no
impact whatever :-(.  I'm done with this thread.
        regards, tom lane


Re: new Configuration patch, implements 'include'

От
mlw
Дата:
Tom Lane wrote:

>mlw <pgsql@mohawksoft.com> writes:
>  
>
>>If no hba_conf and/or ident_conf setting is specified, the default
>>$PGDATA/pg_hba.conf and/or $PGDATA/pg_ident.conf will be used.
>>    
>>
>
>Doesn't anybody see the (a) inconsistency and (b) uselessness of this?
>If you are trying to keep your config files out of the data directory,
>it's hardly sensible to default to finding two out of three there.
>
>We should have a -C that specifies a *directory*, and all three config
>files should be sought therein.  The argument that that somehow forces
>people to use symlinks doesn't convince me at all.
>
>But I've grown tired of arguing, because it's clear that I'm making no
>impact whatever :-(.  I'm done with this thread.
>
Tom, I don't know why you are arguing at all. One thing I wish to 
impress on you, I think it is a point of view you are missing. It isn't 
about something being "easier" as much as it is about being flexable 
enough to fit into the deployment strategy of the admin or vendor.

Sometimes you make things more difficult when you make it more 
standardized.  When I setup a system with Apache, PHP, PostgreSQL, 
named, et al, I am always just irritated that PostgreSQL's configuration 
parameters can not be stored with all the others. I usually make one 
install tarball or zip that contains all the binaries and configuration. 
I can't do that with PostgreSQL.

I don't like the idea of specifying a directory, per se' because if you 
have multiple database installations, how would you share the 
configuration without symlinks?

I will modify my patch to check if the configuration parameter is a 
directory. If it is, it will make the default filenames within the 
directory and post it when it is gone.



Re: new Configuration patch, implements 'include'

От
Bruce Momjian
Дата:
Tom Lane wrote:
> mlw <pgsql@mohawksoft.com> writes:
> > If no hba_conf and/or ident_conf setting is specified, the default
> > $PGDATA/pg_hba.conf and/or $PGDATA/pg_ident.conf will be used.
> 
> Doesn't anybody see the (a) inconsistency and (b) uselessness of this?
> If you are trying to keep your config files out of the data directory,
> it's hardly sensible to default to finding two out of three there.
> 
> We should have a -C that specifies a *directory*, and all three config
> files should be sought therein.  The argument that that somehow forces
> people to use symlinks doesn't convince me at all.

I think the issue here is that symlinks are OK to implement unusual
configuration cases, and I think we can say having the three config
files in different directories is unusual.  I think you have to weigh
the downside of using symlinks for rare configurations compared to the
complexity of specifying the config file locations in three separate
cases.

I had thrown out the idea of putting the config files in their own
directory _under_ /data, like /data/etc, so you could just symlink that
directory to somewhere else.  Makes backups of config files easy, and
makes it initdb-safe, because only the symlink can be under /data. 
However, no one commented on it, so I assume they didn't like it.  It
seems like a nice middle ground to me.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


Re: new Configuration patch, implements 'include'

От
Bruce Momjian
Дата:
mlw wrote:
> I don't like the idea of specifying a directory, per se' because if you 
> have multiple database installations, how would you share the 
> configuration without symlinks?

Oh, for example, you would be sharing postgresql.conf, perhaps, but not
pg_hba.conf.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


Re: new Configuration patch, implements 'include'

От
mlw
Дата:

Bruce Momjian wrote:

>mlw wrote:
>  
>
>>I don't like the idea of specifying a directory, per se' because if you 
>>have multiple database installations, how would you share the 
>>configuration without symlinks?
>>    
>>
>
>Oh, for example, you would be sharing postgresql.conf, perhaps, but not
>pg_hba.conf.
>  
>
Actually, the other way around.

An "official" pg_hba.conf and pg_ident.conf setup by an admin, but 
differing postgresql.conf files for different databases. Does that make 
sense?


>  
>