pgindent run

This commit is contained in:
Ian Barwick
2017-09-11 11:14:13 +09:00
parent 0e6699ecb6
commit a9f4a027a7
36 changed files with 3523 additions and 3288 deletions

View File

@@ -104,4 +104,3 @@ appendShellString(PQExpBuffer buf, const char *str)
appendPQExpBufferChar(buf, '\'');
}

View File

@@ -23,10 +23,8 @@
#ifndef _COMPAT_H_
#define _COMPAT_H_
extern void
appendConnStrVal(PQExpBuffer buf, const char *str);
extern void appendConnStrVal(PQExpBuffer buf, const char *str);
extern void
appendShellString(PQExpBuffer buf, const char *str);
extern void appendShellString(PQExpBuffer buf, const char *str);
#endif

View File

@@ -24,25 +24,25 @@
#include "log.h"
const static char *_progname = NULL;
char config_file_path[MAXPGPATH] = "";
char config_file_path[MAXPGPATH] = "";
static bool config_file_provided = false;
bool config_file_found = false;
bool config_file_found = false;
static void _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
static bool parse_bool(const char *s,
const char *config_item,
ItemList *error_list);
static void _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
static bool parse_bool(const char *s,
const char *config_item,
ItemList *error_list);
static void _parse_line(char *buf, char *name, char *value);
static void parse_event_notifications_list(t_configuration_options *options, const char *arg);
static void _parse_line(char *buf, char *name, char *value);
static void parse_event_notifications_list(t_configuration_options *options, const char *arg);
static void clear_event_notification_list(t_configuration_options *options);
static void parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemList *errors);
static void tablespace_list_append(t_configuration_options *options, const char *arg);
static void tablespace_list_append(t_configuration_options *options, const char *arg);
static void exit_with_config_file_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
@@ -63,10 +63,10 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
struct stat stat_config;
/*
* If a configuration file was provided, check it exists, otherwise
* emit an error and terminate. We assume that if a user explicitly
* provides a configuration file, they'll want to make sure it's
* used and not fall back to any of the defaults.
* If a configuration file was provided, check it exists, otherwise emit
* an error and terminate. We assume that if a user explicitly provides a
* configuration file, they'll want to make sure it's used and not fall
* back to any of the defaults.
*/
if (config_file != NULL && config_file[0] != '\0')
{
@@ -76,8 +76,8 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
if (stat(config_file_path, &stat_config) != 0)
{
log_error(_("provided configuration file \"%s\" not found: %s"),
config_file,
strerror(errno)
config_file,
strerror(errno)
);
exit(ERR_BAD_CONFIG);
}
@@ -92,18 +92,19 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
}
/*
/*-----------
* If no configuration file was provided, attempt to find a default file
* in this order:
* - current directory
* - /etc/repmgr.conf
* - default sysconfdir
* - current directory
* - /etc/repmgr.conf
* - default sysconfdir
*
* here we just check for the existence of the file; parse_config()
* will handle read errors etc.
* here we just check for the existence of the file; parse_config() will
* handle read errors etc.
*
* XXX modify this section so package maintainers can provide a patch
* specifying location of a distribution-specific configuration file
* specifying location of a distribution-specific configuration file
*-----------
*/
if (config_file_provided == false)
{
@@ -159,7 +160,7 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
goto end_search;
}
end_search:
end_search:
if (config_file_found == true)
{
if (verbose == true)
@@ -186,8 +187,8 @@ void
parse_config(t_configuration_options *options, bool terse)
{
/* Collate configuration file errors here for friendlier reporting */
static ItemList config_errors = { NULL, NULL };
static ItemList config_warnings = { NULL, NULL };
static ItemList config_errors = {NULL, NULL};
static ItemList config_warnings = {NULL, NULL};
_parse_config(options, &config_errors, &config_warnings);
@@ -273,7 +274,8 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
/* default to 6 reconnection attempts at intervals of 10 seconds */
options->reconnect_attempts = DEFAULT_RECONNECTION_ATTEMPTS;
options->reconnect_interval = DEFAULT_RECONNECTION_INTERVAL;
options->monitoring_history = false; /* new in 4.0, replaces --monitoring-history */
options->monitoring_history = false; /* new in 4.0, replaces
* --monitoring-history */
options->degraded_monitoring_timeout = -1;
options->async_query_timeout = DEFAULT_ASYNC_QUERY_TIMEOUT;
options->primary_notification_timeout = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT;
@@ -326,16 +328,16 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
{
log_verbose(LOG_NOTICE,
_("no configuration file provided and no default file found - "
"continuing with default values"));
"continuing with default values"));
return;
}
fp = fopen(config_file_path, "r");
/*
* A configuration file has been found, either provided by the user
* or found in one of the default locations. If we can't open it,
* fail with an error.
* A configuration file has been found, either provided by the user or
* found in one of the default locations. If we can't open it, fail with
* an error.
*/
if (fp == NULL)
{
@@ -347,7 +349,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
else
{
log_error(_("unable to open default configuration file \"%s\"; terminating"),
config_file_path);
config_file_path);
}
exit(ERR_BAD_CONFIG);
@@ -356,7 +358,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
/* Read file */
while ((s = fgets(buf, sizeof buf, fp)) != NULL)
{
bool known_parameter = true;
bool known_parameter = true;
/* Parse name/value pair from line */
_parse_line(buf, name, value);
@@ -387,7 +389,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
strncpy(options->replication_user, value, NAMEDATALEN);
else
item_list_append(error_list,
_( "value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters"));
_("value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters"));
}
else if (strcmp(name, "pg_bindir") == 0)
strncpy(options->pg_bindir, value, MAXPGPATH);
@@ -524,7 +526,10 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
else if (strcmp(name, "promote_delay") == 0)
options->promote_delay = repmgr_atoi(value, name, error_list, 1);
/* Following parameters have been deprecated or renamed from 3.x - issue a warning */
/*
* Following parameters have been deprecated or renamed from 3.x -
* issue a warning
*/
else if (strcmp(name, "cluster") == 0)
{
item_list_append(warning_list,
@@ -578,14 +583,18 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
known_parameter = false;
log_warning(_("%s/%s: unknown name/value pair provided; ignoring"), name, value);
}
/*
* Raise an error if a known parameter is provided with an empty value.
* Currently there's no reason why empty parameters are needed; if
* we want to accept those, we'd need to add stricter default checking,
* as currently e.g. an empty `node` value will be converted to '0'.
* Raise an error if a known parameter is provided with an empty
* value. Currently there's no reason why empty parameters are needed;
* if we want to accept those, we'd need to add stricter default
* checking, as currently e.g. an empty `node` value will be converted
* to '0'.
*/
if (known_parameter == true && !strlen(value)) {
char error_message_buf[MAXLEN] = "";
if (known_parameter == true && !strlen(value))
{
char error_message_buf[MAXLEN] = "";
maxlen_snprintf(error_message_buf,
_("\"%s\": no value provided"),
name);
@@ -618,10 +627,11 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
}
else
{
/* Sanity check the provided conninfo string
/*
* Sanity check the provided conninfo string
*
* NOTE: PQconninfoParse() verifies the string format and checks for valid options
* but does not sanity check values
* NOTE: PQconninfoParse() verifies the string format and checks for
* valid options but does not sanity check values
*/
PQconninfoOption *conninfo_options = NULL;
@@ -630,7 +640,8 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
conninfo_options = PQconninfoParse(options->conninfo, &conninfo_errmsg);
if (conninfo_options == NULL)
{
char error_message_buf[MAXLEN] = "";
char error_message_buf[MAXLEN] = "";
snprintf(error_message_buf,
MAXLEN,
_("\"conninfo\": %s (provided: \"%s\")"),
@@ -662,7 +673,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
_("\archive_ready_critical\" must be greater than \"archive_ready_warning\""));
}
if( options->replication_lag_warning >= options->replication_lag_critical)
if (options->replication_lag_warning >= options->replication_lag_critical)
{
item_list_append(error_list,
_("\replication_lag_critical\" must be greater than \"replication_lag_warning\""));
@@ -675,7 +686,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
bool
parse_recovery_conf(const char *data_dir, t_recovery_conf *conf)
{
char recovery_conf_path[MAXPGPATH] = "";
char recovery_conf_path[MAXPGPATH] = "";
FILE *fp;
char *s = NULL,
buf[MAXLINELENGTH] = "";
@@ -780,9 +791,9 @@ _parse_line(char *buf, char *name, char *value)
if (buf[i] == '=')
break;
switch(buf[i])
switch (buf[i])
{
/* Ignore whitespace */
/* Ignore whitespace */
case ' ':
case '\n':
case '\r':
@@ -799,9 +810,9 @@ _parse_line(char *buf, char *name, char *value)
*/
for (; i < MAXLEN; ++i)
{
if (buf[i+1] == ' ')
if (buf[i + 1] == ' ')
continue;
if (buf[i+1] == '\t')
if (buf[i + 1] == '\t')
continue;
break;
@@ -828,17 +839,17 @@ _parse_line(char *buf, char *name, char *value)
static void
parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemList *errors)
{
char *ptr = NULL;
int targ = strtol(value, &ptr, 10);
char *ptr = NULL;
int targ = strtol(value, &ptr, 10);
if (targ < 1)
{
if (errors != NULL)
{
item_list_append_format(
errors,
_("invalid value provided for \"%s\""),
name);
errors,
_("invalid value provided for \"%s\""),
name);
}
return;
}
@@ -852,9 +863,9 @@ parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemL
if (errors != NULL)
{
item_list_append_format(
errors,
_("value provided for \"%s\" must be one of ms/s/min/h/d"),
name);
errors,
_("value provided for \"%s\" must be one of ms/s/min/h/d"),
name);
return;
}
}
@@ -909,11 +920,11 @@ reload_config(t_configuration_options *orig_options)
{
PGconn *conn;
t_configuration_options new_options = T_CONFIGURATION_OPTIONS_INITIALIZER;
bool config_changed = false;
bool log_config_changed = false;
bool config_changed = false;
bool log_config_changed = false;
static ItemList config_errors = { NULL, NULL };
static ItemList config_warnings = { NULL, NULL };
static ItemList config_errors = {NULL, NULL};
static ItemList config_warnings = {NULL, NULL};
log_info(_("reloading configuration file"));
@@ -980,7 +991,7 @@ reload_config(t_configuration_options *orig_options)
/* conninfo */
if (strcmp(orig_options->conninfo, new_options.conninfo) != 0)
{
/* Test conninfo string works*/
/* Test conninfo string works */
conn = establish_db_connection(new_options.conninfo, false);
if (!conn || (PQstatus(conn) != CONNECTION_OK))
{
@@ -1228,13 +1239,14 @@ print_item_list(ItemList *item_list)
int
repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, int minval)
{
char *endptr = NULL;
long longval = 0;
char *endptr = NULL;
long longval = 0;
PQExpBufferData errors;
initPQExpBuffer(&errors);
/* It's possible that some versions of strtol() don't treat an empty
/*
* It's possible that some versions of strtol() don't treat an empty
* string as an error.
*/
if (*value == '\0')
@@ -1253,14 +1265,14 @@ repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, in
_("\"%s\": invalid value (provided: \"%s\")"),
config_item, value);
}
else if ((int32)longval < longval)
else if ((int32) longval < longval)
{
appendPQExpBuffer(&errors,
_("\"%s\": must be a positive signed 32 bit integer, i.e. 2147483647 or less (provided: \"%s\")"),
config_item,
value);
}
else if ((int32)longval < minval)
else if ((int32) longval < minval)
/* Disallow negative values for most parameters */
{
appendPQExpBuffer(&errors,
@@ -1399,7 +1411,7 @@ tablespace_list_append(t_configuration_options *options, const char *arg)
if (!*cell->old_dir || !*cell->new_dir)
{
log_error(_("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""),
arg);
arg);
exit(ERR_BAD_CONFIG);
}
@@ -1505,20 +1517,21 @@ clear_event_notification_list(t_configuration_options *options)
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 = 0;
char *options_string = NULL;
char *options_string_ptr = NULL;
int options_len = 0;
char *options_string = NULL;
char *options_string_ptr = NULL;
/*
* Add parsed options to this list, then copy to an array
* to pass to getopt
* Add parsed options to this list, then copy to an array to pass to
* getopt
*/
static ItemList option_argv = { NULL, NULL };
static ItemList option_argv = {NULL, NULL};
char *argv_item = NULL;
int c, argc_item = 1;
char *argv_item = NULL;
int c,
argc_item = 1;
char **argv_array = NULL;
char **argv_array = NULL;
ItemListCell *cell = NULL;
int optindex = 0;
@@ -1536,8 +1549,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
};
/*
* From PostgreSQL 10, --xlog-method is renamed --wal-method
* and there's also --no-slot, which we'll want to consider.
* 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[] =
{
@@ -1576,8 +1589,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
/*
* 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)
* include an empty string as the first value (normally this would be the
* program name)
*/
argv_array = pg_malloc0(sizeof(char *) * (argc_item + 2));
@@ -1591,7 +1604,7 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
*/
for (cell = option_argv.head; cell; cell = cell->next)
{
int argv_len = strlen(cell->string) + 1;
int argv_len = strlen(cell->string) + 1;
argv_array[c] = pg_malloc0(argv_len);
@@ -1647,8 +1660,9 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
pfree(options_string);
{
int i;
for (i = 0; i < argc_item + 2; i ++)
int i;
for (i = 0; i < argc_item + 2; i++)
pfree(argv_array[i]);
}
pfree(argv_array);

View File

@@ -28,18 +28,19 @@
/* magic number for use in t_recovery_conf */
#define TARGET_TIMELINE_LATEST 0
extern bool config_file_found;
extern char config_file_path[MAXPGPATH];
extern bool config_file_found;
extern char config_file_path[MAXPGPATH];
typedef enum {
typedef enum
{
FAILOVER_MANUAL,
FAILOVER_AUTOMATIC
} failover_mode_opt;
} failover_mode_opt;
typedef struct EventNotificationListCell
{
struct EventNotificationListCell *next;
char event_type[MAXLEN];
char event_type[MAXLEN];
} EventNotificationListCell;
typedef struct EventNotificationList
@@ -67,7 +68,7 @@ typedef struct TablespaceList
typedef struct
{
/* node information */
int node_id;
int node_id;
char node_name[MAXLEN];
char conninfo[MAXLEN];
char replication_user[NAMEDATALEN];
@@ -98,7 +99,7 @@ typedef struct
int replication_lag_critical;
/* repmgrd settings */
failover_mode_opt failover;
failover_mode_opt failover;
char location[MAXLEN];
int priority;
char promote_command[MAXLEN];
@@ -136,7 +137,7 @@ typedef struct
/* undocumented test settings */
int promote_delay;
} t_configuration_options;
} t_configuration_options;
/*
* The following will initialize the structure with a minimal set of options;
@@ -180,13 +181,14 @@ typedef struct
{
char slot[MAXLEN];
char xlog_method[MAXLEN];
bool no_slot; /* from PostgreSQL 10 */
bool no_slot; /* from PostgreSQL 10 */
} t_basebackup_options;
#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", false }
typedef enum {
typedef enum
{
RTA_PAUSE,
RTA_PROMOTE,
RTA_SHUTDOWN
@@ -204,22 +206,22 @@ typedef enum {
typedef struct
{
/* archive recovery settings */
char restore_command[MAXLEN];
char archive_cleanup_command[MAXLEN];
char recovery_end_command[MAXLEN];
char restore_command[MAXLEN];
char archive_cleanup_command[MAXLEN];
char recovery_end_command[MAXLEN];
/* recovery target settings */
char recovery_target_name[MAXLEN];
char recovery_target_time[MAXLEN];
char recovery_target_xid[MAXLEN];
bool recovery_target_inclusive;
int recovery_target_timeline;
RecoveryTargetAction recovery_target_action; /* default: RTA_PAUSE */
char recovery_target_name[MAXLEN];
char recovery_target_time[MAXLEN];
char recovery_target_xid[MAXLEN];
bool recovery_target_inclusive;
int recovery_target_timeline;
RecoveryTargetAction recovery_target_action; /* default: RTA_PAUSE */
/* standby server settings */
bool standby_mode;
char primary_conninfo[MAXLEN];
char primary_slot_name[MAXLEN];
char trigger_file[MAXLEN];
char recovery_min_apply_delay[MAXLEN];
bool standby_mode;
char primary_conninfo[MAXLEN];
char primary_slot_name[MAXLEN];
char trigger_file[MAXLEN];
char recovery_min_apply_delay[MAXLEN];
} t_recovery_conf;
#define T_RECOVERY_CONF_INITIALIZER { \
@@ -245,19 +247,19 @@ bool reload_config(t_configuration_options *orig_options);
bool parse_recovery_conf(const char *data_dir, t_recovery_conf *conf);
int repmgr_atoi(const char *s,
const char *config_item,
ItemList *error_list,
int minval);
int repmgr_atoi(const char *s,
const char *config_item,
ItemList *error_list,
int minval);
bool parse_pg_basebackup_options(const char *pg_basebackup_options,
t_basebackup_options *backup_options,
int server_version_num,
ItemList *error_list);
t_basebackup_options *backup_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);
void exit_with_cli_errors(ItemList *error_list);
void print_item_list(ItemList *item_list);
#endif /* _REPMGR_CONFIGFILE_H_ */
#endif /* _REPMGR_CONFIGFILE_H_ */

View File

@@ -34,7 +34,7 @@ uint64
get_system_identifier(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
uint64 system_identifier = UNKNOWN_SYSTEM_IDENTIFIER;
uint64 system_identifier = UNKNOWN_SYSTEM_IDENTIFIER;
control_file_info = get_controlfile(data_directory);
@@ -53,7 +53,7 @@ DBState
get_db_state(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
DBState state;
DBState state;
control_file_info = get_controlfile(data_directory);
@@ -74,7 +74,7 @@ extern XLogRecPtr
get_latest_checkpoint_location(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
XLogRecPtr checkPoint = InvalidXLogRecPtr;
XLogRecPtr checkPoint = InvalidXLogRecPtr;
control_file_info = get_controlfile(data_directory);
@@ -94,7 +94,7 @@ int
get_data_checksum_version(const char *data_directory)
{
ControlFileInfo *control_file_info = NULL;
int data_checksum_version = -1;
int data_checksum_version = -1;
control_file_info = get_controlfile(data_directory);
@@ -104,7 +104,7 @@ get_data_checksum_version(const char *data_directory)
}
else
{
data_checksum_version = (int)control_file_info->control_file->data_checksum_version;
data_checksum_version = (int) control_file_info->control_file->data_checksum_version;
}
pfree(control_file_info->control_file);

View File

@@ -14,14 +14,14 @@
typedef struct
{
bool control_file_processed;
bool control_file_processed;
ControlFileData *control_file;
} ControlFileInfo;
extern DBState get_db_state(const char *data_directory);
extern const char * describe_db_state(DBState state);
extern int get_data_checksum_version(const char *data_directory);
extern const char *describe_db_state(DBState state);
extern int get_data_checksum_version(const char *data_directory);
extern uint64 get_system_identifier(const char *data_directory);
extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory);
#endif /* _CONTROLDATA_H_ */
#endif /* _CONTROLDATA_H_ */

1090
dbutils.c

File diff suppressed because it is too large Load Diff

262
dbutils.h
View File

@@ -33,52 +33,60 @@
#define ERRBUFF_SIZE 512
typedef enum {
typedef enum
{
UNKNOWN = 0,
PRIMARY,
STANDBY,
BDR
} t_server_type;
typedef enum {
typedef enum
{
REPMGR_INSTALLED = 0,
REPMGR_AVAILABLE,
REPMGR_UNAVAILABLE,
REPMGR_UNKNOWN
REPMGR_UNKNOWN
} ExtensionStatus;
typedef enum {
typedef enum
{
RECTYPE_UNKNOWN = -1,
RECTYPE_PRIMARY,
RECTYPE_STANDBY
} RecoveryType;
typedef enum {
typedef enum
{
RECORD_ERROR = -1,
RECORD_FOUND,
RECORD_NOT_FOUND
} RecordStatus;
typedef enum {
typedef enum
{
MS_NORMAL = 0,
MS_DEGRADED = 1
} MonitoringState;
typedef enum {
typedef enum
{
NODE_STATUS_UNKNOWN = -1,
NODE_STATUS_UP,
NODE_STATUS_DOWN,
NODE_STATUS_UNCLEAN_SHUTDOWN
} NodeStatus;
typedef enum {
typedef enum
{
VR_VOTE_REFUSED = -1,
VR_POSITIVE_VOTE,
VR_NEGATIVE_VOTE
} VoteRequestResult;
typedef enum {
typedef enum
{
SLOT_UNKNOWN = -1,
SLOT_INACTIVE,
SLOT_ACTIVE
@@ -90,36 +98,36 @@ typedef enum {
typedef struct s_node_info
{
/* contents of "repmgr.nodes" */
int node_id;
int upstream_node_id;
int node_id;
int upstream_node_id;
t_server_type type;
char node_name[MAXLEN];
char upstream_node_name[MAXLEN];
char conninfo[MAXLEN];
char repluser[NAMEDATALEN];
char location[MAXLEN];
int priority;
bool active;
char slot_name[MAXLEN];
char config_file[MAXPGPATH];
char node_name[MAXLEN];
char upstream_node_name[MAXLEN];
char conninfo[MAXLEN];
char repluser[NAMEDATALEN];
char location[MAXLEN];
int priority;
bool active;
char slot_name[MAXLEN];
char config_file[MAXPGPATH];
/* used during failover to track node status */
XLogRecPtr last_wal_receive_lsn;
NodeStatus node_status;
RecoveryType recovery_type;
XLogRecPtr last_wal_receive_lsn;
NodeStatus node_status;
RecoveryType recovery_type;
MonitoringState monitoring_state;
PGconn *conn;
PGconn *conn;
/* for ad-hoc use e.g. when working with a list of nodes */
char details[MAXLEN];
bool reachable;
bool attached;
char details[MAXLEN];
bool reachable;
bool attached;
/* various statistics */
int max_wal_senders;
int attached_wal_receivers;
int max_replication_slots;
int total_replication_slots;
int active_replication_slots;
int inactive_replication_slots;
} t_node_info;
int max_wal_senders;
int attached_wal_receivers;
int max_replication_slots;
int total_replication_slots;
int active_replication_slots;
int inactive_replication_slots;
} t_node_info;
#define T_NODE_INFO_INITIALIZER { \
@@ -160,7 +168,7 @@ typedef struct NodeInfoList
{
NodeInfoListCell *head;
NodeInfoListCell *tail;
int node_count;
int node_count;
} NodeInfoList;
#define T_NODE_INFO_LIST_INITIALIZER { \
@@ -171,9 +179,9 @@ typedef struct NodeInfoList
typedef struct s_event_info
{
char *node_name;
char *conninfo_str;
} t_event_info;
char *node_name;
char *conninfo_str;
} t_event_info;
#define T_EVENT_INFO_INITIALIZER { \
NULL, \
@@ -186,9 +194,9 @@ typedef struct s_event_info
*/
typedef struct
{
int size;
char **keywords;
char **values;
int size;
char **keywords;
char **values;
} t_conninfo_param_list;
#define T_CONNINFO_PARAM_LIST_INITIALIZER { \
@@ -202,19 +210,19 @@ typedef struct
*/
typedef struct s_replication_slot
{
char slot_name[MAXLEN];
char slot_type[MAXLEN];
bool active;
} t_replication_slot;
char slot_name[MAXLEN];
char slot_type[MAXLEN];
bool active;
} t_replication_slot;
#define T_REPLICATION_SLOT_INITIALIZER { "", "", false }
typedef struct s_connection_user
{
char username[MAXLEN];
bool is_superuser;
} t_connection_user;
char username[MAXLEN];
bool is_superuser;
} t_connection_user;
#define T_CONNECTION_USER_INITIALIZER { "", false }
@@ -222,15 +230,15 @@ typedef struct s_connection_user
/* represents an entry in bdr.bdr_nodes */
typedef struct s_bdr_node_info
{
char node_sysid[MAXLEN];
uint32 node_timeline;
uint32 node_dboid;
char node_status;
char node_name[MAXLEN];
char node_local_dsn[MAXLEN];
char node_init_from_dsn[MAXLEN];
bool read_only;
uint32 node_seq_id;
char node_sysid[MAXLEN];
uint32 node_timeline;
uint32 node_dboid;
char node_status;
char node_name[MAXLEN];
char node_local_dsn[MAXLEN];
char node_init_from_dsn[MAXLEN];
bool read_only;
uint32 node_seq_id;
} t_bdr_node_info;
#define T_BDR_NODE_INFO_INITIALIZER { \
@@ -251,7 +259,7 @@ typedef struct BdrNodeInfoList
{
BdrNodeInfoListCell *head;
BdrNodeInfoListCell *tail;
int node_count;
int node_count;
} BdrNodeInfoList;
#define T_BDR_NODE_INFO_LIST_INITIALIZER { \
@@ -260,7 +268,8 @@ typedef struct BdrNodeInfoList
0 \
}
typedef struct {
typedef struct
{
char current_timestamp[MAXLEN];
uint64 last_wal_receive_lsn;
uint64 last_wal_replay_lsn;
@@ -280,17 +289,17 @@ typedef struct {
typedef struct
{
char filepath[MAXPGPATH];
char filename[MAXPGPATH];
bool in_data_directory;
char filepath[MAXPGPATH];
char filename[MAXPGPATH];
bool in_data_directory;
} t_configfile_info;
#define T_CONFIGFILE_INFO_INITIALIZER { "", "", false }
typedef struct
{
int size;
int entries;
int size;
int entries;
t_configfile_info **files;
} t_configfile_list;
@@ -298,9 +307,9 @@ typedef struct
typedef struct
{
uint64 system_identifier;
TimeLineID timeline;
XLogRecPtr xlogpos;
uint64 system_identifier;
TimeLineID timeline;
XLogRecPtr xlogpos;
} t_system_identification;
#define T_SYSTEM_IDENTIFICATION_INITIALIZER { \
@@ -310,7 +319,7 @@ typedef struct
}
/* global variables */
extern int server_version_num;
extern int server_version_num;
/* macros */
@@ -319,24 +328,25 @@ extern int server_version_num;
/* utility functions */
XLogRecPtr parse_lsn(const char *str);
XLogRecPtr parse_lsn(const char *str);
extern void wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt, ...)
extern void
wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
bool atobool(const char *value);
bool atobool(const char *value);
/* connection functions */
PGconn *establish_db_connection(const char *conninfo,
const bool exit_on_error);
PGconn *establish_db_connection_quiet(const char *conninfo);
const bool exit_on_error);
PGconn *establish_db_connection_quiet(const char *conninfo);
PGconn *establish_db_connection_as_user(const char *conninfo,
const char *user,
const bool exit_on_error);
const char *user,
const bool exit_on_error);
PGconn *establish_db_connection_by_params(t_conninfo_param_list *param_list,
const bool exit_on_error);
const bool exit_on_error);
PGconn *establish_primary_db_connection(PGconn *conn,
const bool exit_on_error);
const bool exit_on_error);
PGconn *get_primary_connection(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
@@ -363,35 +373,35 @@ bool rollback_transaction(PGconn *conn);
bool check_cluster_schema(PGconn *conn);
/* GUC manipulation functions */
bool set_config(PGconn *conn, const char *config_param, const char *config_value);
bool set_config(PGconn *conn, const char *config_param, const char *config_value);
bool set_config_bool(PGconn *conn, const char *config_param, bool state);
int guc_set(PGconn *conn, const char *parameter, const char *op,
const char *value);
int guc_set_typed(PGconn *conn, const char *parameter, const char *op,
int guc_set(PGconn *conn, const char *parameter, const char *op,
const char *value);
int guc_set_typed(PGconn *conn, const char *parameter, const char *op,
const char *value, const char *datatype);
bool get_pg_setting(PGconn *conn, const char *setting, char *output);
/* server information functions */
bool get_cluster_size(PGconn *conn, char *size);
int get_server_version(PGconn *conn, char *server_version);
bool get_cluster_size(PGconn *conn, char *size);
int get_server_version(PGconn *conn, char *server_version);
RecoveryType get_recovery_type(PGconn *conn);
int get_primary_node_id(PGconn *conn);
bool can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *reason);
int get_ready_archive_files(PGconn *conn, const char *data_directory);
bool identify_system(PGconn *repl_conn, t_system_identification *identification);
bool repmgrd_set_local_node_id(PGconn *conn, int local_node_id);
int get_primary_node_id(PGconn *conn);
bool can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *reason);
int get_ready_archive_files(PGconn *conn, const char *data_directory);
bool identify_system(PGconn *repl_conn, t_system_identification *identification);
bool repmgrd_set_local_node_id(PGconn *conn, int local_node_id);
/* extension functions */
ExtensionStatus get_repmgr_extension_status(PGconn *conn);
/* node management functions */
void checkpoint(PGconn *conn);
void checkpoint(PGconn *conn);
/* node record functions */
t_server_type parse_node_type(const char *type);
const char *get_node_type_string(t_server_type type);
const char *get_node_type_string(t_server_type type);
RecordStatus get_node_record(PGconn *conn, int node_id, t_node_info *node_info);
RecordStatus get_node_record_by_name(PGconn *conn, const char *node_name, t_node_info *node_info);
@@ -445,53 +455,53 @@ int wait_connection_availability(PGconn *conn, long long timeout);
bool is_server_available(const char *conninfo);
/* monitoring functions */
void add_monitoring_record(
PGconn *primary_conn,
PGconn *local_conn,
int primary_node_id,
int local_node_id,
char *monitor_standby_timestamp,
XLogRecPtr primary_last_wal_location,
XLogRecPtr last_wal_receive_lsn,
char *last_xact_replay_timestamp,
long long unsigned int replication_lag_bytes,
long long unsigned int apply_lag_bytes
);
void
add_monitoring_record(
PGconn *primary_conn,
PGconn *local_conn,
int primary_node_id,
int local_node_id,
char *monitor_standby_timestamp,
XLogRecPtr primary_last_wal_location,
XLogRecPtr last_wal_receive_lsn,
char *last_xact_replay_timestamp,
long long unsigned int replication_lag_bytes,
long long unsigned int apply_lag_bytes
);
/* node voting functions */
NodeVotingStatus get_voting_status(PGconn *conn);
VoteRequestResult request_vote(PGconn *conn, t_node_info *this_node, t_node_info *other_node, int electoral_term);
int set_voting_status_initiated(PGconn *conn);
bool announce_candidature(PGconn *conn, t_node_info *this_node, t_node_info *other_node, int electoral_term);
void notify_follow_primary(PGconn *conn, int primary_node_id);
bool get_new_primary(PGconn *conn, int *primary_node_id);
void reset_voting_status(PGconn *conn);
int set_voting_status_initiated(PGconn *conn);
bool announce_candidature(PGconn *conn, t_node_info *this_node, t_node_info *other_node, int electoral_term);
void notify_follow_primary(PGconn *conn, int primary_node_id);
bool get_new_primary(PGconn *conn, int *primary_node_id);
void reset_voting_status(PGconn *conn);
/* replication status functions */
XLogRecPtr get_current_wal_lsn(PGconn *conn);
XLogRecPtr get_last_wal_receive_location(PGconn *conn);
bool get_replication_info(PGconn *conn, ReplInfo *replication_info);
int get_replication_lag_seconds(PGconn *conn);
void get_node_replication_stats(PGconn *conn, t_node_info *node_info);
bool is_downstream_node_attached(PGconn *conn, char *node_name);
XLogRecPtr get_current_wal_lsn(PGconn *conn);
XLogRecPtr get_last_wal_receive_location(PGconn *conn);
bool get_replication_info(PGconn *conn, ReplInfo *replication_info);
int get_replication_lag_seconds(PGconn *conn);
void get_node_replication_stats(PGconn *conn, t_node_info *node_info);
bool is_downstream_node_attached(PGconn *conn, char *node_name);
/* BDR functions */
void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list);
void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list);
RecordStatus get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info);
bool is_bdr_db(PGconn *conn, PQExpBufferData *output);
bool is_active_bdr_node(PGconn *conn, const char *node_name);
bool is_bdr_repmgr(PGconn *conn);
bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
bool add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
void add_extension_tables_to_bdr_replication_set(PGconn *conn);
bool is_bdr_db(PGconn *conn, PQExpBufferData *output);
bool is_active_bdr_node(PGconn *conn, const char *node_name);
bool is_bdr_repmgr(PGconn *conn);
bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
bool add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
void add_extension_tables_to_bdr_replication_set(PGconn *conn);
bool bdr_node_exists(PGconn *conn, const char *node_name);
bool bdr_node_exists(PGconn *conn, const char *node_name);
ReplSlotStatus get_bdr_node_replication_slot_status(PGconn *conn, const char *node_name);
void get_bdr_other_node_name(PGconn *conn, int node_id, char *name_buf);
void get_bdr_other_node_name(PGconn *conn, int node_id, char *name_buf);
bool am_bdr_failover_handler(PGconn *conn, int node_id);
void unset_bdr_failover_handler(PGconn *conn);
#endif /* _REPMGR_DBUTILS_H_ */
bool am_bdr_failover_handler(PGconn *conn, int node_id);
void unset_bdr_failover_handler(PGconn *conn);
#endif /* _REPMGR_DBUTILS_H_ */

View File

@@ -35,7 +35,7 @@
#include "strutil.h"
#include "log.h"
static int unlink_dir_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
static int unlink_dir_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
@@ -107,7 +107,7 @@ create_dir(char *path)
return true;
log_error(_("unable to create directory \"%s\": %s"),
path, strerror(errno));
path, strerror(errno));
return false;
}
@@ -258,7 +258,7 @@ create_pg_dir(char *path, bool force)
if (!create_dir(path))
{
log_error(_("unable to create directory \"%s\"..."),
path);
path);
return false;
}
break;
@@ -270,7 +270,7 @@ create_pg_dir(char *path, bool force)
if (!set_dir_permissions(path))
{
log_error(_("unable to change permissions of directory \"%s\":\n %s"),
path, strerror(errno));
path, strerror(errno));
return false;
}
break;
@@ -296,16 +296,16 @@ create_pg_dir(char *path, bool force)
else if (pg_dir && !force)
{
log_hint(_("This looks like a PostgreSQL directory.\n"
"If you are sure you want to clone here, "
"please check there is no PostgreSQL server "
"running and use the -F/--force option"));
"If you are sure you want to clone here, "
"please check there is no PostgreSQL server "
"running and use the -F/--force option"));
return false;
}
return false;
default:
log_error(_("could not access directory \"%s\": %s"),
path, strerror(errno));
path, strerror(errno));
return false;
}
return true;
@@ -314,11 +314,10 @@ create_pg_dir(char *path, bool force)
static int
unlink_dir_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
int rv = remove(fpath);
int rv = remove(fpath);
if (rv)
perror(fpath);
if (rv)
perror(fpath);
return rv;
return rv;
}

