[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Jul 15 23:46:05 UTC 2015


The branch, master has been updated
       via  2c1c567 winbindd: shorten client list scan
       via  c10e24e winbindd: keep client list sorted by access time
       via  f065100 winbindd: add service routines to support a sorted client list
       via  03282bf doc: clarify "winbind max clients"
       via  33814c3 winbindd: periodically remove timed out clients
       via  5a6a483 winbind client: avoid vicious cycle created by client retry
       via  2a13740 winbindd: verify that client has closed the connection
       via  0c6dc1e async_req: check for errors when monitoring socket for readability
       via  28e1cae winbindd: cleanup client connection if the client closes the connection
       via  6da042d winbindd: set file descriptor limit according to configuration
      from  7105bd3 docs:smb.conf: fix typo in 'smb encrypt' text.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2c1c567ee1a59fa7bf09be0ed0554d2dc01cd0b9
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jul 13 21:42:57 2015 +0300

    winbindd: shorten client list scan
    
    Counting on the client list being sorted by last access time,
    the list scan for removing timed-out clients is shortened - once
    the list is scanned oldest to newest, and once a non-timed-out
    client is found, the scan can stop.
    
    Also, finding the oldest idle client for removing an idle client
    is simplified - oldest idle client is last idle client.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Jul 16 01:45:20 CEST 2015 on sn-devel-104

commit c10e24e1c77a7ec1e020e2b61900eff05daffa29
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jul 13 21:33:41 2015 +0300

    winbindd: keep client list sorted by access time
    
    Keep client list sorted by last access time, newest
    to oldest.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit f065100639cc31de03970d41ee82a3e0ddce9c2d
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jul 13 21:08:16 2015 +0300

    winbindd: add service routines to support a sorted client list
    
    Add some routines that support keeping the client list sorted
    (by last access time) and traversing the list from oldest to
    newest
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 03282bfd41a90a1c725d8831ee6ae7ccea07e6a2
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jul 6 12:13:15 2015 +0300

    doc: clarify "winbind max clients"
    
    Add clarification about the nature of "winbind max clients" parameter.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 33814c39b43fb2adbec5e5d8da90137c5990c59e
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jul 6 21:29:17 2015 +0300

    winbindd: periodically remove timed out clients
    
    Periodically scan winbind client list and close connections
    in which either the client is idle, or the request is taking
    too long to complete.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 5a6a4838f0870a7a48ead2f4e4f21760a026eb83
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Wed Jun 3 00:36:27 2015 +0300

    winbind client: avoid vicious cycle created by client retry
    
    This patch cancels the retry policy of the winbind client.
    
    When winbindd fails to respond to a request within 30 seconds,
    the winbind client closes the connection and retries up to 10
    times.
    
    In some cases, delayed response is a result of multiple
    requests from multiple clients piling up on the winbind domain
    child process. Retrying just piles more and more requests,
    creating a vicious cycle.
    
    Even in the case of a single request taking long to complete,
    there's no point in retrying because the retry request would just
    wait for the current request to complete. Better to wait patiently.
    
    There's one possible benefit in the retry, namely that winbindd typically
    caches the results, and therefore a retry might take a cached result, so
    the net effect of the retry may be to increase the timeout to 300 seconds.
    But a more straightforward way to have a 300 second timeout is to modify the
    timeout. Therefore the timeout is modified from 30 seconds to 300 seconds
    
    (IMHO 300 seconds is too much, but we have "winbind rquest timeout"
    with a default of 60 to make sure the request completes or fails
    within 60 seconds)
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 2a13740492f36b56a389bbe919850abcdc866030
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jun 25 10:12:37 2015 +0300

    winbindd: verify that client has closed the connection
    
    A recent change was to remove a client if the client socket
    has become readable. In this change, a check is added to
    determine the source of the readbility (actual readability,
    closed connection, or some other error), and a suitable
    debug message is printed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 0c6dc1ecf9ae615b19be412b4d80113296628420
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jun 25 09:46:24 2015 +0300

    async_req: check for errors when monitoring socket for readability
    
    Add an option to wait_for_read_send(), so that the request, upon
    calling back, report whether the socket actually contains data
    or is in EOF/error state. EOF is signalled via the EPIPE error.
    
    This is useful for clients which do not expect data to arrive but
    wait for readability to detect a closed socket (i.e. they do not
    intend to actually read the socket when it's readable). Actual data
    arrival would indicate a bug in this case, so the check can
    be used to print an error message.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 28e1cae4918213ba0cc7903a63d6200e69e5d1c7
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jun 25 08:59:20 2015 +0300

    winbindd: cleanup client connection if the client closes the connection
    
    This patch allows for early cleanup of client connections if the client
    has given up.
    Before this patch, any received request would be processed, and then only
    upon transmitting the result to the client would winbindd find out the
    client is no longer with us, possibly leading to a situation where the
    same client tries over and over and increases the number of client
    connections.
    
    This patch monitors the client socket for readability while the request
    is being processed, and closes the client connection if the socket
    becomes readable. The client is not supposed to be writing anything to
    the socket while it is waiting, so readability means either that the client
    has closed the connection, or that it has broken the protocol.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6da042d7c6e516cb9044f24f33df2a683c7de8fe
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jun 22 06:38:04 2015 +0300

    winbindd: set file descriptor limit according to configuration
    
    Set the winbindd process file descriptor limit according to
    the values that affect it in the configuration:
    - Maximum number of clients
    - Number of outgoing connections per domain
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/smbdotconf/winbind/winbindmaxclients.xml |   6 ++
 lib/async_req/async_sock.c                        |  45 +++++++-
 lib/async_req/async_sock.h                        |   4 +-
 nsswitch/wb_common.c                              |  26 ++---
 source3/include/local.h                           |   4 +
 source3/smbd/process.c                            |   4 +-
 source3/winbindd/winbindd.c                       | 120 ++++++++++++++++++++--
 source3/winbindd/winbindd_proto.h                 |   4 +
 source3/winbindd/winbindd_util.c                  |  24 +++++
 9 files changed, 202 insertions(+), 35 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/winbind/winbindmaxclients.xml b/docs-xml/smbdotconf/winbind/winbindmaxclients.xml
index d37ee25..c11d0b6 100644
--- a/docs-xml/smbdotconf/winbind/winbindmaxclients.xml
+++ b/docs-xml/smbdotconf/winbind/winbindmaxclients.xml
@@ -6,6 +6,12 @@
 	<para>This parameter specifies the maximum number of clients
 	the <citerefentry><refentrytitle>winbindd</refentrytitle>
 	<manvolnum>8</manvolnum></citerefentry> daemon can connect with.
+	The parameter is not a hard limit.
+	The <citerefentry><refentrytitle>winbindd</refentrytitle>
+	<manvolnum>8</manvolnum></citerefentry> daemon configures
+	itself to be able to accept at least that many connections,
+	and if the limit is reached, an attempt is made to disconnect
+	idle clients.
 	</para>
 </description>
 
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index d2cda15..bc3780c 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -534,6 +534,8 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 
 struct wait_for_read_state {
 	struct tevent_fd *fde;
+	int fd;
+	bool check_errors;
 };
 
 static void wait_for_read_cleanup(struct tevent_req *req,
@@ -544,8 +546,8 @@ static void wait_for_read_done(struct tevent_context *ev,
 			       void *private_data);
 
 struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
-				      struct tevent_context *ev,
-				      int fd)
+				      struct tevent_context *ev, int fd,
+				      bool check_errors)
 {
 	struct tevent_req *req;
 	struct wait_for_read_state *state;
@@ -562,6 +564,9 @@ struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
 	if (tevent_req_nomem(state->fde, req)) {
 		return tevent_req_post(req, ev);
 	}
+
+	state->fd = fd;
+	state->check_errors = check_errors;
 	return req;
 }
 
@@ -581,10 +586,44 @@ static void wait_for_read_done(struct tevent_context *ev,
 {
 	struct tevent_req *req = talloc_get_type_abort(
 		private_data, struct tevent_req);
+	struct wait_for_read_state *state =
+	    tevent_req_data(req, struct wait_for_read_state);
+	ssize_t nread;
+	char c;
 
-	if (flags & TEVENT_FD_READ) {
+	if ((flags & TEVENT_FD_READ) == 0) {
+		return;
+	}
+
+	if (!state->check_errors) {
 		tevent_req_done(req);
+		return;
 	}
+
+	nread = recv(state->fd, &c, 1, MSG_PEEK);
+
+	if (nread == 0) {
+		tevent_req_error(req, EPIPE);
+		return;
+	}
+
+	if ((nread == -1) && (errno == EINTR)) {
+		/* come back later */
+		return;
+	}
+
+	if ((nread == -1) && (errno == ENOTSOCK)) {
+		/* Ignore this specific error on pipes */
+		tevent_req_done(req);
+		return;
+	}
+
+	if (nread == -1) {
+		tevent_req_error(req, errno);
+		return;
+	}
+
+	tevent_req_done(req);
 }
 
 bool wait_for_read_recv(struct tevent_req *req, int *perr)
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index 1b76fab..abbf822 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -53,8 +53,8 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 			 uint8_t **pbuf, int *perrno);
 
 struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
-				      struct tevent_context *ev,
-				      int fd);
+				      struct tevent_context *ev, int fd,
+				      bool check_errors);
 bool wait_for_read_recv(struct tevent_req *req, int *perr);
 
 #endif
diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
index 3194df1..139f010 100644
--- a/nsswitch/wb_common.c
+++ b/nsswitch/wb_common.c
@@ -535,7 +535,7 @@ static int winbind_read_sock(struct winbindd_context *ctx,
 
 		if (ret == 0) {
 			/* Not ready for read yet... */
-			if (total_time >= 30) {
+			if (total_time >= 300) {
 				/* Timeout */
 				winbind_close_sock(ctx);
 				return -1;
@@ -719,20 +719,16 @@ NSS_STATUS winbindd_request_response(struct winbindd_context *ctx,
 				     struct winbindd_response *response)
 {
 	NSS_STATUS status = NSS_STATUS_UNAVAIL;
-	int count = 0;
 	struct winbindd_context *wb_ctx = ctx;
 
 	if (ctx == NULL) {
 		wb_ctx = &wb_global_ctx;
 	}
 
-	while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
-		status = winbindd_send_request(wb_ctx, req_type, 0, request);
-		if (status != NSS_STATUS_SUCCESS)
-			return(status);
-		status = winbindd_get_response(wb_ctx, response);
-		count += 1;
-	}
+	status = winbindd_send_request(wb_ctx, req_type, 0, request);
+	if (status != NSS_STATUS_SUCCESS)
+		return (status);
+	status = winbindd_get_response(wb_ctx, response);
 
 	return status;
 }
@@ -743,20 +739,16 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx,
 					  struct winbindd_response *response)
 {
 	NSS_STATUS status = NSS_STATUS_UNAVAIL;
-	int count = 0;
 	struct winbindd_context *wb_ctx = ctx;
 
 	if (ctx == NULL) {
 		wb_ctx = &wb_global_ctx;
 	}
 
-	while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
-		status = winbindd_send_request(wb_ctx, req_type, 1, request);
-		if (status != NSS_STATUS_SUCCESS)
-			return(status);
-		status = winbindd_get_response(wb_ctx, response);
-		count += 1;
-	}
+	status = winbindd_send_request(wb_ctx, req_type, 1, request);
+	if (status != NSS_STATUS_SUCCESS)
+		return (status);
+	status = winbindd_get_response(wb_ctx, response);
 
 	return status;
 }
diff --git a/source3/include/local.h b/source3/include/local.h
index 5963eb0..7f97d4e 100644
--- a/source3/include/local.h
+++ b/source3/include/local.h
@@ -204,4 +204,8 @@
 /* Maximum size of RPC data we will accept for one call. */
 #define MAX_RPC_DATA_SIZE (15*1024*1024)
 
+/* A guestimate of how many domains winbindd will be contacting */
+#ifndef WINBIND_MAX_DOMAINS_HINT
+#define WINBIND_MAX_DOMAINS_HINT 10
+#endif
 #endif
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 12ce0d1..6c8a31c 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2859,7 +2859,7 @@ static struct tevent_req *smbd_echo_read_send(
 	state->ev = ev;
 	state->xconn = xconn;
 
-	subreq = wait_for_read_send(state, ev, xconn->transport.sock);
+	subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -2934,7 +2934,7 @@ static void smbd_echo_read_waited(struct tevent_req *subreq)
 		}
 
 		subreq = wait_for_read_send(state, state->ev,
-					    xconn->transport.sock);
+					    xconn->transport.sock, false);
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 4ffe79c..c878ce2 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -42,12 +42,16 @@
 #include "source4/lib/messaging/irpc.h"
 #include "source4/lib/messaging/messaging.h"
 #include "lib/param/param.h"
