Diff for /loncom/lond between versions 1.144 and 1.149

version 1.144, 2003/09/16 09:47:01 version 1.149, 2003/09/30 09:44:13
Line 60 Line 60
 # 09/08/2003 Ron Fox:  Told lond to take care of change logging so we  # 09/08/2003 Ron Fox:  Told lond to take care of change logging so we
 #      don't have to remember it:  #      don't have to remember it:
 # $Log$  # $Log$
   # Revision 1.149  2003/09/30 09:44:13  foxr
   # Tested UpdateHosts ability to
   # - Remove live children for hosts that are no longer in the hosts.tab
   # - Remove live children for hosts whose IPs have changed in the hosts.tab
   #
   # Revision 1.148  2003/09/29 10:09:18  foxr
   # Put in logic to reinit lond itself (except for apache reload).  I don't believe
   # this logic works correctly yet, however lond still does everything it used to doso I'll do the commit anyway.
   #
   # Revision 1.147  2003/09/23 11:23:31  foxr
   # Comlplete implementation of reinit functionality.  Must still implement
   # the actual initialization functionality, but the process can now
   # receive the request and either invoke the appropriate internal function or
   # signal the correct lonc.
   #
   # Revision 1.146  2003/09/16 10:28:14  foxr
   # ReinitProcess - decode the process selector and produce the associated pid
   # filename.  Note: While it is possible to test that valid process selectors are
   # handled properly I am not able to test that invalid process selectors produce
   # the appropriate error as lonManage also blocks the use of invalid process selectors.
   #
   # Revision 1.145  2003/09/16 10:13:20  foxr
   # Added ReinitProcess function to oversee the parsing and processing of the
   # reinit:<process> client request.
   #
 # Revision 1.144  2003/09/16 09:47:01  foxr  # Revision 1.144  2003/09/16 09:47:01  foxr
 # Added skeletal support for SIGUSR2 (update hosts.tab)  # Added skeletal support for SIGUSR2 (update hosts.tab)
 #  #
