diff --git a/perl-xCAT/xCAT/PPCcli.pm b/perl-xCAT/xCAT/PPCcli.pm index a47483e71..d2219d618 100644 --- a/perl-xCAT/xCAT/PPCcli.pm +++ b/perl-xCAT/xCAT/PPCcli.pm @@ -80,7 +80,7 @@ my %mksysconn = ( ############################################## my %rmsysconn = ( fsp => "rmsysconn -o remove -m %s", - bpa => "mksysconn -o remove -e %s" + bpa => "rmsysconn -o remove -e %s" ); ############################################## diff --git a/perl-xCAT/xCAT/PPCconn.pm b/perl-xCAT/xCAT/PPCconn.pm index 440ea96ca..bb2759ee7 100644 --- a/perl-xCAT/xCAT/PPCconn.pm +++ b/perl-xCAT/xCAT/PPCconn.pm @@ -144,6 +144,41 @@ sub lsconn_parse_args if ( scalar @$args) { return(usage( "No additional flag is support by this command" )); } + my $notypetab = xCAT::Table->new('nodetype'); + if (! $notypetab) + { + return( "Failed to open nodetype table.\n"); + } + + my $nodetype; + for my $node ( @{$request->{node}}) + { + my $ent = $notypetab->getNodeAttribs( $node, [qw(nodetype)]); + if ( ! $ent) + { + return( ["Failed to get node type for node $node.\n"]); + } + if ( $ent->{nodetype} ne 'hmc' + and $ent->{nodetype} ne 'fsp' + and $ent->{nodetype} ne 'bpa') + { + return( ["Node type $ent->{nodetype} is not supported for this command.\n"]); + } + if ( ! $nodetype) + { + $nodetype = $ent->{nodetype}; + } + else + { + if ( $nodetype ne $ent->{nodetype}) + { + return( ["Cannot support multiple node types in this command line.\n"]); + } + } + } + + $request->{nodetype} = $nodetype; + $request->{method} = 'lsconn'; return( \%opt); } @@ -246,52 +281,91 @@ sub lsconn my $res = xCAT::PPCcli::lssysconn( $exp); $Rc = shift @$res; - for my $cec_bpa ( keys %$hash) + if ( $request->{nodetype} eq 'hmc') { - my $node_hash = $hash->{$cec_bpa}; - my ($node_name) = keys %$node_hash; - ############################################ - # If lssysconn failed, put error into all - # nodes' return values - ############################################ - if ( $Rc ) + if ( $Rc) { - push @value, [$node_name, @$res[0], $Rc]; - next; + push @value, [$exp->[3], $res->[0], $Rc]; + return \@value; } - ############################ - # Search node in result - ############################ - my $d = $node_hash->{$node_name}; - my ( undef,undef,undef,undef,$type) = @$d; - if ( $type eq 'bpa') + my $vpdtab = xCAT::Table->new('vpd'); + my @vpdentries = $vpdtab->getAllAttribs(qw(node serial mtm)); + my %node_vpd_hash; + for my $vpdent ( @vpdentries) { - $type='frame'; - } - elsif ( $type eq 'fsp') - { - $type='sys'; - } - else - { - push @value, [$node_name, 'Unsupported node type', 1]; - next; - } - - if ( my @res_matched = grep /\Qtype_model_serial_num=$cec_bpa,\E/, @$res) - { - for my $r ( @res_matched) + if ( $vpdent->{node} and $vpdent->{serial} and $vpdent->{mtm}) { - $r =~ s/\Qtype_model_serial_num=$cec_bpa,\E//; - $r =~ s/\Qresource_type=$type,\E//; - $r =~ s/sp=.*?,//; - $r =~ s/sp_phys_loc=.*?,//; - push @value, [$node_name, $r, $Rc]; + $node_vpd_hash{"$vpdent->{mtm}*$vpdent->{serial}"} = $vpdent->{node}; } } - else + for my $r ( @$res) { - push @value, [$node_name, 'Connection not found', 1]; + $r =~ s/type_model_serial_num=([^,]*),//; + my $mtms = $1; + $r =~ s/resource_type=([^,]*),//; + $r =~ s/sp=.*?,//; + $r =~ s/sp_phys_loc=.*?,//; + my $node_name; + if ( exists $node_vpd_hash{$mtms}) + { + $node_name = $node_vpd_hash{$mtms}; + } + else + { + $node_name = $mtms; + } + push @value, [ $node_name, $r, $Rc]; + } + } + else + { + for my $cec_bpa ( keys %$hash) + { + my $node_hash = $hash->{$cec_bpa}; + my ($node_name) = keys %$node_hash; + ############################################ + # If lssysconn failed, put error into all + # nodes' return values + ############################################ + if ( $Rc ) + { + push @value, [$node_name, @$res[0], $Rc]; + next; + } + ############################ + # Search node in result + ############################ + my $d = $node_hash->{$node_name}; + my ( undef,undef,undef,undef,$type) = @$d; + if ( $type eq 'bpa') + { + $type='frame'; + } + elsif ( $type eq 'fsp') + { + $type='sys'; + } + else + { + push @value, [$node_name, 'Unsupported node type', 1]; + next; + } + + if ( my @res_matched = grep /\Qtype_model_serial_num=$cec_bpa,\E/, @$res) + { + for my $r ( @res_matched) + { + $r =~ s/\Qtype_model_serial_num=$cec_bpa,\E//; + $r =~ s/\Qresource_type=$type,\E//; + $r =~ s/sp=.*?,//; + $r =~ s/sp_phys_loc=.*?,//; + push @value, [$node_name, $r, $Rc]; + } + } + else + { + push @value, [$node_name, 'Connection not found', 1]; + } } } return \@value; @@ -318,7 +392,7 @@ sub rmconn my ( undef,undef,undef,undef,$type) = @$d; - my $res = xCAT::PPCcli::mksysconn( $exp, $type, $cec_bpa); + my $res = xCAT::PPCcli::rmsysconn( $exp, $type, $cec_bpa); $Rc = shift @$res; push @value, [$node_name, @$res[0], $Rc]; } diff --git a/perl-xCAT/xCAT/PPCfsp.pm b/perl-xCAT/xCAT/PPCfsp.pm index 77b051004..3c98bdc84 100644 --- a/perl-xCAT/xCAT/PPCfsp.pm +++ b/perl-xCAT/xCAT/PPCfsp.pm @@ -1735,6 +1735,17 @@ sub set_netcfg } return ( [RC_ERROR,"Cannot find interface $inc_name"]) if ( ! exists ($$interfaces{ $real_inc_name})); + my $inc_type; + my @set_entries = (); + if ( $inc_ip eq '0.0.0.0') + { + $inc_type = 'Dynamic'; + push @set_entries, 'IP type to dynamic.'; + } + else + { + $inc_type = 'Static'; + } #not work on AIX # $interfaces->{ $real_inc_name}->{'selected'}->check(); @@ -1742,39 +1753,48 @@ sub set_netcfg $interfaces->{ $real_inc_name}->{'selected'}->value(@tmp_options[1] ); if ( $interfaces->{ $real_inc_name}->{'type'}) { - @tmp_options = $interfaces->{ $real_inc_name}->{'type'}->possible_values(); - $interfaces->{ $real_inc_name}->{'type'}->value(@tmp_options[0]); + my @type_options = @{$interfaces->{ $real_inc_name}->{'type'}->{'menu'}}; + for my $typeopt ( @type_options) + { + if ( $typeopt->{'name'} eq $inc_type) + { + $interfaces->{ $real_inc_name}->{'type'}->value($typeopt->{'value'}); + last; + } + } #not work on AIX # $interfaces->{ $real_inc_name}->{'type'}->value('Static'); } else { - return ( [RC_ERROR,"Cannot set this interface to static type"]); + return ( [RC_ERROR,"Cannot change interface type"]); } - my @set_entries = (); - if ( $inc_ip ) + if ( $inc_type eq 'Static') { - return ( [RC_ERROR,"Cannot set IP address to $inc_ip"]) if (! $interfaces->{ $real_inc_name}->{'ip'}); - $interfaces->{ $real_inc_name}->{'ip'}->value( $inc_ip); - push @set_entries, 'IP address'; - } - if ( $inc_host) - { - return ( [RC_ERROR,"Cannot set hostname to $inc_host"]) if (! $interfaces->{ $real_inc_name}->{'hostname'}); - $interfaces->{ $real_inc_name}->{'hostname'}->value( $inc_host); - push @set_entries, 'hostname'; - } - if ( $inc_gateway) - { - return ( [RC_ERROR,"Cannot set gateway to $inc_gateway"]) if (! $interfaces->{ $real_inc_name}->{'gateway'}); - $interfaces->{ $real_inc_name}->{'gateway'}->value( $inc_gateway); - push @set_entries, 'gateway'; - } - if ( $inc_netmask) - { - return ( [RC_ERROR,"Cannot set netmask to $inc_netmask"]) if (! $interfaces->{ $real_inc_name}->{'netmask'}); - $interfaces->{ $real_inc_name}->{'netmask'}->value( $inc_netmask); - push @set_entries, 'netmask'; + if ( $inc_ip) + { + return ( [RC_ERROR,"Cannot set IP address to $inc_ip"]) if (! $interfaces->{ $real_inc_name}->{'ip'}); + $interfaces->{ $real_inc_name}->{'ip'}->value( $inc_ip); + push @set_entries, 'IP address'; + } + if ( $inc_host) + { + return ( [RC_ERROR,"Cannot set hostname to $inc_host"]) if (! $interfaces->{ $real_inc_name}->{'hostname'}); + $interfaces->{ $real_inc_name}->{'hostname'}->value( $inc_host); + push @set_entries, 'hostname'; + } + if ( $inc_gateway) + { + return ( [RC_ERROR,"Cannot set gateway to $inc_gateway"]) if (! $interfaces->{ $real_inc_name}->{'gateway'}); + $interfaces->{ $real_inc_name}->{'gateway'}->value( $inc_gateway); + push @set_entries, 'gateway'; + } + if ( $inc_netmask) + { + return ( [RC_ERROR,"Cannot set netmask to $inc_netmask"]) if (! $interfaces->{ $real_inc_name}->{'netmask'}); + $interfaces->{ $real_inc_name}->{'netmask'}->value( $inc_netmask); + push @set_entries, 'netmask'; + } } #Click "Continue" button @@ -1788,15 +1808,22 @@ sub set_netcfg #Go to the confirm page $form = HTML::Form->parse( $res->content, $res->base ); $data = $form->click('submit'); + #xCAT::MsgUtils->message("I", "Updating network configuration for node " . $exp->[1] . "..."); + $ua->timeout( 10); $res = $ua->request( $data); - if ($res->is_success()) - { - return ( [SUCCESS, "Success to set " . join ',', @set_entries]); - } - else - { - return ( [RC_ERROR, "Failed to set " . join ',', @set_entries]); - } + ############################################################## + # We cannot get the result of this update, since the network + # is updated, the old URI is invalid anymore + # Return success directory + ############################################################## + #if ($res->is_success()) + #{ + return ( [SUCCESS, "Success to set " . join ',', @set_entries]); + #} + #else + #{ + # return ( [RC_ERROR, "Failed to set " . join ',', @set_entries]); + #} } ########################################################################## diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index 9e65264cd..affc87bd0 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -581,7 +581,8 @@ sub preprocess_nodes { # Direct-attached FSP ######################################## if (( $request->{command} =~ /^(rscan|rspconfig)$/ ) or - ( $request->{hwtype} eq "fsp" or $request->{hwtype} eq "bpa")) { + ( $request->{hwtype} eq "fsp" or $request->{hwtype} eq "bpa") or + ($request->{command} eq 'lsconn' and $request->{nodetype} eq 'hmc')) { my $result = resolve_hcp( $request, $noderange ); return( $result ); } diff --git a/xCAT-server/lib/xcat/plugins/hmc.pm b/xCAT-server/lib/xcat/plugins/hmc.pm index ab5510e87..1e3f45248 100644 --- a/xCAT-server/lib/xcat/plugins/hmc.pm +++ b/xCAT-server/lib/xcat/plugins/hmc.pm @@ -24,7 +24,7 @@ sub handled_commands { rflash => 'nodehm:mgt', mkconn => 'nodehm:mgt', rmconn => 'nodehm:mgt', - chconn => 'nodehm:mgt' + lsconn => 'nodehm:mgt' }; } diff --git a/xCAT-server/lib/xcat/plugins/lsslp.pm b/xCAT-server/lib/xcat/plugins/lsslp.pm index b84ecc706..84abc149d 100644 --- a/xCAT-server/lib/xcat/plugins/lsslp.pm +++ b/xCAT-server/lib/xcat/plugins/lsslp.pm @@ -194,7 +194,7 @@ sub parse_args { # Process command-line flags ############################################# if (!GetOptions( \%opt, - qw(h|help V|Verbose v|version i=s x z w r s=s e=s t=s m c u))) { + qw(h|help V|Verbose v|version i=s x z w r s=s e=s t=s m c u H))) { return( usage() ); } ############################################# @@ -247,14 +247,17 @@ sub parse_args { if ( (exists($opt{r}) + exists($opt{x}) + exists($opt{z})) > 1 ) { return( usage() ); } + if ( (exists($opt{u}) + exists($opt{H})) > 1 ) { + return( usage("Cannot use flags -u and -H together")); + } ############################################# # Command tries ############################################# if ( exists( $opt{t} )) { $maxtries = $opt{t}; - if ( $maxtries !~ /^0?[1-5]$/ ) { - return( usage( "Invalid command tries (1-5)" )); + if ( $maxtries !~ /^0?[1-9]$/ ) { + return( usage( "Invalid command tries (1-9)" )); } } ############################################# @@ -856,6 +859,13 @@ sub runslp { my $url = $data[$i++]; my $attr = $data[$i]; + #Give some intermediate output + my ($url_ip) = $url =~ /:\/\/(\d+\.\d+\.\d+\.\d+)/; + if ( ! $::DISCOVERED_HOST{$url_ip}) + { + send_msg( $request, 0, "Received SLP response from $url_ip."); + $::DISCOVERED_HOST{$url_ip} = 1; + } if ( $verbose ) { trace( $request, ">>>> SrvRqst Response" ); trace( $request, "URL: $url" ); @@ -966,7 +976,7 @@ sub format_output { # Query switch ports ########################################### my $rsp_targets = undef; - if ( $opt{u}) + if ( $opt{u} or $opt{H}) { $rsp_targets = switch_cmd( $request, $values ); } @@ -1093,10 +1103,33 @@ sub gethost_from_url { return undef; } ####################################### - # Convert IP to hostname + # Read host from hosts table ####################################### + if ( ! %::HOST_TAB_CATCH) + { + my $hosttab = xCAT::Table->new( 'hosts' ); + my @entries = $hosttab->getAllNodeAttribs(['node','ip']); + #Assuming IP is unique in hosts table + for my $entry ( @entries) + { + if ( defined $entry->{ 'ip'}) + { + $::HOST_TAB_CATCH{$entry->{ 'ip'}} = $entry->{ 'node'}; + } + } + } + if ( exists $::HOST_TAB_CATCH{ $ip}) + { + return $::HOST_TAB_CATCH{ $ip}; + } + + ############################################################### + # Convert IP to hostname (Accoording to DNS or /etc/hosts + ############################################################### my $host = gethostbyaddr( $packed, AF_INET ); if ( !$host or $! ) { +#Tentative solution +return undef if ($opt{H}); return( $ip ); } ####################################### @@ -1360,6 +1393,23 @@ sub xCATdB { my $outhash = shift; my %keyhash = (); my %updates = (); + my %sn_node = (); + ############################ + # Cache vpd table + ############################ + my $vpdtab = undef; + $vpdtab = xCAT::Table->new('vpd'); + if ($vpdtab) + { + my @ents=$vpdtab->getAllNodeAttribs(['serial','mtm']); + for my $ent ( @ents) + { + if ( $ent->{mtm} and $ent->{serial}) + { + $sn_node{"$ent->{mtm}*$ent->{serial}"} = $ent->{node}; + } + } + } foreach ( keys %$outhash ) { my $data = $outhash->{$_}; @@ -1402,7 +1452,14 @@ sub xCATdB { # May be no Frame with this FSP ######################################## if (( $bpc_model ne "0" ) and ( $bpc_serial ne "0" )) { - $frame = "$bpc_model*$bpc_serial"; + if ( exists $sn_node{"$bpc_model*$bpc_serial"}) + { + $frame = $sn_node{"$bpc_model*$bpc_serial"}; + } + else + { + $frame = "$bpc_model*$bpc_serial"; + } } ######################################## # "Factory-default" FSP name format: @@ -1786,7 +1843,11 @@ sub runcmd { # Fork one process per adapter ########################################### my $children = 0; - $SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { $children--; } }; + $SIG{CHLD} = sub { + my $rc_bak = $?; + while (waitpid(-1, WNOHANG) > 0) { $children--; } + $? = $rc_bak; + }; my $fds = new IO::Select; foreach ( keys %ip_addr ) { @@ -1975,47 +2036,68 @@ sub switch_cmd { if ( $verbose ) { trace( $req, "SWITCH/HOSTS TABLE:" ); } - foreach my $nodename ( @entries ) { - my $ent = undef; - if ( $hosttab) - { - my $enthash = $hosttab->getNodeAttribs( $nodename,[qw(ip)]); - $ent = $enthash->{ip}; - } - if (!$ent) - { - my $net_bin = inet_aton($nodename); - $ent = inet_ntoa($net_bin) if ($net_bin); - } + if ( $opt{u}) + { + foreach my $nodename ( @entries ) { + my $ent = undef; + if ( $hosttab) + { + my $enthash = $hosttab->getNodeAttribs( $nodename,[qw(ip)]); + $ent = $enthash->{ip}; + } + if (!$ent) + { + my $net_bin = inet_aton($nodename); + $ent = inet_ntoa($net_bin) if ($net_bin); + } - if ( !$ent ) { - next; - } + if ( !$ent ) { + next; + } - $hosts{ $nodename} = $ent; - if ( $verbose ) { - trace( $req, "\t\t($nodename)->($ent)" ); + $hosts{ $nodename} = $ent; + if ( $verbose ) { + trace( $req, "\t\t($nodename)->($ent)" ); + } + } + ########################################### + # No MMs/HMCs in hosts/switch table + ########################################### + if ( !%hosts ) { + return undef; } - } - ########################################### - # No MMs/HMCs in hosts/switch table - ########################################### - if ( !%hosts ) { - return undef; } ########################################### # Ping each MM/HMCs to update arp table ########################################### + my %internal_ping_catch; foreach my $ips ( keys %$slp_all ) { my @all_ips = split /,/, $ips; my $rc = 0; for my $single_ip (@all_ips) { - #not sure why runcmd cannot handle the return code - #my $res = xCAT::Utils->runcmd ("ping -c 1 -w 1 $single_ip", -1); - trace ($req, "Trying ping $single_ip"); - my $rc = system("ping -c 1 -w 1 $single_ip 2>/dev/null 1>/dev/null"); - if ( !$::RUNCMD_RC ) + my $rc; + if ( exists $internal_ping_catch{ $single_ip}) + { + $rc = $internal_ping_catch{ $single_ip}; + } + else + { + trace ($req, "Trying ping $single_ip"); + #$rc = system("ping -c 1 -w 1 $single_ip 2>/dev/null 1>/dev/null"); + my $res = `LANG=C ping -c 1 -w 1 $single_ip 2>&1`; + if ( $res =~ /100% packet loss/g) + { + $rc = 1; + } + else + { + $rc = 0; + } + #$rc = $?; + $internal_ping_catch{ $single_ip} = $rc; + } + if ( !$rc ) { $slp_all->{$single_ip} = $slp_all->{ $ips}; delete $slp_all->{ $ips}; @@ -2092,7 +2174,7 @@ sub switch_cmd { if ( $verbose ) { trace( $req, "getting switch information...." ); } - foreach my $ip ( keys %$slp_all ) { + foreach my $ip ( sort keys %$slp_all ) { ####################################### # Not in SLP response ####################################### @@ -2118,7 +2200,7 @@ sub switch_cmd { $name = disti_multi_node( $req, $names, $slp_all->{$ip}); if ( ! $name) { - trace( $req, "Cannot identify node $ip."); + trace( $req, "\t\tCannot identify node $ip."); next; } @@ -2133,43 +2215,78 @@ sub switch_cmd { ####################################### # In hosts table ####################################### - if ( defined( $hosts{$name} )) { - if ( $ip eq $hosts{$name} ) { - if ( $verbose ) { - trace( $req, "\t\t\t$slp_all->{$ip}->{'type'} already set '$ip' - skipping" ); + if ( $opt{u}) + { + if ( defined( $hosts{$name} )) { + if ( $ip eq $hosts{$name} ) { + if ( $verbose ) { + trace( $req, "\t\t\t$slp_all->{$ip}->{'type'} already set '$ip' - skipping" ); + } } - } - else - { - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'args'} = "$hosts{$name},$name"; - if ( $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'type'} ne 'MM') + else { - my %netinfo = xCAT::DBobjUtils->getNetwkInfo([$hosts{$name}]); - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'args'} .= ",$netinfo{$hosts{$name}}{'gateway'},$netinfo{$hosts{$name}}{'mask'}"; + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'args'} = "$hosts{$name},$name"; + if ( $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'type'} ne 'MM') + { + my %netinfo = xCAT::DBobjUtils->getNetwkInfo([$hosts{$name}]); + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'args'} .= ",$netinfo{$hosts{$name}}{'gateway'},$netinfo{$hosts{$name}}{'mask'}"; + } + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'mac'} = $slp_all->{$ip}->{'mac'}; + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'name'} = $name; + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'ip'} = $hosts{$name}; + $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'type'} = $slp_all->{$ip}->{'type'}; } - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'mac'} = $slp_all->{$ip}->{'mac'}; - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'name'} = $name; - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'ip'} = $hosts{$name}; - $targets->{$slp_all->{$ip}->{'type'}}->{$ip}->{'type'} = $slp_all->{$ip}->{'type'}; } } + else + { + #An tentative solution. The final solution should be + #if there is any conflicting, remove this entry + $hosts{$name} = $ip if ( ! $hosts{$name}); + } } ########################################### # No rspconfig target found ########################################### - if ( !%$targets) { + if (( $opt{u} and !%$targets) or ( $opt{H} and !%hosts)) { if ( $verbose ) { trace( $req, "No ARP-Switch-SLP matches found" ); } - return; + return undef; } ########################################### # Update target hardware w/discovery info ########################################### - return rspconfig( $req, $targets ); + return rspconfig( $req, $targets ) if ($opt{u}); + ########################################### + # Update hosts table + ########################################### + send_msg( $req, 0, "Updating hosts table..."); + return update_hosts( $req, \%hosts); } +########################################### +# Update hosts table +########################################### +sub update_hosts +{ + my $req = shift; + my $hosts = shift; + my $hoststab = xCAT::Table->new( 'hosts', -create=>1, -autocommit=>0 ); + if ( !$hoststab) + { + send_msg( $req, 1, "Cannot open hosts table"); + return undef; + } + for my $node (keys %$hosts) + { + send_msg( $req, 0, "\t$node => $hosts->{$node}"); + $hoststab->setNodeAttribs( $node, {ip=>$hosts->{$node}}); + } + $hoststab->commit; + return SUCCESS; +} ########################################################################## # Distinguish ########################################################################## @@ -2179,10 +2296,13 @@ sub disti_multi_node my $names = shift; my $slp = shift; - return undef if ( ! exists $slp->{'cage-number'}); + return undef if ( $slp->{'type'} eq 'FSP' and ! exists $slp->{'cage-number'}); + return undef if ( $slp->{'type'} eq 'BPA' and ! exists $slp->{'frame-number'}); my $ppctab = xCAT::Table->new( 'ppc'); return undef if ( ! $ppctab); + my $nodetypetab = xCAT::Table->new( 'nodetype'); + return undef if ( ! $nodetypetab); my $vpdtab = xCAT::Table->new( 'vpd'); my @nodes = split /,/, $names; @@ -2191,7 +2311,12 @@ sub disti_multi_node { my $id_parent = $ppctab->getNodeAttribs( $node, ['id','parent']); next if (! defined $id_parent or ! exists $id_parent->{'id'}); - if ( $id_parent->{'id'} eq $slp->{'cage-number'}) + my $nodetype = $nodetypetab->getNodeAttribs($node, ['nodetype']); + next if (! defined $nodetype or ! exists $nodetype->{'nodetype'}); + next if ( $nodetype->{'nodetype'} ne lc($slp->{type})); + if ( ($nodetype->{'nodetype'} eq 'fsp' and $id_parent->{'id'} eq $slp->{'cage-number'}) or + ($nodetype->{'nodetype'} eq 'bpa' and $id_parent->{'id'} eq $slp->{ + 'frame-number'})) { my $vpdnode = undef; if ( defined $id_parent->{ 'parent'})#if no parent defined, take it as is.