diff options
author | Alexander Bokovoy <ab@samba.org> | 2008-01-16 12:09:48 +0300 |
---|---|---|
committer | Alexander Bokovoy <ab@samba.org> | 2008-01-16 12:09:48 +0300 |
commit | 68694369fc96354452979b07425f3f48c4f73bbe (patch) | |
tree | 6f4f9870ad48babe85c26af0b86d143e446a0cfe /source3/smbd | |
parent | f426949e8861b3a97d321516edbcbd771b7d6273 (diff) | |
download | samba-68694369fc96354452979b07425f3f48c4f73bbe.tar.gz samba-68694369fc96354452979b07425f3f48c4f73bbe.tar.bz2 samba-68694369fc96354452979b07425f3f48c4f73bbe.zip |
Merge CTDB-related fixes from samba-ctdb 3.0 branch (http://samba.org/~tridge/3_0-ctdb)
Signed-off-by: Alexander Bokovoy <ab@samba.org>(This used to be commit 0c8e23afbbb2d081fc23908bafcad04650bfacea)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/connection.c | 9 | ||||
-rw-r--r-- | source3/smbd/oplock_linux.c | 22 | ||||
-rw-r--r-- | source3/smbd/server.c | 67 |
3 files changed, 89 insertions, 9 deletions
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 @@ -118,6 +118,15 @@ int count_current_connections( const char *sharename, bool clear ) } /**************************************************************************** + 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<<capability); + if (0 == (data.effective & (1<<capability))) { + data.effective |= (1<<capability); - if (capset(&header, &data) == -1) { - DEBUG(3,("Unable to set %d capability (%s)\n", - capability, strerror(errno))); + if (capset(&header, &data) == -1) { + DEBUG(3,("Unable to set %d capability (%s)\n", + capability, strerror(errno))); + } } } /* - Call to set the kernel lease signal handler -*/ + * public function to get linux lease capability. Needed by some VFS modules (eg. gpfs.c) + */ +void linux_set_lease_capability(void) +{ + set_capability(CAP_LEASE); +} + +/* + * Call to set the kernel lease signal handler + */ int linux_set_lease_sighandler(int fd) { if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) { diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 8371d17f10..db241103ed 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -268,10 +268,20 @@ static void add_child_pid(pid_t pid) num_children += 1; } -static void remove_child_pid(pid_t pid) +static void remove_child_pid(pid_t pid, bool unclean_shutdown) { struct child_pid *child; + if (unclean_shutdown) { + /* a child terminated uncleanly so tickle all processes to see + if they can grab any of the pending locks + */ + messaging_send_buf(smbd_messaging_context(), procid_self(), + MSG_SMB_BRL_VALIDATE, NULL, 0); + message_send_all(smbd_messaging_context(), + MSG_SMB_UNLOCK, NULL, 0, NULL); + } + if (lp_max_smbd_processes() == 0) { /* Don't bother with the child list if we don't care anyway */ return; @@ -560,10 +570,27 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ if (got_sig_cld) { pid_t pid; + int status; + got_sig_cld = False; - while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 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, |