diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-02-04 14:36:14 +1100 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2010-02-04 15:37:59 +1100 |
commit | f23b82b58c1cdcbfa9d2631dd7513e4fe3e2538b (patch) | |
tree | 81351771e6d3a0388e4fde55cfab29fb9875c6fe /ctdb/server/ctdb_daemon.c | |
parent | 3eb9735be5697ad3da2fa44507d0f9cc98fa0eaf (diff) | |
download | samba-f23b82b58c1cdcbfa9d2631dd7513e4fe3e2538b.tar.gz samba-f23b82b58c1cdcbfa9d2631dd7513e4fe3e2538b.tar.xz samba-f23b82b58c1cdcbfa9d2631dd7513e4fe3e2538b.zip |
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)
Diffstat (limited to 'ctdb/server/ctdb_daemon.c')
-rw-r--r-- | ctdb/server/ctdb_daemon.c | 17 |
1 files changed, 12 insertions, 5 deletions
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); + } } /* |