repmgr: parse --no-slot in pg_basebackup_options

From PostgreSQL 10 we'll need to know whether this is present when
performing sanity checks for available replication slots.

Add a sanity check for conflicting presence of -S/--slot while we're
at it so we can abort early.
This commit is contained in:
Ian Barwick
2017-03-07 11:04:18 +09:00
committed by Ian Barwick
parent e53f1bf844
commit 5493b57443
2 changed files with 60 additions and 9 deletions

View File

@@ -159,7 +159,7 @@ static char *param_get(t_conninfo_param_list *param_list, const char *param);
static bool parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char *errmsg, bool ignore_application_name);
static void conn_to_param_list(PGconn *conn, t_conninfo_param_list *param_list);
static char *param_list_to_string(t_conninfo_param_list *param_list);
static void parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options, int server_version_num);
static bool parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options, int server_version_num, ItemList *error_list);
static void config_file_list_init(t_configfile_list *list, int max_size);
static void config_file_list_add(t_configfile_list *list, const char *file, const char *filename, bool in_data_dir);
@@ -7029,7 +7029,7 @@ run_basebackup(const char *data_dir, int server_version_num)
* 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, server_version_num);
parse_pg_basebackup_options(options.pg_basebackup_options, &backup_options, server_version_num, NULL);
/* Create pg_basebackup command line options */
@@ -7852,6 +7852,8 @@ check_upstream_config(PGconn *conn, int server_version_num, bool exit_on_error)
bool config_ok = true;
char *wal_error_message = NULL;
t_basebackup_options backup_options = T_BASEBACKUP_OPTIONS_INITIALIZER;
bool backup_options_ok = true;
ItemList backup_option_errors = { NULL, NULL };
bool xlog_stream = true;
enum {
@@ -7877,7 +7879,24 @@ check_upstream_config(PGconn *conn, int server_version_num, bool exit_on_error)
* this will influence some checks
*/
parse_pg_basebackup_options(options.pg_basebackup_options, &backup_options, server_version_num);
backup_options_ok = parse_pg_basebackup_options(
options.pg_basebackup_options,
&backup_options, server_version_num,
&backup_option_errors);
if (backup_options_ok == false)
{
if (exit_on_error == true)
{
log_err(_("error(s) encountered parsing 'pg_basebackup_options'\n"));
print_error_list(&backup_option_errors, LOG_ERR);
log_hint(_("'pg_basebackup_options' is: '%s'\n"), options.pg_basebackup_options);
exit(ERR_BAD_CONFIG);
}
config_ok = false;
}
if (strlen(backup_options.xlog_method) && strcmp(backup_options.xlog_method, "stream") != 0)
xlog_stream = false;
@@ -8762,8 +8781,8 @@ param_list_to_string(t_conninfo_param_list *param_list)
}
static void
parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options, int server_version_num)
static bool
parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options, int server_version_num, ItemList *error_list)
{
int options_len = strlen(pg_basebackup_options) + 1;
char *options_string = pg_malloc(options_len);
@@ -8785,6 +8804,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
struct option *long_options;
bool backup_options_ok = true;
/* We're only interested in these options */
static struct option long_options_9[] =
{
@@ -8793,17 +8814,21 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
{NULL, 0, NULL, 0}
};
/* From PostgreSQL 10, --xlog-method is renamed --wal-method */
/*
* From PostgreSQL 10, --xlog-method is renamed --wal-method
* and there's also --no-slot, which we'll want to consider.
*/
static struct option long_options_10[] =
{
{"slot", required_argument, NULL, 'S'},
{"wal-method", required_argument, NULL, 'X'},
{"no-slot", no_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
/* Don't attempt to tokenise an empty string */
if (!strlen(pg_basebackup_options))
return;
return backup_options_ok;
if (server_version_num >= 100000)
long_options = long_options_10;
@@ -8855,6 +8880,9 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
/* Reset getopt's optind variable */
optind = 0;
/* Prevent getopt from emitting errors */
opterr = 0;
while ((c = getopt_long(argc_item, argv_array, "S:X:", long_options,
&optindex)) != -1)
{
@@ -8866,10 +8894,32 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
case 'X':
strncpy(backup_options->xlog_method, optarg, MAXLEN);
break;
case 1:
backup_options->no_slot = true;
break;
case '?':
if (server_version_num >= 100000 && optopt == 1)
{
if (error_list != NULL)
{
item_list_append(error_list, "invalid use of --no-slot");
}
backup_options_ok = false;
}
break;
}
}
return;
if (backup_options->no_slot == true && backup_options->slot[0] != '\0')
{
if (error_list != NULL)
{
item_list_append(error_list, "--no-slot cannot be used with -S/--slot");
}
backup_options_ok = false;
}
return backup_options_ok;
}
static void

View File

@@ -192,9 +192,10 @@ typedef struct
{
char slot[MAXLEN];
char xlog_method[MAXLEN];
bool no_slot; /* from PostgreSQL 10 */
} t_basebackup_options;
#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "" }
#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", false }
typedef struct
{