mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 08:36:30 +00:00
do not use exit()
We avoid using exit() to be able to clean up when we have to terminate. This includes removal of the PID file as well as closing database connections.
This commit is contained in:
92
repmgrd.c
92
repmgrd.c
@@ -138,6 +138,8 @@ static volatile sig_atomic_t got_SIGHUP = false;
|
|||||||
static void handle_sighup(SIGNAL_ARGS);
|
static void handle_sighup(SIGNAL_ARGS);
|
||||||
static void handle_sigint(SIGNAL_ARGS);
|
static void handle_sigint(SIGNAL_ARGS);
|
||||||
|
|
||||||
|
static void terminate(int retval);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
static void setup_event_handlers(void);
|
static void setup_event_handlers(void);
|
||||||
#endif
|
#endif
|
||||||
@@ -269,7 +271,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
log_err(_("Node information is missing. "
|
log_err(_("Node information is missing. "
|
||||||
"Check the configuration file, or provide one if you have not done so.\n"));
|
"Check the configuration file, or provide one if you have not done so.\n"));
|
||||||
exit(ERR_BAD_CONFIG);
|
terminate(ERR_BAD_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
@@ -291,8 +293,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if(ret_ver != NULL)
|
if(ret_ver != NULL)
|
||||||
log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
|
log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
|
||||||
PQfinish(myLocalConn);
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,7 +328,7 @@ main(int argc, char **argv)
|
|||||||
* should not exit at this point, but for now we do until we have a
|
* should not exit at this point, but for now we do until we have a
|
||||||
* better strategy */
|
* better strategy */
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
exit(1);
|
terminate(1);
|
||||||
|
|
||||||
switch (myLocalMode)
|
switch (myLocalMode)
|
||||||
{
|
{
|
||||||
@@ -371,7 +372,7 @@ main(int argc, char **argv)
|
|||||||
/* XXX
|
/* XXX
|
||||||
* May we do something more verbose ?
|
* May we do something more verbose ?
|
||||||
*/
|
*/
|
||||||
exit(1);
|
terminate(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_SIGHUP)
|
if (got_SIGHUP)
|
||||||
@@ -404,8 +405,7 @@ main(int argc, char **argv)
|
|||||||
&primary_options.node, NULL);
|
&primary_options.node, NULL);
|
||||||
if (primaryConn == NULL)
|
if (primaryConn == NULL)
|
||||||
{
|
{
|
||||||
CloseConnections();
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkClusterConfiguration(myLocalConn, primaryConn);
|
checkClusterConfiguration(myLocalConn, primaryConn);
|
||||||
@@ -493,8 +493,7 @@ WitnessMonitor(void)
|
|||||||
* If we can't reconnect, just exit...
|
* If we can't reconnect, just exit...
|
||||||
* XXX we need to make witness connect to the new master
|
* XXX we need to make witness connect to the new master
|
||||||
*/
|
*/
|
||||||
PQfinish(myLocalConn);
|
terminate(0);
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fast path for the case where no history is requested */
|
/* Fast path for the case where no history is requested */
|
||||||
@@ -575,7 +574,7 @@ StandbyMonitor(void)
|
|||||||
|
|
||||||
if (!CheckConnection(myLocalConn, "standby"))
|
if (!CheckConnection(myLocalConn, "standby"))
|
||||||
{
|
{
|
||||||
handle_sigint(0);
|
terminate(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PQstatus(primaryConn) != CONNECTION_OK)
|
if (PQstatus(primaryConn) != CONNECTION_OK)
|
||||||
@@ -604,7 +603,7 @@ StandbyMonitor(void)
|
|||||||
if (PQstatus(primaryConn) != CONNECTION_OK)
|
if (PQstatus(primaryConn) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
log_err(_("We couldn't reconnect for long enough, exiting...\n"));
|
log_err(_("We couldn't reconnect for long enough, exiting...\n"));
|
||||||
exit(ERR_DB_CON);
|
terminate(ERR_DB_CON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (local_options.failover == AUTOMATIC_FAILOVER)
|
else if (local_options.failover == AUTOMATIC_FAILOVER)
|
||||||
@@ -626,8 +625,7 @@ StandbyMonitor(void)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
log_err(_("It seems like we have been promoted, so exit from monitoring...\n"));
|
log_err(_("It seems like we have been promoted, so exit from monitoring...\n"));
|
||||||
CloseConnections();
|
terminate(1);
|
||||||
handle_sigint(0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
@@ -636,7 +634,7 @@ StandbyMonitor(void)
|
|||||||
|
|
||||||
if (!CheckConnection(myLocalConn, "standby"))
|
if (!CheckConnection(myLocalConn, "standby"))
|
||||||
{
|
{
|
||||||
handle_sigint(0);
|
terminate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -770,8 +768,7 @@ do_failover(void)
|
|||||||
{
|
{
|
||||||
log_err(_("Can't get nodes' info: %s\n"), PQerrorMessage(myLocalConn));
|
log_err(_("Can't get nodes' info: %s\n"), PQerrorMessage(myLocalConn));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(myLocalConn);
|
terminate(ERR_DB_QUERY);
|
||||||
exit(ERR_DB_QUERY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -820,7 +817,7 @@ do_failover(void)
|
|||||||
log_err(_("Can't reach most of the nodes.\n"
|
log_err(_("Can't reach most of the nodes.\n"
|
||||||
"Let the other standby servers decide which one will be the primary.\n"
|
"Let the other standby servers decide which one will be the primary.\n"
|
||||||
"Manual action will be needed to readd this node to the cluster.\n"));
|
"Manual action will be needed to readd this node to the cluster.\n"));
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query all the nodes to determine which ones are ready */
|
/* Query all the nodes to determine which ones are ready */
|
||||||
@@ -841,7 +838,7 @@ do_failover(void)
|
|||||||
if (PQstatus(nodeConn) != CONNECTION_OK)
|
if (PQstatus(nodeConn) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
log_err(_("It seems new problems are arising, manual intervention is needed\n"));
|
log_err(_("It seems new problems are arising, manual intervention is needed\n"));
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlquery_snprintf(sqlquery, "SELECT pg_last_xlog_receive_location()");
|
sqlquery_snprintf(sqlquery, "SELECT pg_last_xlog_receive_location()");
|
||||||
@@ -852,7 +849,7 @@ do_failover(void)
|
|||||||
log_info(_("Connection details: %s\n"), nodes[i].conninfostr);
|
log_info(_("Connection details: %s\n"), nodes[i].conninfostr);
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(nodeConn);
|
PQfinish(nodeConn);
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2)
|
if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2)
|
||||||
@@ -867,7 +864,7 @@ do_failover(void)
|
|||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(nodeConn);
|
PQfinish(nodeConn);
|
||||||
log_info(_("InvalidXLogRecPtr detected in a standby\n"));
|
log_info(_("InvalidXLogRecPtr detected in a standby\n"));
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
XLAssignValue(nodes[i].xlog_location, uxlogid, uxrecoff);
|
XLAssignValue(nodes[i].xlog_location, uxlogid, uxrecoff);
|
||||||
@@ -882,11 +879,10 @@ do_failover(void)
|
|||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(myLocalConn));
|
log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(myLocalConn));
|
||||||
PQfinish(myLocalConn);
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
sprintf(last_wal_standby_applied, "'%X/%X'", 0, 0);
|
sprintf(last_wal_standby_applied, "'%X/%X'", 0, 0);
|
||||||
update_shared_memory(last_wal_standby_applied);
|
update_shared_memory(last_wal_standby_applied);
|
||||||
exit(ERR_DB_QUERY);
|
terminate(ERR_DB_QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write last location in shared memory */
|
/* write last location in shared memory */
|
||||||
@@ -938,7 +934,7 @@ do_failover(void)
|
|||||||
log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(nodeConn));
|
log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(nodeConn));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(nodeConn);
|
PQfinish(nodeConn);
|
||||||
exit(ERR_DB_QUERY);
|
terminate(ERR_DB_QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2)
|
if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2)
|
||||||
@@ -1012,7 +1008,7 @@ do_failover(void)
|
|||||||
if (best_candidate.is_witness)
|
if (best_candidate.is_witness)
|
||||||
{
|
{
|
||||||
log_err(_("%s: Node selected as new master is a witness. Can't be promoted.\n"), progname);
|
log_err(_("%s: Node selected as new master is a witness. Can't be promoted.\n"), progname);
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait */
|
/* wait */
|
||||||
@@ -1026,7 +1022,7 @@ do_failover(void)
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
log_err(_("%s: promote command failed. You could check and try it manually.\n"), progname);
|
log_err(_("%s: promote command failed. You could check and try it manually.\n"), progname);
|
||||||
exit(ERR_BAD_CONFIG);
|
terminate(ERR_BAD_CONFIG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (find_best)
|
else if (find_best)
|
||||||
@@ -1046,13 +1042,13 @@ do_failover(void)
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
log_err(_("%s: follow command failed. You could check and try it manually.\n"), progname);
|
log_err(_("%s: follow command failed. You could check and try it manually.\n"), progname);
|
||||||
exit(ERR_BAD_CONFIG);
|
terminate(ERR_BAD_CONFIG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_err(_("%s: Did not find candidates. You should check and try manually.\n"), progname);
|
log_err(_("%s: Did not find candidates. You should check and try manually.\n"), progname);
|
||||||
exit(ERR_FAILOVER_FAIL);
|
terminate(ERR_FAILOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* to force it to re-calculate mode and master node */
|
/* to force it to re-calculate mode and master node */
|
||||||
@@ -1119,8 +1115,7 @@ checkClusterConfiguration(PGconn *conn, PGconn *primary)
|
|||||||
{
|
{
|
||||||
log_err(_("PQexec failed: %s\n"), PQerrorMessage(conn));
|
log_err(_("PQexec failed: %s\n"), PQerrorMessage(conn));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
CloseConnections();
|
terminate(ERR_DB_QUERY);
|
||||||
exit(ERR_DB_QUERY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1134,8 +1129,7 @@ checkClusterConfiguration(PGconn *conn, PGconn *primary)
|
|||||||
{
|
{
|
||||||
log_err(_("The replication cluster is not configured\n"));
|
log_err(_("The replication cluster is not configured\n"));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
CloseConnections();
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
}
|
}
|
||||||
@@ -1161,8 +1155,7 @@ checkNodeConfiguration(char *conninfo)
|
|||||||
{
|
{
|
||||||
log_err(_("PQexec failed: %s\n"), PQerrorMessage(myLocalConn));
|
log_err(_("PQexec failed: %s\n"), PQerrorMessage(myLocalConn));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
CloseConnections();
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1177,8 +1170,7 @@ checkNodeConfiguration(char *conninfo)
|
|||||||
if (myLocalMode == WITNESS_MODE)
|
if (myLocalMode == WITNESS_MODE)
|
||||||
{
|
{
|
||||||
log_err(_("The witness is not configured\n"));
|
log_err(_("The witness is not configured\n"));
|
||||||
CloseConnections();
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adding the node */
|
/* Adding the node */
|
||||||
@@ -1195,8 +1187,7 @@ checkNodeConfiguration(char *conninfo)
|
|||||||
{
|
{
|
||||||
log_err(_("Cannot insert node details, %s\n"),
|
log_err(_("Cannot insert node details, %s\n"),
|
||||||
PQerrorMessage(primaryConn));
|
PQerrorMessage(primaryConn));
|
||||||
CloseConnections();
|
terminate(ERR_BAD_CONFIG);
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1248,15 +1239,7 @@ void help(const char *progname)
|
|||||||
static void
|
static void
|
||||||
handle_sigint(SIGNAL_ARGS)
|
handle_sigint(SIGNAL_ARGS)
|
||||||
{
|
{
|
||||||
CloseConnections();
|
terminate(0);
|
||||||
logger_shutdown();
|
|
||||||
|
|
||||||
if (pid_file)
|
|
||||||
{
|
|
||||||
remove(pid_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SIGHUP: set flag to re-read config file at next convenient time */
|
/* SIGHUP: set flag to re-read config file at next convenient time */
|
||||||
@@ -1275,6 +1258,20 @@ setup_event_handlers(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
terminate(int retval)
|
||||||
|
{
|
||||||
|
CloseConnections();
|
||||||
|
logger_shutdown();
|
||||||
|
|
||||||
|
if (pid_file)
|
||||||
|
{
|
||||||
|
remove(pid_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_shared_memory(char *last_wal_standby_applied)
|
update_shared_memory(char *last_wal_standby_applied)
|
||||||
@@ -1309,8 +1306,7 @@ update_registration(void)
|
|||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
{
|
{
|
||||||
log_err(_("Cannot update registration: %s\n"), PQerrorMessage(primaryConn));
|
log_err(_("Cannot update registration: %s\n"), PQerrorMessage(primaryConn));
|
||||||
CloseConnections();
|
terminate(ERR_DB_CON);
|
||||||
exit(ERR_DB_CON);
|
|
||||||
}
|
}
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user