From 30fd111cbaf67651f21ca4efd2753c10ac22d277 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Mon, 21 Sep 2015 15:55:29 +0900 Subject: [PATCH] Rework config file handling If no configuration file provided, also check default Postgres sysconfig dir. It would also be useful to check the configuration directory provided by the RPM/DEB packages, not sure if that's programmatically feasible. --- config.c | 74 +++++++++++++++++++++++++++++++++++++------------------ config.h | 5 ++-- repmgr.c | 5 ++-- repmgrd.c | 12 ++++----- 4 files changed, 61 insertions(+), 35 deletions(-) diff --git a/config.c b/config.c index b67a616f..658f7139 100644 --- a/config.c +++ b/config.c @@ -27,9 +27,11 @@ static void parse_event_notifications_list(t_configuration_options *options, const char *arg); static void tablespace_list_append(t_configuration_options *options, const char *arg); +static char config_file_path[MAXPGPATH]; +static bool config_file_provided = false; /* - * parse_config() + * load_config() * * Set default options and overwrite with values from provided configuration * file. @@ -40,30 +42,21 @@ static void tablespace_list_append(t_configuration_options *options, const char * reload_config() */ bool -parse_config(const char *config_file, t_configuration_options *options) +load_config(const char *config_file, t_configuration_options *options, char *argv0) { - char *s, - buff[MAXLINELENGTH]; - char config_file_buf[MAXLEN]; - char name[MAXLEN]; - char value[MAXLEN]; - bool config_file_provided = false; - FILE *fp; - + struct stat config; /* Sanity checks */ /* * If a configuration file was provided, check it exists, otherwise - * emit an error + * emit an error and terminate */ if (config_file[0]) { - struct stat config; + strncpy(config_file_path, config_file, MAXPGPATH); + canonicalize_path(config_file_path); - strncpy(config_file_buf, config_file, MAXLEN); - canonicalize_path(config_file_buf); - - if(stat(config_file_buf, &config) != 0) + if(stat(config_file_path, &config) != 0) { log_err(_("provided configuration file '%s' not found: %s\n"), config_file, @@ -76,16 +69,49 @@ parse_config(const char *config_file, t_configuration_options *options) } /* - * If no configuration file was provided, set to a default file - * which `parse_config()` will attempt to read if it exists + * If no configuration file was provided, attempt to find a default file */ - else + if(config_file_provided == false) { - strncpy(config_file_buf, DEFAULT_CONFIG_FILE, MAXLEN); + char my_exec_path[MAXPGPATH]; + char etc_path[MAXPGPATH]; + + /* First check if one is in the default sysconfdir */ + if (find_my_exec(argv0, my_exec_path) < 0) + { + fprintf(stderr, _("%s: could not find own program executable\n"), argv0); + exit(EXIT_FAILURE); + } + + get_etc_path(my_exec_path, etc_path); + + snprintf(config_file_path, MAXPGPATH, "%s/repmgr.conf", etc_path); + + log_debug(_("Looking for configuration file in %s\n"), etc_path); + + if(stat(config_file_path, &config) != 0) + { + /* Not found - default to ./repmgr.conf */ + strncpy(config_file_path, DEFAULT_CONFIG_FILE, MAXPGPATH); + canonicalize_path(config_file_path); + log_debug(_("Looking for configuration file in %s\n"), config_file_path); + } } + return parse_config(options); +} - fp = fopen(config_file_buf, "r"); + +bool +parse_config(t_configuration_options *options) +{ + FILE *fp; + char *s, + buff[MAXLINELENGTH]; + char name[MAXLEN]; + char value[MAXLEN]; + + fp = fopen(config_file_path, "r"); /* * Since some commands don't require a config file at all, not having one @@ -101,7 +127,7 @@ parse_config(const char *config_file, t_configuration_options *options) { if(config_file_provided) { - log_err(_("unable to open provided configuration file '%s'; terminating\n"), config_file_buf); + log_err(_("unable to open provided configuration file '%s'; terminating\n"), config_file_path); exit(ERR_BAD_CONFIG); } @@ -394,7 +420,7 @@ parse_line(char *buff, char *name, char *value) } bool -reload_config(char *config_file, t_configuration_options * orig_options) +reload_config(t_configuration_options *orig_options) { PGconn *conn; t_configuration_options new_options; @@ -405,7 +431,7 @@ reload_config(char *config_file, t_configuration_options * orig_options) */ log_info(_("reloading configuration file and updating repmgr tables\n")); - parse_config(config_file, &new_options); + parse_config(&new_options); if (new_options.node == -1) { log_warning(_("unable to parse new configuration, retaining current configuration\n")); diff --git a/config.h b/config.h index 2d3b756f..5731d140 100644 --- a/config.h +++ b/config.h @@ -83,9 +83,10 @@ typedef struct #define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", 0, 0, 0, "", { NULL, NULL }, {NULL, NULL} } -bool parse_config(const char *config_file, t_configuration_options *options); +bool load_config(const char *config_file, t_configuration_options *options, char *argv0); +bool reload_config(t_configuration_options *orig_options); +bool parse_config(t_configuration_options *options); void parse_line(char *buff, char *name, char *value); char *trim(char *s); -bool reload_config(char *config_file, t_configuration_options *orig_options); #endif diff --git a/repmgr.c b/repmgr.c index b7b90eeb..b11c49e1 100644 --- a/repmgr.c +++ b/repmgr.c @@ -419,7 +419,6 @@ main(int argc, char **argv) if (runtime_options.verbose && runtime_options.config_file[0]) { - log_notice(_("opening configuration file: %s\n"), runtime_options.config_file); } @@ -429,7 +428,7 @@ main(int argc, char **argv) * however if available we'll parse it anyway for options like 'log_level', * 'use_replication_slots' etc. */ - config_file_parsed = parse_config(runtime_options.config_file, &options); + config_file_parsed = load_config(runtime_options.config_file, &options, argv[0]); /* * Initialise pg_bindir - command line parameter will override @@ -3355,7 +3354,7 @@ do_check_upstream_config(void) bool config_ok; int server_version_num; - parse_config(runtime_options.config_file, &options); + parse_config(&options); /* Connection parameters for upstream server only */ keywords[0] = "host"; diff --git a/repmgrd.c b/repmgrd.c index 6da172b2..80cf20dd 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -202,7 +202,7 @@ main(int argc, char **argv) * which case we'll need to refactor parse_config() not to abort, * and return the error message. */ - parse_config(config_file, &local_options); + load_config(config_file, &local_options, argv[0]); if (daemonize) { @@ -313,7 +313,7 @@ main(int argc, char **argv) check_cluster_configuration(my_local_conn); check_node_configuration(); - if (reload_config(config_file, &local_options)) + if (reload_config(&local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); @@ -362,10 +362,10 @@ main(int argc, char **argv) if (got_SIGHUP) { /* - * if we can reload, then could need to change + * if we can reload the configuration file, then could need to change * my_local_conn */ - if (reload_config(config_file, &local_options)) + if (reload_config(&local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); @@ -426,7 +426,7 @@ main(int argc, char **argv) check_cluster_configuration(my_local_conn); check_node_configuration(); - if (reload_config(config_file, &local_options)) + if (reload_config(&local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); @@ -477,7 +477,7 @@ main(int argc, char **argv) * if we can reload, then could need to change * my_local_conn */ - if (reload_config(config_file, &local_options)) + if (reload_config(&local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true);