--- loncom/Attic/lonc 2001/08/30 20:02:28 1.17 +++ loncom/Attic/lonc 2001/11/26 22:20:26 1.18 @@ -16,7 +16,7 @@ # 12/05 Scott Harrison # 12/05 Gerd Kortemeyer # 01/10/01 Scott Harrison -# 03/14/01,03/15,06/12 Gerd Kortemeyer +# 03/14/01,03/15,06/12,11/26 Gerd Kortemeyer # # based on nonforker from Perl Cookbook # - server who multiplexes without forking @@ -30,6 +30,9 @@ use Fcntl; use Tie::RefHash; use Crypt::IDEA; +my $status=''; +my $lastlog=''; + # grabs exception and records it to log before exiting sub catchexception { my ($signal)=@_; @@ -118,7 +121,9 @@ sub HUNTSMAN { # si local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children map { $wasserver=$children{$_}; + &status("Closing $wasserver"); &logthis('Closing '.$wasserver.': '.&subreply('exit',$wasserver)); + &status("Kill PID $_ for $wasserver"); kill ('INT',$_); } keys %children; my $execdir=$perlvar{'lonDaemons'}; @@ -131,7 +136,9 @@ sub HUPSMAN { # sig local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children map { $wasserver=$children{$_}; + &status("Closing $wasserver"); &logthis('Closing '.$wasserver.': '.&subreply('exit',$wasserver)); + &status("Kill PID $_ for $wasserver"); kill ('INT',$_); } keys %children; &logthis("CRITICAL: Restarting"); @@ -140,6 +147,19 @@ sub HUPSMAN { # sig exec("$execdir/lonc"); # here we go again } +sub checkchildren { + &initnewstatus(); + &logstatus(); + &logthis('Going to check on the children'); + map { + sleep 1; + unless (kill 'USR1' => $_) { + &logthis ('Child '.$_.' is dead'); + &logstatus($$.' is dead'); + } + } sort keys %children; +} + sub USRMAN { &logthis("USR1: Trying to establish connections again"); foreach $thisserver (keys %hostip) { @@ -149,6 +169,7 @@ sub USRMAN { ." >$answer<"); } %childatt=(); + &checkchildren(); } # -------------------------------------------------- Non-critical communication @@ -177,6 +198,7 @@ sub logthis { my $fh=IO::File->new(">>$execdir/logs/lonc.log"); my $now=time; my $local=localtime($now); + $lastlog=$local.': '.$message; print $fh "$local ($$): $message\n"; } @@ -189,6 +211,31 @@ sub logperm { my $fh=IO::File->new(">>$execdir/logs/lonnet.perm.log"); print $fh "$now:$message:$local\n"; } +# ------------------------------------------------------------------ Log status + +sub logstatus { + my $docdir=$perlvar{'lonDocRoot'}; + my $fh=IO::File->new(">>$docdir/lon-status/loncstatus.txt"); + print $fh $$."\t".$status."\t".$lastlog."\n"; +} + +sub initnewstatus { + my $docdir=$perlvar{'lonDocRoot'}; + my $fh=IO::File->new(">$docdir/lon-status/loncstatus.txt"); + my $now=time; + my $local=localtime($now); + print $fh "LONC status $local - parent $$\n\n"; +} + +# -------------------------------------------------------------- Status setting + +sub status { + my $what=shift; + my $now=time; + my $local=localtime($now); + $status=$local.': '.$what; +} + # ---------------------------------------------------- Fork once and dissociate @@ -212,6 +259,8 @@ $SIG{HUP}=$SIG{USR1}='IGNORE'; # Fork off our children, one for every server +&status("Forking ..."); + foreach $thisserver (keys %hostip) { make_new_child($thisserver); } @@ -226,8 +275,10 @@ $SIG{USR1} = \&USRMAN; # And maintain the population. while (1) { + &status("Sleeping"); sleep; # wait for a signal (i.e., child's death) # See who died and start new one + &status("Woke up"); foreach $thisserver (keys %hostip) { if (!$childpid{$thisserver}) { if ($childatt{$thisserver}<$childmaxattempts) { @@ -265,7 +316,8 @@ sub make_new_child { } else { # Child can *not* return from this subroutine. $SIG{INT} = 'DEFAULT'; # make SIGINT kill us as it did before - + $SIG{USR1}= \&logstatus; + # unblock signals sigprocmask(SIG_UNBLOCK, $sigset) or die "Can't unblock SIGINT for fork: $!\n"; @@ -275,7 +327,11 @@ sub make_new_child { $port = "$perlvar{'lonSockDir'}/$conserver"; unlink($port); + # ---------------------------------------------------- Client to network server + +&status("Opening TCP: $conserver"); + unless ( $remotesock = IO::Socket::INET->new(PeerAddr => $hostip{$conserver}, PeerPort => $perlvar{'londPort'}, @@ -289,6 +345,9 @@ unless ( exit; }; # --------------------------------------- Send a ping to make other end do USR1 + +&status("Init dialogue: $conserver"); + print $remotesock "init\n"; $answer=<$remotesock>; print $remotesock "$answer"; @@ -303,12 +362,14 @@ if ($answer ne 'ok') { exit; } sleep 5; +&status("Ponging $conserver"); print $remotesock "pong\n"; $answer=<$remotesock>; chomp($answer); &logthis("Pong reply for $conserver: >$answer<"); # ----------------------------------------------------------- Initialize cipher +&status("Initialize cipher: $conserver"); print $remotesock "ekey\n"; my $buildkey=<$remotesock>; my $key=$conserver.$perlvar{'lonHostID'}; @@ -330,7 +391,7 @@ if ($cipher=new IDEA $cipherkey) { } # ----------------------------------------- We're online, send delayed messages - + &status("Checking for delayed messages"); my @allbuffered; my $path="$perlvar{'lonSockDir'}/delayed"; opendir(DIRHANDLE,$path); @@ -338,6 +399,7 @@ if ($cipher=new IDEA $cipherkey) { closedir(DIRHANDLE); my $dfname; map { + &status("Sending delayed $conserver $_"); $dfname="$path/$_"; &logthis($dfname); my $wcmd; @@ -372,6 +434,7 @@ if ($cipher=new IDEA $cipherkey) { } @allbuffered; # ------------------------------------------------------- Listen to UNIX socket +&status("Opening socket $conserver"); unless ( $server = IO::Socket::UNIX->new(Local => $port, Type => SOCK_STREAM, @@ -413,7 +476,7 @@ while (1) { if ($client == $server) { # accept a new connection - + &status("Accept new connection: $conserver"); $client = $server->accept(); $select->add($client); nonblock($client); @@ -428,6 +491,7 @@ while (1) { delete $outbuffer{$client}; delete $ready{$client}; + &status("Idle $conserver"); $select->remove($client); close $client; next; @@ -512,8 +576,11 @@ sub handle { } $request="enc:$cmdlength:$encrequest\n"; } + &status("Sending $conserver: $request"); print $remotesock "$request"; + &status("Waiting for reply from $conserver: $request"); $answer=<$remotesock>; + &status("Received reply: $request"); if ($answer) { if ($answer =~ /^enc/) { my ($cmd,$cmdlength,$encinput)=split(/:/,$answer); @@ -535,6 +602,7 @@ sub handle { # ===================================================== Done processing request } delete $ready{$client}; + &status("Completed $conserver: $request"); # -------------------------------------------------------------- End non-forker } # ---------------------------------------------------------- End make_new_child