Line 338  sub PushFile { Line 363  sub PushFile {
   
     if(!InstallFile($tablefile, $contents)) {      if(!InstallFile($tablefile, $contents)) {
  &logthis('<font color="red"> Pushfile: unable to install '   &logthis('<font color="red"> Pushfile: unable to install '
  .$tablefile." $! </font>");   .$tablefile." $! </font>");
  return "error:$!";   return "error:$!";
     }      }
     else {      else {
Line 353  sub PushFile { Line 378  sub PushFile {
     return "ok";      return "ok";
   
 }  }
   
   #
   #  Called to re-init either lonc or lond.
   #
   #  Parameters:
   #    request   - The full request by the client.  This is of the form
   #                reinit:<process>  
   #                where <process> is allowed to be either of 
   #                lonc or lond
   #
   #  Returns:
   #     The string to be sent back to the client either:
   #   ok         - Everything worked just fine.
   #   error:why  - There was a failure and why describes the reason.
   #
   #
   sub ReinitProcess {
       my $request = shift;
   
   
       # separate the request (reinit) from the process identifier and
       # validate it producing the name of the .pid file for the process.
       #
       #
       my ($junk, $process) = split(":", $request);
       my $processpidfile = $perlvar{'lonDaemons'}.'/logs/';
       if($process eq 'lonc') {
    $processpidfile = $processpidfile."lonc.pid";
    if (!open(PIDFILE, "< $processpidfile")) {
       return "error:Open failed for $processpidfile";
    }
    my $loncpid = <PIDFILE>;
    close(PIDFILE);
    logthis('<font color="red"> Reinitializing lonc pid='.$loncpid
    ."</font>");
    kill("USR2", $loncpid);
       } elsif ($process eq 'lond') {
    logthis('<font color="red"> Reinitializing self (lond) </font>');
    &UpdateHosts; # Lond is us!!
       } else {
    &logthis('<font color="yellow" Invalid reinit request for '.$process
    ."</font>");
    return "error:Invalid process identifier $process";
       }
       return 'ok';
   }
   
 #  #
 #  Convert an error return code from lcpasswd to a string value.  #  Convert an error return code from lcpasswd to a string value.
 #  #
Line 429  if (-e $pidfile) { Line 501  if (-e $pidfile) {
   
 # ------------------------------------------------------------- Read hosts file  # ------------------------------------------------------------- Read hosts file
   
 open (CONFIG,"$perlvar{'lonTabDir'}/hosts.tab") || die "Can't read host file";  
   
 while (my $configline=<CONFIG>) {  
     my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);  
     chomp($ip); $ip=~s/\D+$//;  
     $hostid{$ip}=$id;  
     $hostdom{$id}=$domain;  
     $hostip{$id}=$ip;  
     if ($id eq $perlvar{'lonHostID'}) { $thisserver=$name; }  
 }  
 close(CONFIG);  
   
 # establish SERVER socket, bind and listen.  # establish SERVER socket, bind and listen.
 $server = IO::Socket::INET->new(LocalPort => $perlvar{'londPort'},  $server = IO::Socket::INET->new(LocalPort => $perlvar{'londPort'},
Line 489  sub HUPSMAN {                      # sig Line 551  sub HUPSMAN {                      # sig
 }  }
   
 #  #
   #    Kill off hashes that describe the host table prior to re-reading it.
   #    Hashes affected are:
   #       %hostid, %hostdom %hostip
   #
   sub KillHostHashes {
       foreach my $key (keys %hostid) {
    delete $hostid{$key};
       }
       foreach my $key (keys %hostdom) {
    delete $hostdom{$key};
       }
       foreach my $key (keys %hostip) {
    delete $hostip{$key};
       }
   }
   #
   #   Read in the host table from file and distribute it into the various hashes:
   #
   #    - %hostid  -  Indexed by IP, the loncapa hostname.
   #    - %hostdom -  Indexed by  loncapa hostname, the domain.
   #    - %hostip  -  Indexed by hostid, the Ip address of the host.
   sub ReadHostTable {
   
       open (CONFIG,"$perlvar{'lonTabDir'}/hosts.tab") || die "Can't read host file";
       
       while (my $configline=<CONFIG>) {
    my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
    chomp($ip); $ip=~s/\D+$//;
    $hostid{$ip}=$id;
    $hostdom{$id}=$domain;
    $hostip{$id}=$ip;
    if ($id eq $perlvar{'lonHostID'}) { $thisserver=$name; }
       }
       close(CONFIG);
   }
   #
   #  Reload the Apache daemon's state.
   #
   sub ReloadApache {
   }
   
   #
 #   Called in response to a USR2 signal.  #   Called in response to a USR2 signal.
 #   - Reread hosts.tab  #   - Reread hosts.tab
 #   - All children connected to hosts that were removed from hosts.tab  #   - All children connected to hosts that were removed from hosts.tab
Line 499  sub HUPSMAN {                      # sig Line 603  sub HUPSMAN {                      # sig
 #     now be honored.  #     now be honored.
 #  #
 sub UpdateHosts {  sub UpdateHosts {
       logthis('<font color="blue"> Updating connections </font>');
       #
       #  The %children hash has the set of IP's we currently have children
       #  on.  These need to be matched against records in the hosts.tab
       #  Any ip's no longer in the table get killed off they correspond to
       #  either dropped or changed hosts.  Note that the re-read of the table
       #  will take care of new and changed hosts as connections come into being.
   
   
       KillHostHashes;
       ReadHostTable;
   
       foreach my $child (keys %children) {
    my $childip = $children{$child};
    if(!$hostid{$childip}) {
       logthis('<font color="blue"> UpdateHosts killing child '
       ." $child for ip $childip </font>");
       kill('INT', $child);
    } else {
       logthis('<font color="green"> keeping child for ip '
       ." $childip (pid=$child) </font>");
    }
       }
       ReloadApache;
 }  }
   
   
 sub checkchildren {  sub checkchildren {
     &initnewstatus();      &initnewstatus();
     &logstatus();      &logstatus();
Line 745  $SIG{HUP}  = \&HUPSMAN; Line 874  $SIG{HUP}  = \&HUPSMAN;
 $SIG{USR1} = \&checkchildren;  $SIG{USR1} = \&checkchildren;
 $SIG{USR2} = \&UpdateHosts;  $SIG{USR2} = \&UpdateHosts;
   
   #  Read the host hashes:
   
   ReadHostTable;
   
 # --------------------------------------------------------------  # --------------------------------------------------------------
 #   Accept connections.  When a connection comes in, it is validated  #   Accept connections.  When a connection comes in, it is validated
Line 769  sub make_new_child { Line 901  sub make_new_child {
         or die "Can't block SIGINT for fork: $!\n";          or die "Can't block SIGINT for fork: $!\n";
   
     die "fork: $!" unless defined ($pid = fork);      die "fork: $!" unless defined ($pid = fork);
   
       $client->sockopt(SO_KEEPALIVE, 1); # Enable monitoring of
                                  # connection liveness.
   
       #
       #  Figure out who we're talking to so we can record the peer in 
       #  the pid hash.
       #
       my $caller = getpeername($client);
       my ($port,$iaddr)=unpack_sockaddr_in($caller);
       $clientip=inet_ntoa($iaddr);
           
     if ($pid) {      if ($pid) {
         # Parent records the child's birth and returns.          # Parent records the child's birth and returns.
         sigprocmask(SIG_UNBLOCK, $sigset)          sigprocmask(SIG_UNBLOCK, $sigset)
             or die "Can't unblock SIGINT for fork: $!\n";              or die "Can't unblock SIGINT for fork: $!\n";
         $children{$pid} = 1;          $children{$pid} = $clientip;
         $children++;          $children++;
         &status('Started child '.$pid);          &status('Started child '.$pid);
         return;          return;
Line 801  sub make_new_child { Line 944  sub make_new_child {
 # =============================================================================  # =============================================================================
             # do something with the connection              # do something with the connection
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
     $client->sockopt(SO_KEEPALIVE, 1);# Enable monitoring of   # see if we know client and check for spoof IP by challenge
                                       # connection liveness.  
             # see if we know client and check for spoof IP by challenge  
  my $caller = getpeername($client);  
             my ($port,$iaddr)=unpack_sockaddr_in($caller);  
             $clientip=inet_ntoa($iaddr);  
             my $clientrec=($hostid{$clientip} ne undef);              my $clientrec=($hostid{$clientip} ne undef);
             &logthis(              &logthis(
 "<font color=yellow>INFO: Connection, $clientip ($hostid{$clientip})</font>"  "<font color=yellow>INFO: Connection, $clientip ($hostid{$clientip})</font>"
Line 952  sub make_new_child { Line 1091  sub make_new_child {
        if ($wasenc == 1) {         if ($wasenc == 1) {
    my $cert = GetCertificate($userinput);     my $cert = GetCertificate($userinput);
    if(ValidManager($cert)) {     if(ValidManager($cert)) {
        print $client "ok\n";         chomp($userinput);
          my $reply = ReinitProcess($userinput);
          print $client  "$reply\n";
    } else {     } else {
        print $client "refused\n";         print $client "refused\n";
    }     }

Removed from v.1.144  
changed lines
  Added in v.1.149


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>