--- loncom/lond 2003/01/13 21:52:11 1.105 +++ loncom/lond 2003/03/02 03:58:55 1.110 @@ -2,7 +2,7 @@ # The LearningOnline Network # lond "LON Daemon" Server (port "LOND" 5663) # -# $Id: lond,v 1.105 2003/01/13 21:52:11 matthew Exp $ +# $Id: lond,v 1.110 2003/03/02 03:58:55 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,36 +31,27 @@ # 10/7,10/8,10/9,10/11,10/13,10/15,11/4,11/16, # 12/7,12/15,01/06,01/11,01/12,01/14,2/8, # 03/07,05/31 Gerd Kortemeyer -# 06/26 Scott Harrison # 06/29,06/30,07/14,07/15,07/17,07/20,07/25,09/18 Gerd Kortemeyer -# 12/05 Scott Harrison # 12/05,12/13,12/29 Gerd Kortemeyer # YEAR=2001 -# Jan 01 Scott Harrison # 02/12 Gerd Kortemeyer -# 03/15 Scott Harrison # 03/24 Gerd Kortemeyer -# 04/02 Scott Harrison # 05/11,05/28,08/30 Gerd Kortemeyer -# 9/30,10/22,11/13,11/15,11/16 Scott Harrison # 11/26,11/27 Gerd Kortemeyer -# 12/20 Scott Harrison # 12/22 Gerd Kortemeyer # YEAR=2002 # 01/20/02,02/05 Gerd Kortemeyer # 02/05 Guy Albertelli -# 02/07 Scott Harrison # 02/12 Gerd Kortemeyer # 02/19 Matthew Hall # 02/25 Gerd Kortemeyer -# 05/11 Scott Harrison +# 01/xx/2003 Ron Fox.. Remove preforking. This makes the general daemon +# logic simpler (and there were problems maintaining the preforked +# population). Since the time averaged connection rate is close to zero +# because lonc's purpose is to maintain near continuous connnections, +# preforking is not really needed. ### -# based on "Perl Cookbook" ISBN 1-56592-243-3 -# preforker - server who forks first -# runs as a daemon -# HUPs -# uses IDEA encryption use lib '/home/httpd/lib/perl/'; use LONCAPA::Configuration; @@ -491,37 +482,35 @@ close(PIDSAVE); &logthis("CRITICAL: ---------- Starting ----------"); &status('Starting'); -# ------------------------------------------------------- Now we are on our own - -# Fork off our children. -for (1 .. $PREFORK) { - make_new_child(); -} + # ----------------------------------------------------- Install signal handlers -&status('Forked children'); $SIG{CHLD} = \&REAPER; $SIG{INT} = $SIG{TERM} = \&HUNTSMAN; $SIG{HUP} = \&HUPSMAN; $SIG{USR1} = \&checkchildren; -# And maintain the population. + + +# -------------------------------------------------------------- +# Accept connections. When a connection comes in, it is validated +# and if good, a child process is created to process transactions +# along the connection. + while (1) { - &status('Sleeping'); - sleep; # wait for a signal (i.e., child's death) - &logthis('Woke up'); - &status('Woke up'); - for ($i = $children; $i < $PREFORK; $i++) { - make_new_child(); # top up the child pool - } + $client = $server->accept() or next; + make_new_child($client); } sub make_new_child { + my $client; my $pid; my $cipher; my $sigset; + + $client = shift; &logthis("Attempting to start child"); # block signal for fork $sigset = POSIX::SigSet->new(SIGINT); @@ -555,10 +544,6 @@ sub make_new_child { &Authen::Krb5::init_context(); &Authen::Krb5::init_ets(); - # handle connections until we've reached $MAX_CLIENTS_PER_CHILD - for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) { - &status('Idle, waiting for connection'); - $client = $server->accept() or last; &status('Accepted connection'); # ============================================================================= # do something with the connection @@ -566,7 +551,7 @@ sub make_new_child { $client->sockopt(SO_KEEPALIVE, 1);# Enable monitoring of # connection liveness. # see if we know client and check for spoof IP by challenge - my $caller=getpeername($client); + my $caller = getpeername($client); my ($port,$iaddr)=unpack_sockaddr_in($caller); my $clientip=inet_ntoa($iaddr); my $clientrec=($hostid{$clientip} ne undef); @@ -870,7 +855,8 @@ sub make_new_child { $fpnow.='/'.$fpparts[$i]; unless (-e $fpnow) { unless (mkdir($fpnow,0777)) { - $fperror="error:$!"; + $fperror="error: ".($!+0) + ." mkdir failed\n"; } } } @@ -1041,7 +1027,8 @@ sub make_new_child { print $hfh "$now:$hostid{$clientip}:$what\n"; print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." IO::File->new Failed\n"; } } # ------------------------------------------------------------------------- put @@ -1069,10 +1056,12 @@ sub make_new_child { if (untie(%hash)) { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!) + ." tie(GDBM) Failed\n"; } } else { print $client "refused\n"; @@ -1111,10 +1100,12 @@ sub make_new_child { if (untie(%hash)) { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } } else { print $client "refused\n"; @@ -1137,10 +1128,12 @@ sub make_new_child { $qresult=~s/\&$//; print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ------------------------------------------------------------------------ eget } elsif ($userinput =~ /^eget/) { @@ -1173,10 +1166,12 @@ sub make_new_child { print $client "error:no_key\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ------------------------------------------------------------------------- del } elsif ($userinput =~ /^del/) { @@ -1201,10 +1196,12 @@ sub make_new_child { if (untie(%hash)) { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ------------------------------------------------------------------------ keys } elsif ($userinput =~ /^keys/) { @@ -1222,13 +1219,15 @@ sub make_new_child { $qresult=~s/\&$//; print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ----------------------------------------------------------------- dumpcurrent - } elsif ($userinput =~ /^dumpcurrent/) { + } elsif ($userinput =~ /^currentdump/) { my ($cmd,$udom,$uname,$namespace) =split(/:/,$userinput); $namespace=~s/\//\_/g; @@ -1250,9 +1249,8 @@ sub make_new_child { next if (exists($data{$symb}) && exists($data{$symb}->{$param}) && $data{$symb}->{'v.'.$param} > $v); - #&logthis("v = ".$v." p = ".$param." s = ".$symb); $data{$symb}->{$param}=$value; - $data{$symb}->{'v.'.$param}=$value; + $data{$symb}->{'v.'.$param}=$v; } if (untie(%hash)) { while (my ($symb,$param_hash) = each(%data)) { @@ -1264,10 +1262,12 @@ sub make_new_child { chop($qresult); print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ------------------------------------------------------------------------ dump } elsif ($userinput =~ /^dump/) { @@ -1298,10 +1298,12 @@ sub make_new_child { chop($qresult); print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ----------------------------------------------------------------------- store } elsif ($userinput =~ /^store/) { @@ -1338,10 +1340,12 @@ sub make_new_child { if (untie(%hash)) { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } } else { print $client "refused\n"; @@ -1372,10 +1376,12 @@ sub make_new_child { $qresult=~s/\&$//; print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # -------------------------------------------------------------------- chatsend } elsif ($userinput =~ /^chatsend/) { @@ -1414,7 +1420,8 @@ sub make_new_child { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." IO::File->new Failed\n"; } # ----------------------------------------------------------------------- idput } elsif ($userinput =~ /^idput/) { @@ -1438,10 +1445,12 @@ sub make_new_child { if (untie(%hash)) { print $client "ok\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ----------------------------------------------------------------------- idget } elsif ($userinput =~ /^idget/) { @@ -1459,10 +1468,12 @@ sub make_new_child { $qresult=~s/\&$//; print $client "$qresult\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." untie(GDBM) Failed\n"; } } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ." tie(GDBM) Failed\n"; } # ---------------------------------------------------------------------- tmpput } elsif ($userinput =~ /^tmpput/) { @@ -1479,7 +1490,8 @@ sub make_new_child { print $client "$id\n"; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ."IO::File->new Failed\n"; } # ---------------------------------------------------------------------- tmpget @@ -1495,9 +1507,22 @@ sub make_new_child { close $store; } else { - print $client "error:$!\n"; + print $client "error: ".($!+0) + ."IO::File->new Failed\n"; } +# ---------------------------------------------------------------------- tmpdel + } elsif ($userinput =~ /^tmpdel/) { + my ($cmd,$id)=split(/:/,$userinput); + chomp($id); + $id=~s/\W/\_/g; + my $execdir=$perlvar{'lonDaemons'}; + if (unlink("$execdir/tmp/$id.tmp")) { + print $client "ok\n"; + } else { + print $client "error: ".($!+0) + ."Unlink tmp Failed\n"; + } # -------------------------------------------------------------------------- ls } elsif ($userinput =~ /^ls/) { my ($cmd,$ulsdir)=split(/:/,$userinput); @@ -1546,21 +1571,19 @@ sub make_new_child { &logthis("WARNING: " ."Rejected client $clientip, closing connection"); } - } + } # ============================================================================= &logthis("CRITICAL: " ."Disconnect from $clientip ($hostid{$clientip})"); - # tidy up gracefully and finish - - $server->close(); + # this exit is VERY important, otherwise the child will become # a producer of more and more children, forking yourself into # process death. exit; - } + }