View File

@@ -19,12 +19,12 @@
#ifndef _DIRUTIL_H_
#define _DIRUTIL_H_
extern int mkdir_p(char *path, mode_t omode);
extern bool set_dir_permissions(char *path);
extern int mkdir_p(char *path, mode_t omode);
extern bool set_dir_permissions(char *path);
extern int check_dir(char *path);
extern bool create_dir(char *path);
extern bool is_pg_dir(char *path);
extern bool create_pg_dir(char *path, bool force);
extern int check_dir(char *path);
extern bool create_dir(char *path);
extern bool is_pg_dir(char *path);
extern bool create_pg_dir(char *path, bool force);
#endif

View File

@@ -44,5 +44,4 @@
#define ERR_REGISTRATION_SYNC 20
#define ERR_OUT_OF_MEMORY 21
#endif /* _ERRCODE_H_ */
#endif /* _ERRCODE_H_ */

39
log.c
View File

@@ -37,7 +37,8 @@
/* #define REPMGR_DEBUG */
static int detect_log_facility(const char *facility);
static void _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_list ap)
static void
_stderr_log_with_level(const char *level_name, int level, const char *fmt, va_list ap)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
int log_type = REPMGR_STDERR;
@@ -45,6 +46,7 @@ int log_level = LOG_NOTICE;
int last_log_level = LOG_INFO;
int verbose_logging = false;
int terse_logging = false;
/*
* Global variable to be set by the main application to ensure any log output
* emitted before logger_init is called, is output in the correct format
@@ -52,7 +54,7 @@ int terse_logging = false;
int logger_output_mode = OM_DAEMON;
extern void
stderr_log_with_level(const char *level_name, int level, const char *fmt, ...)
stderr_log_with_level(const char *level_name, int level, const char *fmt,...)
{
va_list arglist;
@@ -67,8 +69,8 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
char buf[100];
/*
* Store the requested level so that if there's a subsequent
* log_hint() or log_detail(), we can suppress that if appropriate.
* Store the requested level so that if there's a subsequent log_hint() or
* log_detail(), we can suppress that if appropriate.
*/
last_log_level = level;
@@ -80,6 +82,7 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
{
time_t t;
struct tm *tm;
time(&t);
tm = localtime(&t);
strftime(buf, 100, "[%Y-%m-%d %H:%M:%S]", tm);
@@ -97,7 +100,7 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
}
void
log_hint(const char *fmt, ...)
log_hint(const char *fmt,...)
{
va_list ap;
@@ -111,7 +114,7 @@ log_hint(const char *fmt, ...)
void
log_detail(const char *fmt, ...)
log_detail(const char *fmt,...)
{
va_list ap;
@@ -125,7 +128,7 @@ log_detail(const char *fmt, ...)
void
log_verbose(int level, const char *fmt, ...)
log_verbose(int level, const char *fmt,...)
{
va_list ap;
@@ -133,7 +136,7 @@ log_verbose(int level, const char *fmt, ...)
if (verbose_logging == true)
{
switch(level)
switch (level)
{
case LOG_EMERG:
_stderr_log_with_level("EMERG", level, fmt, ap);
@@ -202,8 +205,8 @@ logger_init(t_configuration_options *opts, const char *ident)
}
/*
* STDERR only logging requested - finish here without setting up any further
* logging facility.
* STDERR only logging requested - finish here without setting up any
* further logging facility.
*/
if (logger_output_mode == OM_COMMAND_LINE)
return true;
@@ -251,9 +254,10 @@ logger_init(t_configuration_options *opts, const char *ident)
{
FILE *fd;
/* Check if we can write to the specified file before redirecting
* stderr - if freopen() fails, stderr output will vanish into
* the ether and the user won't know what's going on.
/*
* Check if we can write to the specified file before redirecting
* stderr - if freopen() fails, stderr output will vanish into the
* ether and the user won't know what's going on.
*/
fd = fopen(opts->log_file, "a");
@@ -270,9 +274,9 @@ logger_init(t_configuration_options *opts, const char *ident)
fd = freopen(opts->log_file, "a", stderr);
/*
* It's possible freopen() may still fail due to e.g. a race condition;
* as it's not feasible to restore stderr after a failed freopen(),
* we'll write to stdout as a last resort.
* It's possible freopen() may still fail due to e.g. a race
* condition; as it's not feasible to restore stderr after a failed
* freopen(), we'll write to stdout as a last resort.
*/
if (fd == NULL)
{
@@ -318,7 +322,8 @@ logger_set_verbose(void)
* options and hints.
*/
void logger_set_terse(void)
void
logger_set_terse(void)
{
terse_logging = true;
}

13
log.h
View File

@@ -122,18 +122,21 @@ int detect_log_level(const char *level);
/* Logger initialisation and shutdown */
bool logger_init(t_configuration_options * opts, const char *ident);
bool logger_init(t_configuration_options *opts, const char *ident);
bool logger_shutdown(void);
void logger_set_verbose(void);
void logger_set_terse(void);
void log_detail(const char *fmt, ...)
void
log_detail(const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
void log_hint(const char *fmt, ...)
void
log_hint(const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
void log_verbose(int level, const char *fmt, ...)
void
log_verbose(int level, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern int log_type;
@@ -142,4 +145,4 @@ extern int verbose_logging;
extern int terse_logging;
extern int logger_output_mode;
#endif /* _REPMGR_LOG_H_ */
#endif /* _REPMGR_LOG_H_ */

View File

@@ -34,14 +34,14 @@
void
do_bdr_register(void)
{
PGconn *conn = NULL;
PGconn *conn = NULL;
BdrNodeInfoList bdr_nodes = T_BDR_NODE_INFO_LIST_INITIALIZER;
ExtensionStatus extension_status = REPMGR_UNKNOWN;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
RecordStatus record_status = RECORD_NOT_FOUND;
ExtensionStatus extension_status = REPMGR_UNKNOWN;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
RecordStatus record_status = RECORD_NOT_FOUND;
PQExpBufferData event_details;
bool success = true;
char dbname[MAXLEN];
bool success = true;
char dbname[MAXLEN];
/* sanity-check configuration for BDR-compatability */
if (config_file_options.replication_type != REPLICATION_TYPE_BDR)
@@ -124,7 +124,7 @@ do_bdr_register(void)
/* check for a matching BDR node */
{
bool node_exists = bdr_node_exists(conn, config_file_options.node_name);
bool node_exists = bdr_node_exists(conn, config_file_options.node_name);
if (node_exists == false)
{
@@ -136,15 +136,15 @@ do_bdr_register(void)
}
/*
* before adding the extension tables to the replication set,
* if any other BDR nodes exist, populate repmgr.nodes with a copy
* of existing entries
* before adding the extension tables to the replication set, if any other
* BDR nodes exist, populate repmgr.nodes with a copy of existing entries
*
* currently we won't copy the contents of any other tables
*
*/
{
NodeInfoList local_node_records = T_NODE_INFO_LIST_INITIALIZER;
get_all_node_records(conn, &local_node_records);
if (local_node_records.node_count == 0)
@@ -163,7 +163,7 @@ do_bdr_register(void)
for (bdr_cell = bdr_nodes.head; bdr_cell; bdr_cell = bdr_cell->next)
{
PGconn *bdr_node_conn = NULL;
PGconn *bdr_node_conn = NULL;
NodeInfoList existing_nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL;
ExtensionStatus other_node_extension_status = REPMGR_UNKNOWN;
@@ -235,10 +235,11 @@ do_bdr_register(void)
if (record_status == RECORD_FOUND)
{
bool node_updated = false;
bool node_updated = false;
/*
* At this point we will have established there are no non-BDR records,
* so no need to verify the node type
* At this point we will have established there are no non-BDR
* records, so no need to verify the node type
*/
if (!runtime_options.force)
{
@@ -250,8 +251,8 @@ do_bdr_register(void)
}
/*
* don't permit changing the node name - this must match the
* BDR node name set when the node was registered.
* don't permit changing the node name - this must match the BDR node
* name set when the node was registered.
*/
if (strncmp(node_info.node_name, config_file_options.node_name, MAXLEN) != 0)
@@ -281,7 +282,7 @@ do_bdr_register(void)
else
{
/* create new node record */
bool node_created = create_node_record(conn, "bdr register", &node_info);
bool node_created = create_node_record(conn, "bdr register", &node_info);
if (node_created == true)
{
@@ -306,12 +307,12 @@ do_bdr_register(void)
commit_transaction(conn);
/* Log the event */
create_event_notification(
conn,
&config_file_options,
config_file_options.node_id,
"bdr_register",
true,
event_details.data);
conn,
&config_file_options,
config_file_options.node_id,
"bdr_register",
true,
event_details.data);
termPQExpBuffer(&event_details);
@@ -327,14 +328,14 @@ do_bdr_register(void)
void
do_bdr_unregister(void)
{
PGconn *conn = NULL;
ExtensionStatus extension_status = REPMGR_UNKNOWN;
int target_node_id = UNKNOWN_NODE_ID;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
RecordStatus record_status = RECORD_NOT_FOUND;
bool node_record_deleted = false;
PGconn *conn = NULL;
ExtensionStatus extension_status = REPMGR_UNKNOWN;
int target_node_id = UNKNOWN_NODE_ID;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
RecordStatus record_status = RECORD_NOT_FOUND;
bool node_record_deleted = false;
PQExpBufferData event_details;
char dbname[MAXLEN];
char dbname[MAXLEN];
/* sanity-check configuration for BDR-compatability */
@@ -411,12 +412,12 @@ do_bdr_unregister(void)
/* Log the event */
create_event_notification(
conn,
&config_file_options,
config_file_options.node_id,
"bdr_unregister",
true,
event_details.data);
conn,
&config_file_options,
config_file_options.node_id,
"bdr_unregister",
true,
event_details.data);
PQfinish(conn);

View File

@@ -25,4 +25,4 @@ extern void do_bdr_unregister(void);
extern void do_bdr_help(void);
#endif /* _REPMGR_ACTION_BDR_H_ */
#endif /* _REPMGR_ACTION_BDR_H_ */

View File

@@ -27,7 +27,8 @@
#define SHOW_HEADER_COUNT 7
typedef enum {
typedef enum
{
SHOW_ID = 0,
SHOW_NAME,
SHOW_ROLE,
@@ -35,25 +36,27 @@ typedef enum {
SHOW_UPSTREAM_NAME,
SHOW_LOCATION,
SHOW_CONNINFO
} ShowHeader;
} ShowHeader;
#define EVENT_HEADER_COUNT 6
typedef enum {
typedef enum
{
EV_NODE_ID = 0,
EV_NODE_NAME,
EV_EVENT,
EV_SUCCESS,
EV_TIMESTAMP,
EV_DETAILS
} EventHeader;
} EventHeader;
struct ColHeader {
char title[MAXLEN];
int max_length;
int cur_length;
struct ColHeader
{
char title[MAXLEN];
int max_length;
int cur_length;
};
struct ColHeader headers_show[SHOW_HEADER_COUNT];
@@ -61,8 +64,8 @@ struct ColHeader headers_event[EVENT_HEADER_COUNT];
static int build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length);
static int build_cluster_crosscheck(t_node_status_cube ***cube_dest, int *name_length);
static int build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length);
static int build_cluster_crosscheck(t_node_status_cube ***cube_dest, int *name_length);
static void cube_set_node_status(t_node_status_cube **cube, int n, int node_id, int matrix_node_id, int connection_node_id, int connection_status);
/*
@@ -78,7 +81,7 @@ do_cluster_show(void)
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL;
int i = 0;
ItemList warnings = { NULL, NULL };
ItemList warnings = {NULL, NULL};
/* Connect to local database to obtain cluster connection data */
log_verbose(LOG_INFO, _("connecting to database\n"));
@@ -106,8 +109,8 @@ do_cluster_show(void)
strncpy(headers_show[SHOW_CONNINFO].title, _("Connection string"), MAXLEN);
/*
* NOTE: if repmgr is ever localized into non-ASCII locales,
* use pg_wcssize() or similar to establish printed column length
* NOTE: if repmgr is ever localized into non-ASCII locales, use
* pg_wcssize() or similar to establish printed column length
*/
for (i = 0; i < SHOW_HEADER_COUNT; i++)
@@ -136,171 +139,172 @@ do_cluster_show(void)
/*
* TODO: count nodes marked as "? unreachable" and add a hint about
* the other cluster commands for better determining whether unreachable.
* the other cluster commands for better determining whether
* unreachable.
*/
switch (cell->node_info->type)
{
case PRIMARY:
{
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
if (cell->node_info->active == true)
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
switch (cell->node_info->recovery_type)
if (cell->node_info->active == true)
{
case RECTYPE_PRIMARY:
appendPQExpBuffer(&details, "* running");
break;
case RECTYPE_STANDBY:
switch (cell->node_info->recovery_type)
{
case RECTYPE_PRIMARY:
appendPQExpBuffer(&details, "* running");
break;
case RECTYPE_STANDBY:
appendPQExpBuffer(&details, "! running as standby");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as primary but running as standby",
cell->node_info->node_name, cell->node_info->node_id);
break;
case RECTYPE_UNKNOWN:
appendPQExpBuffer(&details, "! unknown");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) has unknown replication status",
cell->node_info->node_name, cell->node_info->node_id);
break;
}
}
else
{
if (cell->node_info->recovery_type == RECTYPE_PRIMARY)
{
appendPQExpBuffer(&details, "! running");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
}
else
{
appendPQExpBuffer(&details, "! running as standby");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as primary but running as standby",
cell->node_info->node_name, cell->node_info->node_id);
break;
case RECTYPE_UNKNOWN:
appendPQExpBuffer(&details, "! unknown");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) has unknown replication status",
cell->node_info->node_name, cell->node_info->node_id);
break;
&warnings,
"node \"%s\" (ID: %i) is registered as an inactive primary but running as standby",
cell->node_info->node_name, cell->node_info->node_id);
}
}
}
/* node is unreachable */
else
{
if (cell->node_info->recovery_type == RECTYPE_PRIMARY)
/* node is unreachable but marked active */
if (cell->node_info->active == true)
{
appendPQExpBuffer(&details, "! running");
appendPQExpBuffer(&details, "? unreachable");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
&warnings,
"node \"%s\" (ID: %i) is registered as an active primary but is unreachable",
cell->node_info->node_name, cell->node_info->node_id);
}
/* node is unreachable and marked as inactive */
else
{
appendPQExpBuffer(&details, "! running as standby");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as an inactive primary but running as standby",
cell->node_info->node_name, cell->node_info->node_id);
appendPQExpBuffer(&details, "- failed");
}
}
}
/* node is unreachable */
else
{
/* node is unreachable but marked active*/
if (cell->node_info->active == true)
{
appendPQExpBuffer(&details, "? unreachable");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as an active primary but is unreachable",
cell->node_info->node_name, cell->node_info->node_id);
}
/* node is unreachable and marked as inactive */
else
{
appendPQExpBuffer(&details, "- failed");
}
}
}
break;
break;
case STANDBY:
{
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
if (cell->node_info->active == true)
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
switch (cell->node_info->recovery_type)
if (cell->node_info->active == true)
{
case RECTYPE_STANDBY:
appendPQExpBuffer(&details, " running");
break;
case RECTYPE_PRIMARY:
appendPQExpBuffer(&details, "! running as primary");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as standby but running as primary",
cell->node_info->node_name, cell->node_info->node_id);
break;
case RECTYPE_UNKNOWN:
appendPQExpBuffer(&details, "! unknown");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) has unknown replication status",
cell->node_info->node_name, cell->node_info->node_id);
break;
}
}
else
{
if (cell->node_info->recovery_type == RECTYPE_STANDBY)
{
appendPQExpBuffer(&details, "! running");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
switch (cell->node_info->recovery_type)
{
case RECTYPE_STANDBY:
appendPQExpBuffer(&details, " running");
break;
case RECTYPE_PRIMARY:
appendPQExpBuffer(&details, "! running as primary");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as standby but running as primary",
cell->node_info->node_name, cell->node_info->node_id);
break;
case RECTYPE_UNKNOWN:
appendPQExpBuffer(&details, "! unknown");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) has unknown replication status",
cell->node_info->node_name, cell->node_info->node_id);
break;
}
}
else
{
appendPQExpBuffer(&details, "! running as primary");
if (cell->node_info->recovery_type == RECTYPE_STANDBY)
{
appendPQExpBuffer(&details, "! running");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
}
else
{
appendPQExpBuffer(&details, "! running as primary");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running as primary but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
}
}
}
/* node is unreachable */
else
{
/* node is unreachable but marked active */
if (cell->node_info->active == true)
{
appendPQExpBuffer(&details, "? unreachable");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is running as primary but the repmgr node record is inactive",
cell->node_info->node_name, cell->node_info->node_id);
&warnings,
"node \"%s\" (ID: %i) is registered as an active standby but is unreachable",
cell->node_info->node_name, cell->node_info->node_id);
}
else
{
appendPQExpBuffer(&details, "- failed");
}
}
}
/* node is unreachable */
else
{
/* node is unreachable but marked active*/
if (cell->node_info->active == true)
{
appendPQExpBuffer(&details, "? unreachable");
item_list_append_format(
&warnings,
"node \"%s\" (ID: %i) is registered as an active standby but is unreachable",
cell->node_info->node_name, cell->node_info->node_id);
}
else
{
appendPQExpBuffer(&details, "- failed");
}
}
}
break;
break;
case BDR:
{
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
if (cell->node_info->active == true)
appendPQExpBuffer(&details, "* running");
/* node is reachable */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
if (cell->node_info->active == true)
appendPQExpBuffer(&details, "* running");
else
appendPQExpBuffer(&details, "! running");
}
/* node is unreachable */
else
appendPQExpBuffer(&details, "! running");
{
if (cell->node_info->active == true)
appendPQExpBuffer(&details, "? unreachable");
else
appendPQExpBuffer(&details, "- failed");
}
}
/* node is unreachable */
else
{
if (cell->node_info->active == true)
appendPQExpBuffer(&details, "? unreachable");
else
appendPQExpBuffer(&details, "- failed");
}
}
break;
break;
case UNKNOWN:
{
/* this should never happen */
appendPQExpBuffer(&details, "? unknown node type");
}
break;
{
/* this should never happen */
appendPQExpBuffer(&details, "? unknown node type");
}
break;
}
strncpy(cell->node_info->details, details.data, MAXLEN);
@@ -344,7 +348,8 @@ do_cluster_show(void)
for (i = 0; i < SHOW_HEADER_COUNT; i++)
{
int j;
int j;
for (j = 0; j < headers_show[i].max_length; j++)
printf("-");
@@ -361,12 +366,12 @@ do_cluster_show(void)
{
if (runtime_options.output_mode == OM_CSV)
{
int connection_status = (cell->node_info->node_status == NODE_STATUS_UP) ? 0 : -1;
int recovery_type = RECTYPE_UNKNOWN;
int connection_status = (cell->node_info->node_status == NODE_STATUS_UP) ? 0 : -1;
int recovery_type = RECTYPE_UNKNOWN;
/*
* here we explicitly convert the RecoveryType to integer values to
* avoid implicit dependency on the values in the enum
* here we explicitly convert the RecoveryType to integer values
* to avoid implicit dependency on the values in the enum
*/
switch (cell->node_info->recovery_type)
{
@@ -388,12 +393,12 @@ do_cluster_show(void)
}
else
{
printf( " %-*i ", headers_show[SHOW_ID].max_length, cell->node_info->node_id);
printf("| %-*s ", headers_show[SHOW_NAME].max_length, cell->node_info->node_name);
printf("| %-*s ", headers_show[SHOW_ROLE].max_length, get_node_type_string(cell->node_info->type));
printf("| %-*s ", headers_show[SHOW_STATUS].max_length, cell->node_info->details);
printf("| %-*s ", headers_show[SHOW_UPSTREAM_NAME].max_length , cell->node_info->upstream_node_name);
printf("| %-*s ", headers_show[SHOW_LOCATION].max_length , cell->node_info->location);
printf(" %-*i ", headers_show[SHOW_ID].max_length, cell->node_info->node_id);
printf("| %-*s ", headers_show[SHOW_NAME].max_length, cell->node_info->node_name);
printf("| %-*s ", headers_show[SHOW_ROLE].max_length, get_node_type_string(cell->node_info->type));
printf("| %-*s ", headers_show[SHOW_STATUS].max_length, cell->node_info->details);
printf("| %-*s ", headers_show[SHOW_UPSTREAM_NAME].max_length, cell->node_info->upstream_node_name);
printf("| %-*s ", headers_show[SHOW_LOCATION].max_length, cell->node_info->location);
printf("| %-*s\n", headers_show[SHOW_CONNINFO].max_length, cell->node_info->conninfo);
}
}
@@ -429,11 +434,11 @@ do_cluster_show(void)
void
do_cluster_event(void)
{
PGconn *conn = NULL;
PQExpBufferData query;
PQExpBufferData where_clause;
PGresult *res;
int i = 0;
PGconn *conn = NULL;
PQExpBufferData query;
PQExpBufferData where_clause;
PGresult *res;
int i = 0;
conn = establish_db_connection(config_file_options.conninfo, true);
@@ -442,12 +447,12 @@ do_cluster_event(void)
/* LEFT JOIN used here as a node record may have been removed */
appendPQExpBuffer(
&query,
" SELECT e.node_id, n.node_name, e.event, e.successful, \n"
" TO_CHAR(e.event_timestamp, 'YYYY-MM-DD HH24:MI:SS') AS timestamp, \n"
" e.details \n"
" FROM repmgr.events e \n"
"LEFT JOIN repmgr.nodes n ON e.node_id = n.node_id ");
&query,
" SELECT e.node_id, n.node_name, e.event, e.successful, \n"
" TO_CHAR(e.event_timestamp, 'YYYY-MM-DD HH24:MI:SS') AS timestamp, \n"
" e.details \n"
" FROM repmgr.events e \n"
"LEFT JOIN repmgr.nodes n ON e.node_id = n.node_id ");
if (runtime_options.node_id != UNKNOWN_NODE_ID)
{
@@ -457,7 +462,7 @@ do_cluster_event(void)
}
else if (runtime_options.node_name[0] != '\0')
{
char *escaped = escape_string(conn, runtime_options.node_name);
char *escaped = escape_string(conn, runtime_options.node_name);
if (escaped == NULL)
{
@@ -474,7 +479,7 @@ do_cluster_event(void)
if (runtime_options.event[0] != '\0')
{
char *escaped = escape_string(conn, runtime_options.event);
char *escaped = escape_string(conn, runtime_options.event);
if (escaped == NULL)
{
@@ -516,7 +521,8 @@ do_cluster_event(void)
exit(ERR_DB_QUERY);
}
if (PQntuples(res) == 0) {
if (PQntuples(res) == 0)
{
/* print this message directly, rather than as a log line */
printf(_("no matching events found\n"));
PQclear(res);
@@ -536,14 +542,14 @@ do_cluster_event(void)
headers_event[i].max_length = strlen(headers_event[i].title);
}
for(i = 0; i < PQntuples(res); i++)
for (i = 0; i < PQntuples(res); i++)
{
int j;
int j;
for (j = 0; j < EVENT_HEADER_COUNT; j++)
{
headers_event[j].cur_length = strlen(PQgetvalue(res, i, j));
if(headers_event[j].cur_length > headers_event[j].max_length)
if (headers_event[j].cur_length > headers_event[j].max_length)
{
headers_event[j].max_length = headers_event[j].cur_length;
}
@@ -566,7 +572,8 @@ do_cluster_event(void)
printf("-");
for (i = 0; i < EVENT_HEADER_COUNT; i++)
{
int j;
int j;
for (j = 0; j < headers_event[i].max_length; j++)
printf("-");
@@ -578,9 +585,9 @@ do_cluster_event(void)
printf("\n");
for(i = 0; i < PQntuples(res); i++)
for (i = 0; i < PQntuples(res); i++)
{
int j;
int j;
printf(" ");
for (j = 0; j < EVENT_HEADER_COUNT; j++)
@@ -590,7 +597,7 @@ do_cluster_event(void)
PQgetvalue(res, i, j));
if (j < (EVENT_HEADER_COUNT - 1))
printf(" | ");
printf(" | ");
}
printf("\n");
@@ -607,7 +614,8 @@ do_cluster_event(void)
void
do_cluster_crosscheck(void)
{
int i = 0, n = 0;
int i = 0,
n = 0;
char c;
const char *node_header = "Name";
int name_length = strlen(node_header);
@@ -630,7 +638,7 @@ do_cluster_crosscheck(void)
for (i = 0; i < n; i++)
{
int column_node_ix;
int column_node_ix;
printf("%*s | %2d ", name_length,
cube[i]->node_name,
@@ -638,26 +646,27 @@ do_cluster_crosscheck(void)
for (column_node_ix = 0; column_node_ix < n; column_node_ix++)
{
int max_node_status = -2;
int node_ix = 0;
int max_node_status = -2;
int node_ix = 0;
/*
* The value of entry (i,j) is equal to the
* maximum value of all the (i,j,k). Indeed:
* The value of entry (i,j) is equal to the maximum value of all
* the (i,j,k). Indeed:
*
* - if one of the (i,j,k) is 0 (node up), then 0
* (the node is up);
* - if one of the (i,j,k) is 0 (node up), then 0 (the node is
* up);
*
* - if the (i,j,k) are either -1 (down) or -2
* (unknown), then -1 (the node is down);
* - if the (i,j,k) are either -1 (down) or -2 (unknown), then -1
* (the node is down);
*
* - if all the (i,j,k) are -2 (unknown), then -2
* (the node is in an unknown state).
* - if all the (i,j,k) are -2 (unknown), then -2 (the node is in
* an unknown state).
*/
for(node_ix = 0; node_ix < n; node_ix ++)
for (node_ix = 0; node_ix < n; node_ix++)
{
int node_status = cube[node_ix]->matrix_list_rec[i]->node_status_list[column_node_ix]->node_status;
int node_status = cube[node_ix]->matrix_list_rec[i]->node_status_list[column_node_ix]->node_status;
if (node_status > max_node_status)
max_node_status = node_status;
}
@@ -685,7 +694,9 @@ do_cluster_crosscheck(void)
/* clean up allocated cube array */
{
int h, j;
int h,
j;
for (h = 0; h < n; h++)
{
for (i = 0; i < n; i++)
@@ -710,7 +721,9 @@ do_cluster_crosscheck(void)
void
do_cluster_matrix()
{
int i = 0, j = 0, n = 0;
int i = 0,
j = 0,
n = 0;
const char *node_header = "Name";
int name_length = strlen(node_header);
@@ -730,7 +743,7 @@ do_cluster_matrix()
}
else
{
char c;
char c;
printf("%*s | Id ", name_length, node_header);
for (i = 0; i < n; i++)
@@ -753,17 +766,17 @@ do_cluster_matrix()
{
switch (matrix_rec_list[i]->node_status_list[j]->node_status)
{
case -2:
c = '?';
break;
case -1:
c = 'x';
break;
case 0:
c = '*';
break;
default:
exit(ERR_INTERNAL);
case -2:
c = '?';
break;
case -1:
c = 'x';
break;
case 0:
c = '*';
break;
default:
exit(ERR_INTERNAL);
}
printf("| %c ", c);
@@ -789,7 +802,8 @@ do_cluster_matrix()
static void
matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id, int connection_node_id, int connection_status)
{
int i, j;
int i,
j;
for (i = 0; i < n; i++)
{
@@ -812,10 +826,11 @@ matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id,
static int
build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
{
PGconn *conn = NULL;
int i = 0, j = 0;
int local_node_id = UNKNOWN_NODE_ID;
int node_count = 0;
PGconn *conn = NULL;
int i = 0,
j = 0;
int local_node_id = UNKNOWN_NODE_ID;
int node_count = 0;
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL;
@@ -852,9 +867,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
/*
* Allocate an empty matrix record list
*
* -2 == NULL ?
* -1 == Error x
* 0 == OK *
* -2 == NULL ? -1 == Error x 0 == OK *
*/
matrix_rec_list = (t_node_matrix_rec **) pg_malloc0(sizeof(t_node_matrix_rec) * nodes.node_count);
@@ -864,7 +877,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
/* Initialise matrix structure for each node */
for (cell = nodes.head; cell; cell = cell->next)
{
int name_length_cur;
int name_length_cur;
NodeInfoListCell *cell_j;
matrix_rec_list[i] = (t_node_matrix_rec *) pg_malloc0(sizeof(t_node_matrix_rec));
@@ -875,7 +888,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
/*
* Find the maximum length of a node name
*/
name_length_cur = strlen(matrix_rec_list[i]->node_name);
name_length_cur = strlen(matrix_rec_list[i]->node_name);
if (name_length_cur > *name_length)
*name_length = name_length_cur;
@@ -887,7 +900,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
{
matrix_rec_list[i]->node_status_list[j] = (t_node_status_rec *) pg_malloc0(sizeof(t_node_status_rec));
matrix_rec_list[i]->node_status_list[j]->node_id = cell_j->node_info->node_id;
matrix_rec_list[i]->node_status_list[j]->node_status = -2; /* default unknown */
matrix_rec_list[i]->node_status_list[j]->node_status = -2; /* default unknown */
j++;
}
@@ -900,12 +913,14 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
for (cell = nodes.head; cell; cell = cell->next)
{
int connection_status = 0;
int connection_status = 0;
t_conninfo_param_list remote_conninfo = T_CONNINFO_PARAM_LIST_INITIALIZER;
char *host = NULL, *p = NULL;
int connection_node_id = cell->node_info->node_id;
int x, y;
PGconn *node_conn = NULL;
char *host = NULL,
*p = NULL;
int connection_node_id = cell->node_info->node_id;
int x,
y;
PGconn *node_conn = NULL;
initialize_conninfo_params(&remote_conninfo, false);
parse_conninfo_string(cell->node_info->conninfo,
@@ -948,9 +963,9 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
initPQExpBuffer(&command);
/*
* We'll pass cluster name and database connection string to the remote
* repmgr - those are the only values it needs to work, and saves us
* making assumptions about the location of repmgr.conf
* We'll pass cluster name and database connection string to the
* remote repmgr - those are the only values it needs to work, and
* saves us making assumptions about the location of repmgr.conf
*/
appendPQExpBuffer(&command,
"\"%s -d '%s' ",
@@ -975,11 +990,11 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
initPQExpBuffer(&command_output);
(void)remote_command(
host,
runtime_options.remote_user,
command.data,
&command_output);
(void) remote_command(
host,
runtime_options.remote_user,
command.data,
&command_output);
p = command_output.data;
@@ -998,7 +1013,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
nodes.node_count,
connection_node_id,
x,
(y == -1) ? -1 : 0 );
(y == -1) ? -1 : 0);
while (*p && (*p != '\n'))
p++;
@@ -1026,13 +1041,15 @@ static int
build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
{
PGconn *conn = NULL;
int h, i, j;
int h,
i,
j;
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL;
t_node_status_cube **cube;
int node_count = 0;
int node_count = 0;
/* We need to connect to get the list of nodes */
log_info(_("connecting to database\n"));
@@ -1056,9 +1073,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
/*
* Allocate an empty cube matrix structure
*
* -2 == NULL
* -1 == Error
* 0 == OK
* -2 == NULL -1 == Error 0 == OK
*/
cube = (t_node_status_cube **) pg_malloc(sizeof(t_node_status_cube *) * nodes.node_count);
@@ -1067,7 +1082,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
for (cell = nodes.head; cell; cell = cell->next)
{
int name_length_cur = 0;
int name_length_cur = 0;
NodeInfoListCell *cell_i = NULL;
cube[h] = (t_node_status_cube *) pg_malloc(sizeof(t_node_status_cube));
@@ -1077,7 +1092,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
/*
* Find the maximum length of a node name
*/
name_length_cur = strlen(cube[h]->node_name);
name_length_cur = strlen(cube[h]->node_name);
if (name_length_cur > *name_length)
*name_length = name_length_cur;
@@ -1102,7 +1117,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
{
cube[h]->matrix_list_rec[i]->node_status_list[j] = (t_node_status_rec *) pg_malloc0(sizeof(t_node_status_rec));
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_id = cell_j->node_info->node_id;
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_status = -2; /* default unknown */
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_status = -2; /* default unknown */
j++;
}
@@ -1121,7 +1136,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
for (cell = nodes.head; cell; cell = cell->next)
{
int remote_node_id = UNKNOWN_NODE_ID;
int remote_node_id = UNKNOWN_NODE_ID;
PQExpBufferData command;
PQExpBufferData command_output;
@@ -1155,14 +1170,14 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
/* fix to work with --node-id */
if (cube[i]->node_id == config_file_options.node_id)
{
(void)local_command(
command.data,
&command_output);
(void) local_command(
command.data,
&command_output);
}
else
{
t_conninfo_param_list remote_conninfo;
char *host = NULL;
char *host = NULL;
PQExpBufferData quoted_command;
initPQExpBuffer(&quoted_command);
@@ -1181,11 +1196,11 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
log_verbose(LOG_DEBUG, "build_cluster_crosscheck(): executing\n %s", quoted_command.data);
(void)remote_command(
host,
runtime_options.remote_user,
quoted_command.data,
&command_output);
(void) remote_command(
host,
runtime_options.remote_user,
quoted_command.data,
&command_output);
free_conninfo_params(&remote_conninfo);
termPQExpBuffer(&quoted_command);
@@ -1195,7 +1210,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
p = command_output.data;
if(!strlen(command_output.data))
if (!strlen(command_output.data))
{
termPQExpBuffer(&command_output);
continue;
@@ -1203,9 +1218,9 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
for (j = 0; j < (nodes.node_count * nodes.node_count); j++)
{
int matrix_rec_node_id;
int node_status_node_id;
int node_status;
int matrix_rec_node_id;
int node_status_node_id;
int node_status;
if (sscanf(p, "%d,%d,%d", &matrix_rec_node_id, &node_status_node_id, &node_status) != 3)
{
@@ -1243,7 +1258,9 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
static void
cube_set_node_status(t_node_status_cube **cube, int n, int execute_node_id, int matrix_node_id, int connection_node_id, int connection_status)
{
int h, i, j;
int h,
i,
j;
for (h = 0; h < n; h++)

View File

@@ -23,21 +23,21 @@
typedef struct
{
int node_id;
int node_status;
int node_id;
int node_status;
} t_node_status_rec;
typedef struct
{
int node_id;
char node_name[MAXLEN];
int node_id;
char node_name[MAXLEN];
t_node_status_rec **node_status_list;
} t_node_matrix_rec;
typedef struct
{
int node_id;
char node_name[MAXLEN];
int node_id;
char node_name[MAXLEN];
t_node_matrix_rec **matrix_list_rec;
} t_node_status_cube;

File diff suppressed because it is too large Load Diff

View File

@@ -28,4 +28,4 @@ extern void do_node_service(void);
extern void do_node_help(void);
#endif /* _REPMGR_ACTION_NODE_H_ */
#endif /* _REPMGR_ACTION_NODE_H_ */

View File

@@ -43,7 +43,7 @@ do_primary_register(void)
bool record_created = false;
PQExpBufferData event_description;
PQExpBufferData event_description;
log_info(_("connecting to primary database..."));
@@ -83,8 +83,8 @@ do_primary_register(void)
/*
* In --dry-run mode we can't proceed any further as the following code
* attempts to query the repmgr metadata, which won't exist until
* the extension is installed
* attempts to query the repmgr metadata, which won't exist until the
* extension is installed
*/
if (runtime_options.dry_run == true)
{
@@ -100,7 +100,10 @@ do_primary_register(void)
{
if (current_primary_id != config_file_options.node_id)
{
/* it's impossible to add a second primary to a streaming replication cluster */
/*
* it's impossible to add a second primary to a streaming
* replication cluster
*/
log_error(_("there is already an active registered primary (node ID: %i) in this cluster"), current_primary_id);
PQfinish(primary_conn);
PQfinish(conn);
@@ -115,9 +118,10 @@ do_primary_register(void)
begin_transaction(conn);
/*
* Check for an active primary node record with a different ID. This shouldn't
* happen, but could do if an existing primary was shut down without being unregistered.
*/
* Check for an active primary node record with a different ID. This
* shouldn't happen, but could do if an existing primary was shut down
* without being unregistered.
*/
current_primary_id = get_primary_node_id(conn);
if (current_primary_id != NODE_NOT_FOUND && current_primary_id != config_file_options.node_id)
{
@@ -130,8 +134,8 @@ do_primary_register(void)
}
/*
* Check whether there's an existing record for this node, and
* update it if --force set
* Check whether there's an existing record for this node, and update it
* if --force set
*/
record_status = get_node_record(conn, config_file_options.node_id, &node_info);
@@ -199,12 +203,12 @@ do_primary_register(void)
/* Log the event */
create_event_notification(
conn,
&config_file_options,
config_file_options.node_id,
"primary_register",
record_created,
event_description.data);
conn,
&config_file_options,
config_file_options.node_id,
"primary_register",
record_created,
event_description.data);
termPQExpBuffer(&event_description);
@@ -241,12 +245,12 @@ do_primary_register(void)
void
do_primary_unregister(void)
{
PGconn *primary_conn = NULL;
PGconn *local_conn = NULL;
t_node_info local_node_info = T_NODE_INFO_INITIALIZER;
PGconn *primary_conn = NULL;
PGconn *local_conn = NULL;
t_node_info local_node_info = T_NODE_INFO_INITIALIZER;
t_node_info *target_node_info_ptr = NULL;
PGconn *target_node_conn = NULL;
PGconn *target_node_conn = NULL;
NodeInfoList downstream_nodes = T_NODE_INFO_LIST_INITIALIZER;
@@ -257,8 +261,8 @@ do_primary_unregister(void)
get_local_node_record(local_conn, config_file_options.node_id, &local_node_info);
/*
* Obtain a connection to the current primary node - if this isn't possible,
* abort as we won't be able to update the "nodes" table anyway.
* Obtain a connection to the current primary node - if this isn't
* possible, abort as we won't be able to update the "nodes" table anyway.
*/
primary_conn = establish_primary_db_connection(local_conn, false);
@@ -287,7 +291,7 @@ do_primary_unregister(void)
/* Target node is local node? */
if (target_node_info.node_id == UNKNOWN_NODE_ID
|| target_node_info.node_id == config_file_options.node_id)
|| target_node_info.node_id == config_file_options.node_id)
{
target_node_info_ptr = &local_node_info;
}
@@ -306,7 +310,7 @@ do_primary_unregister(void)
if (downstream_nodes.node_count > 0)
{
NodeInfoListCell *cell = NULL;
PQExpBufferData detail;
PQExpBufferData detail;
if (downstream_nodes.node_count == 1)
{
@@ -361,13 +365,16 @@ do_primary_unregister(void)
/* If we can connect to the node, perform some sanity checks on it */
else
{
bool can_unregister = true;
bool can_unregister = true;
RecoveryType recovery_type = get_recovery_type(target_node_conn);
/* Node appears to be a standby */
if (recovery_type == RECTYPE_STANDBY)
{
/* We'll refuse to do anything unless the node record shows it as a primary */
/*
* We'll refuse to do anything unless the node record shows it as
* a primary
*/
if (target_node_info_ptr->type != PRIMARY)
{
log_error(_("node %s (ID: %i) is a %s, unable to unregister"),
@@ -376,9 +383,11 @@ do_primary_unregister(void)
get_node_type_string(target_node_info_ptr->type));
can_unregister = false;
}
/*
* If --F/--force not set, hint that it might be appropriate to
* register the node as a standby rather than unregister as primary
* register the node as a standby rather than unregister as
* primary
*/
else if (!runtime_options.force)
{
@@ -400,8 +409,8 @@ do_primary_unregister(void)
}
else if (recovery_type == RECTYPE_PRIMARY)
{
t_node_info primary_node_info = T_NODE_INFO_INITIALIZER;
bool primary_record_found = false;
t_node_info primary_node_info = T_NODE_INFO_INITIALIZER;
bool primary_record_found = false;
primary_record_found = get_primary_node_record(primary_conn, &primary_node_info);
@@ -415,8 +424,10 @@ do_primary_unregister(void)
PQfinish(primary_conn);
exit(ERR_BAD_CONFIG);
}
/* This appears to be the cluster primary - cowardly refuse
* to delete the record
/*
* This appears to be the cluster primary - cowardly refuse to
* delete the record
*/
if (primary_node_info.node_id == target_node_info_ptr->node_id)
{
@@ -461,8 +472,8 @@ do_primary_unregister(void)
else
{
PQExpBufferData event_details;
bool delete_success = delete_node_record(primary_conn,
target_node_info_ptr->node_id);
bool delete_success = delete_node_record(primary_conn,
target_node_info_ptr->node_id);
if (delete_success == false)
{
@@ -488,11 +499,11 @@ do_primary_unregister(void)
}
create_event_notification(primary_conn,
&config_file_options,
config_file_options.node_id,
"primary_unregister",
true,
event_details.data);
&config_file_options,
config_file_options.node_id,
"primary_unregister",
true,
event_details.data);
termPQExpBuffer(&event_details);
log_info(_("node %s (ID: %i) was successfully unregistered"),

File diff suppressed because it is too large Load Diff

View File

@@ -32,4 +32,4 @@ extern bool do_standby_follow_internal(PGconn *primary_conn, t_node_info *primar
#endif /* _REPMGR_ACTION_STANDBY_H_ */
#endif /* _REPMGR_ACTION_STANDBY_H_ */

View File

@@ -40,11 +40,11 @@ typedef struct
char config_file[MAXPGPATH];
bool dry_run;
bool force;
char pg_bindir[MAXLEN]; /* overrides setting in repmgr.conf */
char pg_bindir[MAXLEN]; /* overrides setting in repmgr.conf */
bool wait;
/* logging options */
char log_level[MAXLEN]; /* overrides setting in repmgr.conf */
char log_level[MAXLEN]; /* overrides setting in repmgr.conf */
bool log_to_file;
bool terse;
bool verbose;
@@ -119,7 +119,7 @@ typedef struct
/* following options for internal use */
char config_archive_dir[MAXPGPATH];
OutputMode output_mode;
} t_runtime_options;
} t_runtime_options;
#define T_RUNTIME_OPTIONS_INITIALIZER { \
/* configuration metadata */ \
@@ -160,12 +160,14 @@ typedef struct
}
typedef enum {
typedef enum
{
barman,
pg_basebackup
} standy_clone_mode;
} standy_clone_mode;
typedef enum {
typedef enum
{
ACTION_UNKNOWN = -1,
ACTION_NONE,
ACTION_START,
@@ -184,21 +186,21 @@ extern t_configuration_options config_file_options;
t_conninfo_param_list source_conninfo;
extern bool config_file_required;
extern char pg_bindir[MAXLEN];
extern bool config_file_required;
extern char pg_bindir[MAXLEN];
extern t_node_info target_node_info;
extern int check_server_version(PGconn *conn, char *server_type, bool exit_on_error, char *server_version_string);
extern int check_server_version(PGconn *conn, char *server_type, bool exit_on_error, char *server_version_string);
extern bool create_repmgr_extension(PGconn *conn);
extern int test_ssh_connection(char *host, char *remote_user);
extern int test_ssh_connection(char *host, char *remote_user);
extern bool local_command(const char *command, PQExpBufferData *outputbuf);
extern standy_clone_mode get_standby_clone_mode(void);
extern int copy_remote_files(char *host, char *remote_user, char *remote_path,
char *local_path, bool is_directory, int server_version_num);
extern int copy_remote_files(char *host, char *remote_user, char *remote_path,
char *local_path, bool is_directory, int server_version_num);
extern void print_error_list(ItemList *error_list, int log_level);
@@ -219,4 +221,4 @@ extern bool data_dir_required_for_action(t_server_action action);
extern void get_node_data_directory(char *data_dir_buf);
extern void init_node_record(t_node_info *node_record);
#endif /* _REPMGR_CLIENT_GLOBAL_H_ */
#endif /* _REPMGR_CLIENT_GLOBAL_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -141,22 +141,22 @@ static struct option long_options[] =
/* "standby switchover" options */
{"remote-config-file", required_argument, NULL, 'C'},
{"always-promote", no_argument, NULL, OPT_ALWAYS_PROMOTE },
{"force-rewind", no_argument, NULL, OPT_FORCE_REWIND },
{"siblings-follow", no_argument, NULL, OPT_SIBLINGS_FOLLOW },
{"always-promote", no_argument, NULL, OPT_ALWAYS_PROMOTE},
{"force-rewind", no_argument, NULL, OPT_FORCE_REWIND},
{"siblings-follow", no_argument, NULL, OPT_SIBLINGS_FOLLOW},
/* "node status" options */
{"is-shutdown-cleanly", no_argument, NULL, OPT_IS_SHUTDOWN_CLEANLY },
{"is-shutdown-cleanly", no_argument, NULL, OPT_IS_SHUTDOWN_CLEANLY},
/* "node check" options */
{"archive-ready", no_argument, NULL, OPT_ARCHIVE_READY },
{"downstream", no_argument, NULL, OPT_DOWNSTREAM },
{"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG },
{"role", no_argument, NULL, OPT_ROLE },
{"slots", no_argument, NULL, OPT_SLOTS },
{"archive-ready", no_argument, NULL, OPT_ARCHIVE_READY},
{"downstream", no_argument, NULL, OPT_DOWNSTREAM},
{"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG},
{"role", no_argument, NULL, OPT_ROLE},
{"slots", no_argument, NULL, OPT_SLOTS},
/* "node join" options */
{"config-files", required_argument, NULL, OPT_CONFIG_FILES },
{"config-files", required_argument, NULL, OPT_CONFIG_FILES},
/* "node service" options */
{"action", required_argument, NULL, OPT_ACTION},
@@ -165,16 +165,16 @@ static struct option long_options[] =
{"checkpoint", no_argument, NULL, OPT_CHECKPOINT},
/* "cluster event" options */
{"all", no_argument, NULL, OPT_ALL },
{"event", required_argument, NULL, OPT_EVENT },
{"limit", required_argument, NULL, OPT_LIMIT },
{"all", no_argument, NULL, OPT_ALL},
{"event", required_argument, NULL, OPT_EVENT},
{"limit", required_argument, NULL, OPT_LIMIT},
/* Following options for internal use */
{"config-archive-dir", required_argument, NULL, OPT_CONFIG_ARCHIVE_DIR},
/* deprecated */
{"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD},
/* legacy alias for -D/--pgdata*/
/* legacy alias for -D/--pgdata */
{"data-dir", required_argument, NULL, OPT_DATA_DIR},
/* --node-id */
{"node", required_argument, NULL, OPT_NODE},
@@ -204,4 +204,4 @@ static void check_cli_parameters(const int action);
static void write_primary_conninfo(char *line, t_conninfo_param_list *param_list);
static bool write_recovery_file_line(FILE *recovery_file, char *recovery_file_path, char *line);
#endif /* _REPMGR_CLIENT_H_ */
#endif /* _REPMGR_CLIENT_H_ */

View File

@@ -49,7 +49,8 @@
PG_MODULE_MAGIC;
typedef enum {
typedef enum
{
LEADER_NODE,
FOLLOWER_NODE,
CANDIDATE_NODE
@@ -59,16 +60,16 @@ typedef struct repmgrdSharedState
{
LWLockId lock; /* protects search/modification */
TimestampTz last_updated;
int local_node_id;
int local_node_id;
/* streaming failover */
NodeState node_state;
NodeVotingStatus voting_status;
int current_electoral_term;
int candidate_node_id;
bool follow_new_primary;
int current_electoral_term;
int candidate_node_id;
bool follow_new_primary;
/* BDR failover */
int bdr_failover_handler;
} repmgrdSharedState;
int bdr_failover_handler;
} repmgrdSharedState;
static repmgrdSharedState *shared_state = NULL;
@@ -81,40 +82,52 @@ void _PG_fini(void);
static void repmgr_shmem_startup(void);
Datum set_local_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_local_node_id);
Datum standby_set_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_set_last_updated);
Datum standby_get_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_get_last_updated);
Datum request_vote(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(request_vote);
Datum get_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_voting_status);
Datum set_voting_status_initiated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_voting_status_initiated);
Datum other_node_is_candidate(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(other_node_is_candidate);
Datum notify_follow_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(notify_follow_primary);
Datum get_new_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_new_primary);
Datum reset_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(reset_voting_status);
Datum am_bdr_failover_handler(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(am_bdr_failover_handler);
Datum unset_bdr_failover_handler(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(unset_bdr_failover_handler);
@@ -209,7 +222,7 @@ repmgr_shmem_startup(void)
Datum
set_local_node_id(PG_FUNCTION_ARGS)
{
int local_node_id = PG_GETARG_INT32(0);
int local_node_id = PG_GETARG_INT32(0);
if (!shared_state)
PG_RETURN_NULL();
@@ -266,15 +279,15 @@ Datum
request_vote(PG_FUNCTION_ARGS)
{
#ifndef BDR_ONLY
StringInfoData query;
XLogRecPtr our_lsn = InvalidXLogRecPtr;
StringInfoData query;
XLogRecPtr our_lsn = InvalidXLogRecPtr;
/* node_id used for logging purposes */
int requesting_node_id = PG_GETARG_INT32(0);
int current_electoral_term = PG_GETARG_INT32(1);
int requesting_node_id = PG_GETARG_INT32(0);
int current_electoral_term = PG_GETARG_INT32(1);
int ret;
bool isnull;
int ret;
bool isnull;
if (!shared_state)
PG_RETURN_NULL();
@@ -299,11 +312,11 @@ request_vote(PG_FUNCTION_ARGS)
initStringInfo(&query);
appendStringInfo(
&query,
&query,
#if (PG_VERSION_NUM >= 100000)
"SELECT pg_catalog.pg_last_wal_receive_lsn()");
"SELECT pg_catalog.pg_last_wal_receive_lsn()");
#else
"SELECT pg_catalog.pg_last_xlog_receive_location()");
"SELECT pg_catalog.pg_last_xlog_receive_location()");
#endif
elog(DEBUG1, "query: %s", query.data);
@@ -331,7 +344,7 @@ request_vote(PG_FUNCTION_ARGS)
LWLockRelease(shared_state->lock);
// should we free "query" here?
/* should we free "query" here? */
SPI_finish();
PG_RETURN_LSN(our_lsn);
@@ -365,7 +378,7 @@ Datum
set_voting_status_initiated(PG_FUNCTION_ARGS)
{
#ifndef BDR_ONLY
int electoral_term;
int electoral_term;
LWLockAcquire(shared_state->lock, LW_SHARED);
shared_state->voting_status = VS_VOTE_INITIATED;
@@ -386,8 +399,8 @@ Datum
other_node_is_candidate(PG_FUNCTION_ARGS)
{
#ifndef BDR_ONLY
int requesting_node_id = PG_GETARG_INT32(0);
int electoral_term = PG_GETARG_INT32(1);
int requesting_node_id = PG_GETARG_INT32(0);
int electoral_term = PG_GETARG_INT32(1);
if (!shared_state)
PG_RETURN_NULL();
@@ -419,7 +432,7 @@ Datum
notify_follow_primary(PG_FUNCTION_ARGS)
{
#ifndef BDR_ONLY
int primary_node_id = PG_GETARG_INT32(0);
int primary_node_id = PG_GETARG_INT32(0);
if (!shared_state)
PG_RETURN_NULL();
@@ -442,7 +455,7 @@ notify_follow_primary(PG_FUNCTION_ARGS)
Datum
get_new_primary(PG_FUNCTION_ARGS)
{
int new_primary_node_id = UNKNOWN_NODE_ID;
int new_primary_node_id = UNKNOWN_NODE_ID;
if (!shared_state)
PG_RETURN_NULL();
@@ -481,8 +494,8 @@ reset_voting_status(PG_FUNCTION_ARGS)
Datum
am_bdr_failover_handler(PG_FUNCTION_ARGS)
{
int node_id = PG_GETARG_INT32(0);
bool am_handler = false;
int node_id = PG_GETARG_INT32(0);
bool am_handler = false;
if (!shared_state)
PG_RETURN_NULL();

View File

@@ -60,17 +60,17 @@
*/
#define DEFAULT_LOCATION "default"
#define DEFAULT_PRIORITY 100
#define DEFAULT_RECONNECTION_ATTEMPTS 6 /* seconds */
#define DEFAULT_RECONNECTION_INTERVAL 10 /* seconds */
#define DEFAULT_MONITORING_INTERVAL 2 /* seconds */
#define DEFAULT_ASYNC_QUERY_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_FOLLOW_TIMEOUT 60 /* seconds */
#define DEFAULT_BDR_RECOVERY_TIMEOUT 30 /* seconds */
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
#define DEFAULT_ARCHIVE_READY_CRITICAL 128 /* WAL files */
#define DEFAULT_REPLICATION_LAG_WARNING 300 /* seconds */
#define DEFAULT_REPLICATION_LAG_CRITICAL 600 /* seconds */
#define DEFAULT_RECONNECTION_ATTEMPTS 6 /* seconds */
#define DEFAULT_RECONNECTION_INTERVAL 10 /* seconds */
#define DEFAULT_MONITORING_INTERVAL 2 /* seconds */
#define DEFAULT_ASYNC_QUERY_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_FOLLOW_TIMEOUT 60 /* seconds */
#define DEFAULT_BDR_RECOVERY_TIMEOUT 30 /* seconds */
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
#define DEFAULT_ARCHIVE_READY_CRITICAL 128 /* WAL files */
#define DEFAULT_REPLICATION_LAG_WARNING 300 /* seconds */
#define DEFAULT_REPLICATION_LAG_CRITICAL 600 /* seconds */
#ifndef RECOVERY_COMMAND_FILE
@@ -83,4 +83,4 @@
#endif /* _REPMGR_H_ */
#endif /* _REPMGR_H_ */

View File

@@ -39,9 +39,9 @@ do_bdr_node_check(void)
void
monitor_bdr(void)
{
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
t_bdr_node_info bdr_node_info = T_BDR_NODE_INFO_INITIALIZER;
RecordStatus record_status;
RecordStatus record_status;
NodeInfoListCell *cell;
PQExpBufferData event_details;
instr_time log_status_interval_start;
@@ -65,8 +65,7 @@ monitor_bdr(void)
}
/*
* Verify that database is a BDR one
* TODO: check if supported BDR version?
* Verify that database is a BDR one TODO: check if supported BDR version?
*/
log_info(_("connected to database, checking for BDR"));
@@ -81,7 +80,10 @@ monitor_bdr(void)
log_error(_("repmgr metadata table 'repmgr.%s' is not in the 'repmgr' replication set"),
"nodes");
/* TODO: add `repmgr bdr sync` or similar for this situation, and hint here */
/*
* TODO: add `repmgr bdr sync` or similar for this situation, and hint
* here
*/
exit(ERR_BAD_CONFIG);
}
@@ -100,8 +102,8 @@ monitor_bdr(void)
record_status = get_node_record(local_conn, config_file_options.node_id, &local_node_info);
/*
* Terminate if we can't find the local node record. This is a "fix-the-config"
* situation, not a lot else we can do.
* Terminate if we can't find the local node record. This is a
* "fix-the-config" situation, not a lot else we can do.
*/
if (record_status != RECORD_FOUND)
{
@@ -139,7 +141,8 @@ monitor_bdr(void)
NULL);
/*
* retrieve list of all nodes - we'll need these if the DB connection goes away
* retrieve list of all nodes - we'll need these if the DB connection goes
* away
*/
get_all_node_records(local_conn, &nodes);
@@ -184,80 +187,81 @@ monitor_bdr(void)
switch (cell->node_info->monitoring_state)
{
case MS_NORMAL:
{
if (is_server_available(cell->node_info->conninfo) == false)
{
/* node is down, we were expecting it to be up */
if (cell->node_info->node_status == NODE_STATUS_UP)
if (is_server_available(cell->node_info->conninfo) == false)
{
instr_time node_unreachable_start;
INSTR_TIME_SET_CURRENT(node_unreachable_start);
cell->node_info->node_status = NODE_STATUS_DOWN;
if (cell->node_info->conn != NULL)
{
PQfinish(cell->node_info->conn);
cell->node_info->conn = NULL;
}
log_warning(_("unable to connect to node %s (ID %i)"),
cell->node_info->node_name, cell->node_info->node_id);
cell->node_info->conn = try_reconnect(cell->node_info);
/* node has recovered - log and continue */
/* node is down, we were expecting it to be up */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
int node_unreachable_elapsed = calculate_elapsed(node_unreachable_start);
instr_time node_unreachable_start;
initPQExpBuffer(&event_details);
INSTR_TIME_SET_CURRENT(node_unreachable_start);
appendPQExpBuffer(&event_details,
_("reconnected to node %i after %i seconds"),
cell->node_info->node_id,
node_unreachable_elapsed);
log_notice("%s", event_details.data);
cell->node_info->node_status = NODE_STATUS_DOWN;
create_event_notification(cell->node_info->conn,
&config_file_options,
config_file_options.node_id,
"bdr_reconnect",
true,
event_details.data);
termPQExpBuffer(&event_details);
if (cell->node_info->conn != NULL)
{
PQfinish(cell->node_info->conn);
cell->node_info->conn = NULL;
}
goto loop;
}
log_warning(_("unable to connect to node %s (ID %i)"),
cell->node_info->node_name, cell->node_info->node_id);
cell->node_info->conn = try_reconnect(cell->node_info);
/* still down after reconnect attempt(s) */
if (cell->node_info->node_status == NODE_STATUS_DOWN)
{
do_bdr_failover(&nodes, cell->node_info);
goto loop;
/* node has recovered - log and continue */
if (cell->node_info->node_status == NODE_STATUS_UP)
{
int node_unreachable_elapsed = calculate_elapsed(node_unreachable_start);
initPQExpBuffer(&event_details);
appendPQExpBuffer(&event_details,
_("reconnected to node %i after %i seconds"),
cell->node_info->node_id,
node_unreachable_elapsed);
log_notice("%s", event_details.data);
create_event_notification(cell->node_info->conn,
&config_file_options,
config_file_options.node_id,
"bdr_reconnect",
true,
event_details.data);
termPQExpBuffer(&event_details);
goto loop;
}
/* still down after reconnect attempt(s) */
if (cell->node_info->node_status == NODE_STATUS_DOWN)
{
do_bdr_failover(&nodes, cell->node_info);
goto loop;
}
}
}
}
}
break;
break;
case MS_DEGRADED:
{
/* degraded monitoring */
if (is_server_available(cell->node_info->conninfo) == true)
{
do_bdr_recovery(&nodes, cell->node_info);
}
/* degraded monitoring */
if (is_server_available(cell->node_info->conninfo) == true)
{
do_bdr_recovery(&nodes, cell->node_info);
}
}
break;
}
break;
}
}
loop:
loop:
/* emit "still alive" log message at regular intervals, if requested */
if (config_file_options.log_status_interval > 0)
{
int log_status_interval_elapsed = calculate_elapsed(log_status_interval_start);
int log_status_interval_elapsed = calculate_elapsed(log_status_interval_start);
if (log_status_interval_elapsed >= config_file_options.log_status_interval)
{
@@ -270,9 +274,9 @@ monitor_bdr(void)
if (cell->node_info->monitoring_state == MS_DEGRADED)
{
log_detail(
_("monitoring node \"%s\" (ID: %i) in degraded mode"),
cell->node_info->node_name,
cell->node_info->node_id);
_("monitoring node \"%s\" (ID: %i) in degraded mode"),
cell->node_info->node_name,
cell->node_info->node_id);
}
}
INSTR_TIME_SET_CURRENT(log_status_interval_start);
@@ -282,8 +286,7 @@ monitor_bdr(void)
if (got_SIGHUP)
{
/*
* if we can reload, then could need to change
* local_conn
* if we can reload, then could need to change local_conn
*/
if (reload_config(&config_file_options))
{
@@ -350,8 +353,8 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
NodeInfoListCell *cell;
PQExpBufferData event_details;
t_event_info event_info = T_EVENT_INFO_INITIALIZER;
t_node_info target_node = T_NODE_INFO_INITIALIZER;
t_node_info failed_node = T_NODE_INFO_INITIALIZER;
t_node_info target_node = T_NODE_INFO_INITIALIZER;
t_node_info failed_node = T_NODE_INFO_INITIALIZER;
RecordStatus record_status;
/* if one of the two nodes is down, cluster will be in a degraded state */
@@ -372,7 +375,10 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
{
log_debug("do_bdr_failover() %s", cell->node_info->node_name);
/* don't attempt to connect to the current monitored node, as that's the one which has failed */
/*
* don't attempt to connect to the current monitored node, as that's
* the one which has failed
*/
if (cell->node_info->node_id == monitored_node->node_id)
continue;
@@ -459,21 +465,21 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
/*
* Create an event record
*
* If we were able to connect to another node, we'll update the
* event log there.
* If we were able to connect to another node, we'll update the event log
* there.
*
* In any case the event notification command will be triggered
* with the event "bdr_failover"
* In any case the event notification command will be triggered with the
* event "bdr_failover"
*/
create_event_notification_extended(
next_node_conn,
&config_file_options,
monitored_node->node_id,
"bdr_failover",
true,
event_details.data,
&event_info);
next_node_conn,
&config_file_options,
monitored_node->node_id,
"bdr_failover",
true,
event_details.data,
&event_info);
log_info("%s", event_details.data);
@@ -490,15 +496,15 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
static void
do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
{
PGconn *recovered_node_conn;
PGconn *recovered_node_conn;
PQExpBufferData event_details;
t_event_info event_info = T_EVENT_INFO_INITIALIZER;
int i;
bool slot_reactivated = false;
int node_recovery_elapsed;
int i;
bool slot_reactivated = false;
int node_recovery_elapsed;
char node_name[MAXLEN] = "";
char node_name[MAXLEN] = "";
log_debug("handling recovery for monitored node %i", monitored_node->node_id);
@@ -519,7 +525,7 @@ do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
/*
* still unable to connect - the local node is probably down, so we can't
* check for reconnection
*/
*/
if (PQstatus(local_conn) != CONNECTION_OK)
{
local_conn = NULL;
@@ -532,11 +538,11 @@ do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
monitored_node->node_status = NODE_STATUS_UP;
appendPQExpBuffer(
&event_details,
_("node \"%s\" (ID: %i) has become available after %i seconds"),
monitored_node->node_name,
monitored_node->node_id,
node_recovery_elapsed);
&event_details,
_("node \"%s\" (ID: %i) has become available after %i seconds"),
monitored_node->node_name,
monitored_node->node_id,
node_recovery_elapsed);
log_notice("%s", event_details.data);
@@ -560,8 +566,8 @@ do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
log_debug("checking for state of replication slot for node \"%s\"", node_name);
slot_status = get_bdr_node_replication_slot_status(
local_conn,
node_name);
local_conn,
node_name);
if (slot_status == SLOT_ACTIVE)
{
@@ -621,13 +627,13 @@ do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
event_info.node_name = monitored_node->node_name;
create_event_notification_extended(
local_conn,
&config_file_options,
config_file_options.node_id,
"bdr_recovery",
true,
event_details.data,
&event_info);
local_conn,
&config_file_options,
config_file_options.node_id,
"bdr_recovery",
true,
event_details.data,
&event_info);
}

View File

@@ -22,4 +22,4 @@
extern void do_bdr_node_check(void);
extern void monitor_bdr(void);
#endif /* _REPMGRD_BDR_H_ */
#endif /* _REPMGRD_BDR_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -19,10 +19,10 @@
#ifndef _REPMGRD_PHYSICAL_H_
#define _REPMGRD_PHYSICAL_H_
void do_physical_node_check(void);
void do_physical_node_check(void);
void monitor_streaming_primary(void);
void monitor_streaming_standby(void);
void close_connections_physical(void);
void monitor_streaming_primary(void);
void monitor_streaming_standby(void);
void close_connections_physical(void);
#endif /* _REPMGRD_PHYSICAL_H_ */
#endif /* _REPMGRD_PHYSICAL_H_ */

124
repmgrd.c
View File

@@ -33,10 +33,10 @@
#define OPT_HELP 1
static char *config_file = NULL;
static bool verbose = false;
static char *pid_file = NULL;
static bool daemonize = false;
static char *config_file = NULL;
static bool verbose = false;
static char *pid_file = NULL;
static bool daemonize = false;
t_configuration_options config_file_options = T_CONFIGURATION_OPTIONS_INITIALIZER;
@@ -46,15 +46,15 @@ PGconn *local_conn = NULL;
/* Collate command line errors here for friendlier reporting */
static ItemList cli_errors = { NULL, NULL };
static ItemList cli_errors = {NULL, NULL};
bool startup_event_logged = false;
bool startup_event_logged = false;
MonitoringState monitoring_state = MS_NORMAL;
instr_time degraded_monitoring_start;
static void close_connections(void);
void (*_close_connections)(void) = NULL;
void (*_close_connections) (void) = NULL;
/*
* Record receipt of SIGHUP; will cause configuration file to be reread
@@ -76,9 +76,9 @@ static void handle_sighup(SIGNAL_ARGS);
static void handle_sigint(SIGNAL_ARGS);
#endif
int calculate_elapsed(instr_time start_time);
void update_registration(PGconn *conn);
void terminate(int retval);
int calculate_elapsed(instr_time start_time);
void update_registration(PGconn *conn);
void terminate(int retval);
int
main(int argc, char **argv)
@@ -116,7 +116,7 @@ main(int argc, char **argv)
set_progname(argv[0]);
srand ( time(NULL) );
srand(time(NULL));
/* Disallow running as root */
if (geteuid() == 0)
@@ -126,7 +126,7 @@ main(int argc, char **argv)
"Please log in (using, e.g., \"su\") as the "
"(unprivileged) user that owns "
"the data directory.\n"
),
),
progname());
exit(1);
}
@@ -136,7 +136,7 @@ main(int argc, char **argv)
switch (c)
{
/* general options */
/* general options */
case '?':
/* Actual help option given */
@@ -154,20 +154,22 @@ main(int argc, char **argv)
exit(SUCCESS);
case 'V':
/*
* in contrast to repmgr3 and earlier, we only display the repmgr version
* as it's not specific to a particular PostgreSQL version
* in contrast to repmgr3 and earlier, we only display the
* repmgr version as it's not specific to a particular
* PostgreSQL version
*/
printf("%s %s\n", progname(), REPMGR_VERSION);
exit(SUCCESS);
/* configuration options */
/* configuration options */
case 'f':
config_file = optarg;
break;
/* daemon options */
/* daemon options */
case 'd':
daemonize = true;
@@ -177,40 +179,42 @@ main(int argc, char **argv)
pid_file = optarg;
break;
/* logging options */
/* logging options */
/* -L/--log-level */
/* -L/--log-level */
case 'L':
{
int detected_cli_log_level = detect_log_level(optarg);
if (detected_cli_log_level != -1)
{
strncpy(cli_log_level, optarg, MAXLEN);
int detected_cli_log_level = detect_log_level(optarg);
if (detected_cli_log_level != -1)
{
strncpy(cli_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;
}
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;
/* legacy options */
/* legacy options */
case 'm':
cli_monitoring_history = true;
break;
default:
unknown_option:
unknown_option:
show_usage();
exit(ERR_BAD_CONFIG);
}
@@ -223,6 +227,7 @@ main(int argc, char **argv)
}
startup_event_logged = false;
/*
* Tell the logger we're a daemon - this will ensure any output logged
* before the logger is initialized will be formatted correctly
@@ -230,15 +235,19 @@ main(int argc, char **argv)
logger_output_mode = OM_DAEMON;
/*
* Parse the configuration file, if provided. If no configuration file
* was provided, or one was but was incomplete, parse_config() will
* abort anyway, with an appropriate message.
* Parse the configuration file, if provided. If no configuration file was
* provided, or one was but was incomplete, parse_config() will abort
* anyway, with an appropriate message.
*/
load_config(config_file, verbose, false, &config_file_options, argv[0]);
/* Some configuration file items can be overriden by command line options */
/* Command-line parameter -L/--log-level overrides any setting in config file*/
/*
* Command-line parameter -L/--log-level overrides any setting in config
* file
*/
if (*cli_log_level != '\0')
{
strncpy(config_file_options.log_level, cli_log_level, MAXLEN);
@@ -304,8 +313,8 @@ main(int argc, char **argv)
* point, but we'll skip that and assume the presence of a node record
* means we're dealing with a supported installation.
*
* The absence of a node record will also indicate that either the node
* or repmgr has not been properly configured.
* The absence of a node record will also indicate that either the node or
* repmgr has not been properly configured.
*/
/* Retrieve record for this node from the local database */
@@ -368,7 +377,7 @@ start_monitoring(void)
local_node_info.node_name,
local_node_info.node_id);
while(true)
while (true)
{
switch (local_node_info.type)
{
@@ -398,13 +407,15 @@ start_monitoring(void)
void
update_registration(PGconn *conn)
{
bool success = update_node_record_conn_priority(local_conn,
&config_file_options);
// check values have actually changed
bool success = update_node_record_conn_priority(local_conn,
&config_file_options);
/* check values have actually changed */
if (success == false)
{
PQExpBufferData errmsg;
initPQExpBuffer(&errmsg);
appendPQExpBuffer(&errmsg,
@@ -620,11 +631,11 @@ show_help(void)
PGconn *
try_reconnect(t_node_info *node_info)
{
PGconn *conn;
PGconn *conn;
int i;
int i;
int max_attempts = config_file_options.reconnect_attempts;
int max_attempts = config_file_options.reconnect_attempts;
for (i = 0; i < max_attempts; i++)
{
@@ -635,10 +646,9 @@ try_reconnect(t_node_info *node_info)
log_notice(_("node has recovered, reconnecting"));
/*
* XXX we should also handle the case where node is pingable
* but connection denied due to connection exhaustion
* - fall back to degraded monitoring?
* - make that configurable
* XXX we should also handle the case where node is pingable but
* connection denied due to connection exhaustion - fall back to
* degraded monitoring? - make that configurable
*/
conn = establish_db_connection(node_info->conninfo, false);
if (PQstatus(conn) == CONNECTION_OK)
@@ -680,14 +690,14 @@ calculate_elapsed(instr_time start_time)
INSTR_TIME_SUBTRACT(current_time, start_time);
return (int)INSTR_TIME_GET_DOUBLE(current_time);
return (int) INSTR_TIME_GET_DOUBLE(current_time);
}
const char *
print_monitoring_state(MonitoringState monitoring_state)
{
switch(monitoring_state)
switch (monitoring_state)
{
case MS_NORMAL:
return "normal";
@@ -730,5 +740,3 @@ terminate(int retval)
exit(retval);
}

View File

@@ -12,18 +12,18 @@
extern volatile sig_atomic_t got_SIGHUP;
extern MonitoringState monitoring_state;
extern instr_time degraded_monitoring_start;
extern instr_time degraded_monitoring_start;
extern t_configuration_options config_file_options;
extern t_node_info local_node_info;
extern PGconn *local_conn;
extern bool startup_event_logged;
extern PGconn *local_conn;
extern bool startup_event_logged;
PGconn *try_reconnect(t_node_info *node_info);
PGconn *try_reconnect(t_node_info *node_info);
int calculate_elapsed(instr_time start_time);
int calculate_elapsed(instr_time start_time);
const char *print_monitoring_state(MonitoringState monitoring_state);
void update_registration(PGconn *conn);
void terminate(int retval);
#endif /* _REPMGRD_H_ */
void update_registration(PGconn *conn);
void terminate(int retval);
#endif /* _REPMGRD_H_ */

View File

@@ -76,7 +76,7 @@ maxpath_snprintf(char *str, const char *format,...)
void
append_where_clause(PQExpBufferData *where_clause, const char *format, ...)
append_where_clause(PQExpBufferData *where_clause, const char *format,...)
{
va_list arglist;
char stringbuf[MAXLEN];
@@ -85,7 +85,7 @@ append_where_clause(PQExpBufferData *where_clause, const char *format, ...)
(void) xvsnprintf(stringbuf, MAXLEN, format, arglist);
va_end(arglist);
if(where_clause->data[0] == '\0')
if (where_clause->data[0] == '\0')
{
appendPQExpBuffer(where_clause,
" WHERE ");
@@ -110,10 +110,10 @@ item_list_append(ItemList *item_list, const char *message)
void
item_list_append_format(ItemList *item_list, const char *format, ...)
item_list_append_format(ItemList *item_list, const char *format,...)
{
ItemListCell *cell;
va_list arglist;
va_list arglist;
cell = (ItemListCell *) pg_malloc0(sizeof(ItemListCell));
@@ -166,11 +166,11 @@ key_value_list_set(KeyValueList *item_list, const char *key, const char *value)
}
void
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value, ...)
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value,...)
{
KeyValueListCell *cell = NULL;
va_list arglist;
int keylen = 0;
va_list arglist;
int keylen = 0;
cell = (KeyValueListCell *) pg_malloc0(sizeof(KeyValueListCell));
@@ -205,7 +205,7 @@ key_value_list_set_format(KeyValueList *item_list, const char *key, const char *
void
key_value_list_set_output_mode (KeyValueList *item_list, const char *key, OutputMode mode)
key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode)
{
KeyValueListCell *cell = NULL;
@@ -250,11 +250,11 @@ check_status_list_set(CheckStatusList *list, const char *item, CheckStatus statu
void
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details, ...)
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details,...)
{
CheckStatusListCell *cell;
va_list arglist;
int itemlen;
va_list arglist;
int itemlen;
cell = (CheckStatusListCell *) pg_malloc0(sizeof(CheckStatusListCell));
@@ -352,7 +352,7 @@ escape_recovery_conf_value(const char *src)
char *
escape_string(PGconn *conn, const char *string)
{
char *escaped_string;
char *escaped_string;
int error;
escaped_string = pg_malloc0(MAXLEN);
@@ -372,7 +372,7 @@ escape_string(PGconn *conn, const char *string)
char *
string_skip_prefix(const char *prefix, char *string)
{
int n;
int n;
n = strlen(prefix);
@@ -386,7 +386,7 @@ string_skip_prefix(const char *prefix, char *string)
char *
string_remove_trailing_newlines(char *string)
{
int n;
int n;
n = strlen(string) - 1;
@@ -436,7 +436,7 @@ parse_follow_command(char *parsed_command, char *template, int node_id)
end_ptr = parsed_command + MAXPGPATH - 1;
*end_ptr = '\0';
for(src_ptr = template; *src_ptr; src_ptr++)
for (src_ptr = template; *src_ptr; src_ptr++)
{
if (*src_ptr == '%')
{

View File

@@ -33,14 +33,16 @@
#define MAXLEN_STR STR(MAXLEN)
typedef enum {
typedef enum
{
CHECK_STATUS_OK = 0,
CHECK_STATUS_WARNING,
CHECK_STATUS_CRITICAL,
CHECK_STATUS_UNKNOWN
} CheckStatus;
typedef enum {
typedef enum
{
OM_NOT_SET = -1,
OM_TEXT,
OM_CSV,
@@ -51,7 +53,7 @@ typedef enum {
typedef struct ItemListCell
{
struct ItemListCell *next;
char *string;
char *string;
} ItemListCell;
typedef struct ItemList
@@ -63,9 +65,9 @@ typedef struct ItemList
typedef struct KeyValueListCell
{
struct KeyValueListCell *next;
char *key;
char *value;
OutputMode output_mode;
char *key;
char *value;
OutputMode output_mode;
} KeyValueListCell;
typedef struct KeyValueList
@@ -78,9 +80,9 @@ typedef struct KeyValueList
typedef struct CheckStatusListCell
{
struct CheckStatusListCell *next;
char *item;
CheckStatus status;
char *details;
char *item;
CheckStatus status;
char *details;
} CheckStatusListCell;
typedef struct CheckStatusList
@@ -100,62 +102,58 @@ maxpath_snprintf(char *str, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern void
item_list_append(ItemList *item_list, const char *message);
item_list_append(ItemList *item_list, const char *message);
extern void
item_list_append_format(ItemList *item_list, const char *format, ...)
item_list_append_format(ItemList *item_list, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern void
item_list_free(ItemList *item_list);
item_list_free(ItemList *item_list);
extern void
key_value_list_set(KeyValueList *item_list, const char *key, const char *value);
key_value_list_set(KeyValueList *item_list, const char *key, const char *value);
extern void
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value, ...)
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern void
key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode);
key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode);
extern const char *
key_value_list_get(KeyValueList *item_list, const char *key);
extern const char *key_value_list_get(KeyValueList *item_list, const char *key);
extern void
key_value_list_free(KeyValueList *item_list);
key_value_list_free(KeyValueList *item_list);
extern void
check_status_list_set(CheckStatusList *list, const char *item, CheckStatus status, const char *details);
check_status_list_set(CheckStatusList *list, const char *item, CheckStatus status, const char *details);
extern void
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details, ...)
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
extern void
check_status_list_free(CheckStatusList *list);
check_status_list_free(CheckStatusList *list);
extern const char * output_check_status(CheckStatus status);
extern const char *output_check_status(CheckStatus status);
extern char *
escape_recovery_conf_value(const char *src);
extern char *escape_recovery_conf_value(const char *src);
extern char *
escape_string(PGconn *conn, const char *string);
extern char *escape_string(PGconn *conn, const char *string);
extern void
append_where_clause(PQExpBufferData *where_clause, const char *clause, ...)
append_where_clause(PQExpBufferData *where_clause, const char *clause,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern char *
string_skip_prefix(const char *prefix, char *string);
extern char *string_skip_prefix(const char *prefix, char *string);
extern char
*string_remove_trailing_newlines(char *string);
*string_remove_trailing_newlines(char *string);
extern char *trim(char *s);
extern char *trim(char *s);
extern void
parse_follow_command(char *parsed_command, char *template, int node_id);
parse_follow_command(char *parsed_command, char *template, int node_id);
#endif /* _STRUTIL_H_ */
#endif /* _STRUTIL_H_ */

View File

@@ -18,11 +18,12 @@
#ifndef _VOTING_H_
#define _VOTING_H_
typedef enum {
typedef enum
{
VS_UNKNOWN = -1,
VS_NO_VOTE,
VS_VOTE_REQUEST_RECEIVED,
VS_VOTE_INITIATED
} NodeVotingStatus;
#endif /* _VOTING_H_ */
#endif /* _VOTING_H_ */