From 71d0887f2c91dc7eea9a0571f2803361513cfcfb Mon Sep 17 00:00:00 2001 From: Ravindra GC Date: Fri, 2 May 2014 13:01:49 +0530 Subject: [PATCH] Cleanup idle winbindd processes --- .../winbind/winbindidlechildcleanupinterval.xml | 16 +++++ lib/param/param_table.c | 9 +++ source3/param/loadparm.c | 1 + source3/winbindd/winbindd.c | 10 ++++ source3/winbindd/winbindd.h | 2 + source3/winbindd/winbindd_dual.c | 1 + source3/winbindd/winbindd_proto.h | 2 + source3/winbindd/winbindd_util.c | 62 ++++++++++++++++++++ 8 files changed, 103 insertions(+) create mode 100644 docs-xml/smbdotconf/winbind/winbindidlechildcleanupinterval.xml diff --git a/docs-xml/smbdotconf/winbind/winbindidlechildcleanupinterval.xml b/docs-xml/smbdotconf/winbind/winbindidlechildcleanupinterval.xml new file mode 100644 index 0000000..6dffea3 --- /dev/null +++ b/docs-xml/smbdotconf/winbind/winbindidlechildcleanupinterval.xml @@ -0,0 +1,16 @@ + + + This parameter specifies the interval (in seconds) for idle + winbindd + 8 processes cleanup handler. + Value of 0 implies cleanup handler is disabled. + + + +0 +120 + diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 8df7d1b..83bcf45 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -4163,6 +4163,15 @@ static struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { + .label = "winbind idle child cleanup interval", + .type = P_INTEGER, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(winbind_idle_child_cleanup_interval), + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { .label = "winbindd socket directory", .type = P_STRING, .p_class = P_GLOBAL, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 8006167..d291fdb 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -861,6 +861,7 @@ static void init_globals(bool reinit_globals) Globals.log_writeable_files_on_exit = false; Globals.create_krb5_conf = true; Globals.winbindMaxDomainConnections = 1; + Globals.winbind_idle_child_cleanup_interval = 0; /* hostname lookups can be very expensive and are broken on a large number of sites (tridge) */ diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 937f68d..dc80c78 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1216,6 +1216,16 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx, } } + DEBUG(10, ("winbind idle cleanup timer = %d\n", lp_winbind_idle_child_cleanup_interval())); + if (lp_winbind_idle_child_cleanup_interval() > 0) { + if (tevent_add_timer(winbind_event_context(), NULL, + timeval_current_ofs(lp_winbind_idle_child_cleanup_interval(),0), + cleanup_idle_winbindd_child, NULL) == NULL) + { + DEBUG(10, ("Could not add cleanup_idle_winbindd_child()\n")); + } + } + } struct winbindd_addrchanged_state { diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 8f89e27..45a25b1 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -138,6 +138,8 @@ struct winbindd_child { pid_t pid; struct winbindd_domain *domain; char *logfilename; + /* time since this child is idle */ + time_t idle_since; int sock; struct tevent_queue *queue; diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index de254e9..951b1af 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1397,6 +1397,7 @@ static bool fork_domain_child(struct winbindd_child *child) state.cli.pid = getpid(); state.cli.request = &request; state.cli.response = &response; + child->idle_since = 0; child->pid = fork(); diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 33a7082..e5b4d58 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -394,6 +394,8 @@ struct winbindd_domain *domain_list(void); bool domain_is_forest_root(const struct winbindd_domain *domain); void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *private_data); +void cleanup_idle_winbindd_child(struct tevent_context *ev, struct tevent_timer *te, + struct timeval now, void *private_data); enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, struct winbindd_cli_state *state); bool init_domain_list(void); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index a00fe14..4bfb6fe 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -563,6 +563,68 @@ void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, return; } +void cleanup_idle_winbindd_child(struct tevent_context *ev, struct tevent_timer *te, + struct timeval now, void *private_data) + +{ + struct winbindd_domain *domain; + int i=0; + + TALLOC_FREE(te); + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + for (i=0; ichildren[i]; + + if (!child || ((child->pid) <= 1) || (child->domain==NULL)) { + + continue; + } + + if (tevent_queue_length(child->queue) > 0) { + child->idle_since = 0; + DEBUG(10, ("cleanup_idle_winbindd_child: child(%d)(%s) still busy\n", + (int)child->pid, child->domain->name)); + + continue; + } + + if (child->idle_since == 0) { + child->idle_since = time_mono(NULL); + continue; + } + + /* exit the child only if it is idle continuosly for 1 min*/ + if (time_mono(NULL) < (child->idle_since + 60)) { + DEBUG(10, ("cleanup_idle_winbindd_child: child(%d)(%s) not idle enough \n", + (int)child->pid, child->domain->name)); + continue; + } + + DEBUG(10, ("cleanup_idle_winbindd_child: exit child (%d)(%s) \n", + (int)child->pid, child->domain->name)); + + /* signal child to exit */ + kill(child->pid, SIGTERM); + } + } + + /* + no need to check if lp_winbind_idle_child_cleanup_interval() is > 0 + because that check is done in initial setup of the handler in winbindd.c + */ + + if (tevent_add_timer(winbind_event_context(), NULL, + timeval_current_ofs(lp_winbind_idle_child_cleanup_interval(),0), + cleanup_idle_winbindd_child, NULL) == NULL) + { + DEBUG(10, ("Could not add cleanup_idle_winbindd_child()\n")); + } + +} + + enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, struct winbindd_cli_state *state) { -- 1.7.9.5