diff --git a/configfile.c b/configfile.c index e7dc326f..e6e06625 100644 --- a/configfile.c +++ b/configfile.c @@ -1354,6 +1354,61 @@ reload_config(t_server_type server_type) } +/* + * Dump the parsed configuration + */ +void +dump_config(void) +{ + ConfigFileSetting *setting; + int i = 0; + + setting = &config_file_settings[0]; + + do { + printf("%s|", setting->name); + switch (setting->type) + { + case CONFIG_INT: + printf("%i", *setting->val.intptr); + break; + case CONFIG_BOOL: + printf("%s", format_bool(*setting->val.boolptr)); + break; + case CONFIG_STRING: + printf("%s", setting->val.strptr); + break; + case CONFIG_FAILOVER_MODE: + printf("%s", format_failover_mode(*setting->val.failovermodeptr)); + break; + case CONFIG_CONNECTION_CHECK_TYPE: + printf("%s", print_connection_check_type(*setting->val.checktypeptr)); + break; + case CONFIG_EVENT_NOTIFICATION_LIST: + { + char *list = print_event_notification_list(setting->val.notificationlistptr); + printf("%s", list); + pfree(list); + } + break; + case CONFIG_TABLESPACE_MAPPING: + { + char *list = print_tablespace_mapping(setting->val.tablespacemappingptr); + printf("%s", list); + pfree(list); + } + break; + default: + /* this should never happen */ + log_error("unhandled setting type %i", (int)setting->type); + } + puts(""); + i++; + setting = &config_file_settings[i]; + } while (setting->name != NULL); + +} + static void exit_with_config_file_errors(ItemList *config_errors, ItemList *config_warnings, bool terse) { @@ -2118,7 +2173,7 @@ print_event_notification_list(EventNotificationList *list) appendPQExpBufferStr(&buf, cell->event_type); if (cell->next) - appendPQExpBufferStr(&buf, ", "); + appendPQExpBufferChar(&buf, ','); cell = cell->next; } @@ -2132,6 +2187,35 @@ print_event_notification_list(EventNotificationList *list) } +char * +print_tablespace_mapping(TablespaceList *tablespace_mapping) +{ + TablespaceListCell *cell; + bool first = true; + PQExpBufferData buf; + char *ptr; + + initPQExpBuffer(&buf); + + for (cell = tablespace_mapping->head; cell; cell = cell->next) + { + if (first == true) + first = false; + else + appendPQExpBufferChar(&buf, ','); + + appendPQExpBuffer(&buf, "%s=%s", + cell->old_dir, cell->new_dir); + } + + ptr = palloc0(strlen(buf.data) + 1); + strncpy(ptr, buf.data, strlen(buf.data)); + + termPQExpBuffer(&buf); + + return ptr; +} + const char * format_failover_mode(failover_mode_opt failover) diff --git a/configfile.h b/configfile.h index 455bffd6..b0791bb7 100644 --- a/configfile.h +++ b/configfile.h @@ -311,6 +311,8 @@ const char *progname(void); void load_config(const char *config_file, bool verbose, bool terse, char *argv0); bool reload_config(t_server_type server_type); +void dump_config(void); + void parse_configuration_item(ItemList *error_list, ItemList *warning_list, const char *name, const char *value); bool parse_recovery_conf(const char *data_dir, t_recovery_conf *conf); @@ -342,6 +344,7 @@ void exit_with_cli_errors(ItemList *error_list, const char *repmgr_command); void print_item_list(ItemList *item_list); const char *print_connection_check_type(ConnectionCheckType type); char *print_event_notification_list(EventNotificationList *list); +char *print_tablespace_mapping(TablespaceList *tablespacemappingptr); extern bool modify_auto_conf(const char *data_dir, KeyValueList *items); diff --git a/repmgr-client-global.h b/repmgr-client-global.h index bf1429f2..9d3211a1 100644 --- a/repmgr-client-global.h +++ b/repmgr-client-global.h @@ -48,6 +48,7 @@ typedef struct bool no_wait; bool compact; bool detail; + bool dump_config; /* logging options */ char log_level[MAXLEN]; /* overrides setting in repmgr.conf */ @@ -151,7 +152,7 @@ typedef struct /* configuration metadata */ \ false, false, false, false, false, \ /* general configuration options */ \ - "", false, false, "", -1, false, false, false, \ + "", false, false, "", -1, false, false, false, false, \ /* logging options */ \ "", false, false, false, false, \ /* output options */ \ diff --git a/repmgr-client.c b/repmgr-client.c index 8de73bd4..bd860504 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -277,6 +277,11 @@ main(int argc, char **argv) runtime_options.detail = true; break; + /* --dump-config */ + case OPT_DUMP_CONFIG: + runtime_options.dump_config = true; + break; + /*---------------------------- * database connection options *---------------------------- @@ -1081,6 +1086,24 @@ main(int argc, char **argv) runtime_options.terse, argv[0]); + + /* + * Handle options which must be executed without a repmgr command + */ + if (runtime_options.dump_config == true) + { + if (repmgr_command != NULL) + { + fprintf(stderr, + _("--dump-config cannot be used in combination with a repmgr command")); + exit(ERR_BAD_CONFIG); + } + dump_config(); + exit(SUCCESS); + } + + + check_cli_parameters(action); /* @@ -1219,8 +1242,6 @@ main(int argc, char **argv) logger_set_level(LOG_ERROR); } - - /* * Node configuration information is not needed for all actions, with * STANDBY CLONE being the main exception. diff --git a/repmgr-client.h b/repmgr-client.h index d0ff820a..7d1df57a 100644 --- a/repmgr-client.h +++ b/repmgr-client.h @@ -104,6 +104,7 @@ #define OPT_CONFIG_ARCHIVE_DIR 2001 #define OPT_DISABLE_WAL_RECEIVER 2002 #define OPT_ENABLE_WAL_RECEIVER 2003 +#define OPT_DUMP_CONFIG 2004 /* deprecated since 4.0 */ #define OPT_CHECK_UPSTREAM_CONFIG 999 @@ -125,6 +126,7 @@ static struct option long_options[] = {"no-wait", no_argument, NULL, 'W'}, {"compact", no_argument, NULL, OPT_COMPACT}, {"detail", no_argument, NULL, OPT_DETAIL}, + {"dump-config", no_argument, NULL, OPT_DUMP_CONFIG}, /* connection options */ {"dbname", required_argument, NULL, 'd'}, diff --git a/strutil.c b/strutil.c index fdbad0c3..ad1444c4 100644 --- a/strutil.c +++ b/strutil.c @@ -386,12 +386,9 @@ output_check_status(CheckStatus status) } return "UNKNOWN"; - } - - /* * Escape a string for use as a parameter in recovery.conf * Caller must free returned value @@ -433,7 +430,6 @@ escape_string(PGconn *conn, const char *string) /* * simple function to escape double quotes only */ - void escape_double_quotes(char *string, PQExpBufferData *out) {