From ac76ec27b933a4f0e1c6840ab1aaef770ed14395 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 16 Aug 2013 11:09:09 -0400 Subject: [PATCH] pg_upgrade: shut down server after auth failure Register atexit() server shutdown if pg_ctl successfully started the server, but we can't connect to it. Backpatch to 9.3. Pavel Raiskup --- contrib/pg_upgrade/server.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c index c1d459dd82..1ad85cf715 100644 --- a/contrib/pg_upgrade/server.c +++ b/contrib/pg_upgrade/server.c @@ -166,7 +166,6 @@ static void stop_postmaster_atexit(void) { stop_postmaster(true); - } @@ -236,10 +235,34 @@ start_postmaster(ClusterInfo *cluster, bool throw_error) false, "%s", cmd); + /* Did it fail and we are just testing if the server could be started? */ if (!pg_ctl_return && !throw_error) return false; - /* Check to see if we can connect to the server; if not, report it. */ + /* + * We set this here to make sure atexit() shuts down the server, + * but only if we started the server successfully. We do it + * before checking for connectivity in case the server started but + * there is a connectivity failure. If pg_ctl did not return success, + * we will exit below. + * + * Pre-9.1 servers do not have PQping(), so we could be leaving the server + * running if authentication was misconfigured, so someday we might went to + * be more aggressive about doing server shutdowns even if pg_ctl fails, + * but now (2013-08-14) it seems prudent to be cautious. We don't want to + * shutdown a server that might have been accidentally started during the + * upgrade. + */ + if (pg_ctl_return) + os_info.running_cluster = cluster; + + /* + * pg_ctl -w might have failed because the server couldn't be started, + * or there might have been a connection problem in _checking_ if the + * server has started. Therefore, even if pg_ctl failed, we continue + * and test for connectivity in case we get a connection reason for the + * failure. + */ if ((conn = get_db_conn(cluster, "template1")) == NULL || PQstatus(conn) != CONNECTION_OK) { @@ -253,13 +276,14 @@ start_postmaster(ClusterInfo *cluster, bool throw_error) } PQfinish(conn); - /* If the connection didn't fail, fail now */ + /* + * If pg_ctl failed, and the connection didn't fail, and throw_error is + * enabled, fail now. This could happen if the server was already running. + */ if (!pg_ctl_return) pg_log(PG_FATAL, "pg_ctl failed to start the %s server, or connection failed\n", CLUSTER_NAME(cluster)); - os_info.running_cluster = cluster; - return true; }