* See src/backend/utils/misc/README for more information.
*
*
- * Copyright (c) 2000-2013, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2014, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "postmaster/walwriter.h"
+#include "replication/slot.h"
#include "replication/syncrep.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/dsm_impl.h"
#include "storage/standby.h"
#include "storage/fd.h"
+#include "storage/pg_shmem.h"
#include "storage/proc.h"
#include "storage/predicate.h"
#include "tcop/tcopprot.h"
#ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB ""
#endif
-#ifndef PG_KRB_SRVNAM
-#define PG_KRB_SRVNAM ""
-#endif
#define CONFIG_FILENAME "postgresql.conf"
#define HBA_FILENAME "pg_hba.conf"
static void assign_session_replication_role(int newval, void *extra);
static bool check_temp_buffers(int *newval, void **extra, GucSource source);
static bool check_phony_autocommit(bool *newval, void **extra, GucSource source);
-static bool check_debug_assertions(bool *newval, void **extra, GucSource source);
static bool check_bonjour(bool *newval, void **extra, GucSource source);
static bool check_ssl(bool *newval, void **extra, GucSource source);
static bool check_stage_log_stats(bool *newval, void **extra, GucSource source);
static void assign_pgstat_temp_directory(const char *newval, void *extra);
static bool check_application_name(char **newval, void **extra, GucSource source);
static void assign_application_name(const char *newval, void *extra);
+static bool check_cluster_name(char **newval, void **extra, GucSource source);
static const char *show_unix_socket_permissions(void);
static const char *show_log_file_mode(void);
{NULL, 0, false}
};
+/*
+ * Although only "on", "off", "try" are documented, we accept all the likely
+ * variants of "on" and "off".
+ */
+static const struct config_enum_entry huge_pages_options[] = {
+ {"off", HUGE_PAGES_OFF, false},
+ {"on", HUGE_PAGES_ON, false},
+ {"try", HUGE_PAGES_TRY, false},
+ {"true", HUGE_PAGES_ON, true},
+ {"false", HUGE_PAGES_OFF, true},
+ {"yes", HUGE_PAGES_ON, true},
+ {"no", HUGE_PAGES_OFF, true},
+ {"1", HUGE_PAGES_ON, true},
+ {"0", HUGE_PAGES_OFF, true},
+ {NULL, 0, false}
+};
+
/*
* Options for enum values stored in other modules
*/
/*
* GUC option variables that are exported from this module
*/
-#ifdef USE_ASSERT_CHECKING
-bool assert_enabled = true;
-#else
-bool assert_enabled = false;
-#endif
bool log_duration = false;
bool Debug_print_plan = false;
bool Debug_print_parse = false;
int num_temp_buffers = 1024;
+char *cluster_name = "";
char *data_directory;
char *ConfigFileName;
char *HbaFileName;
int tcp_keepalives_interval;
int tcp_keepalives_count;
+/*
+ * This really belongs in pg_shmem.c, but is defined here so that it doesn't
+ * need to be duplicated in all the different implementations of pg_shmem.c.
+ */
+int huge_pages;
+
/*
* These variables are all dummies that don't do anything, except in some
* cases provide the value for SHOW to display. The real state is elsewhere
static int block_size;
static int segment_size;
static int wal_block_size;
-static bool data_checksums;
+static bool data_checksums;
static int wal_segment_size;
static bool integer_datetimes;
static int effective_io_concurrency;
+static bool assert_enabled;
/* should be static, but commands/variable.c needs to get at this */
char *role_string;
},
{
- {"wal_log_hintbits", PGC_POSTMASTER, WAL_SETTINGS,
+ {"wal_log_hints", PGC_POSTMASTER, WAL_SETTINGS,
gettext_noop("Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications"),
NULL
},
- &walLogHintbits,
+ &wal_log_hints,
false,
NULL, NULL, NULL
},
NULL, NULL, NULL
},
{
- {"debug_assertions", PGC_USERSET, DEVELOPER_OPTIONS,
- gettext_noop("Turns on various assertion checks."),
- gettext_noop("This is a debugging aid."),
- GUC_NOT_IN_SAMPLE
+ {"debug_assertions", PGC_INTERNAL, PRESET_OPTIONS,
+ gettext_noop("Shows whether the running server has assertion checks enabled."),
+ NULL,
+ GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
},
&assert_enabled,
#ifdef USE_ASSERT_CHECKING
#else
false,
#endif
- check_debug_assertions, NULL, NULL
+ NULL, NULL, NULL
},
{
{
{"data_checksums", PGC_INTERNAL, PRESET_OPTIONS,
- gettext_noop("Shows whether data checksums are turned on for this cluster"),
+ gettext_noop("Shows whether data checksums are turned on for this cluster."),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
},
GUC_UNIT_KB
},
&work_mem,
- 1024, 64, MAX_KILOBYTES,
+ 4096, 64, MAX_KILOBYTES,
NULL, NULL, NULL
},
GUC_UNIT_KB
},
&maintenance_work_mem,
- 16384, 1024, MAX_KILOBYTES,
+ 65536, 1024, MAX_KILOBYTES,
NULL, NULL, NULL
},
NULL, NULL, NULL
},
+ {
+ {"vacuum_multixact_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Minimum age at which VACUUM should freeze a MultiXactId in a table row."),
+ NULL
+ },
+ &vacuum_multixact_freeze_min_age,
+ 5000000, 0, 1000000000,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"vacuum_multixact_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Multixact age at which VACUUM should scan whole table to freeze tuples."),
+ NULL
+ },
+ &vacuum_multixact_freeze_table_age,
+ 150000000, 0, 2000000000,
+ NULL, NULL, NULL
+ },
+
{
{"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_MASTER,
gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
},
{
- {"xloginsert_slots", PGC_POSTMASTER, WAL_SETTINGS,
- gettext_noop("Sets the number of slots for concurrent xlog insertions."),
+ {"xloginsert_locks", PGC_POSTMASTER, WAL_SETTINGS,
+ gettext_noop("Sets the number of locks used for concurrent xlog insertions."),
NULL,
GUC_NOT_IN_SAMPLE
},
- &num_xloginsert_slots,
+ &num_xloginsert_locks,
8, 1, 1000,
NULL, NULL, NULL
},
NULL, NULL, NULL
},
+ {
+ /* see max_connections */
+ {"max_replication_slots", PGC_POSTMASTER, REPLICATION_SENDING,
+ gettext_noop("Sets the maximum number of simultaneously defined replication slots."),
+ NULL
+ },
+ &max_replication_slots,
+ 0, 0, MAX_BACKENDS /* XXX? */ ,
+ NULL, NULL, NULL
+ },
+
{
{"wal_sender_timeout", PGC_SIGHUP, REPLICATION_SENDING,
gettext_noop("Sets the maximum time to wait for WAL replication."),
200000000, 100000000, 2000000000,
NULL, NULL, NULL
},
+ {
+ /* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
+ {"autovacuum_multixact_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
+ gettext_noop("Multixact age at which to autovacuum a table to prevent multixact wraparound."),
+ NULL
+ },
+ &autovacuum_multixact_freeze_max_age,
+ 400000000, 10000000, 2000000000,
+ NULL, NULL, NULL
+ },
{
/* see max_connections */
{"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM,
GUC_UNIT_BLOCKS,
},
&effective_cache_size,
- -1, -1, INT_MAX,
- check_effective_cache_size, NULL, NULL
+ DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX,
+ NULL, NULL, NULL
},
{
{"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM,
gettext_noop("Sets the size reserved for pg_stat_activity.query, in bytes."),
NULL,
+
+ /*
+ * There is no _bytes_ unit, so the user can't supply units for
+ * this.
+ */
},
&pgstat_track_activity_query_size,
1024, 100, 102400,
NULL, NULL, NULL
},
- {
- {"krb_srvname", PGC_SIGHUP, CONN_AUTH_SECURITY,
- gettext_noop("Sets the name of the Kerberos service."),
- NULL
- },
- &pg_krb_srvnam,
- PG_KRB_SRVNAM,
- NULL, NULL, NULL
- },
-
{
{"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
gettext_noop("Sets the Bonjour service name."),
NULL
},
&event_source,
- "PostgreSQL",
+ DEFAULT_EVENT_SOURCE,
NULL, NULL, NULL
},
},
{
+ /*
+ * Can't be set by ALTER SYSTEM as it can lead to recursive definition
+ * of data_directory.
+ */
{"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the server's data directory."),
NULL,
- GUC_SUPERUSER_ONLY
+ GUC_SUPERUSER_ONLY | GUC_DISALLOW_IN_AUTO_FILE
},
&data_directory,
NULL,
GUC_SUPERUSER_ONLY
},
&pgstat_temp_directory,
- "pg_stat_tmp",
+ PG_STAT_TMP_DIR,
check_canonical_path, assign_pgstat_temp_directory, NULL
},
},
&SSLCipherSuites,
#ifdef USE_SSL
- "DEFAULT:!LOW:!EXP:!MD5:@STRENGTH",
+ "HIGH:MEDIUM:+3DES:!aNULL",
#else
"none",
#endif
check_application_name, assign_application_name, NULL
},
+ {
+ {"cluster_name", PGC_POSTMASTER, LOGGING_WHAT,
+ gettext_noop("Sets the name of the cluster which is included in the process title."),
+ NULL,
+ GUC_IS_NAME
+ },
+ &cluster_name,
+ "",
+ check_cluster_name, NULL, NULL
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL
},
+ {
+ {"huge_pages", PGC_POSTMASTER, RESOURCES_MEM,
+ gettext_noop("Use of huge pages on Linux"),
+ NULL
+ },
+ &huge_pages,
+ HUGE_PAGES_TRY, huge_pages_options,
+ NULL, NULL, NULL
+ },
/* End-of-list marker */
{
/*
- * Build the sorted array. This is split out so that it could be
+ * Build the sorted array. This is split out so that it could be
* re-executed after startup (eg, we could allow loadable modules to
* add vars, and then we'd need to re-sort).
*/
/*
* The char* is allocated at the end of the struct since we have no
- * 'static' place to point to. Note that the current value, as well as
+ * 'static' place to point to. Note that the current value, as well as
* the boot and reset values, start out NULL.
*/
var->variable = (char **) (var + 1);
return *res;
/*
- * See if the name is an obsolete name for a variable. We assume that the
+ * See if the name is an obsolete name for a variable. We assume that the
* set of supported old names is short enough that a brute-force search is
* the best way.
*/
*/
SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
+ /*
+ * Now read the config file a second time, allowing any settings in
+ * the PG_AUTOCONF_FILENAME file to take effect. (This is pretty ugly,
+ * but since we have to determine the DataDir before we can find the
+ * autoconf file, the alternatives seem worse.)
+ */
+ ProcessConfigFile(PGC_POSTMASTER);
+
/*
* If timezone_abbreviations wasn't set in the configuration file, install
* the default value. We do it this way because we can't safely install a
*/
pg_timezone_abbrev_initialize();
- set_default_effective_cache_size();
-
/*
* Figure out where pg_hba.conf is, and make sure the path is absolute.
*/
/*
* Do GUC processing at transaction or subtransaction commit or abort, or
* when exiting a function that has proconfig settings, or when undoing a
- * transient assignment to some GUC variables. (The name is thus a bit of
+ * transient assignment to some GUC variables. (The name is thus a bit of
* a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
* During abort, we discard all GUC settings that were applied at nesting
* levels >= nestLevel. nestLevel == 1 corresponds to the main transaction.
* 1: the value is valid
* 0: the name or value is invalid
*/
-bool
+static bool
validate_conf_option(struct config_generic * record, const char *name,
const char *value, GucSource source, int elevel,
bool freemem, void *newval, void **newextra)
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("parameter \"%s\" requires a Boolean value",
+ errmsg("parameter \"%s\" requires a Boolean value",
name)));
return 0;
}
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("invalid value for parameter \"%s\": \"%s\"",
- name, value),
+ errmsg("invalid value for parameter \"%s\": \"%s\"",
+ name, value),
hintmsg ? errhint("%s", _(hintmsg)) : 0));
return 0;
}
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
- *((int *) newval), name, conf->min, conf->max)));
+ *((int *) newval), name, conf->min, conf->max)));
return 0;
}
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("parameter \"%s\" requires a numeric value",
+ errmsg("parameter \"%s\" requires a numeric value",
name)));
return 0;
}
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
- *((double *) newval), name, conf->min, conf->max)));
+ *((double *) newval), name, conf->min, conf->max)));
return 0;
}
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("invalid value for parameter \"%s\": \"%s\"",
- name, value),
- hintmsg ? errhint("%s", _(hintmsg)) : 0));
+ errmsg("invalid value for parameter \"%s\": \"%s\"",
+ name, value),
+ hintmsg ? errhint("%s", _(hintmsg)) : 0));
if (hintmsg != NULL)
pfree(hintmsg);
* If a PGC_BACKEND parameter is changed in the config file,
* we want to accept the new value in the postmaster (whence
* it will propagate to subsequently-started backends), but
- * ignore it in existing backends. This is a tad klugy, but
+ * ignore it in existing backends. This is a tad klugy, but
* necessary because we don't re-read the config file during
* backend start.
+ *
+ * In EXEC_BACKEND builds, this works differently: we load all
+ * nondefault settings from the CONFIG_EXEC_PARAMS file during
+ * backend start. In that case we must accept PGC_SIGHUP
+ * settings, so as to have the same value as if we'd forked
+ * from the postmaster. We detect this situation by checking
+ * IsInitProcessingMode, which is a bit ugly, but it doesn't
+ * seem worth passing down an explicit flag saying we're doing
+ * read_nondefault_variables().
*/
+#ifdef EXEC_BACKEND
+ if (IsUnderPostmaster && !IsInitProcessingMode())
+ return -1;
+#else
if (IsUnderPostmaster)
return -1;
+#endif
}
else if (context != PGC_POSTMASTER && context != PGC_BACKEND &&
source != PGC_S_CLIENT)
* An exception might be made if the reset value is assumed to be "safe".
*
* Note: this flag is currently used for "session_authorization" and
- * "role". We need to prohibit changing these inside a local userid
+ * "role". We need to prohibit changing these inside a local userid
* context because when we exit it, GUC won't be notified, leaving things
* out of sync. (This could be fixed by forcing a new GUC nesting level,
* but that would change behavior in possibly-undesirable ways.) Also, we
else
{
/*
- * Plain string literal or identifier. For quote mode,
+ * Plain string literal or identifier. For quote mode,
* quote it if it's not a vanilla identifier.
*/
if (flags & GUC_LIST_QUOTE)
}
/*
- * Writes updated configuration parameter values into
- * postgresql.auto.conf.temp file. It traverses the list of parameters
- * and quote the string values before writing them to temporaray file.
+ * Write updated configuration parameter values into a temporary file.
+ * This function traverses the list of parameters and quotes the string
+ * values before writing them.
*/
static void
write_auto_conf_file(int fd, const char *filename, ConfigVariable **head_p)
StringInfoData buf;
initStringInfo(&buf);
- appendStringInfoString(&buf, "# Do not edit this file manually! \n");
- appendStringInfoString(&buf, "# It will be overwritten by ALTER SYSTEM command. \n");
+ appendStringInfoString(&buf, "# Do not edit this file manually!\n");
+ appendStringInfoString(&buf, "# It will be overwritten by ALTER SYSTEM command.\n");
/*
* write the file header message before contents, so that if there is no
/*
* This function takes list of all configuration parameters in
- * postgresql.auto.conf and parameter to be updated as input arguments and
+ * PG_AUTOCONF_FILENAME and parameter to be updated as input arguments and
* replace the updated configuration parameter value in a list. If the
* parameter to be updated is new then it is appended to the list of
* parameters.
* and write them all to the automatic configuration file.
*
* The configuration parameters are written to a temporary
- * file then renamed to the final name. The template for the
- * temporary file is postgresql.auto.conf.temp.
+ * file then renamed to the final name.
*
* An LWLock is used to serialize writing to the same file.
*
* In case of an error, we leave the original automatic
- * configuration file (postgresql.auto.conf) intact.
+ * configuration file (PG_AUTOCONF_FILENAME) intact.
*/
void
-AlterSystemSetConfigFile(AlterSystemStmt * altersysstmt)
+AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
{
char *name;
char *value;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- (errmsg("must be superuser to execute ALTER SYSTEM command"))));
+ (errmsg("must be superuser to execute ALTER SYSTEM command"))));
/*
* Validate the name and arguments [value1, value2 ... ].
if (record == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("unrecognized configuration parameter \"%s\"", name)));
+ errmsg("unrecognized configuration parameter \"%s\"", name)));
+ /*
+ * Don't allow the parameters which can't be set in configuration
+ * files to be set in PG_AUTOCONF_FILENAME file.
+ */
if ((record->context == PGC_INTERNAL) ||
- (record->flags & GUC_DISALLOW_IN_FILE))
- ereport(ERROR,
- (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
- errmsg("parameter \"%s\" cannot be changed",
- name)));
+ (record->flags & GUC_DISALLOW_IN_FILE) ||
+ (record->flags & GUC_DISALLOW_IN_AUTO_FILE))
+ ereport(ERROR,
+ (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+ errmsg("parameter \"%s\" cannot be changed",
+ name)));
if (!validate_conf_option(record, name, value, PGC_S_FILE,
ERROR, true, NULL,
&newextra))
ereport(ERROR,
- (errmsg("invalid value for parameter \"%s\": \"%s\"", name, value)));
+ (errmsg("invalid value for parameter \"%s\": \"%s\"", name, value)));
/*
- * Use data directory as reference path for postgresql.auto.conf and it's
- * corresponding temp file
+ * Use data directory as reference path for PG_AUTOCONF_FILENAME and its
+ * corresponding temporary file.
*/
join_path_components(AutoConfFileName, data_directory, PG_AUTOCONF_FILENAME);
canonicalize_path(AutoConfFileName);
snprintf(AutoConfTmpFileName, sizeof(AutoConfTmpFileName), "%s.%s",
AutoConfFileName,
- "temp");
+ "tmp");
/*
- * one backend is allowed to operate on postgresql.auto.conf file, to
+ * One backend is allowed to operate on file PG_AUTOCONF_FILENAME, to
* ensure that we need to update the contents of the file with
* AutoFileLock. To ensure crash safety, first the contents are written to
- * temporary file and then rename it to postgresql.auto.conf. In case
- * there exists a temp file from previous crash, that can be reused.
+ * a temporary file which is then renameed to PG_AUTOCONF_FILENAME. In
+ * case there exists a temp file from previous crash, that can be reused.
*/
LWLockAcquire(AutoFileLock, LW_EXCLUSIVE);
{
if (stat(AutoConfFileName, &st) == 0)
{
- /* open postgresql.auto.conf file */
+ /* open file PG_AUTOCONF_FILENAME */
infile = AllocateFile(AutoConfFileName, "r");
if (infile == NULL)
ereport(ERROR,
(errmsg("failed to open auto conf file \"%s\": %m ",
AutoConfFileName)));
- /* Parse the postgresql.auto.conf file */
+ /* parse it */
ParseConfigFp(infile, AutoConfFileName, 0, LOG, &head, &tail);
FreeFile(infile);
*/
replace_auto_config_value(&head, &tail, AutoConfFileName, name, value);
- /* Write and sync the New contents to postgresql.auto.conf.temp file */
+ /* Write and sync the new contents to the temporary file */
write_auto_conf_file(Tmpfd, AutoConfTmpFileName, &head);
close(Tmpfd);
0);
break;
case VAR_SET_MULTI:
+
/*
* Special-case SQL syntaxes. The TRANSACTION and SESSION
* CHARACTERISTICS cases effectively set more than one variable
* variable. Essentially, we need to duplicate all the active and stacked
* values, but with appropriate validation and datatype adjustment.
*
- * If an assignment fails, we report a WARNING and keep going. We don't
+ * If an assignment fails, we report a WARNING and keep going. We don't
* want to throw ERROR for bad values, because it'd bollix the add-on
* module that's presumably halfway through getting loaded. In such cases
* the default or previous state will become active instead.
/*
* Free up as much as we conveniently can of the placeholder structure.
* (This neglects any stack items, so it's possible for some memory to be
- * leaked. Since this can only happen once per session per variable, it
+ * leaked. Since this can only happen once per session per variable, it
* doesn't seem worth spending much code on.)
*/
set_string_field(pHolder, pHolder->variable, NULL);
else
{
/*
- * We are at the end of the stack. If the active/previous value is
+ * We are at the end of the stack. If the active/previous value is
* different from the reset value, it must represent a previously
* committed session value. Apply it, and then drop the stack entry
* that set_config_option will have created under the impression that
GucSource varsource;
GucContext varscontext;
+ /*
+ * Assert that PGC_BACKEND case in set_config_option() will do the right
+ * thing.
+ */
+ Assert(IsInitProcessingMode());
+
/*
* Open file
*/
/*
* Handle options fetched from pg_db_role_setting.setconfig,
- * pg_proc.proconfig, etc. Caller must specify proper context/source/action.
+ * pg_proc.proconfig, etc. Caller must specify proper context/source/action.
*
* The array parameter must be an array of TEXT (it must not be NULL).
*/
* Validate a proposed option setting for GUCArrayAdd/Delete/Reset.
*
* name is the option name. value is the proposed value for the Add case,
- * or NULL for the Delete/Reset cases. If skipIfNoPermissions is true, it's
+ * or NULL for the Delete/Reset cases. If skipIfNoPermissions is true, it's
* not an error to have no permissions to set the option.
*
* Returns TRUE if OK, FALSE if skipIfNoPermissions is true and user does not
* ERRCODE_INVALID_PARAMETER_VALUE SQLSTATE for check hook failures.
*
* Note that GUC_check_errmsg() etc are just macros that result in a direct
- * assignment to the associated variables. That is ugly, but forced by the
+ * assignment to the associated variables. That is ugly, but forced by the
* limitations of C's macro mechanisms.
*/
void
return true;
}
-static bool
-check_debug_assertions(bool *newval, void **extra, GucSource source)
-{
-#ifndef USE_ASSERT_CHECKING
- if (*newval)
- {
- GUC_check_errmsg("assertion checking is not supported by this build");
- return false;
- }
-#endif
- return true;
-}
-
static bool
check_bonjour(bool *newval, void **extra, GucSource source)
{
pgstat_report_appname(newval);
}
+static bool
+check_cluster_name(char **newval, void **extra, GucSource source)
+{
+ /* Only allow clean ASCII chars in the cluster name */
+ char *p;
+
+ for (p = *newval; *p; p++)
+ {
+ if (*p < 32 || *p > 126)
+ *p = '?';
+ }
+
+ return true;
+}
+
static const char *
show_unix_socket_permissions(void)
{