Regarding Bug 3204 - winbindd: Exceeding 200 client connections, no idle connection found
Jeremy Allison
jra at samba.org
Fri Jul 18 23:44:22 MDT 2014
On Fri, Jul 18, 2014 at 12:09:47PM -0700, Jeremy Allison wrote:
>
> Ok, as this went to samba-technical here is a (test) patch
> for 3.6.x only that attempts to fix this bug.
>
> It adds a new [global] parameter:
>
> winbind request timeout
>
> default value of 60 (seconds). What it does is terminate every client
> connection that has either remained idle for 60 seconds, or has not replied
> within 60 seconds. Initially I worried this was a little aggressive, but I
> don't think so - if a request has take > 60 seconds it's almost certainly dead,
> and pruning idle clients after 60 seconds is also probably ok. Also it's
> tuneable :-).
>
> If this works for people I can forward port to 4.1.next and 4.0.next.
>
> It's also added to the bug report.
>
> Let me know if it helps !
And here is a (fixed) version of the patch
that gets the timeout calculations right
(and slightly rewritten to make those
calculations more clear :-).
Timeout calculations are tricky :-).
Also replaced the old bad patch in the bug
report.
Jeremy.
-------------- next part --------------
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 7303e76..9ef3517 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1696,6 +1696,7 @@ char lp_magicchar(const struct share_params *p );
int lp_winbind_cache_time(void);
int lp_winbind_reconnect_delay(void);
int lp_winbind_max_clients(void);
+int lp_winbind_request_timeout(void);
const char **lp_winbind_nss_info(void);
int lp_algorithmic_rid_base(void);
int lp_name_cache_timeout(void);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index dd63339..c4b3191 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -266,6 +266,7 @@ struct global {
int winbind_cache_time;
int winbind_reconnect_delay;
int winbind_max_clients;
+ int winbind_request_timeout;
char **szWinbindNssInfo;
int iLockSpinTime;
char *szLdapMachineSuffix;
@@ -4772,6 +4773,15 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
+ .label = "winbind request timeout",
+ .type = P_INTEGER,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.winbind_request_timeout,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
+ {
.label = "create krb5 conf",
.type = P_BOOL,
.p_class = P_GLOBAL,
@@ -5435,6 +5445,7 @@ static void init_globals(bool reinit_globals)
Globals.winbind_cache_time = 300; /* 5 minutes */
Globals.winbind_reconnect_delay = 30; /* 30 seconds */
Globals.winbind_max_clients = 200;
+ Globals.winbind_request_timeout = 60; /* 60 seconds */
Globals.bWinbindEnumUsers = False;
Globals.bWinbindEnumGroups = False;
Globals.bWinbindUseDefaultDomain = False;
@@ -6052,6 +6063,7 @@ FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
+FN_GLOBAL_INTEGER(lp_winbind_request_timeout, &Globals.winbind_request_timeout)
FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index f447059..5f84685 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -923,6 +923,41 @@ static bool remove_idle_client(void)
return False;
}
+/*
+ * Terminate all clients whose requests have taken longer than
+ * "winbind request timeout" seconds to process, or have been
+ * idle for more than "winbind request timeout" seconds.
+ */
+
+static void remove_timed_out_clients(void)
+{
+ struct winbindd_cli_state *state, *next = NULL;
+ time_t curr_time = time(NULL);
+ int timeout_val = lp_winbind_request_timeout();
+
+ for (state = winbindd_client_list(); state; state = next) {
+ time_t expiry_time;
+
+ next = state->next;
+ expiry_time = state->last_access + timeout_val;
+
+ if (curr_time > expiry_time) {
+ if (client_is_idle(state)) {
+ DEBUG(5,("Idle client timed out, "
+ "shutting down sock %d, pid %u\n",
+ state->sock,
+ (unsigned int)state->pid));
+ } else {
+ DEBUG(5,("Client request timed out, "
+ "shutting down sock %d, pid %u\n",
+ state->sock,
+ (unsigned int)state->pid));
+ }
+ remove_client(state);
+ }
+ }
+}
+
struct winbindd_listen_state {
bool privileged;
int fd;
@@ -948,6 +983,7 @@ static void winbindd_listen_fde_handler(struct tevent_context *ev,
break;
}
}
+ remove_timed_out_clients();
new_connection(s->fd, s->privileged);
}
More information about the samba-technical
mailing list