+#include "lib/async_req/async_sock.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
+#define SCRUB_CLIENTS_INTERVAL 5
+
 static bool client_is_idle(struct winbindd_cli_state *state);
 static void remove_client(struct winbindd_cli_state *state);
+static void winbindd_setup_max_fds(void);
 
 static bool opt_nocache = False;
 static bool interactive = False;
@@ -145,6 +149,7 @@ static bool reload_services_file(const char *lfile)
 
 	reopen_logs();
 	load_interfaces();
+	winbindd_setup_max_fds();
 
 	return(ret);
 }
@@ -696,7 +701,8 @@ static void process_request(struct winbindd_cli_state *state)
 
 	state->cmd_name = "unknown request";
 	state->recv_fn = NULL;
-	state->last_access = time(NULL);
+	/* client is newest */
+	winbindd_promote_client(state);
 
 	/* Process command */
 
@@ -807,11 +813,15 @@ static void request_finished(struct winbindd_cli_state *state);
 
 static void winbind_client_request_read(struct tevent_req *req);
 static void winbind_client_response_written(struct tevent_req *req);
+static void winbind_client_activity(struct tevent_req *req);
 
 static void request_finished(struct winbindd_cli_state *state)
 {
 	struct tevent_req *req;
 
+	/* free client socket monitoring request */
+	TALLOC_FREE(state->io_req);
+
 	TALLOC_FREE(state->request);
 
 	req = wb_resp_write_send(state, winbind_event_context(),
@@ -921,8 +931,6 @@ static void new_connection(int listen_sock, bool privileged)
 		return;
 	}
 
-	state->last_access = time(NULL);	
-
 	state->privileged = privileged;
 
 	req = wb_req_read_send(state, winbind_event_context(), state->sock,
@@ -964,9 +972,53 @@ static void winbind_client_request_read(struct tevent_req *req)
 		remove_client(state);
 		return;
 	}
+
+	req = wait_for_read_send(state, winbind_event_context(), state->sock,
+				 true);
+	if (req == NULL) {
+		DEBUG(0, ("winbind_client_request_read[%d:%s]:"
+			  " wait_for_read_send failed - removing client\n",
+			  (int)state->pid, state->cmd_name));
+		remove_client(state);
+		return;
+	}
+	tevent_req_set_callback(req, winbind_client_activity, state);
+	state->io_req = req;
+
 	process_request(state);
 }
 
