diff --git a/xCAT-client/bin/pping b/xCAT-client/bin/pping index 49243a266..9dc52dc34 100755 --- a/xCAT-client/bin/pping +++ b/xCAT-client/bin/pping @@ -86,10 +86,20 @@ foreach (@nodes) { $deadnodes{$_}=1; } open (FPING, "nmap -sP ".join(' ',@nodes). " 2> /dev/null|") or die("Cannot open nmap pipe: $!"); +my $node; while () { if (/Host (.*) \(.*\) appears to be up/) { - print "$1: ping\n"; - delete $deadnodes{$1}; + $node=$1; + unless ($deadnodes{$node}) { + foreach (keys %deadnodes) { + if ($node =~ /^$_\./) { + $node = $_; + last; + } + } + } + delete $deadnodes{$node}; + print "$node: ping\n"; } } foreach (sort keys %deadnodes) { diff --git a/xCAT-client/xCAT-client.spec b/xCAT-client/xCAT-client.spec index 758eb948a..39bc67052 100644 --- a/xCAT-client/xCAT-client.spec +++ b/xCAT-client/xCAT-client.spec @@ -21,7 +21,7 @@ Provides: xCAT-client = %{version} # fping is needed by pping (in case xCAT-client is installed by itself on a remote client) %ifos linux -Requires: fping +Requires: nmap %endif %description diff --git a/xCAT-server/lib/xcat/plugins/nodestat.pm b/xCAT-server/lib/xcat/plugins/nodestat.pm index 1f34b19ad..bb43f5081 100644 --- a/xCAT-server/lib/xcat/plugins/nodestat.pm +++ b/xCAT-server/lib/xcat/plugins/nodestat.pm @@ -6,6 +6,7 @@ use Socket; use IO::Handle; use Getopt::Long; my $stat; +my %portservices; sub handled_commands { return { @@ -13,28 +14,6 @@ sub handled_commands { }; } -sub pinghost { - my $node = shift; - my $rc = system("ping -q -n -c 1 -w 1 $node > /dev/null"); - if ($rc == 0) { - return 1; - } else { - return 0; - } -} - -sub nodesockopen { - my $node = shift; - my $port = shift; - my $socket; - my $addr = gethostbyname($node); - my $sin = sockaddr_in($port,$addr); - my $proto = getprotobyname('tcp'); - socket($socket,PF_INET,SOCK_STREAM,$proto) || return 0; - connect($socket,$sin) || return 0; - return 1; -} - sub installer_query { my $node = shift; my $destport = 3001; @@ -128,40 +107,20 @@ sub preprocess_request } } return \@requests; -} - -sub interrogate_node { #Meant to run against confirmed up nodes - my $node=shift; - my $doreq=shift; - my $status = ""; - if (nodesockopen($node,15002)) { - $status.="pbs," - } - if (nodesockopen($node,8002)) { - $status.="xend," - } - if (nodesockopen($node,22)) { - $status.="sshd," - } - $status =~ s/,$//; - if ($status) { - return $status; - } - if ($status = installer_query($node)) { - return $status; - } else { #pingable, but no *clue* as to what the state may be - $doreq->({command=>['nodeset'], - node=>[$node], - arg=>['stat']}, - \&getstat); - return 'ping '.$stat; - } + return 0; } sub process_request { my $request = shift; my $callback = shift; my $doreq = shift; + %portservices = ( + '22' => 'ssh', + '15002' => 'pbs', + '8002' => 'xend', + ); + my @livenodes; + $statselect = new IO::Select; my @nodes = @{$request->{node}}; my %unknownnodes; foreach (@nodes) { @@ -171,69 +130,66 @@ sub process_request { if( !defined $packed_ip) { my %rsp; $rsp{name}=[$_]; - $rsp{data} = [ "Please make sure $_ exists in /etc/hosts" ]; + $rsp{data} = [ "Please make sure $_ exists in /etc/hosts or DNS" ]; $callback->({node=>[\%rsp]}); } } my $node; my $fping; - open($fping,"fping ".join(' ',@nodes). " 2> /dev/null|") or die("Can't start fping: $!"); - while (<$fping>) { - my %rsp; - my $node=$_; - $node =~ s/ .*//; - chomp $node; - if (/ is alive/) { - $rsp{name}=[$node]; - $rsp{data} = [ interrogate_node($node,$doreq) ]; - $callback->({node=>[\%rsp]}); - } elsif (/is unreachable/) { - $rsp{name}=[$node]; - $rsp{data} = [ 'noping' ]; - $callback->({node=>[\%rsp]}); - } elsif (/ address not found/) { - $rsp{name}=[$node]; - $rsp{data} = [ 'nosuchhost' ]; - $callback->({node=>[\%rsp]}); - } - } - @nodes=(); - foreach $node (@nodes) { - my %rsp; - my $text=""; - $rsp{name}=[$node]; - unless (pinghost($node)) { - $rsp{data} = [ 'noping' ]; - $callback->({node=>[\%rsp]}); - next; - } - if (nodesockopen($node,15002)) { - $rsp{data} = [ 'pbs' ]; - $callback->({node=>[\%rsp]}); - next; - } elsif (nodesockopen($node,8002)) { - $rsp{data} = [ 'xend' ]; - $callback->({node=>[\%rsp]}); - next; - } elsif (nodesockopen($node,22)) { - $rsp{data} = [ 'sshd' ]; - $callback->({node=>[\%rsp]}); - next; - } elsif ($text = installer_query($node)) { - $rsp{data} = [ $text ]; - $callback->({node=>[\%rsp]}); - next; - } else { - $doreq->({command=>['nodeset'], - node=>[$node], - arg=>['stat']}, - \&getstat); - $rsp{data} = [ 'ping '.$stat ]; - $callback->({node=>[\%rsp]}); - next; - } + my $ports = join ',',keys %portservices; + my %deadnodes; + foreach (@nodes) { + $deadnodes{$_}=1; } + open($fping,"nmap -p $ports ".join(' ',@nodes). " 2> /dev/null|") or die("Can't start nmap: $!"); + my $currnode=''; + my $port; + my $state; + my %states; + my %rsp; + while (<$fping>) { + if (/Interesting ports on ([^ ]*) /) { + $currnode=$1; + unless ($deadnodes{$1}) { + foreach (keys %deadnodes) { + if ($currnode =~ /^$_\./) { + $currnode = $_; + last; + } + } + } + delete $deadnodes{$currnode}; + } elsif ($currnode) { + if (/^MAC/) { + $rsp{name}=[$currnode]; + my $status = join ',',sort keys %states ; + unless ($status or $status = installer_query($currnode)) { #pingable, but no *clue* as to what the state may be + $doreq->({command=>['nodeset'], + node=>[$currnode], + arg=>['stat']}, + \&getstat); + $status= 'ping '.$stat; + } + + $rsp{data} = [ $status ]; + $callback->({node=>[\%rsp]}); + $currnode=""; + %states=(); + next; + } + if (/^PORT/) { next; } + ($port,$state) = split; + if ($port =~ /^(\d*)\// and $state eq 'open') { + $states{$portservices{$1}}=1; + } + } + } + foreach $currnode (sort keys %deadnodes) { + $rsp{name}=[$currnode]; + $rsp{data} = [ 'noping' ]; + $callback->({node=>[\%rsp]}); + } } sub usage { diff --git a/xCAT/xCAT.spec b/xCAT/xCAT.spec index c81e04fee..b73de9b9f 100644 --- a/xCAT/xCAT.spec +++ b/xCAT/xCAT.spec @@ -19,7 +19,7 @@ Requires: xCAT-server xCAT-client perl-DBD-SQLite %ifos linux # yaboot-xcat is pulled in so any MN can manage ppc nodes -Requires: atftp dhcp httpd nfs-utils expect fping bind perl-XML-Parser vsftpd yaboot-xcat +Requires: atftp dhcp httpd nfs-utils expect nmap bind perl-XML-Parser vsftpd yaboot-xcat %ifarch s390x # No additional requires for zLinux right now %else diff --git a/xCATsn/xCATsn.spec b/xCATsn/xCATsn.spec index f56879df5..46ceaf255 100644 --- a/xCATsn/xCATsn.spec +++ b/xCATsn/xCATsn.spec @@ -18,7 +18,7 @@ Requires: xCAT-server xCAT-client perl-xCAT perl-XML-Parser %ifos linux # yaboot-xcat is pulled in so any SN can manage ppc nodes -Requires: atftp dhcp httpd nfs-utils expect fping bind yaboot-xcat +Requires: atftp dhcp httpd nfs-utils expect nmap bind yaboot-xcat %ifarch s390x # No additional requires for zLinux right now %else