I have some code below.  The parent sends each child an IP address.  The
child grabs some values via SNMP.

The problem looks to be if the child is sent the IP of a non-responding
device, the child hangs.

For instance.  If I spawn 50 children, and give the parent a list of
1000 devices with only 900 being able to be connected to, the script
hangs completely.  If I spawn 101 processes (One more process then
unreachable devices), the script will finish and report it's findings.

Any ideas how I can regain the children, or spawn new ones if old ones
hang?

-Mike

Script Below:


> #!/usr/bin/perl -w
>                                                                                      
>                      
>     use strict;
>     use IO::Pipe;
>     use IO::Handle;
>     use Proc::Fork;
>     use Net::SNMP;
>     use SNMP;
>                                                                                      
>                      
>     my $num_children = 50;               # no. of children
>     my $control = IO::Pipe->new;        # control channel
>     my $start=time();
>     # Spawn off some children
>     my @child;
>     for my $num (1 .. $num_children) {
>         my $data = IO::Pipe->new;       # data channel
>                                                                                      
>                      
>         child {
>             $data->reader;
>             $control->writer;
>             $control->autoflush(1);
>                                                                                      
>                      
>             print $control "$num\n";
>             while (<$data>) {
>                 chomp;
>                 my $chip = $_;
>                 my $com='notdisplayed';
>                 my (%VALUES,@tmp,@macparts,$SESSION);
>                                                                                      
>                      
>                 $SESSION = new SNMP::Session( DestHost       => $chip,
>                                             Community      => $com,
>                                             Version        => 2,
>                                             Timeout        => 1000,
>                                             Retries        => 1,
>                                             UseSprintValue => 1) || print $control 
> "$num\n";
>               $VALUES{'ip_address'} = $chip;
>               $VALUES{'sysDescr'}    = $SESSION->get(".1.3.6.1.2.1.1.1.0");

>  $VALUES{'mac_address'} = $SESSION->get(".1.3.6.1.2.1.17.1.1.0");
>               $VALUES{'level_up'}    = 
> $SESSION->get(".1.3.6.1.2.1.10.127.1.2.2.1.3.2");
>               $VALUES{'level_down'}  = 
> $SESSION->get(".1.3.6.1.2.1.10.127.1.1.1.1.6.3");
>               $VALUES{'sn_ratio'}    = 
> $SESSION->get(".1.3.6.1.2.1.10.127.1.1.4.1.5.3");
>               $VALUES{'sw_ver'}      = $SESSION->get(".1.3.6.1.2.1.69.1.3.5.0");
>               $VALUES{'config_file'} = $SESSION->get(".1.3.6.1.2.1.69.1.4.5.0");
>               $VALUES{'firmware_ver'} = $SESSION->get(".1.3.6.1.2.1.69.1.3.2.0");
>               $VALUES{'date'}        = `date +%Y-%m-%d\\ %H:%M:%S`; chomp 
> $VALUES{'date'};
>               print STDERR "Child: $num - $VALUES{'mac_address'} - $chip\n";
>               if($VALUES{'mac_address'}){
>                 @macparts=split(/\"/, $VALUES{'mac_address'});
>                 $VALUES{'mac_address'} = $macparts[1];
>                 chomp $VALUES{'mac_address'};
>                 $VALUES{'mac_address'} =~ s/\ /:/g;
>                 $VALUES{'mac_address'} =~ s/:$//;
>               }
>                                                                                      
>                      
>               if (! $VALUES{'firmware_ver'}) {
>               $VALUES{'firmware_ver'} = 'Undefined';
>               }
>                                                                                      
>                      
>               if($VALUES{'mac_address'}){
>               #open(MODEMDATA, ">modemdata/$VALUES{'ip_address'}");
>               open(MODEMDATA, ">>modemdata.txt");
>               print MODEMDATA "$VALUES{'mac_address'},";
>               if($VALUES{'ip_address'}){ print MODEMDATA "$VALUES{'ip_address'},"; } 
> else { print MODEMDATA ","; }
>               if($VALUES{'level_up'}){ print MODEMDATA "$VALUES{'level_up'},"; } 
> else { print MODEMDATA ","; }
>               if($VALUES{'level_down'}){ print MODEMDATA "$VALUES{'level_down'},"; } 
> else { print MODEMDATA ","; }
>               if($VALUES{'sn_ratio'}){ print MODEMDATA "$VALUES{'sn_ratio'},"; } 
> else { print MODEMDATA ","; }
>               if($VALUES{'date'}){ print MODEMDATA "$VALUES{'date'},"; } else { 
> print MODEMDATA ","; }
>               if($VALUES{'config_file'}){ print MODEMDATA "$VALUES{'config_file'},"; 
> } else { print MODEMDATA ","; }
>               if($VALUES{'firmware_ver'}){ print MODEMDATA 
> "$VALUES{'firmware_ver'},"; } else { print MODEMDATA ","; }

> if($VALUES{'sysDescr'}){ print MODEMDATA "$VALUES{'sysDescr'},"; } else { print 
> MODEMDATA ","; }
>               if($VALUES{'sw_ver'}){ print MODEMDATA "$VALUES{'sw_ver'}\n"; } else { 
> print MODEMDATA "\n"; }
>               close(MODEMDATA);
>                 }
>                                                                                      
>                      
>                 print $control "$num\n";
>             }
>             exit;
>         };
>                                                                                      
>                      
>         # parent
>         $data->writer;
>         $data->autoflush(1);
>         push @child, $data;
>         next;
>                                                                                      
>                      
>     }
>     my $startcmts=time();
>     # send data to children as they become ready
>     my($res_ip,@cmip,$key,%res_ip,$ip,%VALUES,@tmp,@macparts,$SESSION);
>     my $oid_ip=".1.3.6.1.2.1.10.127.1.3.3.1.3";
>     my ($session,$error_line) = Net::SNMP->session(
>                                 -hostname => '192.168.200.1',
>                                 -version => 2,
>                                 -community => 'notdisplayed'
>                                 );
>     if (!defined($res_ip=$session->get_table($oid_ip))) {
>                 printf(" %s\n", $session->error);
>                 $error_line=$session->error;
>                 $session->close;
>                 next;
>         }
>     my $ipc=0;

>     foreach $key (sort keys %$res_ip) {
>       $cmip[$ipc]=$$res_ip{$key};
>       $ipc++;
>     }
>     my $endcmts=time();
>     my $n = 0;
>     my $modemcount=0;
>     my $en = scalar(@cmip);
>                                                                                      
>                      
>     $control->reader;
>     while(<$control>) {
>         chomp;
>         my $fh = $child[$_ - 1];
>         if($cmip[$n] ne '0.0.0.0'){
>           print $fh "$cmip[$n]\n";
>           print STDERR "$fh - $cmip[$n] -";
>           $modemcount++;
>         }
>         $n++;
>         last if $n == $en;
>     }
>                                                                                      
>                      
>     # reap the children
>     close $_ for @child;
>     1 while wait > 0;
>                                                                                      
>                      
>     my $end=time();
>     my $howsec=($end - $start);
>     my $howlong;
>     $howlong = $howsec." Seconds.";
>     print STDERR "Total Modems: $en\n";
>     print STDERR "CMTS Response Time: ".($endcmts - $startcmts)." Seconds\n";
>     print STDERR "Responding Modems: ".($modemcount - 1)."\n";
>     print STDERR "Time To Process: $howlong\n";
> exit;



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to