]> granicus.if.org Git - pgbouncer/commitdiff
if cannot login to target db at all, notify clients (by killing them)
authorMarko Kreen <markokr@gmail.com>
Fri, 11 Jan 2008 14:18:44 +0000 (14:18 +0000)
committerMarko Kreen <markokr@gmail.com>
Fri, 11 Jan 2008 14:18:44 +0000 (14:18 +0000)
include/proto.h
src/proto.c
src/server.c

index 053ca3e10de9ea363bc347d6514802c93ba37788..72133b6fca8a28dcd81bcbed4c99c9158757ca5f 100644 (file)
@@ -36,6 +36,7 @@ bool get_header(MBuf *data, PktHdr *pkt) _MUSTCHECK;
 
 bool send_pooler_error(PgSocket *client, bool send_ready, const char *msg)  /*_MUSTCHECK*/;
 void log_server_error(const char *note, PktHdr *pkt);
+void parse_server_error(PktHdr *pkt, const char **level_p, const char **msg_p);
 
 void add_welcome_parameter(PgPool *pool, const char *key, const char *val);
 void finish_welcome_msg(PgSocket *server);
index 6471726d9668fbdb8cb67cdff9ddf3affdc6aaa9..2a43fca467eb68de6fd4757f86b2370299bd1635 100644 (file)
@@ -117,7 +117,7 @@ bool send_pooler_error(PgSocket *client, bool send_ready, const char *msg)
 /*
  * Parse server error message and log it.
  */
-void log_server_error(const char *note, PktHdr *pkt)
+void parse_server_error(PktHdr *pkt, const char **level_p, const char **msg_p)
 {
        const char *level = NULL, *msg = NULL, *val;
        int type;
@@ -133,6 +133,16 @@ void log_server_error(const char *note, PktHdr *pkt)
                else if (type == 'M')
                        msg = val;
        }
+       *level_p = level;
+       *msg_p = msg;
+}
+
+void log_server_error(const char *note, PktHdr *pkt)
+{
+       const char *level = NULL, *msg = NULL;
+
+       parse_server_error(pkt, &level, &msg);
+
        if (!msg || !level)
                log_error("%s: corrupt error message", note);
        else
index a7f6df23a96664d4bbf4f31bc50f0b75f33219b7..4aab0b31dbab1f27c3ed41b64f8693d37b7d20ac 100644 (file)
@@ -55,6 +55,24 @@ static bool load_parameter(PgSocket *server, PktHdr *pkt, bool startup)
        return true;
 }
 
+/* we cannot log in at all, notify clients */
+static void kill_pool_logins(PgPool *pool, PktHdr *errpkt)
+{
+       List *item, *tmp;
+       PgSocket *client;
+       const char *level, *msg;
+
+       parse_server_error(errpkt, &level, &msg);
+
+       statlist_for_each_safe(item, &pool->waiting_client_list, tmp) {
+               client = container_of(item, PgSocket, head);
+               if (!client->wait_for_welcome)
+                       continue;
+
+               disconnect_client(client, true, msg);
+       }
+}
+
 /* process packets on server auth phase */
 static bool handle_server_startup(PgSocket *server, PktHdr *pkt)
 {
@@ -74,7 +92,11 @@ static bool handle_server_startup(PgSocket *server, PktHdr *pkt)
                break;
 
        case 'E':               /* ErrorResponse */
-               log_server_error("S: login failed", pkt);
+               if (!server->pool->welcome_msg_ready)
+                       kill_pool_logins(server->pool, pkt);
+               else
+                       log_server_error("S: login failed", pkt);
+
                disconnect_server(server, true, "login failed");
                break;