+static void winbind_client_activity(struct tevent_req *req)
+{
+	struct winbindd_cli_state *state =
+	    tevent_req_callback_data(req, struct winbindd_cli_state);
+	int err;
+	bool has_data;
+
+	has_data = wait_for_read_recv(req, &err);
+
+	if (has_data) {
+		DEBUG(0, ("winbind_client_activity[%d:%s]:"
+			  "unexpected data from client - removing client\n",
+			  (int)state->pid, state->cmd_name));
+	} else {
+		if (err == EPIPE) {
+			DEBUG(6, ("winbind_client_activity[%d:%s]: "
+				  "client has closed connection - removing "
+				  "client\n",
+				  (int)state->pid, state->cmd_name));
+		} else {
+			DEBUG(2, ("winbind_client_activity[%d:%s]: "
+				  "client socket error (%s) - removing "
+				  "client\n",
+				  (int)state->pid, state->cmd_name,
+				  strerror(err)));
+		}
+	}
+
+	remove_client(state);
+}
+
 /* Remove a client connection from client connection list */
 
 static void remove_client(struct winbindd_cli_state *state)
@@ -1034,16 +1086,13 @@ static bool client_is_idle(struct winbindd_cli_state *state) {
 static bool remove_idle_client(void)
 {
 	struct winbindd_cli_state *state, *remove_state = NULL;
-	time_t last_access = 0;
 	int nidle = 0;
 
 	for (state = winbindd_client_list(); state; state = state->next) {
 		if (client_is_idle(state)) {
 			nidle++;
-			if (!last_access || state->last_access < last_access) {
-				last_access = state->last_access;
-				remove_state = state;
-			}
+			/* list is sorted by access time */
+			remove_state = state;
 		}
 	}
 
@@ -1065,14 +1114,14 @@ static bool remove_idle_client(void)
 
 static void remove_timed_out_clients(void)
 {
-	struct winbindd_cli_state *state, *next = NULL;
+	struct winbindd_cli_state *state, *prev = NULL;
 	time_t curr_time = time(NULL);
 	int timeout_val = lp_winbind_request_timeout();
 
-	for (state = winbindd_client_list(); state; state = next) {
+	for (state = winbindd_client_list_tail(); state; state = prev) {
 		time_t expiry_time;
 
-		next = state->next;
+		prev = winbindd_client_list_prev(state);
 		expiry_time = state->last_access + timeout_val;
 
 		if (curr_time > expiry_time) {
@@ -1088,10 +1137,28 @@ static void remove_timed_out_clients(void)
 					(unsigned int)state->pid));
 			}
 			remove_client(state);
+		} else {
+			/* list is sorted, previous clients in
+			   list are newer */
+			break;
 		}
 	}
 }
 
