diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-10-09 23:13:22 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-10-09 23:13:22 +0000 |
commit | 337ffcddbae15a3bde25b17dbb8a0832c597003f (patch) | |
tree | 8901b4f89003a45b6a7ebf5fc1a75c6506dd3264 /src/backend/utils | |
parent | 0d069c53c3b01b37388473c123f0a78a09d7d3e5 (diff) | |
download | postgresql-337ffcddbae15a3bde25b17dbb8a0832c597003f.tar.gz postgresql-337ffcddbae15a3bde25b17dbb8a0832c597003f.zip |
Adjust configuration-files GUC behavior as per my recent proposal.
The vars are renamed to data_directory, config_file, hba_file, and
ident_file, and are guaranteed to be set to accurate absolute paths
during postmaster startup.
This commit does not yet do anything about hiding path values from
non-superusers.
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/init/miscinit.c | 42 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 204 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 12 |
3 files changed, 172 insertions, 86 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 346ae3b9516..5a81c0467b3 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.134 2004/10/04 14:55:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.135 2004/10/09 23:13:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -171,7 +171,34 @@ SetDataDir(const char *dir) AssertArg(dir); /* If presented path is relative, convert to absolute */ - if (!is_absolute_path(dir)) + new = make_absolute_path(dir); + + if (DataDir) + free(DataDir); + DataDir = new; +} + +/* + * If the given pathname isn't already absolute, make it so, interpreting + * it relative to the current working directory. + * + * Also canonicalizes the path. The result is always a malloc'd copy. + * + * Note: it is probably unwise to use this in running backends, since they + * have chdir'd to a database-specific subdirectory; the results would not be + * consistent across backends. Currently this is used only during postmaster + * or standalone-backend startup. + */ +char * +make_absolute_path(const char *path) +{ + char *new; + + /* Returning null for null input is convenient for some callers */ + if (path == NULL) + return NULL; + + if (!is_absolute_path(path)) { char *buf; size_t buflen; @@ -200,28 +227,27 @@ SetDataDir(const char *dir) } } - new = malloc(strlen(buf) + 1 + strlen(dir) + 1); + new = malloc(strlen(buf) + strlen(path) + 2); if (!new) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); - sprintf(new, "%s/%s", buf, dir); + sprintf(new, "%s/%s", buf, path); free(buf); } else { - new = strdup(dir); + new = strdup(path); if (!new) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); } + /* Make sure punctuation is canonical, too */ canonicalize_path(new); - if (DataDir) - free(DataDir); - DataDir = new; + return new; } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 8e2deeeb007..a788e53266e 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.240 2004/10/08 01:36:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.241 2004/10/09 23:13:10 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -64,7 +64,9 @@ #define PG_KRB_SRVTAB "" #endif -#define CONFIG_FILENAME "postgresql.conf" +#define CONFIG_FILENAME "postgresql.conf" +#define HBA_FILENAME "pg_hba.conf" +#define IDENT_FILENAME "pg_ident.conf" #ifdef EXEC_BACKEND #define CONFIG_EXEC_PARAMS "global/config_exec_params" @@ -114,13 +116,6 @@ static const char *assign_canonical_path(const char *newval, bool doit, GucSourc /* - * These are initialized by SelectConfigFiles. - */ -char *ConfigDir = NULL; -char *ConfigFileName = NULL; - - -/* * GUC option variables that are exported from this module */ #ifdef USE_ASSERT_CHECKING @@ -154,9 +149,10 @@ int client_min_messages = NOTICE; int log_min_duration_statement = -1; -char *guc_hbafile; -char *guc_identfile; -char *external_pidfile; +char *ConfigFileName; +char *HbaFileName; +char *IdentFileName; +char *external_pid_file; /* @@ -183,7 +179,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 *data_directory; static char *custom_variable_classes; static int max_function_args; static int max_index_keys; @@ -1685,11 +1681,11 @@ static struct config_string ConfigureNamesString[] = { {"log_directory", PGC_SIGHUP, LOGGING_WHERE, gettext_noop("Sets the destination directory for log files."), - gettext_noop("May be specified as relative to the cluster directory " + gettext_noop("May be specified as relative to the data directory " "or as absolute path.") }, &Log_directory, - "pg_log", NULL, NULL + "pg_log", assign_canonical_path, NULL }, { {"log_filename", PGC_SIGHUP, LOGGING_WHERE, @@ -1789,38 +1785,48 @@ static struct config_string ConfigureNamesString[] = }, { - {"pgdata", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Sets the location of the data directory"), + {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's data directory"), NULL }, - &guc_pgdata, - NULL, assign_canonical_path, NULL + &data_directory, + NULL, NULL, NULL }, { - {"hba_conf", PGC_SIGHUP, FILE_LOCATIONS, - gettext_noop("Sets the location of the \"hba\" configuration file"), + {"config_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's main configuration file"), + NULL, + GUC_DISALLOW_IN_FILE + }, + &ConfigFileName, + NULL, NULL, NULL + }, + + { + {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's \"hba\" configuration file"), NULL }, - &guc_hbafile, - NULL, assign_canonical_path, NULL + &HbaFileName, + NULL, NULL, NULL }, { - {"ident_conf", PGC_SIGHUP, FILE_LOCATIONS, - gettext_noop("Sets the location of the \"ident\" configuration file"), + {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's \"ident\" configuration file"), NULL }, - &guc_identfile, - NULL, assign_canonical_path, NULL + &IdentFileName, + NULL, NULL, NULL }, { - {"external_pidfile", PGC_POSTMASTER, FILE_LOCATIONS, + {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Writes the postmaster PID to the specified file"), NULL }, - &external_pidfile, + &external_pid_file, NULL, assign_canonical_path, NULL }, @@ -2453,47 +2459,52 @@ InitializeGUCOptions(void) bool SelectConfigFiles(const char *userDoption, const char *progname) { - char *Doption; + char *configdir; + char *fname; 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); + /* configdir is -D option, or $PGDATA if no -D */ + if (userDoption) + configdir = make_absolute_path(userDoption); + else + configdir = make_absolute_path(getenv("PGDATA")); /* - * 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". + * Find the configuration file: if config_file was specified on the + * command line, use it, else use configdir/postgresql.conf. In any + * case ensure the result is an absolute path, so that it will be + * interpreted the same way by future backends. */ - if (stat(Doption, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) + if (ConfigFileName) + fname = make_absolute_path(ConfigFileName); + else if (!configdir) { - ConfigDir = Doption; - ConfigFileName = guc_malloc(FATAL, - strlen(ConfigDir) + strlen(CONFIG_FILENAME) + 2); - sprintf(ConfigFileName, "%s/%s", ConfigDir, CONFIG_FILENAME); + write_stderr("%s does not know where to find the server configuration file.\n" + "You must specify the --config_file or -D invocation " + "option or set the PGDATA environment variable.\n", + progname); + return false; } else { - ConfigFileName = Doption; + fname = guc_malloc(FATAL, + strlen(configdir) + strlen(CONFIG_FILENAME) + 2); + sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME); } + /* + * Set the ConfigFileName GUC variable to its final value, ensuring + * that it can't be overridden later. + */ + SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE); + free(fname); + + /* + * Now read the config file for the first time. + */ if (stat(ConfigFileName, &stat_buf) != 0) { - write_stderr("%s cannot access the data directory or configuration file \"%s\": %s\n", + write_stderr("%s cannot access the server configuration file \"%s\": %s\n", progname, ConfigFileName, strerror(errno)); return false; } @@ -2501,32 +2512,81 @@ SelectConfigFiles(const char *userDoption, const char *progname) ProcessConfigFile(PGC_POSTMASTER); /* - * If the config file specified pgdata, use that as DataDir; - * otherwise use ConfigDir (the original Doption) if set; - * else punt. + * If the data_directory GUC variable has been set, use that as DataDir; + * otherwise use configdir if set; else punt. * - * Note: SetDataDir will copy and canonicalize its argument, + * Note: SetDataDir will copy and absolute-ize its argument, * so we don't have to. */ - if (guc_pgdata) - SetDataDir(guc_pgdata); - else if (ConfigDir) - SetDataDir(ConfigDir); + if (data_directory) + SetDataDir(data_directory); + 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", + "This can be specified as \"data_directory\" in \"%s\", " + "or by the -D invocation option, or by the " + "PGDATA environment variable.\n", + progname, ConfigFileName); + return false; + } + + /* + * Reflect the final DataDir value back into the data_directory GUC var. + * (If you are wondering why we don't just make them a single variable, + * it's because the EXEC_BACKEND case needs DataDir to be transmitted to + * child backends specially.) + */ + SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE); + + /* + * Figure out where pg_hba.conf is, and make sure the path is absolute. + */ + if (HbaFileName) + fname = make_absolute_path(HbaFileName); + else if (!configdir) + { + write_stderr("%s does not know where to find the \"hba\" configuration file.\n" + "This can be specified as \"hba_file\" in \"%s\", " + "or by the -D invocation option, or by the " + "PGDATA environment variable.\n", progname, ConfigFileName); return false; } + else + { + fname = guc_malloc(FATAL, + strlen(configdir) + strlen(HBA_FILENAME) + 2); + sprintf(fname, "%s/%s", configdir, HBA_FILENAME); + } + SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE); + free(fname); /* - * 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. + * Likewise for pg_ident.conf. */ - if (!ConfigDir) - ConfigDir = DataDir; + if (IdentFileName) + fname = make_absolute_path(IdentFileName); + else if (!configdir) + { + write_stderr("%s does not know where to find the \"ident\" configuration file.\n" + "This can be specified as \"ident_file\" in \"%s\", " + "or by the -D invocation option, or by the " + "PGDATA environment variable.\n", + progname, ConfigFileName); + return false; + } + else + { + fname = guc_malloc(FATAL, + strlen(configdir) + strlen(IDENT_FILENAME) + 2); + sprintf(fname, "%s/%s", configdir, IDENT_FILENAME); + } + SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE); + free(fname); + + free(configdir); /* If timezone is not set, determine what the OS uses */ pg_timezone_initialize(); @@ -5703,7 +5763,6 @@ assign_canonical_path(const char *newval, bool doit, GucSource source) { if (doit) { - /* We have to create a new pointer to force the change */ char *canon_val = guc_strdup(ERROR, newval); canonicalize_path(canon_val); @@ -5713,4 +5772,5 @@ assign_canonical_path(const char *newval, bool doit, GucSource source) return newval; } + #include "guc-file.c" diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 3c689c7eacb..59004a73c05 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -30,13 +30,13 @@ #--------------------------------------------------------------------------- # 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 +# switch or PGDATA environment variable, represented here as ConfigDir. +# data_directory = 'ConfigDir' # use data in another directory +# hba_file = 'ConfigDir/pg_hba.conf' # the host-based authentication file +# ident_file = 'ConfigDir/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 +# If external_pid_file is not explicitly set, no extra pid file is written. +# external_pid_file = '(none)' # write an extra pid file #--------------------------------------------------------------------------- |