From f23b82b58c1cdcbfa9d2631dd7513e4fe3e2538b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Feb 2010 14:36:14 +1100 Subject: ctdb: when we fill the client packet queue we need to drop the client We can't just drop packets to the list, as those packets could be part of the core protocol the client is using. This happens (for example) when Samba is doing a traverse. If we drop a traverse packet then Samba hangs indefinately. We are better off dropping the ctdb socket to Samba. (This used to be ctdb commit a7a86dafa4d88a6bbc6a71b77ed79a178fd802a6) --- ctdb/server/ctdb_daemon.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'ctdb/server/ctdb_daemon.c') diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index 7fbbf3fffb7..5903f69635d 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -100,8 +100,9 @@ static int daemon_queue_send(struct ctdb_client *client, struct ctdb_req_header client->ctdb->statistics.client_packets_sent++; if (hdr->operation == CTDB_REQ_MESSAGE) { if (ctdb_queue_length(client->queue) > client->ctdb->tunable.max_queue_depth_drop_msg) { - DEBUG(DEBUG_ERR,("Drop CTDB_REQ_MESSAGE to client. Queue full.\n")); - return 0; + DEBUG(DEBUG_ERR,("CTDB_REQ_MESSAGE queue full - killing client connection.\n")); + talloc_free(client); + return -1; } } return ctdb_queue_send(client->queue, (uint8_t *)hdr, hdr->length); @@ -280,6 +281,10 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state) memcpy(&r->data[0], dstate->call->reply_data.dptr, r->datalen); res = daemon_queue_send(client, &r->hdr); + if (res == -1) { + /* client is dead - return immediately */ + return; + } if (res != 0) { DEBUG(DEBUG_ERR, (__location__ " Failed to queue packet from daemon to client\n")); } @@ -890,6 +895,7 @@ static void daemon_control_callback(struct ctdb_context *ctdb, struct ctdb_client *client = state->client; struct ctdb_reply_control *r; size_t len; + int ret; /* construct a message to send to the client containing the data */ len = offsetof(struct ctdb_reply_control, data) + data.dsize; @@ -910,9 +916,10 @@ static void daemon_control_callback(struct ctdb_context *ctdb, memcpy(&r->data[r->datalen], errormsg, r->errorlen); } - daemon_queue_send(client, &r->hdr); - - talloc_free(state); + ret = daemon_queue_send(client, &r->hdr); + if (ret != -1) { + talloc_free(state); + } } /* -- cgit