Diff for /loncom/Attic/lonManage between versions 1.18 and 1.25

version 1.18, 2003/10/28 11:55:58 version 1.25, 2003/11/04 11:52:06
Line 63  use lib "."; Line 63  use lib ".";
 use strict; # Because it's good practice.  use strict; # Because it's good practice.
 use English; # Cause I like meaningful names.  use English; # Cause I like meaningful names.
 use Getopt::Long;  use Getopt::Long;
 use IO::Socket::UNIX; # To communicate with lonc.  
 use LondConnection;  use LondConnection;
   use IO::Poll qw(POLLRDNORM POLLWRNORM POLLIN POLLHUP POLLOUT);
   
 # File scoped variables:  # File scoped variables:
   
 my %perlvar; # Perl variable defs from apache config.  my %perlvar; # Perl variable defs from apache config.
 my %hostshash; # Host table as a host indexed hash.  my %hostshash; # Host table as a host indexed hash.
   
 my $MyHost; # Host name to use as me.  my $MyHost=""; # Host name to use as me.
 my $ForeignHostTab; # Name of foreign hosts table.  my $ForeignHostTab=""; # Name of foreign hosts table.
   
   my $DefaultServerPort =  5663; # Default server port if standalone.
   my $ServerPort; # Port used to connect to lond.
   
   my $TransitionTimeout = 5; # Poll timeout in seconds.
   
   
   # LondConnection::SetDebug(10);
   
   
 #  #
 #   prints out utility's command usage info.  #   prints out utility's command usage info.
Line 110  USAGE Line 119  USAGE
   
   
 }  }
   
   #
   #  Make a direct connection to the lond in 'host'.  The port is 
   #  gotten from the global variable:  ServerPort.
   #  Returns:
   #    The connection or undef if one could not be formed.
   #
   sub MakeLondConnection {
       my $host = shift;
   
       my $Connection = LondConnection->new($host, $ServerPort);
       return return $Connection;
   }
   #
   #   Process the connection state machine until the connection
   #   becomes idle. This is used both to negotiate the initial
   #   connection, during which the LondConnection sequences a rather 
   #   complex state machine and during the transaction itself
   #   for a simpler set of transitions.
   #   All we really need to be concerned with is whether or not
   #   we're readable or writable and the final state:
   #
   #   Parameter:
   #       connection   - Represents the LondConnection to be sequenced.
   #       timeout      - Maximum time to wait for readable/writable sockets.
   #                      in seconds. < 0 waits forever.
   #   Return:
   #       'ok'         - We got to idle ok.
   #       'error:msg'  - An error occured. msg describes the error.
   #
   sub SequenceStateMachine {
       my $connection   = shift;
       my $timeout      = shift;
   
       my $Socket       = $connection->GetSocket;
       my $returnstatus = "ok";              # optimist!!!
       my $error        = 0;              # Used to force early loop termination
                                                 # damned perl has no break!!.
       my $state        = $connection->GetState;
   
       while(($connection->GetState ne "Idle") && (!$error)) {
    #
    # Figure out what the connection wants. read/write and wait for it
    # or for the timeout.
    #
    my $wantread = $connection->WantReadable;
    my $poll     = new IO::Poll;
    $poll->mask($Socket, => $wantread ? POLLIN : POLLOUT);
    $poll->poll($timeout);
    my $done     = $poll->handles();
    if(scalar($done) == 0) {            # no handles ready... timeout!!
       $returnstatus  = "error:";
       $returnstatus .= "Timeout in state $state\n";
       $error         = 1;
    } else {
       my $status;
       $status        = $wantread ? $connection->Readable :
                            $connection->Writable;
       if($status != 0) {
    $returnstatus  =  "error:";
    $returnstatus .=  " I/O failed in state $state\n";
    $error = 1;
       }
    }
    $state = $connection->GetState;
       }
       return $returnstatus;
   }
   
   #
   #    This function runs through the section of the connection
   #   state machine that has to do with negotiating the startup 
   #   sequence with lond.  The general strategy is to loop
   #   until the connection state becomes idle or disconnected.
   #   Disconnected indicates an error or rejection of the
   #   connection at some point in the negotiation.
   #   idle indicates a connection ready for a request.
   #   The main loop consults the object to determine if it
   #   wants to be writeable or readable, waits for that
   #   condition on the socket (with timeout) and  then issues
   #   the appropriate LondConnection call. Note that
   #   LondConnection is capable of doing everything necessary
   #   to get to the initial idle state.
   # 
   #
   #  Parameters:
   #     connection - A connection that has been created with
   #                  the remote lond.  This connection should
   #                  be in the Connected state ready to send
   #                  the init sequence.
   #
   sub NegotiateStartup {
       my $connection = shift;
       my $returnstatus = "ok"; # Optimistic!!.
   
       my $state      = $connection->GetState;
       if($state ne "Connected") {
    print "Error: Initial lond connection state: $state should be Connected\n";
    return "error";
       }
   
       return SequenceStateMachine($connection, $TransitionTimeout);
   }
 #  #
 #   Lifted from lonnet.pm - and we need to figure out a way to get it back in.  #   Perform a transaction with the remote lond.
 #   Performas a transaction with lond via the lonc proxy server.  #   Paramters:
   #      connection - the connection object that represents
   #                   a LondConnection to the remote lond.
   #      command    - The request to send to the remote system.
   #   Returns:
   #       The 'reaction' of the lond to this command.
   #       However if the connection to lond is lost during the transaction
   #       or some other error occurs, the text "error:con_lost" is returned.
   #    
   sub PerformTransaction {
       my $connection  = shift;
       my $command     = shift;
       my $retval;                          # What we'll returnl.
   
      
       #  Set up the connection to do the transaction then
       #  do the I/O until idle or error.
       #
       $connection->InitiateTransaction($command);
   
       my $status = SequenceStateMachine($connection, $TransitionTimeout);
       if($status eq "ok") {
    $retval = $connection->GetReply;
       } else {
    $retval = $status;
       }
   
       return $retval;
   }
   #
   # Performs a transaction direct to a remote lond.
 #   Parameter:  #   Parameter:
 #      cmd  - The text of the request.  #      cmd  - The text of the request.
 #      host - The host to which the request ultimately goes.  #      host - The host to which the request ultimately goes.
