More functionality for "standby clone"

This commit is contained in:
Ian Barwick
2017-04-29 22:41:43 +09:00
parent dc347f1484
commit bcb17dd71a
8 changed files with 1102 additions and 79 deletions

148
config.c
View File

@@ -539,11 +539,12 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
}
/* add warning about changed "barman_" parameter meanings */
if (options->barman_server[0] == '\0' && options->barman_server[0] != '\0')
if ((options->barman_host[0] == '\0' && options->barman_server[0] != '\0') ||
(options->barman_host[0] != '\0' && options->barman_server[0] == '\0'))
{
item_list_append(warning_list,
item_list_append(error_list,
_("use \"barman_host\" for the hostname of the Barman server"));
item_list_append(warning_list,
item_list_append(error_list,
_("use \"barman_server\" for the name of the [server] section in the Barman configururation file"));
}
@@ -923,3 +924,144 @@ parse_event_notifications_list(t_configuration_options *options, const char *arg
}
}
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);
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;
struct option *long_options;
bool backup_options_ok = true;
/* We're only interested in these options */
static struct option long_options_9[] =
{
{"slot", required_argument, NULL, 'S'},
{"xlog-method", required_argument, NULL, 'X'},
{NULL, 0, NULL, 0}
};
/*
* 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 backup_options_ok;
if (server_version_num >= 100000)
long_options = long_options_10;
else
long_options = long_options_9;
/* Copy the string before operating on it with strtok() */
strncpy(options_string, pg_basebackup_options, options_len);
/* Extract arguments into a list and keep a count of the total */
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;
}
/*
* Array of argument values to pass to getopt_long - this will need to
* include an empty string as the first value (normally this would be
* the program name)
*/
argv_array = pg_malloc0(sizeof(char *) * (argc_item + 2));
/* Insert a blank dummy program name at the start of the array */
argv_array[0] = pg_malloc0(1);
c = 1;
/*
* Copy the previously extracted arguments from our list to the array
*/
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;
/* 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)
{
switch (c)
{
case 'S':
strncpy(backup_options->slot, optarg, MAXLEN);
break;
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;
}
}
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;
}