--- loncom/loncnew 2006/08/25 21:12:19 1.76 +++ loncom/loncnew 2007/03/27 19:38:36 1.77 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # lonc maintains the connections to remote computers # -# $Id: loncnew,v 1.76 2006/08/25 21:12:19 albertel Exp $ +# $Id: loncnew,v 1.77 2007/03/27 19:38:36 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -115,6 +115,7 @@ my $LondConnecting = 0; # True wh my $DieWhenIdle = 1; # When true children die when trimmed -> 0. +my $hosts_tab = 1; # True if we are using a static hosts.tab my $I_am_child = 0; # True if this is the child process. # @@ -331,11 +332,13 @@ sub child_exit { # during which no listens will be done on the # lonnet client socket. # - my $lock_file = GetLoncSocketPath().".lock"; + my $lock_file = &GetLoncSocketPath().".lock"; open(LOCK,">$lock_file"); print LOCK "Contents not important"; close(LOCK); - + if ($hosts_tab) { + unlink(&GetLoncSocketPath()); + } exit(0); } # Now figure out how we exit: @@ -1805,25 +1808,67 @@ sub parent_client_connection { my ($event) = @_; my $watcher = $event->w; my $socket = $watcher->fd; + if ($hosts_tab) { - # Lookup the host associated with this socket: - - my $host = $listening_to{$socket}; + # Lookup the host associated with this socket: + + my $host = $listening_to{$socket}; - # Start the child: + # Start the child: + + + + &Debug(9,"Creating child for $host (parent_client_connection)"); + &CreateChild($host, $socket); + + # Clean up the listen since now the child takes over until it exits. + $watcher->cancel(); # Nolonger listening to this event + delete($listening_to{$socket}); + delete($parent_dispatchers{$host}); + $socket->close(); + + } else { + my $connection = $socket->accept(); # Accept the client connection. + Event->io(cb => \&get_remote_hostname, + poll => 'r', + data => "", + fd => $connection); + } + } +} + +sub get_remote_hostname { + my ($event) = @_; + my $watcher = $event->w; + my $socket = $watcher->fd; + my $thisread; + my $rv = $socket->recv($thisread, 1, 0); + Debug(8, "rcv: data length = ".length($thisread)." read =".$thisread); + if (!defined($rv) || length($thisread) == 0) { + # Likely eof on socket. + Debug(5,"Client Socket closed on lonc for p_c_c"); + close($socket); + $watcher->cancel(); + return; + } + + my $data = $watcher->data().$thisread; + $watcher->data($data); + if($data =~ /\n$/) { # Request entirely read. + chomp($data); + } else { + return; + } - &Debug(9,"Creating child for $host (parent_client_connection)"); - &CreateChild($host, $socket); + &Debug(5,"Creating child for $data (parent_client_connection)"); + &CreateChild($data); # Clean up the listen since now the child takes over until it exits. - $watcher->cancel(); # Nolonger listening to this event - delete($listening_to{$socket}); - delete($parent_dispatchers{$host}); + $socket->send("done\n"); $socket->close(); - } } # parent_listen: @@ -1845,7 +1890,7 @@ sub parent_listen { my ($loncapa_host) = @_; Debug(5, "parent_listen: $loncapa_host"); - my $socket = &SetupLoncListener($loncapa_host); + my $socket = &SetupLoncListener($loncapa_host); $listening_to{$socket} = $loncapa_host; if (!$socket) { die "Unable to create a listen socket for $loncapa_host"; @@ -1854,14 +1899,26 @@ sub parent_listen { my $lock_file = &GetLoncSocketPath($loncapa_host).".lock"; unlink($lock_file); # No problem if it doesn't exist yet [startup e.g.] - my $watcher = Event->io(cb => \&parent_client_connection, - poll => 'r', - desc => "Parent listener unix socket ($loncapa_host)", - fd => $socket); + my $watcher = + Event->io(cb => \&parent_client_connection, + poll => 'r', + desc => "Parent listener unix socket ($loncapa_host)", + data => "", + fd => $socket); $parent_dispatchers{$loncapa_host} = $watcher; } +sub parent_clean_up { + my ($loncapa_host) = @_; + Debug(5, "parent_clean_up: $loncapa_host"); + + my $socket_file = &GetLoncSocketPath($loncapa_host); + unlink($socket_file); # No problem if it doesn't exist yet [startup e.g.] + my $lock_file = $socket_file.".lock"; + unlink($lock_file); # No problem if it doesn't exist yet [startup e.g.] +} + # listen_on_all_unix_sockets: # This sub initiates a listen on all unix domain lonc client sockets. @@ -1891,6 +1948,11 @@ sub listen_on_all_unix_sockets { } } +sub listen_on_common_socket { + Debug(5, "listen_on_common_socket"); + &parent_listen('common'); +} + # server_died is called whenever a child process exits. # Since this is dispatched via a signal, we must process all # dead children until there are no more left. The action @@ -1915,8 +1977,12 @@ sub server_died { &Debug(9, "Caught sigchild for $host"); delete($ChildHash{$pid}); delete($HostToPid{$host}); - &parent_listen($host); - + if ($hosts_tab) { + &parent_listen($host); + } else { + &parent_clean_up($host); + } + } else { &Debug(5, "Caught sigchild for pid not in hosts hash: $pid"); } @@ -1976,7 +2042,11 @@ my $HostIterator = LondConnection::GetHo if ($DieWhenIdle) { $RemoteHost = "[parent]"; - &listen_on_all_unix_sockets(); + if ($hosts_tab) { + &listen_on_all_unix_sockets(); + } else { + &listen_on_common_socket(); + } } else { while (! $HostIterator->end()) { @@ -2014,9 +2084,15 @@ if ($DieWhenIdle) { $parent_handlers{TERM} = Event->signal(cb => \&Terminate, desc => "Parent TERM handler", signal => "TERM"); - $parent_handlers{HUP} = Event->signal(cb => \&Restart, - desc => "Parent HUP handler.", - signal => "HUP"); + if ($hosts_tab) { + $parent_handlers{HUP} = Event->signal(cb => \&Restart, + desc => "Parent HUP handler.", + signal => "HUP"); + } else { + $parent_handlers{HUP} = Event->signal(cb => \&KillThemAll, + desc => "Parent HUP handler.", + signal => "HUP"); + } $parent_handlers{USR1} = Event->signal(cb => \&CheckKids, desc => "Parent USR1 handler", signal => "USR1"); @@ -2039,7 +2115,11 @@ if ($DieWhenIdle) { $SIG{INT} = \&Terminate; $SIG{TERM} = \&Terminate; - $SIG{HUP} = \&Restart; + if ($hosts_tab) { + $SIG{HUP} = \&Restart; + } else { + $SIG{HUP} = \&KillThemAll; + } $SIG{USR1} = \&CheckKids; $SIG{USR2} = \&UpdateKids; # LonManage update request. @@ -2124,8 +2204,11 @@ sub UpdateKids { # The down side is transactions that are in flight will get timed out # (lost unless they are critical). - &Restart(); - + if ($hosts_tab) { + &Restart(); + } else { + &KillThemAll(); + } } @@ -2165,8 +2248,6 @@ sub KillThemAll { Log("CRITICAL", "Nicely Killing lonc for $serving pid = $pid"); kill 'QUIT' => $pid; } - - }