svn commit: samba r23424 - in branches: SAMBA_3_0/source/nsswitch SAMBA_3_0_26/source/nsswitch

jra at samba.org jra at samba.org
Mon Jun 11 22:28:28 GMT 2007


Author: jra
Date: 2007-06-11 22:28:27 +0000 (Mon, 11 Jun 2007)
New Revision: 23424

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=23424

Log:
Thanks to Jerry, we finally tracked down the :
winbindd: Exceeding 200 client connections, no idle connection found"
bug #3204. This fixes it in Jerry's testing !
Jeremy.

Modified:
   branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c
   branches/SAMBA_3_0_26/source/nsswitch/winbindd_dual.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c	2007-06-11 20:56:17 UTC (rev 23423)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c	2007-06-11 22:28:27 UTC (rev 23424)
@@ -96,6 +96,7 @@
 	struct winbindd_request *request;
 	struct winbindd_response *response;
 	void (*continuation)(void *private_data, BOOL success);
+	struct timed_event *reply_timeout_event;
 	void *private_data;
 };
 
@@ -160,8 +161,38 @@
 			  async_request_sent, state);
 }
 
+/****************************************************************
+ Handler triggered if the child winbindd doesn't respond within
+ a given timeout.
+****************************************************************/
+
+static void async_request_timeout_handler(struct event_context *ctx,
+					struct timed_event *te,
+					const struct timeval *now,
+					void *private_data)
+{
+	struct winbindd_async_request *state =
+		talloc_get_type_abort(private_data, struct winbindd_async_request);
+
+	/* Deal with the reply - set to error. */
+
+	async_reply_recv(private_data, False);
+
+	/* 
+	 * Close the socket to the child. Should cause the
+	 * child to exit.
+	 */
+
+	DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. "
+		"Closing connection to it.\n",
+		state->child->pid ));
+
+	winbind_child_died(state->child->pid);
+}
+
 static void async_request_sent(void *private_data_data, BOOL success)
 {
+	uint32_t timeout = 30;
 	struct winbindd_async_request *state =
 		talloc_get_type_abort(private_data_data, struct winbindd_async_request);
 
@@ -180,6 +211,33 @@
 			 &state->response->result,
 			 sizeof(state->response->result),
 			 async_reply_recv, state);
+
+	/* 
+	 * Normal timeouts are 30s, but auth requests may take a long
+	 * time to timeout.
+	 */
+
+	if (state->request->cmd == WINBINDD_PAM_AUTH ||
+			state->request->cmd == WINBINDD_PAM_AUTH_CRAP ) {
+
+		timeout = 300;
+	}
+
+	/* 
+	 * Set up a timeout of 1 minute for the response.
+	 * If we don't get it close the child socket and
+	 * report failure.
+	 */
+
+	state->reply_timeout_event = event_add_timed(winbind_event_context(),
+							NULL,
+							timeval_current_ofs(timeout,0),
+							"async_request_timeout",
+							async_request_timeout_handler,
+							state);
+	if (!state->reply_timeout_event) {
+		smb_panic("async_request_sent: failed to add timeout handler.\n");
+	}
 }
 
 static void async_reply_recv(void *private_data, BOOL success)
@@ -188,6 +246,10 @@
 		talloc_get_type_abort(private_data, struct winbindd_async_request);
 	struct winbindd_child *child = state->child;
 
+	if (state->reply_timeout_event) {
+		TALLOC_FREE(state->reply_timeout_event);
+	}
+
 	state->response->length = sizeof(struct winbindd_response);
 
 	if (!success) {

Modified: branches/SAMBA_3_0_26/source/nsswitch/winbindd_dual.c
===================================================================
--- branches/SAMBA_3_0_26/source/nsswitch/winbindd_dual.c	2007-06-11 20:56:17 UTC (rev 23423)
+++ branches/SAMBA_3_0_26/source/nsswitch/winbindd_dual.c	2007-06-11 22:28:27 UTC (rev 23424)
@@ -96,6 +96,7 @@
 	struct winbindd_request *request;
 	struct winbindd_response *response;
 	void (*continuation)(void *private_data, BOOL success);
+	struct timed_event *reply_timeout_event;
 	void *private_data;
 };
 
@@ -160,8 +161,38 @@
 			  async_request_sent, state);
 }
 
+/****************************************************************
+ Handler triggered if the child winbindd doesn't respond within
+ a given timeout.
+****************************************************************/
+
+static void async_request_timeout_handler(struct event_context *ctx,
+					struct timed_event *te,
+					const struct timeval *now,
+					void *private_data)
+{
+	struct winbindd_async_request *state =
+		talloc_get_type_abort(private_data, struct winbindd_async_request);
+
+	/* Deal with the reply - set to error. */
+
+	async_reply_recv(private_data, False);
+
+	/* 
+	 * Close the socket to the child. Should cause the
+	 * child to exit.
+	 */
+
+	DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. "
+		"Closing connection to it.\n",
+		state->child->pid ));
+
+	winbind_child_died(state->child->pid);
+}
+
 static void async_request_sent(void *private_data_data, BOOL success)
 {
+	uint32_t timeout = 30;
 	struct winbindd_async_request *state =
 		talloc_get_type_abort(private_data_data, struct winbindd_async_request);
 
@@ -180,6 +211,33 @@
 			 &state->response->result,
 			 sizeof(state->response->result),
 			 async_reply_recv, state);
+
+	/* 
+	 * Normal timeouts are 30s, but auth requests may take a long
+	 * time to timeout.
+	 */
+
+	if (state->request->cmd == WINBINDD_PAM_AUTH ||
+			state->request->cmd == WINBINDD_PAM_AUTH_CRAP ) {
+
+		timeout = 300;
+	}
+
+	/* 
+	 * Set up a timeout of 1 minute for the response.
+	 * If we don't get it close the child socket and
+	 * report failure.
+	 */
+
+	state->reply_timeout_event = event_add_timed(winbind_event_context(),
+							NULL,
+							timeval_current_ofs(timeout,0),
+							"async_request_timeout",
+							async_request_timeout_handler,
+							state);
+	if (!state->reply_timeout_event) {
+		smb_panic("async_request_sent: failed to add timeout handler.\n");
+	}
 }
 
 static void async_reply_recv(void *private_data, BOOL success)
@@ -188,6 +246,10 @@
 		talloc_get_type_abort(private_data, struct winbindd_async_request);
 	struct winbindd_child *child = state->child;
 
+	if (state->reply_timeout_event) {
+		TALLOC_FREE(state->reply_timeout_event);
+	}
+
 	state->response->length = sizeof(struct winbindd_response);
 
 	if (!success) {



More information about the samba-cvs mailing list