Line 121  USAGE Line 263  USAGE
 #      lond/lonc etc.  #      lond/lonc etc.
 #  #
 sub subreply {  sub subreply {
     my ($cmd,$server)=@_;      my $cmd = shift;
     my $peerfile="$perlvar{'lonSockDir'}/$server";      my $host = shift;
     my $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",  
                                      Type    => SOCK_STREAM,  
                                      Timeout => 10)      my $connection  = MakeLondConnection($host);
        or return "con_lost";      if ($connection eq undef) {
     print $client "$cmd\n";   return "Connect Failed";
     my $answer=<$client>;      }
     if (!$answer) { $answer="con_lost"; }      my $reply = NegotiateStartup($connection);
     chomp($answer);      if($reply ne "ok") {
     return $answer;   return "connection negotiation failed";
       }
       my $reply =  PerformTransaction($connection, $cmd);
       return $reply;
   
   
        #    my ($cmd,$server)=@_;
        #    my $peerfile="$perlvar{'lonSockDir'}/$server";
        #    my $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",
        #                                     Type    => SOCK_STREAM,
        #                                     Timeout => 10)
        #       or return "con_lost";
        #    print $client "$cmd\n";
        #    my $answer=<$client>;
        #    if (!$answer) { $answer="con_lost"; }
        #    chomp($answer);
        #    return $answer;
 }  }
 #   >>> BUGBUG <<<   #   >>> BUGBUG <<< 
 #  #
Line 227  sub ParseArgs { Line 385  sub ParseArgs {
     return @result;      return @result;
 }  }
 #  #
 #  Read the loncapa configuration stuff.  #  Read the loncapa configuration stuff.  If ForeignHostTab is empty,
   #  assume we are part of a loncapa cluster and read the hosts.tab
   #  file from the config directory.  Otherwise, ForeignHossTab
   #  is the name of an alternate configuration file to read in 
   #  standalone mode.
 #  #
 sub ReadConfig {  sub ReadConfig {
     my $perlvarref = LondConnection::read_conf('loncapa.conf');  
     %perlvar       = %{$perlvarref};  
     my $hoststab   = LondConnection::read_hosts(  
  "$perlvar{'lonTabDir'}/hosts.tab");  
     %hostshash     = %{$hoststab};  
   
       if($ForeignHostTab eq "") {
    my $perlvarref = LondConnection::read_conf('loncapa.conf');
    %perlvar       = %{$perlvarref};
    my $hoststab   = LondConnection::read_hosts(
       "$perlvar{'lonTabDir'}/hosts.tab");
    %hostshash     = %{$hoststab};
    $MyHost        = $perlvar{lonHostID}; # Set hostname from vars.
    $ServerPort    = $perlvar{londPort};
       } else {
   
    LondConnection::ReadForeignConfig($MyHost, $ForeignHostTab);
     my $hoststab = LondConnection::read_hosts($ForeignHostTab); #  we need to know too.
     %hostshash   = %{$hoststab};
     $ServerPort    = $DefaultServerPort;
         }
       
 }  }
 #  #
 #  Determine if the target host is valid.  #  Determine if the target host is valid.
Line 388  sub ReinitProcess { Line 561  sub ReinitProcess {
 }  }
 #--------------------------- Entry point: --------------------------  #--------------------------- Entry point: --------------------------
   
 ReadConfig; # Read the configuration info (incl.hosts).  
   
   
 #  Parse the parameters  #  Parse the parameters
Line 408  if ($EUID != 0) { Line 580  if ($EUID != 0) {
     die "ENOPRIV - No privilege for requested operation"      die "ENOPRIV - No privilege for requested operation"
 }  }
   
   #
   #   Read the configuration file.
   #   
   
   ReadConfig; # Read the configuration info (incl.hosts).
   
 #   Based on the operation requested invoke the appropriate function:  #   Based on the operation requested invoke the appropriate function:
   

Removed from v.1.18  
changed lines
  Added in v.1.25


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