Dru has asked for the wisdom of the Perl Monks concerning the following question:

Morning Monks,

I have the following script which worked in my testing, but of course when I try to put it into production, it failed. The problem is, the script executes the failover sub before the run subroutine has completed resulting in ip conflicts. Can someone take a look at my code and let me know how I can prevent the failover sub from executing until the run sub is complete.

Thanks,
Dru
#!/usr/bin/perl -w # This script tests to see if the primary fw is up. If it is not, then + it will attempt to connect via ssh to it and bring it down and make +itself the primary. use strict; use Mail::Sender; use IO::Socket::INET; use Net::SSH qw(ssh); my @host = qw[ 192.168.9.2 192.168.1.2 192.168.2.2 192.168.6.2 ]; my $port = '256'; # Check to see if all interfaces are listening on the fw port. If not, + run the connect sub. foreach (@host) { check($_, $port); } sub check { my ($ip, $port) = @_; my $sock = IO::Socket::INET->new( PeerAddr => $ip, PeerPort => $port, Proto => 'tcp', Timeout => 5, ); if ($sock) { print "$ip is listening on port $port\n"; return 1; } else{ print "$ip is NOT listening on port $port proceeding to failover. +\n" and &connect(); return; } } my $stout; my $success; # Attempt to connect to any of the fw's interfaces and then execute th +e run subroutine sub connect { for(@host){ $stout = run($_); unless($stout == 256) { $success++; last; } print "$_ not responding, trying next host\n"; } print "All hosts not responding" unless $success; } # Use Net::SSH to connect to the primary firewall and execute the down +_pri script to bring it's interfaces down. sub run { my $host = $_[0]; my $user = 'root'; my $cmd = '/usr/local/scripts/down_pri.pl'; ssh("$user\@$host", $cmd); if($stout == 256) { print "Problem sshing: $!\n" and exit; } else{ &failover(); } } # Run local commands on this server sub failover{ ... my @cmds = ($cmd1, $cmd2, $cmd3, $cmd4, $cmd5, $cmd6, $cmd7, $cmd8, $ +cmd9, $cmd10, $cmd11); foreach (@cmds){ system($_); } mail(); } # This sub uses the Mail::Sender module to email to our pagers sub mail { ... }

Replies are listed 'Best First'.
Re: Waiting for one Sub to Exit First
by physi (Friar) on Jan 31, 2003 at 15:34 UTC
    As far as I understand that, you're making a double loop.

    First you call :

    foreach (@host) { check($_, $port); }
    and for every host you call &connect. In the connect sub you loop again thru all the hosts:
    for(@host){ $stout = run($_); unless($stout == 256) { $success++; last; }

    So you probably reach your failover earlier than wanted ?

    ----------------------------------- --the good, the bad and the physi-- -----------------------------------
Re: Waiting for one Sub to Exit First
by robartes (Priest) on Jan 31, 2003 at 15:20 UTC
    I'm not quite sure I follow you. You say that the failover() sub executes before the run() sub is finished.

    Yet, from your source code, it seems that the failover() sub is called from only when all of the other actions in run() are done.

    Is this part of a larger, multithreaded script? Or do you mean that failover() executes before down_ip.pl finishes on the other host?

    CU
    Robartes-