From 68694369fc96354452979b07425f3f48c4f73bbe Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:09:48 +0300 Subject: Merge CTDB-related fixes from samba-ctdb 3.0 branch (http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 0c8e23afbbb2d081fc23908bafcad04650bfacea) --- source3/smbd/connection.c | 9 ++++++ source3/smbd/oplock_linux.c | 22 +++++++++++---- source3/smbd/server.c | 67 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 9 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 016c8adb1b..d7063c9989 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -117,6 +117,15 @@ int count_current_connections( const char *sharename, bool clear ) return cs.curr_connections; } +/**************************************************************************** + Count the number of connections open across all shares. +****************************************************************************/ + +int count_all_current_connections(void) +{ + return count_current_connections(NULL, True /* clear stale entries */); +} + /**************************************************************************** Claim an entry in the connections database. ****************************************************************************/ diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index 05021b6c74..fa7cb42bc6 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -93,17 +93,27 @@ static void set_capability(unsigned capability) return; } - data.effective |= (1< 0) { - remove_child_pid(pid); + while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) { + bool unclean_shutdown = False; + + /* If the child terminated normally, assume + it was an unclean shutdown unless the + status is 0 + */ + if (WIFEXITED(status)) { + unclean_shutdown = WEXITSTATUS(status); + } + /* If the child terminated due to a signal + we always assume it was unclean. + */ + if (WIFSIGNALED(status)) { + unclean_shutdown = True; + } + remove_child_pid(pid, unclean_shutdown); } } @@ -603,6 +630,15 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ continue; } + + + /* If the idle timeout fired and we don't have any connected + * users, exit gracefully. We should be running under a process + * controller that will restart us if necessry. + */ + if (num == 0 && count_all_current_connections() == 0) { + exit_server_cleanly("idle timeout"); + } /* process pending nDNS responses */ if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) { @@ -906,6 +942,29 @@ void exit_server_fault(void) exit_server("critical server fault"); } + +/**************************************************************************** +received when we should release a specific IP +****************************************************************************/ +static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data, + uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) +{ + const char *ip = (const char *)data->data; + char addr[INET6_ADDRSTRLEN]; + + if (strcmp(client_socket_addr(get_client_fd(),addr,sizeof(addr)), ip) == 0) { + /* we can't afford to do a clean exit - that involves + database writes, which would potentially mean we + are still running after the failover has finished - + we have to get rid of this process ID straight + away */ + DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n", + ip)); + _exit(0); + } +} + + /**************************************************************************** Initialise connect, service and file structs. ****************************************************************************/ @@ -1305,6 +1364,8 @@ extern void build_options(bool screen); /* register our message handlers */ messaging_register(smbd_messaging_context(), NULL, MSG_SMB_FORCE_TDIS, msg_force_tdis); + messaging_register(smbd_messaging_context(), NULL, + MSG_SMB_RELEASE_IP, msg_release_ip); if ((lp_keepalive() != 0) && !(event_add_idle(smbd_event_context(), NULL, -- cgit