summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-06-10 14:21:07 +0000
committerKarolin Seeger <kseeger@samba.org>2014-07-15 12:46:11 +0200
commit7e38fcb93e699cd55f000ae019671283c3464723 (patch)
tree5bf7b53bf3fd82f568fe72607029adbf37f6e5f7 /source3/lib
parent406e412ab681ba08ffdc182e999fb73a63abbbde (diff)
downloadsamba-7e38fcb93e699cd55f000ae019671283c3464723.tar.gz
msg_channel: Fix a 100% CPU loop
In a ctdb setup, msg_read_got_ctdb did not set channel->pending_req to NULL. In smbXsrv_session_close_loop in any error condition this leads to a 100% loop. smbXsrv_session_close_loop continously retries, but because close_channel->pending_req is != NULL, msg_read_send will always return EBUSY, making smbXsrv_session_close_loop retry infinitely. This patch makes sure that msg_read_got_ctdb correctly NULLs out pending_req. msg_channel.c does not exist in master anymore, so this patch is 4.1 only. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Bug: https://bugzilla.samba.org/show_bug.cgi?id=10663 100% smbd cpu loop in ctdb setups
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/msg_channel.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/source3/lib/msg_channel.c b/source3/lib/msg_channel.c
index 8e23fd44c4..55d102ab32 100644
--- a/source3/lib/msg_channel.c
+++ b/source3/lib/msg_channel.c
@@ -213,6 +213,7 @@ fail:
}
static void msg_read_got_ctdb(struct tevent_req *subreq);
+static int msg_read_state_destructor(struct msg_read_state *s);
struct tevent_req *msg_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -248,6 +249,8 @@ struct tevent_req *msg_read_send(TALLOC_CTX *mem_ctx,
}
channel->pending_req = req;
+ talloc_set_destructor(state, msg_read_state_destructor);
+
channel->ev = ev;
msg_tdb_event = messaging_tdb_event(state, channel->msg, ev);
@@ -268,6 +271,12 @@ struct tevent_req *msg_read_send(TALLOC_CTX *mem_ctx,
return req;
}
+static int msg_read_state_destructor(struct msg_read_state *s)
+{
+ s->channel->pending_req = NULL;
+ return 0;
+}
+
static void msg_read_got_ctdb(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
@@ -278,6 +287,8 @@ static void msg_read_got_ctdb(struct tevent_req *subreq)
enum ndr_err_code ndr_err;
int ret;
+ state->channel->pending_req = NULL;
+
ret = ctdb_msg_read_recv(subreq, talloc_tos(),
&blob.data, &blob.length);
TALLOC_FREE(subreq);
@@ -316,6 +327,7 @@ static void msg_read_got_ctdb(struct tevent_req *subreq)
return;
}
tevent_req_set_callback(subreq, msg_read_got_ctdb, req);
+ state->channel->pending_req = req;
}
int msg_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,