--- loncom/loncnew 2004/10/05 10:10:31 1.64 +++ loncom/loncnew 2007/03/28 00:23:46 1.80 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # lonc maintains the connections to remote computers # -# $Id: loncnew,v 1.64 2004/10/05 10:10:31 foxr Exp $ +# $Id: loncnew,v 1.80 2007/03/28 00:23:46 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -61,6 +61,7 @@ use LONCAPA::LondConnection; use LONCAPA::LondTransaction; use LONCAPA::Configuration; use LONCAPA::HashIterator; +use Fcntl qw(:flock); # Read the httpd configuration file to get perl variables @@ -73,12 +74,12 @@ my %perlvar = %{$perlvarref}; # parent and shared variables. my %ChildHash; # by pid -> host. -my %HostToPid; # By host -> pid. -my %HostHash; # by loncapaname -> IP. my %listening_to; # Socket->host table for who the parent # is listening to. my %parent_dispatchers; # host-> listener watcher events. +my %parent_handlers; # Parent signal handlers... + my $MaxConnectionCount = 10; # Will get from config later. my $ClientConnection = 0; # Uniquifier for client events. @@ -87,6 +88,7 @@ my $NextDebugLevel= 2; # So Sigint can my $IdleTimeout= 600; # Wait 10 minutes before pruning connections. my $LogTransactions = 0; # When True, all transactions/replies get logged. +my $executable = $0; # Get the full path to me. # # The variables below are only used by the child processes. @@ -102,16 +104,15 @@ my $ConnectionCount = 0; my $IdleSeconds = 0; # Number of seconds idle. my $Status = ""; # Current status string. my $RecentLogEntry = ""; -my $ConnectionRetries=2; # Number of connection retries allowed. -my $ConnectionRetriesLeft=2; # Number of connection retries remaining. +my $ConnectionRetries=5; # Number of connection retries allowed. +my $ConnectionRetriesLeft=5; # Number of connection retries remaining. my $LondVersion = "unknown"; # Version of lond we talk with. my $KeyMode = ""; # e.g. ssl, local, insecure from last connect. my $LondConnecting = 0; # True when a connection is being built. -# DO NOT SET THE NEXT VARIABLE TO NON ZERO!!!!!!!!!!!!!!! -my $DieWhenIdle = 0; # When true children die when trimmed -> 0. +my $hosts_tab = 0; # True if we are using a static hosts.tab my $I_am_child = 0; # True if this is the child process. # @@ -149,6 +150,7 @@ sub UpdateStatus { Makes an entry into the permanent log file. =cut + sub LogPerm { my $message=shift; my $execdir=$perlvar{'lonDaemons'}; @@ -194,7 +196,7 @@ sub Log { my $now = time; my $local = localtime($now); my $finalformat = "$local ($$) [$RemoteHost] [$Status] "; - my $finalformat = $finalformat.$format."\n"; + $finalformat = $finalformat.$format."\n"; # open the file and put the result. @@ -268,6 +270,7 @@ sub SocketDump { and as what we return in a SIGUSR1 =cut + sub ShowStatus { my $state = shift; my $now = time; @@ -278,13 +281,14 @@ sub ShowStatus { =pod -=head 2 SocketTimeout +=head2 SocketTimeout Called when an action on the socket times out. The socket is destroyed and any active transaction is failed. =cut + sub SocketTimeout { my $Socket = shift; Log("WARNING", "A socket timeout was detected"); @@ -302,12 +306,13 @@ sub SocketTimeout { } } + # # This function should be called by the child in all cases where it must -# exit. If the child process is running with the DieWhenIdle turned on -# it must create a lock file for the AF_UNIX socket in order to prevent -# connection requests from lonnet in the time between process exit -# and the parent picking up the listen again. +# exit. The child process must create a lock file for the AF_UNIX socket +# in order to prevent connection requests from lonnet in the time between +# process exit and the parent picking up the listen again. +# # Parameters: # exit_code - Exit status value, however see the next parameter. # message - If this optional parameter is supplied, the exit @@ -318,24 +323,22 @@ sub child_exit { # Regardless of how we exit, we may need to do the lock thing: - if($DieWhenIdle) { - # - # Create a lock file since there will be a time window - # between our exit and the parent's picking up the listen - # during which no listens will be done on the - # lonnet client socket. - # - my $lock_file = GetLoncSocketPath().".lock"; - open(LOCK,">$lock_file"); - print LOCK "Contents not important"; - close(LOCK); - - exit(0); + # + # Create a lock file since there will be a time window + # between our exit and the parent's picking up the listen + # during which no listens will be done on the + # lonnet client socket. + # + my $lock_file = &GetLoncSocketPath().".lock"; + open(LOCK,">$lock_file"); + print LOCK "Contents not important"; + close(LOCK); + if ($hosts_tab) { + unlink(&GetLoncSocketPath()); } - # Now figure out how we exit: - if($message) { - die $message; + if ($message) { + die($message); } else { exit($exit_code); } @@ -369,7 +372,7 @@ sub Tick { KillSocket($Socket); $IdleSeconds = 0; # Otherwise all connections get trimmed to fast. UpdateStatus(); - if(($ConnectionCount == 0) && $DieWhenIdle) { + if(($ConnectionCount == 0)) { &child_exit(0); } @@ -417,6 +420,7 @@ sub Tick { $KeyMode = ""; $clock_watcher->cancel(); } + &UpdateStatus(); } =pod @@ -670,9 +674,9 @@ sub FailTransaction { if ($ConnectionRetriesLeft > 0) { Log("WARNING", "Failing transaction " - .$transaction->getRequest()); + .$transaction->getLoggableRequest()); } - Debug(1, "Failing transaction: ".$transaction->getRequest()); + Debug(1, "Failing transaction: ".$transaction->getLoggableRequest()); if (!$transaction->isDeferred()) { # If the transaction is deferred we'll get to it. my $client = $transaction->getClient(); Debug(1," Replying con_lost to ".$transaction->getRequest()); @@ -682,12 +686,14 @@ sub FailTransaction { } =pod + =head1 EmptyQueue Fails all items in the work queue with con_lost. Note that each item in the work queue is a transaction. =cut + sub EmptyQueue { $ConnectionRetriesLeft--; # Counts as connection failure too. while($WorkQueue->Count()) { @@ -703,6 +709,7 @@ sub EmptyQueue { Close all connections open on lond prior to exit e.g. =cut + sub CloseAllLondConnections { foreach my $Socket (keys %ActiveConnections) { if(exists($ActiveTransactions{$Socket})) { @@ -711,7 +718,6 @@ sub CloseAllLondConnections { KillSocket($Socket); } } -=cut =pod @@ -733,8 +739,8 @@ Parameters: nonzero if we are allowed to create a new connection. - =cut + sub KillSocket { my $Socket = shift; @@ -946,7 +952,7 @@ sub LondReadable { # We need to be writable for this and probably don't belong # here inthe first place. - Deubg(6, "SendingRequest state encountered in readable"); + Debug(6, "SendingRequest state encountered in readable"); $Watcher->poll("w"); $Watcher->cb(\&LondWritable); @@ -1147,6 +1153,7 @@ sub LondWritable { =pod =cut + sub QueueDelayed { Debug(3,"QueueDelayed called"); @@ -1154,19 +1161,28 @@ sub QueueDelayed { Debug(4, "Delayed path: ".$path); opendir(DIRHANDLE, $path); - - my @alldelayed = grep /\.$RemoteHost$/, readdir DIRHANDLE; + + my @all_host_ids; + my $host_iterator = &LondConnection::GetHostIterator(); + while (!$host_iterator->end()) { + my ($host_id,$host_name) = @{$host_iterator->get()}[0,3]; + if ($host_name eq $RemoteHost) { + push(@all_host_ids, $host_id); + } + $host_iterator->next(); + } + my $host_id_re = '(?:'.join('|',@all_host_ids).')'; + my @alldelayed = grep(/\.$host_id_re$/, readdir(DIRHANDLE)); closedir(DIRHANDLE); - my $dfname; - my $reqfile; - foreach $dfname (sort @alldelayed) { - $reqfile = "$path/$dfname"; - Debug(4, "queueing ".$reqfile); + foreach my $dfname (sort(@alldelayed)) { + my $reqfile = "$path/$dfname"; + my ($host_id) = ($dfname =~ /\.([^.]*)$/); + Debug(4, "queueing ".$reqfile." for $host_id"); my $Handle = IO::File->new($reqfile); my $cmd = <$Handle>; chomp $cmd; # There may or may not be a newline... $cmd = $cmd."\n"; # now for sure there's exactly one newline. - my $Transaction = LondTransaction->new($cmd); + my $Transaction = LondTransaction->new("sethost:$host_id:$cmd"); $Transaction->SetDeferred($reqfile); QueueTransaction($Transaction); } @@ -1391,7 +1407,7 @@ sub ClientRequest { # Accept a connection request for a client (lonc child) and # start up an event watcher to keep an eye on input from that # Event. This can be called both from NewClient and from -# ChildProcess if we are started in DieWhenIdle mode. +# ChildProcess. # Parameters: # $socket - The listener socket. # Returns: @@ -1507,15 +1523,14 @@ another event handler to subess requests =cut sub SetupLoncListener { + my ($host,$SocketName) = @_; + if (!$host) { $host = &GetServerHost(); } + if (!$SocketName) { $SocketName = &GetLoncSocketPath($host); } - my $host = GetServerHost(); # Default host. - if (@_) { - ($host) = @_ # Override host with parameter. - } - my $socket; - my $SocketName = GetLoncSocketPath($host); unlink($SocketName); + + my $socket; unless ($socket =IO::Socket::UNIX->new(Local => $SocketName, Listen => 250, Type => SOCK_STREAM)) { @@ -1555,6 +1570,7 @@ into the status file. We also use this to reset the retries count in order to allow the client to retry connections with a previously dead server. + =cut sub ChildStatus { @@ -1563,26 +1579,31 @@ sub ChildStatus { Debug(2, "Reporting child status because : ".$watcher->data); my $docdir = $perlvar{'lonDocRoot'}; - my $fh = IO::File->new(">>$docdir/lon-status/loncstatus.txt"); - print $fh $$."\t".$RemoteHost."\t".$Status."\t". + + open(LOG,">>$docdir/lon-status/loncstatus.txt"); + flock(LOG,LOCK_EX); + print LOG $$."\t".$RemoteHost."\t".$Status."\t". $RecentLogEntry."\n"; # # Write out information about each of the connections: # if ($DebugLevel > 2) { - print $fh "Active connection statuses: \n"; + print LOG "Active connection statuses: \n"; my $i = 1; print STDERR "================================= Socket Status Dump:\n"; foreach my $item (keys %ActiveConnections) { my $Socket = $ActiveConnections{$item}->data; my $state = $Socket->GetState(); - print $fh "Connection $i State: $state\n"; + print LOG "Connection $i State: $state\n"; print STDERR "---------------------- Connection $i \n"; $Socket->Dump(-1); # Ensure it gets dumped.. $i++; } } + flock(LOG,LOCK_UN); + close(LOG); $ConnectionRetriesLeft = $ConnectionRetries; + UpdateStatus(); } =pod @@ -1603,12 +1624,14 @@ sub SignalledToDeath { chomp($signal); Log("CRITICAL", "Abnormal exit. Child $$ for $RemoteHost " ."died through "."\"$signal\""); - LogPerm("F:lonc: $$ on $RemoteHost signalled to death: " - ."\"$signal\""); + #LogPerm("F:lonc: $$ on $RemoteHost signalled to death: " +# ."\"$signal\""); exit 0; } +=pod + =head2 ToggleDebug This sub toggles trace debugging on and off. @@ -1624,6 +1647,8 @@ sub ToggleDebug { } +=pod + =head2 ChildProcess This sub implements a child process for a single lonc daemon. @@ -1634,7 +1659,7 @@ Optional parameter: =cut sub ChildProcess { - # If we are in DieWhenIdle mode, we've inherited all the + # We've inherited all the # events of our parent and those have to be cancelled or else # all holy bloody chaos will result.. trust me, I already made # >that< mistake. @@ -1650,9 +1675,19 @@ sub ChildProcess { Debug(5, "Killing watcher for $listener"); $watcher->cancel(); - undef $parent_dispatchers{$listener}; + delete($parent_dispatchers{$listener}); } + + # kill off the parent's signal handlers too! + # + + for my $handler (keys %parent_handlers) { + my $watcher = $parent_handlers{$handler}; + $watcher->cancel(); + delete($parent_handlers{$handler}); + } + $I_am_child = 1; # Seems like in spite of it all I may still getting # parent event dispatches.. flag I'm a child. @@ -1692,7 +1727,7 @@ sub ChildProcess { desc => 'Lonc Listener Unix Socket', fd => $socket); - $Event::Debuglevel = $DebugLevel; + $Event::DebugLevel = $DebugLevel; Debug(9, "Making initial lond connection for ".$RemoteHost); @@ -1700,12 +1735,9 @@ sub ChildProcess { # &MakeLondConnection(); // let first work request do it. - # If We are in diwhenidle, need to accept the connection since the - # event may not fire. + # need to accept the connection since the event may not fire. - if ($DieWhenIdle) { - &accept_client($socket); - } + &accept_client($socket); Debug(9,"Entering event loop"); my $ret = Event::loop(); # Start the main event loop. @@ -1727,7 +1759,6 @@ sub CreateChild { if($pid) { # Parent $RemoteHost = "Parent"; $ChildHash{$pid} = $host; - $HostToPid{$host}= $pid; sigprocmask(SIG_UNBLOCK, $sigset); } else { # child. @@ -1766,25 +1797,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, POSIX::BUFSIZ, 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: @@ -1806,23 +1879,43 @@ sub parent_listen { my ($loncapa_host) = @_; Debug(5, "parent_listen: $loncapa_host"); - my $socket = &SetupLoncListener($loncapa_host); + my ($socket,$file); + if (!$loncapa_host) { + $loncapa_host = 'common_parent'; + $file = $perlvar{'lonSockCreate'}; + } else { + $file = &GetLoncSocketPath($loncapa_host); + } + $socket = &SetupLoncListener($loncapa_host,$file); + $listening_to{$socket} = $loncapa_host; if (!$socket) { die "Unable to create a listen socket for $loncapa_host"; } - my $lock_file = &GetLoncSocketPath($loncapa_host).".lock"; + my $lock_file = $file.".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. @@ -1845,13 +1938,18 @@ sub listen_on_all_unix_sockets { my $host_iterator = &LondConnection::GetHostIterator(); while (!$host_iterator->end()) { my $host_entry_ref = $host_iterator->get(); - my $host_name = $host_entry_ref->[0]; + my $host_name = $host_entry_ref->[3]; Debug(9, "Listen for $host_name"); &parent_listen($host_name); $host_iterator->next(); } } +sub listen_on_common_socket { + Debug(5, "listen_on_common_socket"); + &parent_listen(); +} + # 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 @@ -1875,9 +1973,12 @@ sub server_died { if($host) { # It's for real... &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"); } @@ -1933,20 +2034,12 @@ ShowStatus("Forking node servers"); Log("CRITICAL", "--------------- Starting children ---------------"); LondConnection::ReadConfig; # Read standard config files. -my $HostIterator = LondConnection::GetHostIterator; -if ($DieWhenIdle) { - $RemoteHost = "[parent]"; +$RemoteHost = "[parent]"; +if ($hosts_tab) { &listen_on_all_unix_sockets(); } else { - - while (! $HostIterator->end()) { - - my $hostentryref = $HostIterator->get(); - CreateChild($hostentryref->[0]); - $HostHash{$hostentryref->[0]} = $hostentryref->[4]; - $HostIterator->next(); - } + &listen_on_common_socket(); } $RemoteHost = "Parent Server"; @@ -1956,46 +2049,44 @@ $RemoteHost = "Parent Server"; ShowStatus("Parent keeping the flock"); -if ($DieWhenIdle) { - # We need to setup a SIGChild event to handle the exit (natural or otherwise) - # of the children. - - Event->signal(cb => \&server_died, - desc => "Child exit handler", - signal => "CHLD"); - - - $Event::DebugLevel = $DebugLevel; - Debug(9, "Parent entering event loop"); - my $ret = Event::loop(); - die "Main Event loop exited: $ret"; - +# We need to setup a SIGChild event to handle the exit (natural or otherwise) +# of the children. +Event->signal(cb => \&server_died, + desc => "Child exit handler", + signal => "CHLD"); + + +# Set up all the other signals we set up. + +$parent_handlers{INT} = Event->signal(cb => \&Terminate, + desc => "Parent INT handler", + signal => "INT"); +$parent_handlers{TERM} = Event->signal(cb => \&Terminate, + desc => "Parent TERM handler", + signal => "TERM"); +if ($hosts_tab) { + $parent_handlers{HUP} = Event->signal(cb => \&Restart, + desc => "Parent HUP handler.", + signal => "HUP"); } else { - # - # Set up parent signals: - # - - $SIG{INT} = \&Terminate; - $SIG{TERM} = \&Terminate; - $SIG{HUP} = \&Restart; - $SIG{USR1} = \&CheckKids; - $SIG{USR2} = \&UpdateKids; # LonManage update request. - - while(1) { - my $deadchild = wait(); - if(exists $ChildHash{$deadchild}) { # need to restart. - my $deadhost = $ChildHash{$deadchild}; - delete($HostToPid{$deadhost}); - delete($ChildHash{$deadchild}); - Log("WARNING","Lost child pid= ".$deadchild. - "Connected to host ".$deadhost); - Log("INFO", "Restarting child procesing ".$deadhost); - CreateChild($deadhost); - } - } -} - + $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"); +$parent_handlers{USR2} = Event->signal(cb => \&UpdateKids, + desc => "Parent USR2 handler.", + signal => "USR2"); + +# Start procdesing events. + +$Event::DebugLevel = $DebugLevel; +Debug(9, "Parent entering event loop"); +my $ret = Event::loop(); +die "Main Event loop exited: $ret"; =pod @@ -2016,11 +2107,14 @@ sub CheckKids { my $now=time; my $local=localtime($now); print $fh "LONC status $local - parent $$ \n\n"; + foreach my $host (keys %parent_dispatchers) { + print $fh "LONC Parent process listening for $host\n"; + } foreach my $pid (keys %ChildHash) { Debug(2, "Sending USR1 -> $pid"); kill 'USR1' => $pid; # Tell Child to report status. - sleep 1; # Wait so file doesn't intermix. } + } =pod @@ -2053,80 +2147,17 @@ sub UpdateKids { Log("INFO", "Updating connections via SIGUSR2"); - # Just in case we need to kill our own lonc, we wait a few seconds to - # give it a chance to receive and relay lond's response to the - # re-init command. - # - - sleep(2); # Wait a couple of seconds. - - my %hosts; # Indexed by loncapa hostname, value=ip. - - # Need to re-read the host table: - - - LondConnection::ReadConfig(); - my $I = LondConnection::GetHostIterator; - while (! $I->end()) { - my $item = $I->get(); - $hosts{$item->[0]} = $item->[4]; - $I->next(); - } - - # The logic below is written for clarity not for efficiency. - # Since I anticipate that this function is only rarely called, that's - # appropriate. There are certainly ways to combine the loops below, - # and anyone wishing to obscure the logic is welcome to go for it. - # Note that we don't re-direct sigchild. Instead we do what's needed - # to the data structures that keep track of children to ensure that - # when sigchild is honored, no new child is born. - # - - # For each existing child; if it's host doesn't exist, kill the child. - - foreach my $child (keys %ChildHash) { - my $oldhost = $ChildHash{$child}; - if (!(exists $hosts{$oldhost})) { - Log("CRITICAL", "Killing child for $oldhost host no longer exists"); - delete $ChildHash{$child}; - delete $HostToPid{$oldhost}; - kill 'QUIT' => $child; - } - } - # For each remaining existing child; if it's host's ip has changed, - # Restart the child on the new IP. - - foreach my $child (keys %ChildHash) { - my $oldhost = $ChildHash{$child}; - my $oldip = $HostHash{$oldhost}; - if ($hosts{$oldhost} ne $oldip) { - - # kill the old child. + # I'm not sure what I was thinking in the first implementation. + # someone will have to work hard to convince me the effect is any + # different than Restart, especially now that we don't start up + # per host servers automatically, may as well just restart. + # The down side is transactions that are in flight will get timed out + # (lost unless they are critical). - Log("CRITICAL", "Killing child for $oldhost host ip has changed..."); - delete $ChildHash{$child}; - delete $HostToPid{$oldhost}; - kill 'QUIT' => $child; - - # Do the book-keeping needed to start a new child on the - # new ip. - - $HostHash{$oldhost} = $hosts{$oldhost}; - CreateChild($oldhost); - } - } - # Finally, for each new host, not in the host hash, create a - # enter the host and create a new child. - # Force a status display of any existing process. - - foreach my $host (keys %hosts) { - if(!(exists $HostHash{$host})) { - Log("INFO", "New host $host discovered in hosts.tab..."); - $HostHash{$host} = $hosts{$host}; - CreateChild($host); - } else { - kill 'HUP' => $HostToPid{$host}; # status display. - } + if ($hosts_tab) { + &Restart(); + } else { + &KillThemAll(); } } @@ -2146,7 +2177,7 @@ sub Restart { Log("CRITICAL", "Restarting"); my $execdir = $perlvar{'lonDaemons'}; unlink("$execdir/logs/lonc.pid"); - exec("$execdir/loncnew"); + exec("$executable"); } =pod @@ -2167,8 +2198,6 @@ sub KillThemAll { Log("CRITICAL", "Nicely Killing lonc for $serving pid = $pid"); kill 'QUIT' => $pid; } - - } @@ -2190,6 +2219,7 @@ sub really_kill_them_all_dammit unlink("$execdir/logs/lonc.pid"); } } + =pod =head1 Terminate