+static void winbindd_scrub_clients_handler(struct tevent_context *ev,
+					   struct tevent_timer *te,
+					   struct timeval current_time,
+					   void *private_data)
+{
+	remove_timed_out_clients();
+	if (tevent_add_timer(ev, ev,
+			     timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
+			     winbindd_scrub_clients_handler, NULL) == NULL) {
+		DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
+		exit(1);
+	}
+}
+
 struct winbindd_listen_state {
 	bool privileged;
 	int fd;
@@ -1130,6 +1197,35 @@ char *get_winbind_priv_pipe_dir(void)
 	return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
 }
 
+static void winbindd_setup_max_fds(void)
+{
+	int num_fds = MAX_OPEN_FUDGEFACTOR;
+	int actual_fds;
+
+	num_fds += lp_winbind_max_clients();
+	/* Add some more to account for 2 sockets open
+	   when the client transitions from unprivileged
+	   to privileged socket
+	*/
+	num_fds += lp_winbind_max_clients() / 10;
+
+	/* Add one socket per child process
+	   (yeah there are child processes other than the
+	   domain children but only domain children can vary
+	   with configuration
+	*/
+	num_fds += lp_winbind_max_domain_connections() *
+		   (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
+
+	actual_fds = set_maxfiles(num_fds);
+
+	if (actual_fds < num_fds) {
+		DEBUG(1, ("winbindd_setup_max_fds: Information only: "
+			  "requested %d open files, %d are available.\n",
+			  num_fds, actual_fds));
+	}
+}
+
 static bool winbindd_setup_listeners(void)
 {
 	struct winbindd_listen_state *pub_state = NULL;
@@ -1196,6 +1292,8 @@ static bool winbindd_setup_listeners(void)
 	}
 	tevent_fd_set_auto_close(fde);
 
+	winbindd_scrub_clients_handler(winbind_event_context(), NULL,
+				       timeval_current(), NULL);
 	return true;
 failed:
 	TALLOC_FREE(pub_state);
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 5ad69e2..9920a3f 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -430,8 +430,12 @@ char *fill_domain_username_talloc(TALLOC_CTX *ctx,
 				  const char *user,
 				  bool can_assume);
 struct winbindd_cli_state *winbindd_client_list(void);
+struct winbindd_cli_state *winbindd_client_list_tail(void);
+struct winbindd_cli_state *
+winbindd_client_list_prev(struct winbindd_cli_state *cli);
 void winbindd_add_client(struct winbindd_cli_state *cli);
 void winbindd_remove_client(struct winbindd_cli_state *cli);
+void winbindd_promote_client(struct winbindd_cli_state *cli);
 int winbindd_num_clients(void);
 NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
 				  TALLOC_CTX *mem_ctx,
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index d73327c..233b5c9 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -1206,10 +1206,26 @@ struct winbindd_cli_state *winbindd_client_list(void)
 	return _client_list;
 }
 
+/* Return list-tail of all connected clients */
+
+struct winbindd_cli_state *winbindd_client_list_tail(void)
+{
+	return DLIST_TAIL(_client_list);
+}
+
+/* Return previous (read:newer) client in list */
+
+struct winbindd_cli_state *
+winbindd_client_list_prev(struct winbindd_cli_state *cli)
+{
+	return DLIST_PREV(cli);
+}
+
 /* Add a connection to the list */
 
 void winbindd_add_client(struct winbindd_cli_state *cli)
 {
+	cli->last_access = time(NULL);
 	DLIST_ADD(_client_list, cli);
 	_num_clients++;
 }
@@ -1222,6 +1238,14 @@ void winbindd_remove_client(struct winbindd_cli_state *cli)
 	_num_clients--;
 }
 
+/* Move a client to head or list */
+
+void winbindd_promote_client(struct winbindd_cli_state *cli)
+{
+	cli->last_access = time(NULL);
+	DLIST_PROMOTE(_client_list, cli);
+}
+
 /* Return number of open clients */


-- 
Samba Shared Repository



More information about the samba-cvs mailing list