diff --git a/dbutils.c b/dbutils.c index 51d768e2..2225e649 100644 --- a/dbutils.c +++ b/dbutils.c @@ -71,25 +71,22 @@ establishDBConnectionByParams(const char *keywords[], const char *values[],const return conn; } -bool +int is_standby(PGconn *conn) { PGresult *res; - bool result = false; + int result = 0; res = PQexec(conn, "SELECT pg_is_in_recovery()"); - if (PQresultStatus(res) != PGRES_TUPLES_OK) + if (res == NULL || PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("Can't query server mode: %s"), PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - exit(ERR_DB_QUERY); + result = -1; } - - if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0) - result = true; + else if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0) + result = 1; PQclear(res); return result; diff --git a/dbutils.h b/dbutils.h index 69c1a73d..1f2b7799 100644 --- a/dbutils.h +++ b/dbutils.h @@ -26,7 +26,7 @@ PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error); PGconn *establishDBConnectionByParams(const char *keywords[], const char *values[], const bool exit_on_error); -bool is_standby(PGconn *conn); +int is_standby(PGconn *conn); bool is_witness(PGconn *conn, char *schema, char *cluster, int node_id); bool is_pgup(PGconn *conn, int timeout); char *pg_version(PGconn *conn, char* major_version); diff --git a/repmgr.c b/repmgr.c index 85847e86..9ff03ec3 100644 --- a/repmgr.c +++ b/repmgr.c @@ -491,6 +491,7 @@ do_master_register(void) bool schema_exists = false; char schema_quoted[MAXLEN]; char master_version[MAXVERSIONSTR]; + int ret; conn = establishDBConnection(options.conninfo, true); @@ -506,9 +507,13 @@ do_master_register(void) /* Check we are a master */ log_info(_("%s connected to master, checking its state\n"), progname); - if (is_standby(conn)) + ret = is_standby(conn); + + if (ret) { - log_err(_("Trying to register a standby node as a master\n")); + log_err(_(ret == 1 ? "Trying to register a standby node as a master\n" : + "Connection to node lost!\n")); + PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -620,7 +625,7 @@ do_standby_register(void) { PGconn *conn; PGconn *master_conn; - int master_id; + int master_id, ret; PGresult *res; char sqlquery[QUERY_STR_LEN]; @@ -645,9 +650,12 @@ do_standby_register(void) } /* Check we are a standby */ - if (!is_standby(conn)) + ret = is_standby(conn); + if (ret == 0 || ret == -1) { - log_err(_("repmgr: This node should be a standby (%s)\n"), options.conninfo); + log_err(_(ret == 0 ? "repmgr: This node should be a standby (%s)\n" : + "repmgr: connection to node (%s) lost\n"), options.conninfo); + PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -770,7 +778,7 @@ do_standby_clone(void) char sqlquery[QUERY_STR_LEN]; int r = 0, retval = SUCCESS; - int i; + int i, is_standby_retval; bool flag_success = false; bool test_mode = false; @@ -830,10 +838,13 @@ do_standby_clone(void) } /* Check we are cloning a primary node */ - if (is_standby(conn)) + is_standby_retval = is_standby(conn); + if (is_standby_retval) { + log_err(_(is_standby_retval == 1 ? "The command should clone a primary node\n" : + "Connection to node lost!\n")); + PQfinish(conn); - log_err(_("\nThe command should clone a primary node\n")); exit(ERR_BAD_CONFIG); } @@ -1253,7 +1264,7 @@ do_standby_promote(void) PGconn *old_master_conn; int old_master_id; - int r; + int r, retval; char data_dir[MAXLEN]; char recovery_file_path[MAXFILENAME]; char recovery_done_path[MAXFILENAME]; @@ -1275,9 +1286,12 @@ do_standby_promote(void) } /* Check we are in a standby node */ - if (!is_standby(conn)) + retval = is_standby(conn); + if (retval == 0 || retval == -1) { - log_err(_("%s: The command should be executed on a standby node\n"), progname); + log_err(_(retval == 0 ? "%s: The command should be executed on a standby node\n" : + "%s: connection to node lost!\n"), progname); + PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -1333,9 +1347,11 @@ do_standby_promote(void) /* reconnect to check we got promoted */ log_info(_("%s connecting to now restarted database\n"), progname); conn = establishDBConnection(options.conninfo, true); - if (is_standby(conn)) + retval = is_standby(conn); + if (retval) { - log_err(_("\n%s: STANDBY PROMOTE failed, this is still a standby node.\n"), progname); + log_err(_(retval == 1 ? "%s: STANDBY PROMOTE failed, this is still a standby node.\n" : + "%s: connection to node lost!\n"), progname); } else { @@ -1357,7 +1373,7 @@ do_standby_follow(void) PGconn *master_conn; int master_id; - int r; + int r, retval; char data_dir[MAXLEN]; char master_version[MAXVERSIONSTR]; @@ -1369,9 +1385,12 @@ do_standby_follow(void) /* Check we are in a standby node */ log_info(_("%s connected to standby, checking its state\n"), progname); - if (!is_standby(conn)) + retval = is_standby(conn); + if (retval == 0 || retval == -1) { - log_err(_("\n%s: The command should be executed in a standby node\n"), progname); + log_err(_(retval == 0 ? "%s: The command should be executed in a standby node\n" : + "%s: connection to node lost!\n"), progname); + PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -1406,9 +1425,12 @@ do_standby_follow(void) } /* Check we are going to point to a master */ - if (is_standby(master_conn)) + retval = is_standby(master_conn); + if (retval) { - log_err(_("%s: The node to follow should be a master\n"), progname); + log_err(_(retval == 1 ? "%s: The node to follow should be a master\n" : + "%s: connection to node lost!\n"), progname); + PQfinish(conn); PQfinish(master_conn); exit(ERR_BAD_CONFIG); @@ -1491,7 +1513,7 @@ do_witness_create(void) char buf[MAXLEN]; FILE *pg_conf = NULL; - int r = 0; + int r = 0, retval; int i; char master_version[MAXVERSIONSTR]; @@ -1522,9 +1544,12 @@ do_witness_create(void) } /* Check we are connecting to a primary node */ - if (is_standby(masterconn)) + retval = is_standby(masterconn); + if (retval) { - log_err(_("The command should not run on a standby node\n")); + log_err(_(retval == 1 ? "The command should not run on a standby node\n" : + "Connection to node lost!\n")); + PQfinish(masterconn); exit(ERR_BAD_CONFIG); } diff --git a/repmgrd.c b/repmgrd.c index b70a3807..04873cca 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -165,7 +165,7 @@ main(int argc, char **argv) }; int optindex; - int c; + int c, ret; bool daemonize = false; char standby_version[MAXVERSIONSTR]; @@ -301,14 +301,21 @@ main(int argc, char **argv) */ do { + ret = is_standby(myLocalConn); + /* * Set my server mode, establish a connection to primary * and start monitor */ if (is_witness(myLocalConn, repmgr_schema, local_options.cluster_name, local_options.node)) myLocalMode = WITNESS_MODE; - else if (is_standby(myLocalConn)) + else if (ret == 1) myLocalMode = STANDBY_MODE; + /* XXX we did this before changing is_standby() to return int; we + * should not exit at this point, but for now we do until we have a + * better strategy */ + else if (ret == -1) + exit(1); else /* is the master */ myLocalMode = PRIMARY_MODE;