Whack some sense into the configuration-file-location patch.

Refactor code into something reasonably understandable, cause
use of the feature to not fail in standalone backends or in
EXEC_BACKEND case, fix sloppy guc.c table entries, make the
documentation minimally usable.
This commit is contained in:
Tom Lane 2004-10-08 01:36:36 +00:00
parent f4f6caa9b0
commit 7ca3a0f3e2
12 changed files with 310 additions and 277 deletions

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/postgres-ref.sgml,v 1.43 2004/02/03 17:34:02 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/postgres-ref.sgml,v 1.44 2004/10/08 01:36:32 tgl Exp $
PostgreSQL documentation
-->
@ -357,7 +357,7 @@ PostgreSQL documentation
<listitem>
<para>
Default data direction location
Default data directory location
</para>
</listitem>
</varlistentry>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/postmaster.sgml,v 1.52 2004/09/20 00:04:19 neilc Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/postmaster.sgml,v 1.53 2004/10/08 01:36:32 tgl Exp $
PostgreSQL documentation
-->
@ -67,27 +67,22 @@ PostgreSQL documentation
One <command>postmaster</command> always manages the data
from exactly one database cluster. A database cluster is a
collection of databases that is stored at a common file system
location. When the <command>postmaster</command> starts it needs
to know the location of the database cluster files (<quote>data
area</quote>).
location (the <quote>data area</quote>).
More than one <command>postmaster</command> process can run on a system
at one time as long as they use different data areas and different
at one time, so long as they use different data areas and different
communication ports (see below). A data area is created with <xref
linkend="app-initdb">.
</para>
<para>
The <quote>data area</> is specified by the <option>-D</option> option
When the <command>postmaster</command> starts it needs
to know the location of the data area.
The location must be 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</> variable 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.
Typically, <option>-D</option> or <envar>PGDATA</envar> points
directly to the data area directory created by <application>initdb</>.
Other possible file layouts are discussed in
<xref linkend="runtime-config-file-locations">.
</para>
</refsect1>
@ -154,8 +149,9 @@ PostgreSQL documentation
<term><option>-D <replaceable class="parameter">datadir</replaceable></option></term>
<listitem>
<para>
Specifies the file system location of the data directory. See
discussion above.
Specifies the file system location of the data directory or
configuration file(s). See
<xref linkend="runtime-config-file-locations"> for details.
</para>
</listitem>
</varlistentry>
@ -394,7 +390,7 @@ PostgreSQL documentation
<listitem>
<para>
Default data direction location
Default data directory location
</para>
</listitem>
</varlistentry>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.285 2004/09/29 06:27:11 neilc Exp $
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.286 2004/10/08 01:36:31 tgl Exp $
-->
<Chapter Id="runtime">
@ -564,17 +564,16 @@ SET ENABLE_SEQSCAN TO OFF;
any desired selection condition.
</para>
<sect2 id="runtime-config-configuration-files">
<title>Configuration Files</title>
<sect2 id="runtime-config-file-locations">
<title>File Locations</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).
Specifies the directory to use for data storage.
This option can only be set at server start.
</para>
</listitem>
</varlistentry>
@ -585,6 +584,8 @@ SET ENABLE_SEQSCAN TO OFF;
<para>
Specifies the file name to use for configuration of host-based
authentication (HBA).
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
@ -595,6 +596,8 @@ SET ENABLE_SEQSCAN TO OFF;
<para>
Specifies the file name to use for configuration of
<application>ident</> authentication.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> file.
</para>
</listitem>
</varlistentry>
@ -605,11 +608,50 @@ SET ENABLE_SEQSCAN TO OFF;
<para>
Specifies the location of an additional <application>postmaster</>
process-id (PID) file for use by server administration programs.
This option can only be set at server start.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
In a default installation, none of the above options is set explicitly
in the <filename>postgresql.conf</filename> file. In this case, the
data directory is specified by the <option>-D</option> command-line
option or the <envar>PGDATA</envar> environment variable; there is no
default for it. The configuration files are all placed within the
data directory.
</para>
<para>
It is also possible to separate the configuration files from the data
directory, which can ease administration. (In particular it is often
easier to ensure that the configuration files are properly backed-up
when they are kept separate.) To do this, the <option>-D</option>
command-line option or <envar>PGDATA</envar> environment variable
must point to the directory containing the configuration files,
and the <varname>pgdata</> option is set in
<filename>postgresql.conf</filename> (or on the command line) to show
where the data directory is actually located.
</para>
<para>
If you wish, you can also make the <option>-D</option>
command-line option or <envar>PGDATA</envar> environment variable
point directly to the master configuration file (which then need not be
named <filename>postgresql.conf</filename>). The <varname>pgdata</>
option must be set to determine the data directory location.
The other configuration files will by default be sought
in the data directory.
</para>
<para>
With any of these approaches, you can specify the locations of the
secondary configuration files (<filename>pg_hba.conf</> and
<filename>pg_ident.conf</>) by setting <varname>hba_conf</> and/or
<varname>ident_conf</> in the master configuration file. These options
override the normal locations and names of the secondary files.
</para>
</sect2>
<sect2 id="runtime-config-connection">

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.193 2004/08/29 05:06:41 momjian Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.194 2004/10/08 01:36:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -210,7 +210,7 @@ BootstrapMain(int argc, char *argv[])
char *dbname;
int flag;
int xlogop = BS_XLOG_NOP;
char *userPGDATA = NULL;
char *userDoption = NULL;
/*
* initialize globals
@ -240,10 +240,7 @@ BootstrapMain(int argc, char *argv[])
/* Set defaults, to be overriden by explicit options below */
dbname = NULL;
if (!IsUnderPostmaster)
{
InitializeGUCOptions();
userPGDATA = getenv("PGDATA"); /* Null if no PGDATA variable */
}
/* Ignore the initial -boot argument, if present */
if (argc > 1 && strcmp(argv[1], "-boot") == 0)
@ -257,7 +254,7 @@ BootstrapMain(int argc, char *argv[])
switch (flag)
{
case 'D':
userPGDATA = optarg;
userDoption = optarg;
break;
case 'd':
{
@ -328,24 +325,6 @@ BootstrapMain(int argc, char *argv[])
if (!dbname || argc != optind)
usage();
if (!IsUnderPostmaster)
{
if (!userPGDATA)
{
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"
"either by specifying the -D invocation option or by setting the\n"
"PGDATA environment variable.\n",
argv[0]);
proc_exit(1);
}
SetDataDir(userPGDATA);
}
/* Validate we have been given a reasonable-looking DataDir */
Assert(DataDir);
ValidatePgVersion(DataDir);
/*
* Identify myself via ps
*/
@ -372,12 +351,14 @@ BootstrapMain(int argc, char *argv[])
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
if (!SelectConfigFiles(userDoption, argv[0]))
proc_exit(1);
}
/* Validate we have been given a reasonable-looking DataDir */
Assert(DataDir);
ValidatePgVersion(DataDir);
/* If standalone, create lockfile for data directory */
if (!IsUnderPostmaster)
CreateDataDirLockFile(DataDir, false);

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.130 2004/09/18 01:22:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.131 2004/10/08 01:36:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1044,16 +1044,16 @@ load_hba(void)
if (hba_lines || hba_line_nums)
free_lines(&hba_lines, &hba_line_nums);
/* HBA filename in config file */
if (guc_hbafile)
{
/* HBA filename specified in config file */
conf_file = pstrdup(guc_hbafile);
}
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);
conf_file = palloc(strlen(ConfigDir) + strlen(CONF_FILE) + 2);
sprintf(conf_file, "%s/%s", ConfigDir, CONF_FILE);
}
file = AllocateFile(conf_file, "r");
@ -1198,16 +1198,15 @@ load_ident(void)
if (ident_lines || ident_line_nums)
free_lines(&ident_lines, &ident_line_nums);
/* IDENT filename in config file */
if (guc_identfile)
{
/* IDENT filename specified in config file */
map_file = pstrdup(guc_identfile);
}
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);
map_file = palloc(strlen(ConfigDir) + strlen(USERMAP_FILE) + 2);
sprintf(map_file, "%s/%s", ConfigDir, USERMAP_FILE);
}
file = AllocateFile(map_file, "r");

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.429 2004/10/07 17:04:54 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.430 2004/10/08 01:36:34 tgl Exp $
*
* NOTES
*
@ -236,8 +236,7 @@ extern int optreset;
/*
* postmaster.c - function prototypes
*/
static void checkDataDir(const char *checkdir);
static bool onlyConfigSpecified(const char *checkdir);
static void checkDataDir(void);
#ifdef USE_RENDEZVOUS
static void reg_reply(DNSServiceRegistrationReplyErrorType errorCode,
@ -311,7 +310,7 @@ PostmasterMain(int argc, char *argv[])
{
int opt;
int status;
char *userPGDATA = NULL;
char *userDoption = NULL;
int i;
progname = get_progname(argv[0]);
@ -375,8 +374,6 @@ PostmasterMain(int argc, char *argv[])
*/
InitializeGUCOptions();
userPGDATA = getenv("PGDATA"); /* default value */
opterr = 1;
while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)
@ -400,7 +397,7 @@ PostmasterMain(int argc, char *argv[])
/* Can no longer set the backend executable file to use. */
break;
case 'D':
userPGDATA = optarg;
userDoption = optarg;
break;
case 'd':
{
@ -530,61 +527,15 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(1);
}
if (userPGDATA)
{
userPGDATA = strdup(userPGDATA);
canonicalize_path(userPGDATA);
}
/*
* Locate the proper configuration files and data directory, and
* read postgresql.conf for the first time.
*/
if (!SelectConfigFiles(userDoption, progname))
ExitPostmaster(2);
if (onlyConfigSpecified(userPGDATA))
{
/*
* It is either a file name or a directory with no
* global/pg_control file, and hence not a data directory.
*/
user_pgconfig = userPGDATA;
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 */
pg_timezone_initialize();
/* Verify that DataDir looks reasonable */
checkDataDir();
#ifdef EXEC_BACKEND
write_nondefault_variables(PGC_POSTMASTER);
@ -831,6 +782,24 @@ PostmasterMain(int argc, char *argv[])
if (!CreateOptsFile(argc, argv, my_exec_path))
ExitPostmaster(1);
/*
* Write the external PID file if requested
*/
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
write_stderr("%s: could not write external pid file \"%s\": %s\n",
progname, external_pidfile, strerror(errno));
}
/*
* Set up signal handlers for the postmaster process.
*
@ -907,66 +876,30 @@ 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
*/
static void
checkDataDir(const char *checkdir)
checkDataDir(void)
{
char path[MAXPGPATH];
FILE *fp;
struct stat stat_buf;
if (checkdir == NULL)
{
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"
"either by specifying the -D invocation option or by setting the\n"
"PGDATA environment variable.\n",
progname);
ExitPostmaster(2);
}
Assert(DataDir);
if (stat(checkdir, &stat_buf) == -1)
if (stat(DataDir, &stat_buf) != 0)
{
if (errno == ENOENT)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("data directory \"%s\" does not exist",
checkdir)));
DataDir)));
else
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not read permissions of directory \"%s\": %m",
checkdir)));
DataDir)));
}
/*
@ -981,14 +914,14 @@ checkDataDir(const char *checkdir)
ereport(FATAL,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("data directory \"%s\" has group or world access",
checkdir),
DataDir),
errdetail("Permissions should be u=rwx (0700).")));
#endif
/* Look for PG_VERSION before looking for pg_control */
ValidatePgVersion(checkdir);
ValidatePgVersion(DataDir);
snprintf(path, sizeof(path), "%s/global/pg_control", checkdir);
snprintf(path, sizeof(path), "%s/global/pg_control", DataDir);
fp = AllocateFile(path, PG_BINARY_R);
if (fp == NULL)
@ -996,7 +929,7 @@ checkDataDir(const char *checkdir)
write_stderr("%s: could not find the database system\n"
"Expected to find it in the directory \"%s\",\n"
"but could not open file \"%s\": %s\n",
progname, checkdir, path, strerror(errno));
progname, DataDir, path, strerror(errno));
ExitPostmaster(2);
}
FreeFile(fp);
@ -3457,6 +3390,12 @@ write_backend_variables(char *filename, Port *port)
StrNCpy(str_buf, DataDir, MAXPGPATH);
write_array_var(str_buf, fp);
StrNCpy(str_buf, ConfigDir, MAXPGPATH);
write_array_var(str_buf, fp);
StrNCpy(str_buf, ConfigFileName, MAXPGPATH);
write_array_var(str_buf, fp);
write_array_var(ListenSocket, fp);
write_var(MyCancelKey, fp);
@ -3531,6 +3470,12 @@ read_backend_variables(char *filename, Port *port)
read_array_var(str_buf, fp);
SetDataDir(str_buf);
read_array_var(str_buf, fp);
ConfigDir = strdup(str_buf);
read_array_var(str_buf, fp);
ConfigFileName = strdup(str_buf);
read_array_var(ListenSocket, fp);
read_var(MyCancelKey, fp);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.433 2004/09/26 00:26:25 tgl Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.434 2004/10/08 01:36:35 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -2156,7 +2156,7 @@ PostgresMain(int argc, char *argv[], const char *username)
{
int flag;
const char *dbname = NULL;
char *userPGDATA = NULL;
char *userDoption = NULL;
bool secure;
int errs = 0;
int debug_flag = 0;
@ -2226,10 +2226,7 @@ PostgresMain(int argc, char *argv[], const char *username)
EchoQuery = false;
if (!IsUnderPostmaster)
{
InitializeGUCOptions();
userPGDATA = getenv("PGDATA");
}
/* ----------------
* parse command line arguments
@ -2274,9 +2271,9 @@ PostgresMain(int argc, char *argv[], const char *username)
SetConfigOption("shared_buffers", optarg, ctx, gucsource);
break;
case 'D': /* PGDATA directory */
case 'D': /* PGDATA or config directory */
if (secure)
userPGDATA = optarg;
userDoption = optarg;
break;
case 'd': /* debug level */
@ -2571,28 +2568,11 @@ PostgresMain(int argc, char *argv[], const char *username)
on_proc_exit(log_disconnections, 0);
}
if (!IsUnderPostmaster)
{
if (!userPGDATA)
{
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"
"either by specifying the -D invocation option or by setting the\n"
"PGDATA environment variable.\n",
argv[0]);
proc_exit(1);
}
SetDataDir(userPGDATA);
}
Assert(DataDir);
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
if (!SelectConfigFiles(userDoption, argv[0]))
proc_exit(1);
}
/*
@ -2685,6 +2665,7 @@ PostgresMain(int argc, char *argv[], const char *username)
* Validate we have been given a reasonable-looking DataDir (if
* under postmaster, assume postmaster did this already).
*/
Assert(DataDir);
ValidatePgVersion(DataDir);
/*

View File

@ -4,14 +4,13 @@
*
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.25 2004/08/31 22:43:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.26 2004/10/08 01:36:35 tgl Exp $
*/
%{
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
@ -22,8 +21,6 @@
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
#define CONFIG_FILENAME "postgresql.conf"
static unsigned ConfigFileLineno;
enum {
@ -128,7 +125,6 @@ void
ProcessConfigFile(GucContext context)
{
int elevel;
char *filename;
int token, parse_state;
char *opt_name, *opt_value;
struct name_value_pair *item, *head, *tail;
@ -147,46 +143,13 @@ ProcessConfigFile(GucContext context)
else
elevel = ERROR;
/*
* Handle the various possibilities for config file location
*/
if (user_pgconfig)
{
struct stat sb;
if (stat(user_pgconfig, &sb) != 0)
{
ereport(elevel,
(errcode_for_file_access(),
errmsg("could not access configuration file \"%s\": %m",
user_pgconfig)));
return;
}
if (S_ISDIR(sb.st_mode))
{
filename = palloc(strlen(user_pgconfig) + strlen(CONFIG_FILENAME) + 2);
sprintf(filename, "%s/%s", user_pgconfig, CONFIG_FILENAME);
user_pgconfig_is_dir = true;
}
else
filename = pstrdup(user_pgconfig); /* Use explicit file */
}
else
{
/* Find config in datadir */
filename = palloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
sprintf(filename, "%s/%s", DataDir, CONFIG_FILENAME);
}
fp = AllocateFile(filename, "r");
fp = AllocateFile(ConfigFileName, "r");
if (!fp)
{
ereport(elevel,
(errcode_for_file_access(),
errmsg("could not open configuration file \"%s\": %m",
filename)));
pfree(filename);
ConfigFileName)));
return;
}
@ -273,7 +236,6 @@ ProcessConfigFile(GucContext context)
}
FreeFile(fp);
pfree(filename);
/*
* Check if all options are valid
@ -303,13 +265,12 @@ ProcessConfigFile(GucContext context)
ereport(elevel,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error in file \"%s\" line %u, near end of line",
filename, ConfigFileLineno - 1)));
ConfigFileName, ConfigFileLineno - 1)));
else
ereport(elevel,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
filename, ConfigFileLineno, yytext)));
pfree(filename);
ConfigFileName, ConfigFileLineno, yytext)));
}

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.239 2004/09/24 19:43:03 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.240 2004/10/08 01:36:35 tgl Exp $
*
*--------------------------------------------------------------------
*/
@ -20,6 +20,7 @@
#include <float.h>
#include <limits.h>
#include <unistd.h>
#include <sys/stat.h>
#include "utils/guc.h"
#include "utils/guc_tables.h"
@ -58,18 +59,13 @@
#include "utils/pg_locale.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
#define PG_KRB_SRVTAB ""
#endif
#define CONFIG_FILENAME "postgresql.conf"
#ifdef EXEC_BACKEND
#define CONFIG_EXEC_PARAMS "global/config_exec_params"
#endif
@ -118,7 +114,14 @@ static const char *assign_canonical_path(const char *newval, bool doit, GucSourc
/*
* Debugging options
* These are initialized by SelectConfigFiles.
*/
char *ConfigDir = NULL;
char *ConfigFileName = NULL;
/*
* GUC option variables that are exported from this module
*/
#ifdef USE_ASSERT_CHECKING
bool assert_enabled = true;
@ -151,6 +154,10 @@ int client_min_messages = NOTICE;
int log_min_duration_statement = -1;
char *guc_hbafile;
char *guc_identfile;
char *external_pidfile;
/*
* These variables are all dummies that don't do anything, except in some
@ -176,6 +183,7 @@ static char *server_encoding_string;
static char *server_version_string;
static char *timezone_string;
static char *XactIsoLevel_string;
static char *guc_pgdata;
static char *custom_variable_classes;
static int max_function_args;
static int max_index_keys;
@ -231,6 +239,8 @@ const char *const config_group_names[] =
{
/* UNGROUPED */
gettext_noop("Ungrouped"),
/* FILE_LOCATIONS */
gettext_noop("File Locations"),
/* CONN_AUTH */
gettext_noop("Connections and Authentication"),
/* CONN_AUTH_SETTINGS */
@ -291,10 +301,12 @@ const char *const config_group_names[] =
gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"),
/* COMPAT_OPTIONS_CLIENT */
gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"),
/* PRESET_OPTIONS */
gettext_noop("Preset Options"),
/* CUSTOM_OPTIONS */
gettext_noop("Customized Options"),
/* DEVELOPER_OPTIONS */
gettext_noop("Developer Options"),
/* COMPILE_OPTIONS */
gettext_noop("Compiled-in Options"),
/* help_config wants this array to be null-terminated */
NULL
};
@ -833,7 +845,7 @@ static struct config_bool ConfigureNamesBool[] =
#endif
{
{"integer_datetimes", PGC_INTERNAL, COMPILE_OPTIONS,
{"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Datetimes are integer based"),
NULL,
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1282,7 +1294,7 @@ static struct config_int ConfigureNamesInt[] =
},
{
{"max_function_args", PGC_INTERNAL, COMPILE_OPTIONS,
{"max_function_args", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the maximum number of function arguments"),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1292,7 +1304,7 @@ static struct config_int ConfigureNamesInt[] =
},
{
{"max_index_keys", PGC_INTERNAL, COMPILE_OPTIONS,
{"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the maximum number of index keys"),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1302,7 +1314,7 @@ static struct config_int ConfigureNamesInt[] =
},
{
{"max_identifier_length", PGC_INTERNAL, COMPILE_OPTIONS,
{"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the maximum identifier length"),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1312,7 +1324,7 @@ static struct config_int ConfigureNamesInt[] =
},
{
{"block_size", PGC_INTERNAL, COMPILE_OPTIONS,
{"block_size", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows size of a disk block"),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1640,7 +1652,7 @@ static struct config_string ConfigureNamesString[] =
{
/* Can't be set in postgresql.conf */
{"server_version", PGC_INTERNAL, UNGROUPED,
{"server_version", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the server version."),
NULL,
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
@ -1777,25 +1789,37 @@ static struct config_string ConfigureNamesString[] =
},
{
{"pgdata", PGC_POSTMASTER, 0, gettext_noop("Sets the location of the data directory"), NULL},
{"pgdata", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the location of the data directory"),
NULL
},
&guc_pgdata,
NULL, assign_canonical_path, NULL
},
{
{"hba_conf", PGC_SIGHUP, 0, gettext_noop("Sets the location of the \"hba\" configuration file"), NULL},
{"hba_conf", PGC_SIGHUP, FILE_LOCATIONS,
gettext_noop("Sets the location of the \"hba\" configuration file"),
NULL
},
&guc_hbafile,
NULL, assign_canonical_path, NULL
},
{
{"ident_conf", PGC_SIGHUP, 0, gettext_noop("Sets the location of the \"ident\" configuration file"), NULL},
{"ident_conf", PGC_SIGHUP, FILE_LOCATIONS,
gettext_noop("Sets the location of the \"ident\" configuration file"),
NULL
},
&guc_identfile,
NULL, assign_canonical_path, NULL
},
{
{"external_pidfile", PGC_POSTMASTER, 0, gettext_noop("Writes the postmaster PID to the specified file"), NULL},
{"external_pidfile", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Writes the postmaster PID to the specified file"),
NULL
},
&external_pidfile,
NULL, assign_canonical_path, NULL
},
@ -2247,6 +2271,9 @@ guc_name_compare(const char *namea, const char *nameb)
/*
* Initialize GUC options during program startup.
*
* Note that we cannot read the config file yet, since we have not yet
* processed command-line switches.
*/
void
InitializeGUCOptions(void)
@ -2412,6 +2439,102 @@ InitializeGUCOptions(void)
}
/*
* Select the configuration files and data directory to be used, and
* do the initial read of postgresql.conf.
*
* This is called after processing command-line switches.
* userDoption is the -D switch value if any (NULL if unspecified).
* progname is just for use in error messages.
*
* Returns true on success; on failure, prints a suitable error message
* to stderr and returns false.
*/
bool
SelectConfigFiles(const char *userDoption, const char *progname)
{
char *Doption;
struct stat stat_buf;
/* If user did not specify -D, it defaults to $PGDATA */
if (!userDoption)
userDoption = getenv("PGDATA");
/* If no PGDATA either, we are completely lost */
if (!userDoption)
{
write_stderr("%s does not know where to find the database system data.\n"
"You must specify the -D invocation option or set the "
"PGDATA environment variable.\n",
progname);
return false;
}
/* Get a writable copy and canonicalize the path */
Doption = guc_strdup(FATAL, userDoption);
canonicalize_path(Doption);
/*
* If it is a directory, point ConfigDir to it, and expect to
* find postgresql.conf within. Otherwise it had better be
* the actual config file, and the file had better set "pgdata".
*/
if (stat(Doption, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode))
{
ConfigDir = Doption;
ConfigFileName = guc_malloc(FATAL,
strlen(ConfigDir) + strlen(CONFIG_FILENAME) + 2);
sprintf(ConfigFileName, "%s/%s", ConfigDir, CONFIG_FILENAME);
}
else
{
ConfigFileName = Doption;
}
if (stat(ConfigFileName, &stat_buf) != 0)
{
write_stderr("%s cannot access the data directory or configuration file \"%s\": %s\n",
progname, ConfigFileName, strerror(errno));
return false;
}
ProcessConfigFile(PGC_POSTMASTER);
/*
* If the config file specified pgdata, use that as DataDir;
* otherwise use ConfigDir (the original Doption) if set;
* else punt.
*
* Note: SetDataDir will copy and canonicalize its argument,
* so we don't have to.
*/
if (guc_pgdata)
SetDataDir(guc_pgdata);
else if (ConfigDir)
SetDataDir(ConfigDir);
else
{
write_stderr("%s does not know where to find the database system data.\n"
"This should be specified as \"pgdata\" in \"%s\".\n",
progname, ConfigFileName);
return false;
}
/*
* Set ConfigDir as DataDir unless we had another value (which is to say,
* Doption pointed to a directory). This determines the default location
* of secondary configuration files that will be read later.
*/
if (!ConfigDir)
ConfigDir = DataDir;
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
return true;
}
/*
* Reset all options to their saved default values (implements RESET ALL)
*/

View File

@ -26,13 +26,17 @@
#---------------------------------------------------------------------------
# CONFIGURATION FILES
# FILE LOCATIONS
#---------------------------------------------------------------------------
# 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
# The default values of these variables are driven from the -D command line
# switch or PGDATA environment variable, represented here as $PGDATA.
# pgdata = '$PGDATA' # use data in another directory
# hba_conf = '$PGDATA/pg_hba.conf' # the host-based authentication file
# ident_conf = '$PGDATA/pg_ident.conf' # the IDENT configuration file
# If external_pidfile is not explicitly set, no extra pid file is written.
# external_pidfile = '(none)' # write an extra pid file
#---------------------------------------------------------------------------

View File

@ -7,7 +7,7 @@
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.51 2004/08/29 05:06:58 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.52 2004/10/08 01:36:36 tgl Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
@ -135,13 +135,12 @@ extern int log_min_messages;
extern int client_min_messages;
extern int log_min_duration_statement;
extern char *guc_pgdata;
extern char *ConfigDir;
extern char *ConfigFileName;
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,
GucContext context, GucSource source);
@ -188,6 +187,7 @@ extern const char *GetConfigOption(const char *name);
extern const char *GetConfigOptionResetString(const char *name);
extern void ProcessConfigFile(GucContext context);
extern void InitializeGUCOptions(void);
extern bool SelectConfigFiles(const char *userDoption, const char *progname);
extern void ResetAllOptions(void);
extern void AtEOXact_GUC(bool isCommit, bool isSubXact);
extern void BeginReportingGUCOptions(void);

View File

@ -7,7 +7,7 @@
*
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.16 2004/08/29 05:06:58 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.17 2004/10/08 01:36:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -39,6 +39,7 @@ union config_var_value
enum config_group
{
UNGROUPED,
FILE_LOCATIONS,
CONN_AUTH,
CONN_AUTH_SETTINGS,
CONN_AUTH_SECURITY,
@ -69,9 +70,9 @@ enum config_group
COMPAT_OPTIONS,
COMPAT_OPTIONS_PREVIOUS,
COMPAT_OPTIONS_CLIENT,
DEVELOPER_OPTIONS,
COMPILE_OPTIONS,
CUSTOM_OPTIONS
PRESET_OPTIONS,
CUSTOM_OPTIONS,
DEVELOPER_OPTIONS
};
/*