diff --git a/config.c b/config.c index befb4ab9..93ac9fc3 100644 --- a/config.c +++ b/config.c @@ -1,5 +1,6 @@ /* * config.c - Functions to parse the config file + * * Copyright (C) 2ndQuadrant, 2010-2016 * * This program is free software: you can redistribute it and/or modify @@ -26,7 +27,7 @@ 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 void exit_with_errors(ErrorList *config_errors); +static void exit_with_errors(ItemList *config_errors); const static char *_progname = NULL; static char config_file_path[MAXPGPATH]; @@ -201,7 +202,7 @@ parse_config(t_configuration_options *options) char *conninfo_errmsg = NULL; /* Collate configuration file errors here for friendlier reporting */ - static ErrorList config_errors = { NULL, NULL }; + static ItemList config_errors = { NULL, NULL }; bool node_found = false; @@ -333,7 +334,7 @@ parse_config(t_configuration_options *options) } else { - error_list_append(&config_errors,_("value for 'failover' must be 'automatic' or 'manual'\n")); + item_list_append(&config_errors,_("value for 'failover' must be 'automatic' or 'manual'\n")); } } else if (strcmp(name, "priority") == 0) @@ -406,7 +407,7 @@ parse_config(t_configuration_options *options) _("no value provided for parameter \"%s\""), name); - error_list_append(&config_errors, error_message_buf); + item_list_append(&config_errors, error_message_buf); } } @@ -415,11 +416,11 @@ parse_config(t_configuration_options *options) if (node_found == false) { - error_list_append(&config_errors, _("\"node\": parameter was not found")); + item_list_append(&config_errors, _("\"node\": parameter was not found")); } else if (options->node == 0) { - error_list_append(&config_errors, _("\"node\": must be greater than zero")); + item_list_append(&config_errors, _("\"node\": must be greater than zero")); } if (strlen(options->conninfo)) @@ -439,7 +440,7 @@ parse_config(t_configuration_options *options) _("\"conninfo\": %s"), conninfo_errmsg); - error_list_append(&config_errors, error_message_buf); + item_list_append(&config_errors, error_message_buf); } PQconninfoFree(conninfo_options); @@ -770,11 +771,11 @@ reload_config(t_configuration_options *orig_options) void -error_list_append(ErrorList *error_list, char *error_message) +item_list_append(ItemList *item_list, char *error_message) { - ErrorListCell *cell; + ItemListCell *cell; - cell = (ErrorListCell *) pg_malloc0(sizeof(ErrorListCell)); + cell = (ItemListCell *) pg_malloc0(sizeof(ItemListCell)); if (cell == NULL) { @@ -782,19 +783,19 @@ error_list_append(ErrorList *error_list, char *error_message) exit(ERR_BAD_CONFIG); } - cell->error_message = pg_malloc0(MAXLEN); - strncpy(cell->error_message, error_message, MAXLEN); + cell->string = pg_malloc0(MAXLEN); + strncpy(cell->string, error_message, MAXLEN); - if (error_list->tail) + if (item_list->tail) { - error_list->tail->next = cell; + item_list->tail->next = cell; } else { - error_list->head = cell; + item_list->head = cell; } - error_list->tail = cell; + item_list->tail = cell; } @@ -804,7 +805,7 @@ error_list_append(ErrorList *error_list, char *error_message) * otherwise exit */ int -repmgr_atoi(const char *value, const char *config_item, ErrorList *error_list, bool allow_negative) +repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, bool allow_negative) { char *endptr; long longval = 0; @@ -853,7 +854,7 @@ repmgr_atoi(const char *value, const char *config_item, ErrorList *error_list, b exit(ERR_BAD_CONFIG); } - error_list_append(error_list, error_message_buf); + item_list_append(error_list, error_message_buf); } return (int32) longval; @@ -995,15 +996,15 @@ parse_event_notifications_list(t_configuration_options *options, const char *arg static void -exit_with_errors(ErrorList *config_errors) +exit_with_errors(ItemList *config_errors) { - ErrorListCell *cell; + ItemListCell *cell; log_err(_("%s: following errors were found in the configuration file.\n"), progname()); for (cell = config_errors->head; cell; cell = cell->next) { - log_err("%s\n", cell->error_message); + log_err("%s\n", cell->string); } exit(ERR_BAD_CONFIG); diff --git a/config.h b/config.h index dac706af..6f7133bd 100644 --- a/config.h +++ b/config.h @@ -1,5 +1,6 @@ /* * config.h + * * Copyright (c) 2ndQuadrant, 2010-2016 * * This program is free software: you can redistribute it and/or modify @@ -92,17 +93,17 @@ typedef struct */ #define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", "", 0, 0, 0, 0, "", { NULL, NULL }, {NULL, NULL} } -typedef struct ErrorListCell +typedef struct ItemListCell { - struct ErrorListCell *next; - char *error_message; -} ErrorListCell; + struct ItemListCell *next; + char *string; +} ItemListCell; -typedef struct ErrorList +typedef struct ItemList { - ErrorListCell *head; - ErrorListCell *tail; -} ErrorList; + ItemListCell *head; + ItemListCell *tail; +} ItemList; void set_progname(const char *argv0); const char * progname(void); @@ -112,10 +113,10 @@ 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); -void error_list_append(ErrorList *error_list, char *error_message); +void item_list_append(ItemList *item_list, char *error_message); int repmgr_atoi(const char *s, const char *config_item, - ErrorList *error_list, + ItemList *error_list, bool allow_negative); - +extern bool config_file_found; #endif diff --git a/dbutils.c b/dbutils.c index c962ba0d..c0034fbf 100644 --- a/dbutils.c +++ b/dbutils.c @@ -1,5 +1,6 @@ /* * dbutils.c - Database connection/management functions + * * Copyright (C) 2ndQuadrant, 2010-2016 * * This program is free software: you can redistribute it and/or modify diff --git a/dbutils.h b/dbutils.h index d96667fa..89b40454 100644 --- a/dbutils.h +++ b/dbutils.h @@ -1,5 +1,6 @@ /* * dbutils.h + * * Copyright (c) 2ndQuadrant, 2010-2016 * * This program is free software: you can redistribute it and/or modify @@ -77,7 +78,7 @@ typedef struct s_replication_slot bool active; } t_replication_slot; - +extern char repmgr_schema[MAXLEN]; PGconn *_establish_db_connection(const char *conninfo, const bool exit_on_error, diff --git a/repmgr.c b/repmgr.c index 3f05351d..ad7db6d1 100644 --- a/repmgr.c +++ b/repmgr.c @@ -1,5 +1,6 @@ /* * repmgr.c - Command interpreter for the repmgr package + * * Copyright (C) 2ndQuadrant, 2010-2016 * * This module is a command-line utility to easily setup a cluster of @@ -117,7 +118,7 @@ static void do_check_upstream_config(void); static void do_help(void); static void exit_with_errors(void); -static void print_error_list(ErrorList *error_list, int log_level); +static void print_error_list(ItemList *error_list, int log_level); static bool remote_command(const char *host, const char *user, const char *command, PQExpBufferData *outputbuf); static void format_db_cli_params(const char *conninfo, char *output); @@ -126,6 +127,7 @@ static bool copy_file(const char *old_filename, const char *new_filename); static bool read_backup_label(const char *local_data_directory, struct BackupLabel *out_backup_label); static void param_set(const char *param, const char *value); +static void parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options); /* Global variables */ static PQconninfoOption *opts = NULL; @@ -155,8 +157,8 @@ static char *repmgr_slot_name_ptr = NULL; static char path_buf[MAXLEN] = ""; /* Collate command line errors and warnings here for friendlier reporting */ -ErrorList cli_errors = { NULL, NULL }; -ErrorList cli_warnings = { NULL, NULL }; +ItemList cli_errors = { NULL, NULL }; +ItemList cli_warnings = { NULL, NULL }; static struct BackupLabel backup_label; @@ -228,7 +230,6 @@ main(int argc, char **argv) exit(1); } - param_count = 0; defs = PQconndefaults(); @@ -417,7 +418,7 @@ main(int argc, char **argv) PQExpBufferData invalid_log_level; initPQExpBuffer(&invalid_log_level); appendPQExpBuffer(&invalid_log_level, _("Invalid log level \"%s\" provided"), optarg); - error_list_append(&cli_errors, invalid_log_level.data); + item_list_append(&cli_errors, invalid_log_level.data); termPQExpBuffer(&invalid_log_level); } break; @@ -439,7 +440,7 @@ main(int argc, char **argv) PQExpBufferData invalid_mode; initPQExpBuffer(&invalid_mode); appendPQExpBuffer(&invalid_mode, _("Invalid pg_ctl shutdown mode \"%s\" provided"), optarg); - error_list_append(&cli_errors, invalid_mode.data); + item_list_append(&cli_errors, invalid_mode.data); termPQExpBuffer(&invalid_mode); } } @@ -458,7 +459,7 @@ main(int argc, char **argv) if (targ < 1) { - error_list_append(&cli_errors, _("Invalid value provided for '-r/--recovery-min-apply-delay'")); + item_list_append(&cli_errors, _("Invalid value provided for '-r/--recovery-min-apply-delay'")); break; } if (ptr && *ptr) @@ -467,7 +468,7 @@ main(int argc, char **argv) strcmp(ptr, "min") != 0 && strcmp(ptr, "h") != 0 && strcmp(ptr, "d") != 0) { - error_list_append(&cli_errors, _("Value provided for '-r/--recovery-min-apply-delay' must be one of ms/s/min/h/d")); + item_list_append(&cli_errors, _("Value provided for '-r/--recovery-min-apply-delay' must be one of ms/s/min/h/d")); break; } } @@ -500,7 +501,7 @@ main(int argc, char **argv) initPQExpBuffer(&unknown_option); appendPQExpBuffer(&unknown_option, _("Unknown option '%s'"), argv[optind - 1]); - error_list_append(&cli_errors, unknown_option.data); + item_list_append(&cli_errors, unknown_option.data); } } } @@ -526,7 +527,7 @@ main(int argc, char **argv) PQExpBufferData conninfo_error; initPQExpBuffer(&conninfo_error); appendPQExpBuffer(&conninfo_error, _("error parsing conninfo:\n%s"), errmsg); - error_list_append(&cli_errors, conninfo_error.data); + item_list_append(&cli_errors, conninfo_error.data); termPQExpBuffer(&conninfo_error); free(errmsg); @@ -614,7 +615,7 @@ main(int argc, char **argv) PQExpBufferData unknown_mode; initPQExpBuffer(&unknown_mode); appendPQExpBuffer(&unknown_mode, _("Unknown server mode '%s'"), server_mode); - error_list_append(&cli_errors, unknown_mode.data); + item_list_append(&cli_errors, unknown_mode.data); } } @@ -663,14 +664,14 @@ main(int argc, char **argv) if (action == NO_ACTION) { if (server_cmd == NULL) { - error_list_append(&cli_errors, "No server command provided"); + item_list_append(&cli_errors, "No server command provided"); } else { PQExpBufferData unknown_action; initPQExpBuffer(&unknown_action); appendPQExpBuffer(&unknown_action, _("Unknown server command '%s'"), server_cmd); - error_list_append(&cli_errors, unknown_action.data); + item_list_append(&cli_errors, unknown_action.data); } } @@ -686,7 +687,7 @@ main(int argc, char **argv) appendPQExpBuffer(&additional_host_arg, _("Conflicting parameters: you can't use %s while providing a node separately."), conninfo_provided == true ? "host=" : "-h/--host"); - error_list_append(&cli_errors, additional_host_arg.data); + item_list_append(&cli_errors, additional_host_arg.data); } else { @@ -701,7 +702,7 @@ main(int argc, char **argv) PQExpBufferData too_many_args; initPQExpBuffer(&too_many_args); appendPQExpBuffer(&too_many_args, _("too many command-line arguments (first extra is \"%s\")"), argv[optind]); - error_list_append(&cli_errors, too_many_args.data); + item_list_append(&cli_errors, too_many_args.data); } check_parameters_for_action(action); @@ -4614,10 +4615,17 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, static int run_basebackup(const char *data_dir, int server_version) { - char script[MAXLEN]; - int r = 0; - PQExpBufferData params; - TablespaceListCell *cell; + char script[MAXLEN]; + int r = 0; + PQExpBufferData params; + TablespaceListCell *cell; + t_basebackup_options backup_options = T_BASEBACKUP_OPTIONS_INITIALIZER; + + /* + * Parse the pg_basebackup_options provided in repmgr.conf - we'll want + * to check later whether certain options were set by the user + */ + parse_pg_basebackup_options(options.pg_basebackup_options, &backup_options); /* Create pg_basebackup command line options */ @@ -4678,33 +4686,39 @@ run_basebackup(const char *data_dir, int server_version) * created a slot with reserved LSN, and will stream from that slot to avoid * WAL buildup on the master using the -S/--slot, which requires -X/--xlog-method=stream */ + if (!strlen(backup_options.xlog_method)) { - /* - * We're going to check first if the user set the xlog method in the repmgr.conf - * file. We don't want to have conflicts with pg_basebackup due to specifying the - * method twice. - */ - const char xlog_short[4] = "-X "; - const char xlog_long[14] = "--xlog-method"; - if (strstr(options.pg_basebackup_options, xlog_short) == NULL && strstr(options.pg_basebackup_options, xlog_long) == NULL ) - { - appendPQExpBuffer(¶ms, " -X stream"); - } + appendPQExpBuffer(¶ms, " -X stream"); } /* * From 9.6, pg_basebackup accepts -S/--slot, which forces WAL streaming to use * the specified replication slot. If replication slot usage is specified, the - * slot will already have been created + * slot will already have been created. * - * XXX verify that -X/--xlog-method is set to "stream" + * NOTE: currently there's no way of disabling the --slot option while using + * --xlog-method=stream - it's hard to imagine a use case for this, so no + * provision has been made for doing it. + * + * NOTE: + * It's possible to set 'pg_basebackup_options' with an invalid combination + * of values for --xlog-method and --slot - we're not checking that, just that + * we're not overriding any user-supplied values */ if (server_version >= 90600 && options.use_replication_slots) { - const char slot_short[4] = "-S "; - const char slot_long[7] = "--slot"; + bool slot_add = true; - if (strstr(options.pg_basebackup_options, slot_short) == NULL && strstr(options.pg_basebackup_options, slot_long) == NULL ) + /* + * Check whether 'pg_basebackup_options' in repmgr.conf has the --slot option set, + * or if --xlog-method is set to a value other than "stream" (in which case we can't + * use --slot). + */ + if(strlen(backup_options.slot) || strcmp(backup_options.xlog_method, "stream") != 0) { + slot_add = false; + } + + if (slot_add == true) { appendPQExpBuffer(¶ms, " -S %s", repmgr_slot_name_ptr); } @@ -4748,11 +4762,11 @@ check_parameters_for_action(const int action) */ if (connection_param_provided) { - error_list_append(&cli_warnings, _("master connection parameters not required when executing MASTER REGISTER")); + item_list_append(&cli_warnings, _("master connection parameters not required when executing MASTER REGISTER")); } if (runtime_options.dest_dir[0]) { - error_list_append(&cli_warnings, _("destination directory not required when executing MASTER REGISTER")); + item_list_append(&cli_warnings, _("destination directory not required when executing MASTER REGISTER")); } break; case STANDBY_REGISTER: @@ -4764,11 +4778,11 @@ check_parameters_for_action(const int action) */ if (connection_param_provided) { - error_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY REGISTER")); + item_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY REGISTER")); } if (runtime_options.dest_dir[0]) { - error_list_append(&cli_warnings, _("destination directory not required when executing STANDBY REGISTER")); + item_list_append(&cli_warnings, _("destination directory not required when executing STANDBY REGISTER")); } break; case STANDBY_UNREGISTER: @@ -4780,11 +4794,11 @@ check_parameters_for_action(const int action) */ if (connection_param_provided) { - error_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY UNREGISTER")); + item_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY UNREGISTER")); } if (runtime_options.dest_dir[0]) { - error_list_append(&cli_warnings, _("destination directory not required when executing STANDBY UNREGISTER")); + item_list_append(&cli_warnings, _("destination directory not required when executing STANDBY UNREGISTER")); } break; case STANDBY_PROMOTE: @@ -4797,11 +4811,11 @@ check_parameters_for_action(const int action) */ if (connection_param_provided) { - error_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY PROMOTE")); + item_list_append(&cli_warnings, _("master connection parameters not required when executing STANDBY PROMOTE")); } if (runtime_options.dest_dir[0]) { - error_list_append(&cli_warnings, _("destination directory not required when executing STANDBY PROMOTE")); + item_list_append(&cli_warnings, _("destination directory not required when executing STANDBY PROMOTE")); } break; @@ -4818,12 +4832,12 @@ check_parameters_for_action(const int action) { if (!runtime_options.host[0]) { - error_list_append(&cli_errors, _("master hostname (-h/--host) required when executing STANDBY FOLLOW with -D/--data-dir option")); + item_list_append(&cli_errors, _("master hostname (-h/--host) required when executing STANDBY FOLLOW with -D/--data-dir option")); } if (host_param_provided && !runtime_options.dest_dir[0]) { - error_list_append(&cli_errors, _("local data directory (-D/--data-dir) required when executing STANDBY FOLLOW with -h/--host option")); + item_list_append(&cli_errors, _("local data directory (-D/--data-dir) required when executing STANDBY FOLLOW with -h/--host option")); } } break; @@ -4838,12 +4852,12 @@ check_parameters_for_action(const int action) if (strcmp(runtime_options.host, "") == 0) { - error_list_append(&cli_errors, _("master hostname (-h/--host) required when executing STANDBY CLONE")); + item_list_append(&cli_errors, _("master hostname (-h/--host) required when executing STANDBY CLONE")); } if (runtime_options.fast_checkpoint && runtime_options.rsync_only) { - error_list_append(&cli_warnings, _("-c/--fast-checkpoint has no effect when using -r/--rsync-only")); + item_list_append(&cli_warnings, _("-c/--fast-checkpoint has no effect when using -r/--rsync-only")); } config_file_required = false; break; @@ -4854,19 +4868,19 @@ check_parameters_for_action(const int action) case STANDBY_ARCHIVE_CONFIG: if (strcmp(runtime_options.config_archive_dir, "") == 0) { - error_list_append(&cli_errors, _("--config-archive-dir required when executing STANDBY ARCHIVE_CONFIG")); + item_list_append(&cli_errors, _("--config-archive-dir required when executing STANDBY ARCHIVE_CONFIG")); } break; case STANDBY_RESTORE_CONFIG: if (strcmp(runtime_options.config_archive_dir, "") == 0) { - error_list_append(&cli_errors, _("--config-archive-dir required when executing STANDBY RESTORE_CONFIG")); + item_list_append(&cli_errors, _("--config-archive-dir required when executing STANDBY RESTORE_CONFIG")); } if (strcmp(runtime_options.dest_dir, "") == 0) { - error_list_append(&cli_errors, _("-D/--data-dir required when executing STANDBY RESTORE_CONFIG")); + item_list_append(&cli_errors, _("-D/--data-dir required when executing STANDBY RESTORE_CONFIG")); } config_file_required = false; @@ -4876,7 +4890,7 @@ check_parameters_for_action(const int action) /* Require data directory */ if (strcmp(runtime_options.dest_dir, "") == 0) { - error_list_append(&cli_errors, _("-D/--data-dir required when executing WITNESS CREATE")); + item_list_append(&cli_errors, _("-D/--data-dir required when executing WITNESS CREATE")); } /* allow all parameters to be supplied */ break; @@ -4895,27 +4909,27 @@ check_parameters_for_action(const int action) { if (runtime_options.fast_checkpoint) { - error_list_append(&cli_warnings, _("-c/--fast-checkpoint can only be used when executing STANDBY CLONE")); + item_list_append(&cli_warnings, _("-c/--fast-checkpoint can only be used when executing STANDBY CLONE")); } if (runtime_options.ignore_external_config_files) { - error_list_append(&cli_warnings, _("--ignore-external-config-files can only be used when executing STANDBY CLONE")); + item_list_append(&cli_warnings, _("--ignore-external-config-files can only be used when executing STANDBY CLONE")); } if (*runtime_options.recovery_min_apply_delay) { - error_list_append(&cli_warnings, _("--recovery-min-apply-delay can only be used when executing STANDBY CLONE")); + item_list_append(&cli_warnings, _("--recovery-min-apply-delay can only be used when executing STANDBY CLONE")); } if (runtime_options.rsync_only) { - error_list_append(&cli_warnings, _("-r/--rsync-only can only be used when executing STANDBY CLONE")); + item_list_append(&cli_warnings, _("-r/--rsync-only can only be used when executing STANDBY CLONE")); } if (wal_keep_segments_used) { - error_list_append(&cli_warnings, _("-w/--wal-keep-segments can only be used when executing STANDBY CLONE")); + item_list_append(&cli_warnings, _("-w/--wal-keep-segments can only be used when executing STANDBY CLONE")); } } @@ -4924,7 +4938,7 @@ check_parameters_for_action(const int action) { if (pg_rewind_supplied == true) { - error_list_append(&cli_warnings, _("--pg_rewind can only be used when executing STANDBY SWITCHOVER")); + item_list_append(&cli_warnings, _("--pg_rewind can only be used when executing STANDBY SWITCHOVER")); } } @@ -4933,7 +4947,7 @@ check_parameters_for_action(const int action) { if (runtime_options.csv_mode) { - error_list_append(&cli_warnings, _("--csv can only be used when executing CLUSTER SHOW")); + item_list_append(&cli_warnings, _("--csv can only be used when executing CLUSTER SHOW")); } } @@ -5703,9 +5717,9 @@ exit_with_errors(void) static void -print_error_list(ErrorList *error_list, int log_level) +print_error_list(ItemList *error_list, int log_level) { - ErrorListCell *cell; + ItemListCell *cell; for (cell = error_list->head; cell; cell = cell->next) { @@ -5713,10 +5727,10 @@ print_error_list(ErrorList *error_list, int log_level) { /* Currently we only need errors and warnings */ case LOG_ERR: - log_err("%s\n", cell->error_message); + log_err("%s\n", cell->string); break; case LOG_WARNING: - log_warning("%s\n", cell->error_message); + log_warning("%s\n", cell->string); break; } @@ -5906,3 +5920,88 @@ param_set(const char *param, const char *value) */ } + +static void +parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options) +{ + int options_len = strlen(pg_basebackup_options) + 1; + char *options_string = pg_malloc(options_len); + + char *options_string_ptr = options_string; + /* + * Add parsed options to this list, then copy to an array + * to pass to getopt + */ + static ItemList option_argv = { NULL, NULL }; + + char *argv_item; + int c, argc_item = 1; + + char **argv_array; + ItemListCell *cell; + + int optindex = 0; + + static struct option long_options[] = + { + {"slot", required_argument, NULL, 'S'}, + {"xlog-method", required_argument, NULL, 'X'}, + {NULL, 0, NULL, 0} + }; + + /* Don't attempt to tokenise an empty string */ + if (!strlen(pg_basebackup_options)) + return; + + /* + * Copy the string before operating on it with strtok() + */ + strncpy(options_string, pg_basebackup_options, options_len); + + while ((argv_item = strtok(options_string_ptr, " ")) != NULL) + { + item_list_append(&option_argv, argv_item); + + argc_item++; + + if (options_string_ptr != NULL) + options_string_ptr = NULL; + } + + argv_array = pg_malloc0(sizeof(char *) * (argc_item + 2)); + + /* Copy a dummy program name to the start of the array */ + argv_array[0] = pg_malloc0(1); + strncpy(argv_array[0], "", 4); + + c = 1; + + for (cell = option_argv.head; cell; cell = cell->next) + { + int argv_len = strlen(cell->string) + 1; + + argv_array[c] = pg_malloc0(argv_len); + + strncpy(argv_array[c], cell->string, argv_len); + + c++; + } + + argv_array[c] = NULL; + + while ((c = getopt_long(argc_item, argv_array, "S:X:", long_options, + &optindex)) != -1) + { + switch (c) + { + case 'S': + strncpy(backup_options->slot, optarg, MAXLEN); + break; + case 'X': + strncpy(backup_options->xlog_method, optarg, MAXLEN); + break; + } + } + + return; +} diff --git a/repmgr.h b/repmgr.h index 20690eea..ed34ec75 100644 --- a/repmgr.h +++ b/repmgr.h @@ -52,7 +52,6 @@ /* Run time options type */ typedef struct { - char dbname[MAXLEN]; char host[MAXLEN]; char username[MAXLEN]; @@ -110,7 +109,13 @@ struct BackupLabel XLogRecPtr min_failover_slot_lsn; }; -extern char repmgr_schema[MAXLEN]; -extern bool config_file_found; + +typedef struct +{ + char slot[MAXLEN]; + char xlog_method[MAXLEN]; +} t_basebackup_options; + +#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "" } #endif diff --git a/repmgrd.c b/repmgrd.c index 4982ae71..0c44d6ab 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -1,5 +1,6 @@ /* * repmgrd.c - Replication manager daemon + * * Copyright (C) 2ndQuadrant, 2010-2016 * * This module connects to the nodes of a replication cluster and monitors