diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-04-24 04:11:27 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-04-24 04:11:27 +0000 |
commit | a67b5ac62fcd3e8bcef668a29094635a548e5744 (patch) | |
tree | a8a4ef1f3231dbfb0422620c8cae5b891a0c1339 /source3/nsswitch | |
parent | 27173b205f05aebd9226fa43fc40424bf8e79a72 (diff) | |
download | samba-a67b5ac62fcd3e8bcef668a29094635a548e5744.tar.gz samba-a67b5ac62fcd3e8bcef668a29094635a548e5744.tar.bz2 samba-a67b5ac62fcd3e8bcef668a29094635a548e5744.zip |
a new "dual daemon" operating mode for winbindd
this mode improves the response time of winbindd by having a
background process update the cache while the forground process
responds to queries from cache.
You can enable this mode using the -B command line option. It is quite
experimental, which is why it is not the default.
(This used to be commit c0feff97eefdf5a70e5973e247b395dbdf5d2ef2)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd.c | 135 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 16 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_proto.h | 10 |
3 files changed, 112 insertions, 49 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 479be79574..b198b4a163 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -4,6 +4,7 @@ Winbind daemon for ntdom nss module Copyright (C) by Tim Potter 2000, 2001 + Copyright (C) Andrew Tridgell 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,7 +27,8 @@ struct winbindd_cli_state *client_list; static int num_clients; -BOOL opt_nocache; +BOOL opt_nocache = False; +BOOL opt_dual_daemon = False; /* Reload configuration */ @@ -365,9 +367,10 @@ static void remove_client(struct winbindd_cli_state *state) } } + /* Process a complete received packet from a client */ -static void process_packet(struct winbindd_cli_state *state) +void winbind_process_packet(struct winbindd_cli_state *state) { /* Process request */ @@ -379,11 +382,16 @@ static void process_packet(struct winbindd_cli_state *state) state->read_buf_len = 0; state->write_buf_len = sizeof(struct winbindd_response); + + /* we might need to send it to the dual daemon */ + if (opt_dual_daemon) { + dual_send_request(state); + } } /* Read some data from a client connection */ -static void client_read(struct winbindd_cli_state *state) +void winbind_client_read(struct winbindd_cli_state *state) { int n; @@ -397,8 +405,11 @@ static void client_read(struct winbindd_cli_state *state) } while (n == -1 && errno == EINTR); + DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len )); + + /* Read failed, kill client */ + if (n == -1 || n == 0) { - /* Read failed, kill client */ DEBUG(5,("read failed on sock %d, pid %d: %s\n", state->sock, state->pid, (n == -1) ? strerror(errno) : "EOF")); @@ -407,8 +418,6 @@ static void client_read(struct winbindd_cli_state *state) return; } - DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len )); - /* Update client state */ state->read_buf_len += n; @@ -528,6 +537,10 @@ static void process_loop(int accept_sock) timeout.tv_sec = WINBINDD_ESTABLISH_LOOP; timeout.tv_usec = 0; + if (opt_dual_daemon) { + maxfd = dual_select_setup(&w_fds, maxfd); + } + /* Set up client readers and writers */ state = client_list; @@ -582,6 +595,10 @@ static void process_loop(int accept_sock) if (selret > 0) { + if (opt_dual_daemon) { + dual_select(&w_fds); + } + if (FD_ISSET(accept_sock, &r_fds)) new_connection(accept_sock); @@ -595,7 +612,7 @@ static void process_loop(int accept_sock) /* Read data */ - client_read(state); + winbind_client_read(state); /* * If we have the start of a @@ -619,7 +636,7 @@ static void process_loop(int accept_sock) if (state->read_buf_len == sizeof(state->request)) { - process_packet(state); + winbind_process_packet(state); } } @@ -655,6 +672,57 @@ static void process_loop(int accept_sock) } } + +/* + these are split out from the main winbindd for use by the background daemon + */ +int winbind_setup_common(void) +{ + load_interfaces(); + + secrets_init(); + + /* Get list of domains we look up requests for. This includes the + domain which we are a member of as well as any trusted + domains. */ + + init_domain_list(); + + ZERO_STRUCT(server_state); + + /* Winbind daemon initialisation */ + + if (!winbindd_param_init()) + return 1; + + if (!winbindd_idmap_init()) + return 1; + + /* Unblock all signals we are interested in as they may have been + blocked by the parent process. */ + + BlockSignals(False, SIGINT); + BlockSignals(False, SIGQUIT); + BlockSignals(False, SIGTERM); + BlockSignals(False, SIGUSR1); + BlockSignals(False, SIGUSR2); + BlockSignals(False, SIGHUP); + + /* Setup signal handlers */ + + CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */ + CatchSignal(SIGQUIT, termination_handler); + CatchSignal(SIGTERM, termination_handler); + + CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ + + CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */ + CatchSignal(SIGHUP, sighup_handler); + + return 0; +} + + /* Main function */ struct winbindd_state server_state; /* Server state information */ @@ -664,6 +732,7 @@ static void usage(void) { printf("Usage: winbindd [options]\n"); printf("\t-i interactive mode\n"); + printf("\t-B dual daemon mode\n"); printf("\t-n disable cacheing\n"); printf("\t-d level set debug level\n"); printf("\t-s configfile choose smb.conf location\n"); @@ -708,7 +777,7 @@ int main(int argc, char **argv) /* Initialise samba/rpc client stuff */ - while ((opt = getopt(argc, argv, "id:s:nh")) != EOF) { + while ((opt = getopt(argc, argv, "id:s:nhB")) != EOF) { switch (opt) { /* Don't become a daemon */ @@ -716,6 +785,11 @@ int main(int argc, char **argv) interactive = True; break; + /* dual daemon system */ + case 'B': + opt_dual_daemon = True; + break; + /* disable cacheing */ case 'n': opt_nocache = True; @@ -782,46 +856,13 @@ int main(int argc, char **argv) setpgid( (pid_t)0, (pid_t)0); #endif - load_interfaces(); - - secrets_init(); - - /* Get list of domains we look up requests for. This includes the - domain which we are a member of as well as any trusted - domains. */ - - init_domain_list(); - - ZERO_STRUCT(server_state); - - /* Winbind daemon initialisation */ - - if (!winbindd_param_init()) - return 1; + if (opt_dual_daemon) { + do_dual_daemon(); + } - if (!winbindd_idmap_init()) + if (winbind_setup_common() != 0) { return 1; - - /* Unblock all signals we are interested in as they may have been - blocked by the parent process. */ - - BlockSignals(False, SIGINT); - BlockSignals(False, SIGQUIT); - BlockSignals(False, SIGTERM); - BlockSignals(False, SIGUSR1); - BlockSignals(False, SIGUSR2); - BlockSignals(False, SIGHUP); - - /* Setup signal handlers */ - - CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */ - CatchSignal(SIGQUIT, termination_handler); - CatchSignal(SIGTERM, termination_handler); - - CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ - - CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */ - CatchSignal(SIGHUP, sighup_handler); + } /* Initialise messaging system */ diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 9bd95fdd86..f65705e0fb 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -51,7 +51,7 @@ void wcache_flush_cache(void) if (opt_nocache) return; wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, - TDB_DEFAULT, O_RDWR | O_CREAT | O_TRUNC, 0600); + TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600); if (!wcache->tdb) { DEBUG(0,("Failed to open winbindd_cache.tdb!\n")); @@ -205,11 +205,17 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force) { NTSTATUS status; unsigned time_diff; + unsigned cache_time = lp_winbind_cache_time(); + + /* trying to reconnect is expensive, don't do it too often */ + if (domain->sequence_number == DOM_SEQUENCE_NONE) { + cache_time *= 8; + } time_diff = time(NULL) - domain->last_seq_check; /* see if we have to refetch the domain sequence number */ - if (!force && (time_diff < lp_winbind_cache_time())) { + if (!force && (time_diff < cache_time)) { return; } @@ -289,9 +295,15 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache, centry->sequence_number = centry_uint32(centry); if (centry_expired(domain, centry)) { + extern BOOL opt_dual_daemon; + if (opt_dual_daemon) { + extern BOOL backgroud_process; + backgroud_process = True; + } else { centry_free(centry); return NULL; } + } return centry; } diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index f3830cd63c..8cac542b88 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -6,6 +6,9 @@ /* The following definitions come from nsswitch/winbindd.c */ +void winbind_process_packet(struct winbindd_cli_state *state); +void winbind_client_read(struct winbindd_cli_state *state); +int winbind_setup_common(void); int main(int argc, char **argv); /* The following definitions come from nsswitch/winbindd_ads.c */ @@ -39,6 +42,13 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, struct cli_state **cli); void winbindd_cm_status(void); +/* The following definitions come from nsswitch/winbindd_dual.c */ + +int dual_select_setup(fd_set *fds, int maxfd); +void dual_select(fd_set *fds); +void dual_send_request(struct winbindd_cli_state *state); +void do_dual_daemon(void); + /* The following definitions come from nsswitch/winbindd_group.c */ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state); |