mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
"node check": initial general output
This commit is contained in:
@@ -29,6 +29,7 @@ static void _do_node_status_is_shutdown(void);
|
||||
static void _do_node_archive_config(void);
|
||||
static void _do_node_restore_config(void);
|
||||
|
||||
|
||||
void
|
||||
do_node_status(void)
|
||||
{
|
||||
@@ -282,14 +283,6 @@ do_node_status(void)
|
||||
"disabled");
|
||||
}
|
||||
|
||||
// if standby (and in recovery), show:
|
||||
// upstream
|
||||
// -> check if matches expected; parse recovery.conf for < 9.6 (must be superuser),
|
||||
// otherwise use pg_stat_wal_receiver
|
||||
// streaming/in archive recovery/disconnected
|
||||
// last received
|
||||
// last replayed
|
||||
// lag if streaming, or if in recovery can compare with upstream
|
||||
|
||||
if (node_info.type == STANDBY)
|
||||
{
|
||||
@@ -511,17 +504,33 @@ void _do_node_status_is_shutdown(void)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configuration file required
|
||||
*/
|
||||
void
|
||||
do_node_check(void)
|
||||
{
|
||||
PGconn *conn = NULL;
|
||||
PQExpBufferData output;
|
||||
|
||||
t_node_info node_info = T_NODE_INFO_INITIALIZER;
|
||||
|
||||
CheckStatusList status_list = { NULL, NULL };
|
||||
CheckStatusListCell *cell = NULL;
|
||||
|
||||
|
||||
if (strlen(config_file_options.conninfo))
|
||||
conn = establish_db_connection(config_file_options.conninfo, true);
|
||||
else
|
||||
conn = establish_db_connection_by_params(&source_conninfo, true);
|
||||
|
||||
if (get_node_record(conn, config_file_options.node_id, &node_info) != RECORD_FOUND)
|
||||
{
|
||||
log_error(_("no record found for node %i"), config_file_options.node_id);
|
||||
PQfinish(conn);
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* handle specific checks
|
||||
* ====================== */
|
||||
if (runtime_options.archiver == true)
|
||||
@@ -538,17 +547,59 @@ do_node_check(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* output general overview */
|
||||
|
||||
initPQExpBuffer(&output);
|
||||
|
||||
//(void) do_node_check_role(conn, runtime_options.output_mode, &output);
|
||||
(void) do_node_check_replication_lag(conn, runtime_options.output_mode, &status_list);
|
||||
(void) do_node_check_archiver(conn, runtime_options.output_mode, &status_list);
|
||||
|
||||
|
||||
if (runtime_options.output_mode == OM_CSV)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
else
|
||||
{
|
||||
appendPQExpBuffer(
|
||||
&output,
|
||||
"Node \"%s\":\n",
|
||||
node_info.node_name);
|
||||
|
||||
for (cell = status_list.head; cell; cell = cell->next)
|
||||
{
|
||||
appendPQExpBuffer(
|
||||
&output,
|
||||
"\t%s: %s",
|
||||
cell->item,
|
||||
output_check_status(cell->status));
|
||||
|
||||
if (strlen(cell->details))
|
||||
{
|
||||
appendPQExpBuffer(
|
||||
&output,
|
||||
" (%s)",
|
||||
cell->details);
|
||||
}
|
||||
appendPQExpBuffer(&output, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("%s", output.data);
|
||||
termPQExpBuffer(&output);
|
||||
check_status_list_free(&status_list);
|
||||
|
||||
PQfinish(conn);
|
||||
}
|
||||
|
||||
CheckStatus
|
||||
do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output)
|
||||
{
|
||||
bool own_buffer = false;
|
||||
int ready_archive_files = 0;
|
||||
PQExpBufferData buf;
|
||||
CheckStatus status = CHECK_STATUS_UNKNOWN;
|
||||
PQExpBufferData details;
|
||||
|
||||
if (mode == OM_CSV)
|
||||
{
|
||||
@@ -556,13 +607,7 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
if (output == NULL)
|
||||
{
|
||||
initPQExpBuffer(&buf);
|
||||
output = &buf;
|
||||
own_buffer = true;
|
||||
}
|
||||
|
||||
initPQExpBuffer(&details);
|
||||
|
||||
ready_archive_files = get_ready_archive_files(conn, config_file_options.data_directory);
|
||||
|
||||
@@ -574,24 +619,21 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=CRITICAL --files=%i --threshold=%i",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_critical);
|
||||
&details,
|
||||
"--files=%i --threshold=%i",
|
||||
ready_archive_files, config_file_options.archiver_lag_critical);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_ARCHIVER CRITICAL: %i pending files (critical: %i)",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_critical);
|
||||
&details,
|
||||
"%i pending files (critical: %i)",
|
||||
ready_archive_files, config_file_options.archiver_lag_critical);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"CRITICAL - %i pending files (threshold: %i)",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_critical);
|
||||
&details,
|
||||
"%i pending files, threshold: %i",
|
||||
ready_archive_files, config_file_options.archiver_lag_critical);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -606,24 +648,21 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=WARNING --files=%i --threshold=%i",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_warning);
|
||||
&details,
|
||||
"--files=%i --threshold=%i",
|
||||
ready_archive_files, config_file_options.archiver_lag_warning);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_ARCHIVER WARNING: %i pending files (warning: %i)",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_warning);
|
||||
&details,
|
||||
"%i pending files (warning: %i)",
|
||||
ready_archive_files, config_file_options.archiver_lag_warning);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"WARNING - %i pending files (threshold: %i)",
|
||||
ready_archive_files,
|
||||
config_file_options.archiver_lag_warning);
|
||||
&details,
|
||||
"%i pending files (threshold: %i)",
|
||||
ready_archive_files, config_file_options.archiver_lag_warning);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -637,19 +676,12 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
switch (mode)
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=UNKNOWN");
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_ARCHIVER UNKNOWN: unable to check archive_status directory");
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"UNKNOWN - unable to check archive_status directory");
|
||||
&details,
|
||||
"unable to check archive_status directory");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -664,21 +696,14 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=OK --files=%i",
|
||||
ready_archive_files);
|
||||
&details,
|
||||
"--files=%i", ready_archive_files);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_ARCHIVER OK: %i pending files",
|
||||
ready_archive_files);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"OK - %i pending files",
|
||||
ready_archive_files);
|
||||
&details,
|
||||
"%i pending files", ready_archive_files);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -686,23 +711,49 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
}
|
||||
}
|
||||
|
||||
if (own_buffer == true)
|
||||
switch (mode)
|
||||
{
|
||||
printf("%s\n", buf.data);
|
||||
termPQExpBuffer(&buf);
|
||||
case OM_OPTFORMAT:
|
||||
{
|
||||
printf("--status=%s %s\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
}
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
printf("PG_ARCHIVER %s: %s\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
if (list_output != NULL)
|
||||
{
|
||||
check_status_list_set(list_output,
|
||||
"WAL archiving",
|
||||
status,
|
||||
details.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s (%s)\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
termPQExpBuffer(&details);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
CheckStatus
|
||||
do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *output)
|
||||
do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output)
|
||||
{
|
||||
CheckStatus status = CHECK_STATUS_UNKNOWN;
|
||||
bool own_buffer = false;
|
||||
PQExpBufferData buf;
|
||||
int lag_seconds = 0;
|
||||
PQExpBufferData details;
|
||||
|
||||
if (mode == OM_CSV)
|
||||
{
|
||||
@@ -710,12 +761,7 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
if (output == NULL)
|
||||
{
|
||||
initPQExpBuffer(&buf);
|
||||
output = &buf;
|
||||
own_buffer = true;
|
||||
}
|
||||
initPQExpBuffer(&details);
|
||||
|
||||
lag_seconds = get_replication_lag_seconds(conn);
|
||||
|
||||
@@ -729,24 +775,21 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=CRITICAL --lag=%i --threshold=%i",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_critical);
|
||||
&details,
|
||||
"--lag=%i --threshold=%i",
|
||||
lag_seconds, config_file_options.replication_lag_critical);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_REPLICATION_LAG CRITICAL: %i seconds (critical: %i)",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_critical);
|
||||
&details,
|
||||
"%i seconds (critical: %i)",
|
||||
lag_seconds, config_file_options.replication_lag_critical);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"CRITICAL - %i seconds (threshold: %i)",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_critical);
|
||||
&details,
|
||||
"%i seconds, threshold: %i)",
|
||||
lag_seconds, config_file_options.replication_lag_critical);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -761,24 +804,21 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=WARNING --lag=%i --threshold=%i",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_warning);
|
||||
&details,
|
||||
"--lag=%i --threshold=%i",
|
||||
lag_seconds, config_file_options.replication_lag_warning);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_REPLICATION_LAG WARNING: %i seconds (warning: %i)",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_warning);
|
||||
&details,
|
||||
"%i seconds (warning: %i)",
|
||||
lag_seconds, config_file_options.replication_lag_warning);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"WARNING - %i seconds (threshold: %i)",
|
||||
lag_seconds,
|
||||
config_file_options.replication_lag_warning);
|
||||
&details,
|
||||
"%i seconds, threshold: %i)",
|
||||
lag_seconds, config_file_options.replication_lag_warning);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -792,19 +832,12 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
switch (mode)
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=UNKNOWN");
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_REPLICATION_LAG UNKNOWN: unable to query replication lag");
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"UNKNOWN - unable to query replication lag");
|
||||
&details,
|
||||
"unable to query replication lag");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -819,20 +852,15 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
{
|
||||
case OM_OPTFORMAT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"--status=OK --files=%i",
|
||||
&details,
|
||||
"--lag=%i",
|
||||
lag_seconds);
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"PG_REPLICATION_LAG OK: %i seconds",
|
||||
lag_seconds);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
appendPQExpBuffer(
|
||||
output,
|
||||
"OK - %i seconds",
|
||||
&details,
|
||||
"%i seconds",
|
||||
lag_seconds);
|
||||
break;
|
||||
|
||||
@@ -841,14 +869,39 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *ou
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (own_buffer == true)
|
||||
switch (mode)
|
||||
{
|
||||
printf("%s\n", buf.data);
|
||||
termPQExpBuffer(&buf);
|
||||
case OM_OPTFORMAT:
|
||||
{
|
||||
printf("--status=%s %s\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
}
|
||||
break;
|
||||
case OM_NAGIOS:
|
||||
printf("PG_REPLICATION_LAG %s: %s\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
break;
|
||||
case OM_TEXT:
|
||||
if (list_output != NULL)
|
||||
{
|
||||
check_status_list_set(list_output,
|
||||
"Replication lag",
|
||||
status,
|
||||
details.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s (%s)\n",
|
||||
output_check_status(status),
|
||||
details.data);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
termPQExpBuffer(&details);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -1572,3 +1625,5 @@ copy_file(const char *src_file, const char *dest_file)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
extern void do_node_status(void);
|
||||
extern void do_node_check(void);
|
||||
extern CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output);
|
||||
extern CheckStatus do_node_check_replication_lag(PGconn *conn, OutputMode mode, PQExpBufferData *output);
|
||||
//extern CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output);
|
||||
extern CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
|
||||
|
||||
extern CheckStatus do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
|
||||
|
||||
|
||||
extern void do_node_rejoin(void);
|
||||
extern void do_node_service(void);
|
||||
|
||||
@@ -159,13 +159,6 @@ typedef enum {
|
||||
} t_server_action;
|
||||
|
||||
|
||||
typedef enum {
|
||||
CHECK_STATUS_OK = 0,
|
||||
CHECK_STATUS_WARNING,
|
||||
CHECK_STATUS_CRITICAL,
|
||||
CHECK_STATUS_UNKNOWN
|
||||
} CheckStatus;
|
||||
|
||||
|
||||
/* global configuration structures */
|
||||
extern t_runtime_options runtime_options;
|
||||
|
||||
99
strutil.c
99
strutil.c
@@ -130,8 +130,8 @@ item_list_append_format(ItemList *item_list, const char *format, ...)
|
||||
void
|
||||
item_list_free(ItemList *item_list)
|
||||
{
|
||||
ItemListCell *cell;
|
||||
ItemListCell *next_cell;
|
||||
ItemListCell *cell = NULL;
|
||||
ItemListCell *next_cell = NULL;
|
||||
|
||||
cell = item_list->head;
|
||||
|
||||
@@ -155,9 +155,9 @@ 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, ...)
|
||||
{
|
||||
KeyValueListCell *cell;
|
||||
KeyValueListCell *cell = NULL;
|
||||
va_list arglist;
|
||||
int keylen;
|
||||
int keylen = 0;
|
||||
|
||||
cell = (KeyValueListCell *) pg_malloc0(sizeof(KeyValueListCell));
|
||||
|
||||
@@ -194,7 +194,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)
|
||||
{
|
||||
KeyValueListCell *cell;
|
||||
KeyValueListCell *cell = NULL;
|
||||
|
||||
for (cell = item_list->head; cell; cell = cell->next)
|
||||
{
|
||||
@@ -229,6 +229,95 @@ key_value_list_free(KeyValueList *item_list)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
check_status_list_set(CheckStatusList *list, const char *item, CheckStatus status, const char *details)
|
||||
{
|
||||
check_status_list_set_format(list, item, status, "%s", details);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details, ...)
|
||||
{
|
||||
CheckStatusListCell *cell;
|
||||
va_list arglist;
|
||||
int itemlen;
|
||||
|
||||
cell = (CheckStatusListCell *) pg_malloc0(sizeof(CheckStatusListCell));
|
||||
|
||||
if (cell == NULL)
|
||||
{
|
||||
log_error(_("unable to allocate memory; terminating."));
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
itemlen = strlen(item);
|
||||
|
||||
cell->item = pg_malloc0(itemlen + 1);
|
||||
cell->details = pg_malloc0(MAXLEN);
|
||||
cell->status = status;
|
||||
|
||||
strncpy(cell->item, item, itemlen);
|
||||
|
||||
va_start(arglist, details);
|
||||
(void) xvsnprintf(cell->details, MAXLEN, details, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
|
||||
if (list->tail)
|
||||
list->tail->next = cell;
|
||||
else
|
||||
list->head = cell;
|
||||
|
||||
list->tail = cell;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
check_status_list_free(CheckStatusList *list)
|
||||
{
|
||||
CheckStatusListCell *cell = NULL;
|
||||
CheckStatusListCell *next_cell = NULL;
|
||||
|
||||
cell = list->head;
|
||||
|
||||
while (cell != NULL)
|
||||
{
|
||||
next_cell = cell->next;
|
||||
pfree(cell->item);
|
||||
pfree(cell->details);
|
||||
pfree(cell);
|
||||
cell = next_cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
output_check_status(CheckStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case CHECK_STATUS_OK:
|
||||
return "OK";
|
||||
case CHECK_STATUS_WARNING:
|
||||
return "WARNING";
|
||||
case CHECK_STATUS_CRITICAL:
|
||||
return "CRITICAL";
|
||||
case CHECK_STATUS_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Escape a string for use as a parameter in recovery.conf
|
||||
* Caller must free returned value
|
||||
|
||||
36
strutil.h
36
strutil.h
@@ -19,6 +19,14 @@
|
||||
|
||||
#define MAXLEN_STR STR(MAXLEN)
|
||||
|
||||
|
||||
typedef enum {
|
||||
CHECK_STATUS_OK = 0,
|
||||
CHECK_STATUS_WARNING,
|
||||
CHECK_STATUS_CRITICAL,
|
||||
CHECK_STATUS_UNKNOWN
|
||||
} CheckStatus;
|
||||
|
||||
typedef enum {
|
||||
OM_NOT_SET = -1,
|
||||
OM_TEXT,
|
||||
@@ -54,6 +62,22 @@ typedef struct KeyValueList
|
||||
} KeyValueList;
|
||||
|
||||
|
||||
typedef struct CheckStatusListCell
|
||||
{
|
||||
struct CheckStatusListCell *next;
|
||||
char *item;
|
||||
CheckStatus status;
|
||||
char *details;
|
||||
} CheckStatusListCell;
|
||||
|
||||
typedef struct CheckStatusList
|
||||
{
|
||||
CheckStatusListCell *head;
|
||||
CheckStatusListCell *tail;
|
||||
} CheckStatusList;
|
||||
|
||||
|
||||
|
||||
extern int
|
||||
maxlen_snprintf(char *str, const char *format,...)
|
||||
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
|
||||
@@ -88,6 +112,18 @@ key_value_list_get(KeyValueList *item_list, const char *key);
|
||||
extern void
|
||||
key_value_list_free(KeyValueList *item_list);
|
||||
|
||||
extern void
|
||||
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, ...)
|
||||
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
|
||||
|
||||
extern void
|
||||
check_status_list_free(CheckStatusList *list);
|
||||
|
||||
extern const char * output_check_status(CheckStatus status);
|
||||
|
||||
extern char *
|
||||
escape_recovery_conf_value(const char *src);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user