diff --git a/xCAT-client/bin/ppping b/xCAT-client/bin/ppping new file mode 100755 index 000000000..1aaf5d290 --- /dev/null +++ b/xCAT-client/bin/ppping @@ -0,0 +1,140 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +#Note, this ppping still frontends fping. I think it would be possible to write a perl equivalent, but +#I've not had the time. Net::Ping shows perl code I could see being adapted for a somewhat +#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async +#method Net::Ping provides. +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use IO::Socket::SSL; +use XML::Simple; +if ($^O =~ /^linux/i) { + $XML::Simple::PREFERRED_PARSER='XML::Parser'; +} +use Data::Dumper; +use IO::Handle; +use IO::Select; +use xCAT::Utils; +use Getopt::Long; +my $interface; + +my $USAGE="Usage: ppping [-i|--interface interface] [-s|--serial] noderange + ppping -h|--help + pping -v|--version\n"; + +# parse the options +if(!GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION, + 's|serial' => \$::SERIAL, + 'interface=s' => \$interface)) +{ + print "$USAGE"; + exit 1; +} + +if ($::HELP) { print "$USAGE"; exit 0} +if ($::VERSION) {print xCAT::Utils->Version() . "\n"; exit 0} + +my $xcathost='localhost:3001'; +if ($ENV{XCATHOST}) { + $xcathost=$ENV{XCATHOST}; +} + +unless (@ARGV) { + print "$USAGE"; + exit 1; +} +my $noderange = $ARGV[0]; +my $client = IO::Socket::SSL->new( + PeerAddr=>$xcathost, + SSL_key_file=>$ENV{HOME}."/.xcat/client-cred.pem", + SSL_cert_file=>$ENV{HOME}."/.xcat/client-cred.pem", + SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem", + SSL_use_cert => 1, + #SSL_verify_mode => 1, + ); +die "Connection failure: $!\n" unless ($client); +my %cmdref = (command => 'noderange', noderange => $noderange); +$SIG{ALRM} = sub { die "No response getting noderange" }; +alarm(15); +print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []); +alarm(15); +my $response=""; +my @nodes=(); +while (<$client>) { + alarm(0); + $response .= $_; + if ($response =~ m/<\/xcatresponse>/) { + $rsp=XMLin($response, ForceArray => ['node']); + $response=''; + if ($rsp->{warning}) { + printf "Warning: ".$rsp->{warning}."\n"; + } + if ($rsp->{error}) { + die ("ERROR: ".$rsp->{error}."\n"); + } elsif ($rsp->{node}) { + @nodes=@{$rsp->{node}}; + } + if ($rsp->{serverdone}) { + last; + } + } +} +close($client); +my $children = 0; +my $inputs = new IO::Select; +$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } }; + +unless (scalar(@nodes)) { + exit; +} + +my @reachable_nodes=(); +my @unreachable_nodes=(); +open (PPING, "$::XCATROOT/bin/pping ".join(',',@nodes). " 2> /dev/null|") or die("Cannot open pping-internal pipe: $!"); +while () { + if ($_ =~ / ping/) { + my @a_tmp=split(':', $_); + push(@reachable_nodes, $a_tmp[0]); + } + else { + my @a_tmp=split(':', $_); + push(@unreachable_nodes, $a_tmp[0]); + } +} +close(PPING); + +foreach(@unreachable_nodes) { + print "$_: noping\n"; +} + +my $i_string=""; +if ($interface) { $i_string="-i $interface"; } + +if (@reachable_nodes > 0) { + my $allnodes=join(',', @nodes); + if ($::SERIAL) { + foreach(@reachable_nodes) { + my $result=`$::XCATROOT/bin/xdsh $_ -B -e $::XCATROOT/sbin/pping2 "$i_string -q $allnodes" 2>&1`; + print "$result"; + } + } else { + my $node_string=join(',', @reachable_nodes); + open (PPING2, "$::XCATROOT/bin/xdsh $node_string -B -s -e $::XCATROOT/sbin/pping2 \"$i_string -q $allnodes\" 2> /dev/null|") or die("Cannot open pping-internal pipe: $!"); + while () { + print "$_"; + } + close(PPING2); + } + +} + +exit 0; + + + diff --git a/xCAT-client/pods/man1/ppping.1.pod b/xCAT-client/pods/man1/ppping.1.pod index 70a169864..f58d5617e 100644 --- a/xCAT-client/pods/man1/ppping.1.pod +++ b/xCAT-client/pods/man1/ppping.1.pod @@ -15,10 +15,10 @@ B {B<-v>|B<--version>} =head1 DESCRIPTION B is a utility used to test ping between nodes in the noderange. -B will return an unsorted list of nodes with a ping or noping status. The list is actually sorted by first ping, unless -s is specified. +B will return an unsorted list of nodes with a noping status. B front-ends ping and fping if available. -This command does not support the xcatd client/server communication. It must be run on the management node. +This command does not support the xcatd client/server communication. It must be run on the management node. =head1 OPTIONS diff --git a/xCAT-client/sbin/pping2 b/xCAT-client/sbin/pping2 new file mode 100755 index 000000000..aed31d8fd --- /dev/null +++ b/xCAT-client/sbin/pping2 @@ -0,0 +1,70 @@ +#!/bin/ksh +#egan@us.ibm.com +#(C)IBM Corp +# + +SERIAL="" +ETH="" +Q=0 +while [ -n "$1" ] +do + case "$1" in + -q) + Q=1 + shift + ;; + -s) + SERIAL="on" + shift + ;; + -i) + shift + ETH=$1 + shift + ;; + *) + LEFT="$LEFT $1" + shift + ;; + esac +done + +if [ -n "$LEFT" ] +then + set $LEFT +fi + +nodes=`echo $1 |sed "s/,/ /g"` +if [ -n "$ETH" ]; then + nodes=`echo $nodes |sed "s/ /-$ETH /g"` + nodes="$nodes-$ETH" +fi + +which fping >/dev/null 2>&1 +if [ "$?" = "0" ]; then + if [ "$Q" = "1" ]; then + fping $nodes 2>&1 | grep -v 'is alive' | sed "s/ is unreachable/: noping/" + else + fping $nodes 2>&1 | sed "s/ is alive/: ping/" | sed "s/ is unreachable/: noping/" + fi +else + JOBS="" + for i in $nodes + do + (if ping -c1 $i >/dev/null 2>&1 + then + if [ "$Q" = "0" ]; then + echo "$i: ping" + fi + else + echo "$i: noping" + fi) & + if [ -z "$SERIAL" ]; then + JOBS="$JOBS $!" + else + wait $! + fi + done + wait +fi +exit 0