From 6cd61f0d1e1e1a343d9eb017714d6d093cedacfb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 10 Jun 2014 14:21:07 +0000 Subject: [PATCH] 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 --- source3/lib/msg_channel.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/lib/msg_channel.c b/source3/lib/msg_channel.c index 8e23fd4..55d102a 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, -- 1.8.1.2