diff options
author | Jeremy Allison <jra@samba.org> | 2008-03-06 17:43:25 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-03-06 17:43:25 -0800 |
commit | 5440c752ff270cc674d46f2dfa2ceb47dac030f6 (patch) | |
tree | 257f05b1188e806d6b340bb65ea7d1ff12f5f060 /source/nmbd | |
parent | 7c3550f82c51ce173b13e568762f728ecb881e85 (diff) | |
download | samba-5440c752ff270cc674d46f2dfa2ceb47dac030f6.tar.gz samba-5440c752ff270cc674d46f2dfa2ceb47dac030f6.tar.xz samba-5440c752ff270cc674d46f2dfa2ceb47dac030f6.zip |
Fix bug #5267 - nmbd shuts down when network interfaces go down.
Cause nmbd to wait for an interface, in a mode where SIGTERM
will kills us (same way we wait on startup for an interface).
Jeremy.
Diffstat (limited to 'source/nmbd')
-rw-r--r-- | source/nmbd/nmbd.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index 378b6f3dbe0..00d252940af 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -163,23 +163,31 @@ static void expire_names_and_servers(time_t t) /************************************************************************** ** Reload the list of network interfaces. + Doesn't return until a network interface is up. ************************************************************************** */ -static bool reload_interfaces(time_t t) +static void reload_interfaces(time_t t) { static time_t lastt; int n; struct subnet_record *subrec; - if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False; + if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) { + return; + } + lastt = t; - if (!interfaces_changed()) return False; + if (!interfaces_changed()) { + return; + } /* the list of probed interfaces has changed, we may need to add/remove some subnets */ load_interfaces(); + try_again: + /* find any interfaces that need adding */ for (n=iface_count() - 1; n >= 0; n--) { char str[INET6_ADDRSTRLEN]; @@ -268,12 +276,33 @@ static bool reload_interfaces(time_t t) rescan_listen_set = True; - /* We need to shutdown if there are no subnets... */ + /* We need to wait if there are no subnets... */ if (FIRST_SUBNET == NULL) { - DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n")); - return True; + void (*saved_handler)(int); + + DEBUG(0,("reload_interfaces: " + "No subnets to listen to. Waiting..\n")); + + /* + * Whilst we're waiting for an interface, allow SIGTERM to + * cause us to exit. + */ + + saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL ); + + /* We only count IPv4 interfaces here. */ + while (iface_count_v4() == 0) { + sleep(5); + load_interfaces(); + } + + /* + * We got an interface, restore our normal term handler. + */ + + CatchSignal( SIGTERM, SIGNAL_CAST saved_handler ); + goto try_again; } - return False; } /**************************************************************************** ** @@ -310,8 +339,6 @@ static bool reload_nmbd_services(bool test) /**************************************************************************** ** * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP - * We use buf here to return bool result to process() when reload_interfaces() - * detects that there are no subnets. **************************************************************************** */ static void msg_reload_nmbd_services(struct messaging_context *msg, @@ -324,14 +351,7 @@ static void msg_reload_nmbd_services(struct messaging_context *msg, dump_all_namelists(); reload_nmbd_services( True ); reopen_logs(); - - if (data->data) { - /* We were called from process() */ - /* If reload_interfaces() returned True */ - /* we need to shutdown if there are no subnets... */ - /* pass this info back to process() */ - *((bool *)data->data) = reload_interfaces(0); - } + reload_interfaces(0); } static void msg_nmbd_send_packet(struct messaging_context *msg, @@ -401,7 +421,6 @@ static void msg_nmbd_send_packet(struct messaging_context *msg, static void process(void) { bool run_election; - bool no_subnets; while( True ) { time_t t = time(NULL); @@ -612,26 +631,17 @@ static void process(void) */ if(reload_after_sighup) { - DATA_BLOB blob = data_blob_const(&no_subnets, - sizeof(no_subnets)); DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) ); msg_reload_nmbd_services(nmbd_messaging_context(), NULL, MSG_SMB_CONF_UPDATED, - procid_self(), &blob); + procid_self(), NULL); - if(no_subnets) { - TALLOC_FREE(frame); - return; - } reload_after_sighup = 0; } /* check for new network interfaces */ - if(reload_interfaces(t)) { - TALLOC_FREE(frame); - return; - } + reload_interfaces(t); /* free up temp memory */ TALLOC_FREE(frame); |