diff --git a/CREDITS b/CREDITS index 86b8dea1..09b5d46e 100644 --- a/CREDITS +++ b/CREDITS @@ -8,3 +8,4 @@ Gabriele Bartolini Bas van Oostveen Hannu Krosing Cédric Villemain +Charles Duffy diff --git a/HISTORY b/HISTORY index 14a881d9..b7dd303b 100644 --- a/HISTORY +++ b/HISTORY @@ -1,4 +1,4 @@ -1.0.0 2010-12-05 First public release +1.0.0 2010-12-05 First public release (Greg Smith) 1.0.1 2011-02-XX Fix missing "--force" option in help Correct warning message for wal_keep_segments (Bas van Oostveen) @@ -13,4 +13,6 @@ Avoid buffer overruns by using snprintf etc. (Gabriele) Fix use of database query after close (Gabriele) Add information about progress during "standby clone" (Gabriele) - + Fix double free error in repmgrd (Charles Duffy) + Make repmgr exit with an error code when encountering an error (Charles) + Standardize on error return codes, use in repmgrd too (Greg) diff --git a/README.rst b/README.rst index 6addf0b0..0cd9edb4 100644 --- a/README.rst +++ b/README.rst @@ -539,6 +539,23 @@ and the same in the standby. The repmgr daemon creates 2 connections: one to the master and another to the standby. +Error codes +----------- + +When the repmgr or repmgrd program exits, it will set one of the +following + +* SUCCESS 0: Program ran successfully. + +* ERR_BAD_CONFIG 1: One of the configuration checks the program makes failed. +* ERR_BAD_RSYNC 2: An rsync call made by the program returned an error. +* ERR_STOP_BACKUP 3: A ``pg_stop_backup()`` call made by the program didn't succeed. +* ERR_NO_RESTART 4: An attempt to restart a PostgreSQL instance failed. +* ERR_NEEDS_XLOG 5: Could note create the ``pg_xlog`` directory when cloning. +* ERR_DB_CON 6: Error when trying to connect to a database. +* ERR_DB_QUERY 7: Error executing a database query. +* ERR_PROMOTED 8: Exiting program because the node has been promoted to master. + Detailed walkthrough ==================== diff --git a/config.c b/config.c index 53113bb1..8e9b4c6f 100644 --- a/config.c +++ b/config.c @@ -30,7 +30,7 @@ parse_config(const char* config_file, t_configuration_options* options) if (fp == NULL) { fprintf(stderr, _("Could not find configuration file '%s'\n"), config_file); - exit(1); + exit(ERR_BAD_CONFIG); } /* Initialize */ @@ -75,14 +75,14 @@ parse_config(const char* config_file, t_configuration_options* options) { fprintf(stderr, "Cluster name is missing. " "Check the configuration file.\n"); - exit(1); + exit(ERR_BAD_CONFIG); } if (config->node == -1) { fprintf(stderr, "Node information is missing. " "Check the configuration file.\n"); - exit(1); + exit(ERR_BAD_CONFIG); } } diff --git a/dbutils.c b/dbutils.c index 38b8c05f..446062e1 100644 --- a/dbutils.c +++ b/dbutils.c @@ -36,7 +36,7 @@ establishDBConnection(const char *conninfo, const bool exit_on_error) if (exit_on_error) { PQfinish(conn); - exit(1); + exit(ERR_DB_CON); } } @@ -57,7 +57,7 @@ is_standby(PGconn *conn) fprintf(stderr, "Can't query server mode: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); - exit(1); + exit(ERR_NO_DB_CON); } if (strcmp(PQgetvalue(res, 0, 0), "f") == 0) @@ -89,7 +89,7 @@ pg_version(PGconn *conn, char* major_version) fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); - exit(1); + exit(ERR_DB_QUERY); } major_version1 = atoi(PQgetvalue(res, 0, 0)); major_version2 = PQgetvalue(res, 0, 1); @@ -123,7 +123,7 @@ guc_setted(PGconn *conn, const char *parameter, const char *op, const char *valu fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); - exit(1); + exit(ERR_DB_QUERY); } if (PQntuples(res) == 0) { @@ -152,7 +152,7 @@ get_cluster_size(PGconn *conn) fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); - exit(1); + exit(ERR_DB_QUERY); } size = PQgetvalue(res, 0, 0); PQclear(res); @@ -184,7 +184,7 @@ getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id) fprintf(stderr, "Can't get nodes info: %s\n", PQerrorMessage(standby_conn)); PQclear(res1); PQfinish(standby_conn); - exit(1); + exit(ERR_DB_QUERY); } for (i = 0; i < PQntuples(res1); i++) diff --git a/repmgr.c b/repmgr.c index 606f57fa..08bca365 100644 --- a/repmgr.c +++ b/repmgr.c @@ -101,12 +101,12 @@ main(int argc, char **argv) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); - exit(0); + exit(SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf("%s (PostgreSQL) " PG_VERSION "\n", progname); - exit(0); + exit(SUCCESS); } } diff --git a/repmgr.h b/repmgr.h index 6267e028..a8455e80 100644 --- a/repmgr.h +++ b/repmgr.h @@ -47,11 +47,15 @@ /* Exit return code */ +#define SUCCESS 0 #define ERR_BAD_CONFIG 1 #define ERR_BAD_RSYNC 2 #define ERR_STOP_BACKUP 3 #define ERR_NO_RESTART 4 #define ERR_NEEDS_XLOG 5 +#define ERR_DB_CON 6 +#define ERR_DB_QUERY 7 +#define ERR_PROMOTED 8 /* Run time options type */ typedef struct { diff --git a/repmgrd.c b/repmgrd.c index 01872071..9a5eb0d4 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -107,12 +107,12 @@ main(int argc, char **argv) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); - exit(0); + exit(SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf("%s (PostgreSQL) " PG_VERSION "\n", progname); - exit(0); + exit(SUCCESS); } } @@ -129,7 +129,7 @@ main(int argc, char **argv) break; default: usage(); - exit(1); + exit(ERR_BAD_CONFIG); } } @@ -143,7 +143,7 @@ main(int argc, char **argv) { log_err("Node information is missing. " "Check the configuration file.\n"); - exit(1); + exit(ERR_BAD_CONFIG); } logger_init(progname, local_options.loglevel, local_options.logfacility); snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name); @@ -156,7 +156,7 @@ main(int argc, char **argv) { PQfinish(myLocalConn); log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); - exit(1); + exit(ERR_BAD_CONFIG); } /* @@ -175,7 +175,7 @@ main(int argc, char **argv) /* I need the id of the primary as well as a connection to it */ primaryConn = getMasterConnection(myLocalConn, local_options.node, local_options.cluster_name, &primary_options.node); if (primaryConn == NULL) - exit(1); + exit(ERR_BAD_CONFIG); } checkClusterConfiguration(); @@ -258,7 +258,7 @@ MonitorExecute(void) if (PQstatus(primaryConn) != CONNECTION_OK) { log_err(_("We couldn't reconnect for long enough, exiting...")); - exit(1); + exit(ERR_DB_CON); } /* Check if we still are a standby, we could have been promoted */ @@ -266,7 +266,7 @@ MonitorExecute(void) { log_err(_("It seems like we have been promoted, so exit from monitoring...")); CloseConnections(); - exit(1); + exit(ERR_PROMOTED); } /* @@ -354,7 +354,7 @@ checkClusterConfiguration(void) PQclear(res); PQfinish(myLocalConn); PQfinish(primaryConn); - exit(1); + exit(ERR_DB_QUERY); } /* @@ -368,7 +368,7 @@ checkClusterConfiguration(void) PQclear(res); PQfinish(myLocalConn); PQfinish(primaryConn); - exit(1); + exit(ERR_BAD_CONFIG); } PQclear(res); } @@ -393,7 +393,7 @@ checkNodeConfiguration(char *conninfo) PQclear(res); PQfinish(myLocalConn); PQfinish(primaryConn); - exit(1); + exit(ERR_BAD_CONFIG); } /* @@ -414,7 +414,7 @@ checkNodeConfiguration(char *conninfo) PQerrorMessage(primaryConn)); PQfinish(myLocalConn); PQfinish(primaryConn); - exit(1); + exit(ERR_BAD_CONFIG); } } PQclear(res);