Commit 130f89e9 authored by Bruce Momjian's avatar Bruce Momjian

Allow configuration files to be placed outside the data directory.

Add new postgresql.conf variables to point to data, pg_hba.conf, and
pg_ident.conf files.

Needs more documentation.
parent b4a98c5f
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/postmaster.sgml,v 1.50 2004/06/21 04:06:04 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/postmaster.sgml,v 1.51 2004/07/11 00:18:41 momjian Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -67,15 +67,28 @@ PostgreSQL documentation ...@@ -67,15 +67,28 @@ PostgreSQL documentation
One <command>postmaster</command> always manages the data One <command>postmaster</command> always manages the data
from exactly one database cluster. A database cluster is a from exactly one database cluster. A database cluster is a
collection of databases that is stored at a common file system collection of databases that is stored at a common file system
location. When the <command>postmaster</command> starts it needs to know the location location. When the <command>postmaster</command> starts it needs
of the database cluster files (<quote>data area</quote>). This is to know the location of the database cluster files (<quote>data
done with the <option>-D</option> invocation option or the area</quote>).
<envar>PGDATA</envar> environment variable; there is no default. More than one <command>postmaster</command> process can run on a system
More than one <command>postmaster</command> process can run on a system at one time, at one time as long as they use different data areas and different
as long as they use different data areas and different
communication ports (see below). A data area is created with <xref communication ports (see below). A data area is created with <xref
linkend="app-initdb">. linkend="app-initdb">.
</para> </para>
<para>
The <quote>data area</> is specified by the <option>-D</option> option
or the <envar>PGDATA</envar> environment variable; there is no default.
Typically, it points to a directory created by <application>
initdb</>. However, for administrative flexibility, you can
point to a directory containing only configuration files:
<filename>postgresql.conf</>, <filename>pg_hba.conf</>, and
<filename>pg_ident.conf</>. You can then set
<filename>postgresql.conf</>'s <varname>pgdata</> to point to the
data directory. You can also point just to the server configuration file
like <filename>postgresql.conf</> and set its variables to point to the
other configuration files and the data directory.
</para>
</refsect1> </refsect1>
<refsect1 id="app-postmaster-options"> <refsect1 id="app-postmaster-options">
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.268 2004/06/27 22:58:19 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.269 2004/07/11 00:18:40 momjian Exp $
--> -->
<Chapter Id="runtime"> <Chapter Id="runtime">
...@@ -563,6 +563,54 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -563,6 +563,54 @@ SET ENABLE_SEQSCAN TO OFF;
any desired selection condition. any desired selection condition.
</para> </para>
<sect2 id="runtime-config-configuration-files">
<title>Configuration Files</title>
<variablelist>
<varlistentry id="guc-pgdata" xreflabel="pgdata">
<term><varname>pgdata</varname> (<type>string</type>)</term>
<listitem>
<para>
Specifies the directory to use for data storage (everything except
configuration files).
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-hba-conf" xreflabel="hba-conf">
<term><varname>hba_conf</varname> (<type>string</type>)</term>
<listitem>
<para>
Specifies the file name to use for configuration of host-based
authentication (HBA).
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-ident-conf" xreflabel="ident-conf">
<term><varname>ident_conf</varname> (<type>string</type>)</term>
<listitem>
<para>
Specifies the file name to use for configuration of
<application>ident</> authentication.
</para>
</listitem>
</varlistentry>
<varlistentry id="external-pidfile" xreflabel="external-pidfile">
<term><varname>external_pidfile</varname> (<type>string</type>)</term>
<listitem>
<para>
Specifies the location of an additional <application>postmaster</>
process-id (PID) file for use by server administration programs.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 id="runtime-config-connection"> <sect2 id="runtime-config-connection">
<title>Connections and Authentication</title> <title>Connections and Authentication</title>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.185 2004/06/24 21:02:24 tgl Exp $ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.186 2004/07/11 00:18:43 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -212,7 +212,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -212,7 +212,7 @@ BootstrapMain(int argc, char *argv[])
char *dbname; char *dbname;
int flag; int flag;
int xlogop = BS_XLOG_NOP; int xlogop = BS_XLOG_NOP;
char *potential_DataDir = NULL; char *userPGDATA = NULL;
/* /*
* initialize globals * initialize globals
...@@ -236,8 +236,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -236,8 +236,7 @@ BootstrapMain(int argc, char *argv[])
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
InitializeGUCOptions(); InitializeGUCOptions();
potential_DataDir = getenv("PGDATA"); /* Null if no PGDATA userPGDATA = getenv("PGDATA"); /* Null if no PGDATA variable */
* variable */
} }
/* Ignore the initial -boot argument, if present */ /* Ignore the initial -boot argument, if present */
...@@ -252,7 +251,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -252,7 +251,7 @@ BootstrapMain(int argc, char *argv[])
switch (flag) switch (flag)
{ {
case 'D': case 'D':
potential_DataDir = optarg; userPGDATA = optarg;
break; break;
case 'd': case 'd':
{ {
...@@ -326,7 +325,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -326,7 +325,7 @@ BootstrapMain(int argc, char *argv[])
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
if (!potential_DataDir) if (!userPGDATA)
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the database system data.\n"
"You must specify the directory that contains the database system\n" "You must specify the directory that contains the database system\n"
...@@ -335,7 +334,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -335,7 +334,7 @@ BootstrapMain(int argc, char *argv[])
argv[0]); argv[0]);
proc_exit(1); proc_exit(1);
} }
SetDataDir(potential_DataDir); SetDataDir(userPGDATA);
} }
/* Validate we have been given a reasonable-looking DataDir */ /* Validate we have been given a reasonable-looking DataDir */
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.125 2004/05/30 23:40:26 neilc Exp $ * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.126 2004/07/11 00:18:43 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/pg_list.h" #include "nodes/pg_list.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "utils/guc.h"
/* Max size of username ident server can return */ /* Max size of username ident server can return */
...@@ -1029,17 +1030,22 @@ load_user(void) ...@@ -1029,17 +1030,22 @@ load_user(void)
void void
load_hba(void) load_hba(void)
{ {
int bufsize;
FILE *file; /* The config file we have to read */ FILE *file; /* The config file we have to read */
char *conf_file; /* The name of the config file */ char *conf_file; /* The name of the config file */
if (hba_lines || hba_line_nums) if (hba_lines || hba_line_nums)
free_lines(&hba_lines, &hba_line_nums); free_lines(&hba_lines, &hba_line_nums);
/* Put together the full pathname to the config file. */ /* HBA filename in config file */
bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char); if (guc_hbafile)
conf_file = (char *) palloc(bufsize); conf_file = pstrdup(guc_hbafile);
snprintf(conf_file, bufsize, "%s/%s", DataDir, CONF_FILE); else
{
char *confloc = (user_pgconfig_is_dir) ? user_pgconfig : DataDir;
/* put together the full pathname to the config file */
conf_file = palloc(strlen(confloc) + strlen(CONF_FILE) + 2);
sprintf(conf_file, "%s/%s", confloc, CONF_FILE);
}
file = AllocateFile(conf_file, "r"); file = AllocateFile(conf_file, "r");
if (file == NULL) if (file == NULL)
...@@ -1178,16 +1184,20 @@ load_ident(void) ...@@ -1178,16 +1184,20 @@ load_ident(void)
FILE *file; /* The map file we have to read */ FILE *file; /* The map file we have to read */
char *map_file; /* The name of the map file we have to char *map_file; /* The name of the map file we have to
* read */ * read */
int bufsize;
if (ident_lines || ident_line_nums) if (ident_lines || ident_line_nums)
free_lines(&ident_lines, &ident_line_nums); free_lines(&ident_lines, &ident_line_nums);
/* put together the full pathname to the map file */ /* IDENT filename in config file */
bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char); if (guc_identfile)
map_file = (char *) palloc(bufsize); map_file = pstrdup(guc_identfile);
snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_FILE); else
{
/* put together the full pathname to the map file */
char *confloc = (user_pgconfig_is_dir) ? user_pgconfig : DataDir;
map_file = (char *) palloc(strlen(confloc) + strlen(USERMAP_FILE) + 2);
sprintf(map_file, "%s/%s", confloc, USERMAP_FILE);
}
file = AllocateFile(map_file, "r"); file = AllocateFile(map_file, "r");
if (file == NULL) if (file == NULL)
{ {
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.406 2004/07/10 23:29:16 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.407 2004/07/11 00:18:43 momjian Exp $
* *
* NOTES * NOTES
* *
...@@ -233,6 +233,7 @@ extern int optreset; ...@@ -233,6 +233,7 @@ extern int optreset;
* postmaster.c - function prototypes * postmaster.c - function prototypes
*/ */
static void checkDataDir(const char *checkdir); static void checkDataDir(const char *checkdir);
static bool onlyConfigSpecified(const char *checkdir);
#ifdef USE_RENDEZVOUS #ifdef USE_RENDEZVOUS
static void reg_reply(DNSServiceRegistrationReplyErrorType errorCode, static void reg_reply(DNSServiceRegistrationReplyErrorType errorCode,
void *context); void *context);
...@@ -306,7 +307,7 @@ PostmasterMain(int argc, char *argv[]) ...@@ -306,7 +307,7 @@ PostmasterMain(int argc, char *argv[])
{ {
int opt; int opt;
int status; int status;
char *potential_DataDir = NULL; char *userPGDATA = NULL;
int i; int i;
progname = get_progname(argv[0]); progname = get_progname(argv[0]);
...@@ -370,7 +371,7 @@ PostmasterMain(int argc, char *argv[]) ...@@ -370,7 +371,7 @@ PostmasterMain(int argc, char *argv[])
*/ */
InitializeGUCOptions(); InitializeGUCOptions();
potential_DataDir = getenv("PGDATA"); /* default value */ userPGDATA = getenv("PGDATA"); /* default value */
opterr = 1; opterr = 1;
...@@ -395,7 +396,7 @@ PostmasterMain(int argc, char *argv[]) ...@@ -395,7 +396,7 @@ PostmasterMain(int argc, char *argv[])
/* Can no longer set the backend executable file to use. */ /* Can no longer set the backend executable file to use. */
break; break;
case 'D': case 'D':
potential_DataDir = optarg; userPGDATA = optarg;
break; break;
case 'd': case 'd':
{ {
...@@ -524,13 +525,49 @@ PostmasterMain(int argc, char *argv[]) ...@@ -524,13 +525,49 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(1); ExitPostmaster(1);
} }
/* if (onlyConfigSpecified(userPGDATA))
* Now we can set the data directory, and then read postgresql.conf. {
*/ /*
checkDataDir(potential_DataDir); /* issues error messages */ * It is either a file name or a directory with no
SetDataDir(potential_DataDir); * global/pg_control file, and hence not a data directory.
*/
user_pgconfig = userPGDATA;
ProcessConfigFile(PGC_POSTMASTER);
ProcessConfigFile(PGC_POSTMASTER); if (!guc_pgdata) /* Got a pgdata from the config file? */
{
write_stderr("%s does not know where to find the database system data.\n"
"This should be specified as 'pgdata' in %s%s.\n",
progname, userPGDATA,
user_pgconfig_is_dir ? "/postgresql.conf" : "");
ExitPostmaster(2);
}
checkDataDir(guc_pgdata);
SetDataDir(guc_pgdata);
}
else
{
/* Now we can set the data directory, and then read postgresql.conf. */
checkDataDir(userPGDATA);
SetDataDir(userPGDATA);
ProcessConfigFile(PGC_POSTMASTER);
}
if (external_pidfile)
{
FILE *fpidfile = fopen(external_pidfile, "w");
if (fpidfile)
{
fprintf(fpidfile, "%d\n", MyProcPid);
fclose(fpidfile);
/* Should we remove the pid file on postmaster exit? */
}
else
fprintf(stderr,
gettext("%s could not write to external pid file %s\n"),
progname, external_pidfile);
}
/* If timezone is not set, determine what the OS uses */ /* If timezone is not set, determine what the OS uses */
pg_timezone_initialize(); pg_timezone_initialize();
...@@ -848,6 +885,32 @@ PostmasterMain(int argc, char *argv[]) ...@@ -848,6 +885,32 @@ PostmasterMain(int argc, char *argv[])
} }
static bool
onlyConfigSpecified(const char *checkdir)
{
char path[MAXPGPATH];
struct stat stat_buf;
if (checkdir == NULL) /* checkDataDir handles this */
return FALSE;
if (stat(checkdir, &stat_buf) == -1) /* ditto */
return FALSE;
if (S_ISREG(stat_buf.st_mode)) /* It's a regular file, so assume it's explict */
return TRUE;
else if (S_ISDIR(stat_buf.st_mode)) /* It's a directory, is it a config or system dir? */
{
snprintf(path, MAXPGPATH, "%s/global/pg_control", checkdir);
/* If this is not found, it is a config-only directory */
if (stat(path, &stat_buf) == -1)
return TRUE;
}
return FALSE;
}
/* /*
* Validate the proposed data directory * Validate the proposed data directory
*/ */
...@@ -862,8 +925,8 @@ checkDataDir(const char *checkdir) ...@@ -862,8 +925,8 @@ checkDataDir(const char *checkdir)
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the database system data.\n"
"You must specify the directory that contains the database system\n" "You must specify the directory that contains the database system\n"
"either by specifying the -D invocation option or by setting the\n" "or configuration files by either specifying the -D invocation option\n"
"PGDATA environment variable.\n", "or by setting the PGDATA environment variable.\n",
progname); progname);
ExitPostmaster(2); ExitPostmaster(2);
} }
...@@ -873,12 +936,12 @@ checkDataDir(const char *checkdir) ...@@ -873,12 +936,12 @@ checkDataDir(const char *checkdir)
if (errno == ENOENT) if (errno == ENOENT)
ereport(FATAL, ereport(FATAL,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("data directory \"%s\" does not exist", errmsg("data or configuration location \"%s\" does not exist",
checkdir))); checkdir)));
else else
ereport(FATAL, ereport(FATAL,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read permissions of directory \"%s\": %m", errmsg("could not read permissions of \"%s\": %m",
checkdir))); checkdir)));
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.422 2004/07/01 00:51:11 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.423 2004/07/11 00:18:44 momjian Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2164,7 +2164,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2164,7 +2164,7 @@ PostgresMain(int argc, char *argv[], const char *username)
{ {
int flag; int flag;
const char *dbname = NULL; const char *dbname = NULL;
char *potential_DataDir = NULL; char *userPGDATA = NULL;
bool secure; bool secure;
int errs = 0; int errs = 0;
int debug_flag = 0; int debug_flag = 0;
...@@ -2235,7 +2235,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2235,7 +2235,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
InitializeGUCOptions(); InitializeGUCOptions();
potential_DataDir = getenv("PGDATA"); userPGDATA = getenv("PGDATA");
} }
/* ---------------- /* ----------------
...@@ -2283,7 +2283,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2283,7 +2283,7 @@ PostgresMain(int argc, char *argv[], const char *username)
case 'D': /* PGDATA directory */ case 'D': /* PGDATA directory */
if (secure) if (secure)
potential_DataDir = optarg; userPGDATA = optarg;
break; break;
case 'd': /* debug level */ case 'd': /* debug level */
...@@ -2574,12 +2574,12 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2574,12 +2574,12 @@ PostgresMain(int argc, char *argv[], const char *username)
* set up handler to log session end. * set up handler to log session end.
*/ */
if (IsUnderPostmaster && Log_disconnections) if (IsUnderPostmaster && Log_disconnections)
on_proc_exit(log_disconnections,0); on_proc_exit(log_disconnections, 0);
} }
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
if (!potential_DataDir) if (!userPGDATA)
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the database system data.\n"
"You must specify the directory that contains the database system\n" "You must specify the directory that contains the database system\n"
...@@ -2588,7 +2588,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2588,7 +2588,7 @@ PostgresMain(int argc, char *argv[], const char *username)
argv[0]); argv[0]);
proc_exit(1); proc_exit(1);
} }
SetDataDir(potential_DataDir); SetDataDir(userPGDATA);
} }
Assert(DataDir); Assert(DataDir);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.22 2004/05/26 15:07:38 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.23 2004/07/11 00:18:44 momjian Exp $
*/ */
%{ %{
...@@ -129,43 +129,24 @@ free_name_value_list(struct name_value_pair * list) ...@@ -129,43 +129,24 @@ free_name_value_list(struct name_value_pair * list)
* function does not return if an error occurs. If an error occurs, no * function does not return if an error occurs. If an error occurs, no
* values will be changed. * values will be changed.
*/ */
void static void
ProcessConfigFile(GucContext context) ReadConfigFile(char *filename, GucContext context)
{ {
int token, parse_state; int token, parse_state;
char *opt_name, *opt_value; char *opt_name, *opt_value;
char *filename;
struct name_value_pair *item, *head, *tail; struct name_value_pair *item, *head, *tail;
int elevel; int elevel;
FILE * fp; FILE * fp;
Assert(context == PGC_POSTMASTER || context == PGC_BACKEND
|| context == PGC_SIGHUP);
Assert(DataDir);
elevel = (context == PGC_SIGHUP) ? DEBUG4 : ERROR; elevel = (context == PGC_SIGHUP) ? DEBUG4 : ERROR;
/*
* Open file
*/
filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
if (filename == NULL)
{
ereport(elevel,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return;
}
sprintf(filename, "%s/" CONFIG_FILENAME, DataDir);
fp = AllocateFile(filename, "r"); fp = AllocateFile(filename, "r");
if (!fp) if (!fp)
{ {
free(filename); free(filename);
/* File not found is fine */ ereport(elevel,
if (errno != ENOENT) (errcode_for_file_access(),
ereport(elevel, errmsg("could not open configuration file \"%s\": %m", filename)));
(errcode_for_file_access(),
errmsg("could not open configuration file \"%s\": %m", CONFIG_FILENAME)));
return; return;
} }
...@@ -197,7 +178,8 @@ ProcessConfigFile(GucContext context) ...@@ -197,7 +178,8 @@ ProcessConfigFile(GucContext context)
token = yylex(); token = yylex();
if (token != GUC_ID && token != GUC_STRING && if (token != GUC_ID && token != GUC_STRING &&
token != GUC_INTEGER && token != GUC_REAL && token != GUC_INTEGER &&
token != GUC_REAL &&
token != GUC_UNQUOTED_STRING) token != GUC_UNQUOTED_STRING)
goto parse_error; goto parse_error;
opt_value = strdup(yytext); opt_value = strdup(yytext);
...@@ -259,7 +241,6 @@ ProcessConfigFile(GucContext context) ...@@ -259,7 +241,6 @@ ProcessConfigFile(GucContext context)
} }
FreeFile(fp); FreeFile(fp);
free(filename);
/* /*
* Check if all options are valid * Check if all options are valid
...@@ -282,12 +263,11 @@ ProcessConfigFile(GucContext context) ...@@ -282,12 +263,11 @@ ProcessConfigFile(GucContext context)
parse_error: parse_error:
FreeFile(fp); FreeFile(fp);
free(filename);
free_name_value_list(head); free_name_value_list(head);
ereport(elevel, ereport(elevel,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error in file \"%s\" line %u, near token \"%s\"", errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
CONFIG_FILENAME, ConfigFileLineno, yytext))); filename, ConfigFileLineno, yytext)));
return; return;
out_of_memory: out_of_memory:
...@@ -300,6 +280,65 @@ ProcessConfigFile(GucContext context) ...@@ -300,6 +280,65 @@ ProcessConfigFile(GucContext context)
return; return;
} }
/*
* Function to read and process the configuration file. The
* parameter indicates the context that 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 (user_pgconfig)
{
struct stat sb;
if (stat(user_pgconfig, &sb) != 0)
{
int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
elog(elevel, "Configuration file \"%s\" does not exist", user_pgconfig);
return;
}
if (S_ISDIR(sb.st_mode))
{
/* This will cause a small one time memory leak
* if the user also specifies hba_conf,
* ident_conf, and data_dir
*/
filename = malloc(strlen(user_pgconfig) + strlen(CONFIG_FILENAME) + 2);
sprintf(filename, "%s/%s", user_pgconfig, CONFIG_FILENAME);
user_pgconfig_is_dir = true;
}
else
filename = strdup(user_pgconfig); /* Use explicit file */
}
else
{
/* Use datadir for config */
filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
sprintf(filename, "%s/%s", DataDir, CONFIG_FILENAME);
}
if (filename == NULL)
{
int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
elog(elevel, "out of memory");
return;
}
ReadConfigFile(filename, context);
free(filename);
}
/* ---------------- /* ----------------
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.213 2004/07/05 23:14:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.214 2004/07/11 00:18:44 momjian Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -57,6 +57,13 @@ ...@@ -57,6 +57,13 @@
#include "utils/pg_locale.h" #include "utils/pg_locale.h"
#include "pgstat.h" #include "pgstat.h"
char *guc_pgdata;
char *guc_hbafile;
char *guc_identfile;
char *external_pidfile;
char *user_pgconfig = NULL;
bool user_pgconfig_is_dir = false;
#ifndef PG_KRB_SRVTAB #ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB "" #define PG_KRB_SRVTAB ""
...@@ -107,6 +114,7 @@ static bool assign_stage_log_stats(bool newval, bool doit, GucSource source); ...@@ -107,6 +114,7 @@ static bool assign_stage_log_stats(bool newval, bool doit, GucSource source);
static bool assign_log_stats(bool newval, bool doit, GucSource source); static bool assign_log_stats(bool newval, bool doit, GucSource source);
static bool assign_transaction_read_only(bool newval, bool doit, GucSource source); static bool assign_transaction_read_only(bool newval, bool doit, GucSource source);
static void ReadConfigFile(char *filename, GucContext context);
/* /*
* Debugging options * Debugging options
...@@ -1701,15 +1709,40 @@ static struct config_string ConfigureNamesString[] = ...@@ -1701,15 +1709,40 @@ static struct config_string ConfigureNamesString[] =
NULL, assign_custom_variable_classes, NULL NULL, assign_custom_variable_classes, NULL
}, },
{
{"pgdata", PGC_POSTMASTER, 0, gettext_noop("Sets the location of the data directory"), NULL},
&guc_pgdata,
NULL, NULL, NULL
},
{
{"hba_conf", PGC_SIGHUP, 0, gettext_noop("Sets the location of the \"hba\" configuration file"), NULL},
&guc_hbafile,
NULL, NULL, NULL
},
{
{"ident_conf", PGC_SIGHUP, 0, gettext_noop("Sets the location of the \"ident\" configuration file"), NULL},
&guc_identfile,
NULL, NULL, NULL
},
{
{"external_pidfile", PGC_POSTMASTER, 0, gettext_noop("Writes the postmaster PID to the specified file"), NULL},
&external_pidfile,
NULL, NULL, NULL
},
/* End-of-list marker */ /* End-of-list marker */
{ {
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
} }
}; };
/******** end of options list ********/
/******** end of options list ********/
/* /*
* To allow continued support of obsolete names for GUC variables, we apply * To allow continued support of obsolete names for GUC variables, we apply
* the following mappings to any unrecognized name. Note that an old name * the following mappings to any unrecognized name. Note that an old name
......
...@@ -21,6 +21,16 @@ ...@@ -21,6 +21,16 @@
# "pg_ctl reload". # "pg_ctl reload".
#---------------------------------------------------------------------------
# CONFIGURATION FILES
#---------------------------------------------------------------------------
# pgdata = '/usr/local/pgsql/data' # use data in another directory
# hba_conf = '/etc/pgsql/pg_hba.conf' # use hba info in another directory
# ident_conf = '/etc/pgsql/pg_ident.conf' # use ident info in another directory
# external_pidfile= '/var/run/postgresql.pid' # write an extra pid file
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION # CONNECTIONS AND AUTHENTICATION
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.48 2004/07/01 00:51:44 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.49 2004/07/11 00:18:45 momjian Exp $
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
#ifndef GUC_H #ifndef GUC_H
...@@ -135,6 +135,13 @@ extern int log_min_messages; ...@@ -135,6 +135,13 @@ extern int log_min_messages;
extern int client_min_messages; extern int client_min_messages;
extern int log_min_duration_statement; extern int log_min_duration_statement;
extern char *guc_pgdata;
extern char *guc_hbafile;
extern char *guc_identfile;
extern char *external_pidfile;
extern char *user_pgconfig;
extern bool user_pgconfig_is_dir;
extern void SetConfigOption(const char *name, const char *value, extern void SetConfigOption(const char *name, const char *value,
GucContext context, GucSource source); GucContext context, GucSource source);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment