diff --git a/config.c b/config.c index 2e161453..f97f99b6 100644 --- a/config.c +++ b/config.c @@ -22,7 +22,7 @@ static void tablespace_list_append(t_configuration_options *options, const char static char *trim(char *s); -static void exit_with_errors(ItemList *config_errors, ItemList *config_warnings, bool terse); +static void exit_with_config_file_errors(ItemList *config_errors, ItemList *config_warnings, bool terse); void @@ -172,7 +172,7 @@ parse_config(t_configuration_options *options, bool terse) /* errors found - exit after printing details, and any warnings */ if (config_errors.head != NULL) { - exit_with_errors(&config_errors, &config_warnings, terse); + exit_with_config_file_errors(&config_errors, &config_warnings, terse); } if (terse == false && config_warnings.head != NULL) @@ -649,7 +649,7 @@ reload_config(t_configuration_options *orig_options) /* TODO: don't emit warnings if --terse and no errors */ static void -exit_with_errors(ItemList *config_errors, ItemList *config_warnings, bool terse) +exit_with_config_file_errors(ItemList *config_errors, ItemList *config_warnings, bool terse) { ItemListCell *cell; @@ -675,6 +675,30 @@ exit_with_errors(ItemList *config_errors, ItemList *config_warnings, bool terse) } +void +exit_with_cli_errors(ItemList *error_list) +{ + fprintf(stderr, _("The following command line errors were encountered:\n")); + + print_item_list(error_list); + + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname()); + + exit(ERR_BAD_CONFIG); +} + +void +print_item_list(ItemList *item_list) +{ + ItemListCell *cell; + + for (cell = item_list->head; cell; cell = cell->next) + { + fprintf(stderr, " %s\n", cell->string); + } +} + + /* diff --git a/config.h b/config.h index aab5a201..fe81912f 100644 --- a/config.h +++ b/config.h @@ -167,4 +167,7 @@ bool parse_pg_basebackup_options(const char *pg_basebackup_options, int server_version_num, ItemList *error_list); +/* called by repmgr-client and repmgrd */ +void exit_with_cli_errors(ItemList *error_list); +void print_item_list(ItemList *item_list); #endif diff --git a/repmgr-client.c b/repmgr-client.c index 29eb87dd..5758ca8a 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -58,8 +58,8 @@ t_node_info target_node_info = T_NODE_INFO_INITIALIZER; /* Collate command line errors and warnings here for friendlier reporting */ -ItemList cli_errors = { NULL, NULL }; -ItemList cli_warnings = { NULL, NULL }; +static ItemList cli_errors = { NULL, NULL }; +static ItemList cli_warnings = { NULL, NULL }; int main(int argc, char **argv) @@ -410,7 +410,7 @@ main(int argc, char **argv) { PQExpBufferData invalid_log_level; initPQExpBuffer(&invalid_log_level); - appendPQExpBuffer(&invalid_log_level, _("Invalid log level \"%s\" provided"), optarg); + appendPQExpBuffer(&invalid_log_level, _("invalid log level \"%s\" provided"), optarg); item_list_append(&cli_errors, invalid_log_level.data); termPQExpBuffer(&invalid_log_level); } @@ -534,7 +534,7 @@ main(int argc, char **argv) /* Exit here already if errors in command line options found */ if (cli_errors.head != NULL) { - exit_with_errors(); + exit_with_cli_errors(&cli_errors); } /* @@ -674,7 +674,7 @@ main(int argc, char **argv) */ if (cli_errors.head != NULL) { - exit_with_errors(); + exit_with_cli_errors(&cli_errors); } /* @@ -1148,30 +1148,6 @@ action_name(const int action) return "UNKNOWN ACTION"; } -static void -exit_with_errors(void) -{ - fprintf(stderr, _("The following command line errors were encountered:\n")); - - print_item_list(&cli_errors); - - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname()); - - exit(ERR_BAD_CONFIG); -} - - -static void -print_item_list(ItemList *item_list) -{ - ItemListCell *cell; - - for (cell = item_list->head; cell; cell = cell->next) - { - fprintf(stderr, " %s\n", cell->string); - } -} - void print_error_list(ItemList *error_list, int log_level) diff --git a/repmgr-client.h b/repmgr-client.h index eb430408..9ce9bc2e 100644 --- a/repmgr-client.h +++ b/repmgr-client.h @@ -144,8 +144,7 @@ static void do_help(void); static const char *action_name(const int action); -static void exit_with_errors(void); -static void print_item_list(ItemList *item_list); + static void check_cli_parameters(const int action); static void write_primary_conninfo(char *line, t_conninfo_param_list *param_list); diff --git a/repmgrd.c b/repmgrd.c index 6724184e..ee16d133 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -26,6 +26,9 @@ static PGconn *local_conn = NULL; static PGconn *master_conn = NULL; +/* Collate command line errors here for friendlier reporting */ +static ItemList cli_errors = { NULL, NULL }; + /* * Record receipt SIGHUP; will cause configuration file to be reread at the * appropriate point in the main loop. @@ -51,6 +54,7 @@ main(int argc, char **argv) { int optindex; int c; + char log_level[MAXLEN] = ""; bool monitoring_history = false; static struct option long_options[] = @@ -67,6 +71,7 @@ main(int argc, char **argv) {"pid-file", required_argument, NULL, 'p'}, /* logging options */ + {"log-level", required_argument, NULL, 'L'}, {"verbose", no_argument, NULL, 'v'}, /* legacy options */ @@ -89,7 +94,7 @@ main(int argc, char **argv) exit(1); } - while ((c = getopt_long(argc, argv, "?Vf:vdp:m", long_options, &optindex)) != -1) + while ((c = getopt_long(argc, argv, "?Vf:L:vdp:m", long_options, &optindex)) != -1) { switch (c) { @@ -137,6 +142,24 @@ main(int argc, char **argv) /* logging options */ + /* -L/--log-level */ + case 'L': + { + int detected_log_level = detect_log_level(optarg); + if (detected_log_level != -1) + { + strncpy(log_level, optarg, MAXLEN); + } + else + { + PQExpBufferData invalid_log_level; + initPQExpBuffer(&invalid_log_level); + appendPQExpBuffer(&invalid_log_level, _("invalid log level \"%s\" provided"), optarg); + item_list_append(&cli_errors, invalid_log_level.data); + termPQExpBuffer(&invalid_log_level); + } + break; + } case 'v': verbose = true; break; @@ -154,6 +177,19 @@ main(int argc, char **argv) } } + /* Exit here already if errors in command line options found */ + if (cli_errors.head != NULL) + { + exit_with_cli_errors(&cli_errors); + } + + /* Some configuration file items can be overriden by command line options */ + /* Command-line parameter -L/--log-level overrides any setting in config file*/ + if (*log_level != '\0') + { + strncpy(config_file_options.loglevel, log_level, MAXLEN); + } + /* * Tell the logger we're a daemon - this will ensure any output logged * before the logger is initialized will be formatted correctly @@ -207,7 +243,7 @@ static void daemonize_process(void) { char *ptr, - path[MAXLEN]; + path[MAXPGPATH]; pid_t pid = fork(); int ret; @@ -218,7 +254,8 @@ daemonize_process(void) exit(ERR_SYS_FAILURE); break; - case 0: /* child process */ + case 0: + /* create independent session ID */ pid = setsid(); if (pid == (pid_t) -1) { @@ -229,20 +266,22 @@ daemonize_process(void) /* ensure that we are no longer able to open a terminal */ pid = fork(); - if (pid == -1) /* error case */ + /* error case */ + if (pid == -1) { log_error(_("error in fork():\n %s"), strerror(errno)); exit(ERR_SYS_FAILURE); } - if (pid != 0) /* parent process */ + /* parent process */ + if (pid != 0) { exit(0); } - /* a child just flows along */ + /* child process */ - memset(path, 0, MAXLEN); + memset(path, 0, MAXPGPATH); for (ptr = config_file + strlen(config_file); ptr > config_file; --ptr) { @@ -257,6 +296,7 @@ daemonize_process(void) *path = '/'; } + log_info("dir now %s", path); ret = chdir(path); if (ret != 0) {