diff --git a/perl-xCAT/xCAT/zvmUtils.pm b/perl-xCAT/xCAT/zvmUtils.pm
index 306b1ad1b..d18008afb 100644
--- a/perl-xCAT/xCAT/zvmUtils.pm
+++ b/perl-xCAT/xCAT/zvmUtils.pm
@@ -13,7 +13,6 @@ use xCAT::MsgUtils;
use xCAT::Utils;
use xCAT::Table;
use xCAT::NetworkUtils;
-use File::Copy;
use File::Basename;
use strict;
use warnings;
@@ -2851,4 +2850,131 @@ sub findzFcpDeviceAttr {
);
return \%attrs;
+}
+
+#-------------------------------------------------------
+
+=head3 findUsablezHcpNetwork
+
+ Description : Find a useable NIC shared with the zHCP for a given user Id
+ Arguments : User (root or non-root)
+ zHCP
+ User Id to find a useable NIC on
+ DHCP is used or not (0 or 1)
+ Returns : NIC, device channel, and layer (2 or 3)
+ Example : my ($nic, $channel, $layer) = xCAT::zvmUtils->findUsablezHcpNetwork($user, $hcp, $userId, $dhcp);
+
+=cut
+
+#-------------------------------------------------------
+sub findUsablezHcpNetwork {
+ # Get inputs
+ my ( $class, $user, $hcp, $userId, $dhcp ) = @_;
+
+ my $sudo = "sudo";
+ if ($user eq "root") {
+ $sudo = "";
+ }
+
+ my $nic = ''; # Usuable NIC on zHCP
+ my $channel = ''; # Device channel where NIC is attached
+ my $layer;
+ my $i;
+ my @words;
+
+ # Get the networks used by the zHCP
+ my @hcpNetworks = xCAT::zvmCPUtils->getNetworkNamesArray($user, $hcp);
+
+ # Search directory entry for network name
+ my $userEntry = `ssh $user\@$hcp "$sudo $::DIR/smcli Image_Query_DM -T $userId" | sed '\$d'`;
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() smcli Image_Query_DM -T $userId");
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() $userEntry");
+
+ my $out = `echo "$userEntry" | grep "NICDEF"`;
+ my @lines = split('\n', $out);
+
+ # Go through each line
+ for ($i = 0; $i < @lines; $i++) {
+ # Go through each network device attached to zHCP
+ foreach (@hcpNetworks) {
+
+ # If network device is found
+ if ($lines[$i] =~ m/ $_/i) {
+ # Get network layer
+ $layer = xCAT::zvmCPUtils->getNetworkLayer($user, $hcp, $_);
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() NIC:$_ layer:$layer");
+
+ # If template using DHCP, layer must be 2
+ if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
+ # Save network name
+ $nic = $_;
+
+ # Get network virtual address
+ @words = split(' ', $lines[$i]);
+
+ # Get virtual address (channel)
+ # Convert subchannel to decimal
+ $channel = sprintf('%d', hex($words[1]));
+
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() Candidate found NIC:$nic channel:$channel layer:$layer");
+ return ($nic, $channel, $layer);
+ } else {
+ # Go to next network available
+ $nic = '';
+ }
+ }
+ }
+ }
+
+ # If network device is not found
+ if (!$nic) {
+ # Check for user profile
+ my $profileName = `echo "$userEntry" | grep "INCLUDE"`;
+ if ($profileName) {
+ @words = split(' ', xCAT::zvmUtils->trimStr($profileName));
+
+ # Get user profile
+ my $userProfile = xCAT::zvmUtils->getUserProfile($user, $hcp, $words[1]);
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() $userProfile");
+
+ # Get the NICDEF statement containing the HCP network
+ $out = `echo "$userProfile" | grep "NICDEF"`;
+ @lines = split('\n', $out);
+
+ # Go through each line
+ for ($i = 0; $i < @lines; $i++) {
+ # Go through each network device attached to zHCP
+ foreach (@hcpNetworks) {
+
+ # If network device is found
+ if ($lines[$i] =~ m/ $_/i) {
+ # Get network layer
+ $layer = xCAT::zvmCPUtils->getNetworkLayer($user, $hcp, $_);
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() NIC:$_ layer:$layer");
+
+ # If template using DHCP, layer must be 2
+ if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
+ # Save network name
+ $nic = $_;
+
+ # Get network virtual address
+ @words = split(' ', $lines[$i]);
+
+ # Get virtual address (channel)
+ # Convert subchannel to decimal
+ $channel = sprintf('%d', hex($words[1]));
+
+ xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() Candidate found NIC:$nic channel:$channel layer:$layer");
+ return ($nic, $channel, $layer);
+ } else {
+ # Go to next network available
+ $nic = '';
+ }
+ }
+ } # End of foreach
+ } # End of for
+ } # End of if
+ }
+
+ return;
}
\ No newline at end of file
diff --git a/xCAT-server/lib/xcat/plugins/zvm.pm b/xCAT-server/lib/xcat/plugins/zvm.pm
index 286c2020b..1e02404e4 100644
--- a/xCAT-server/lib/xcat/plugins/zvm.pm
+++ b/xCAT-server/lib/xcat/plugins/zvm.pm
@@ -4797,148 +4797,105 @@ sub nodeSet {
}
}
- # Get the networks used by the zHCP
- my @hcpNets = xCAT::zvmCPUtils->getNetworkNamesArray($::SUDOER, $hcp);
-
- my $hcpNetName = '';
- my $channel;
+ # Get the noderes.primarynic
+ my $channel = '';
my $layer;
my $i;
- # Search directory entry for network name
- my $userEntry = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Query_DM -T $userId" | sed '\$d'`;
- xCAT::zvmUtils->printSyslog("smcli Image_Query_DM -T $userId | sed '\$d'");
- $out = `echo "$userEntry" | grep "NICDEF"`;
- my @lines = split( '\n', $out );
+ @propNames = ( 'primarynic', 'nfsserver', 'xcatmaster' );
+ $propVals = xCAT::zvmUtils->getNodeProps( 'noderes', $node, @propNames );
- # Go through each line
- for ( $i = 0 ; $i < @lines ; $i++ ) {
- # Go through each network device attached to zHCP
- foreach (@hcpNets) {
-
- # If network device is found
- if ( $lines[$i] =~ m/ $_/i ) {
- # Get network layer
- $layer = xCAT::zvmCPUtils->getNetworkLayer($::SUDOER, $hcp, $_);
-
- # If template using DHCP, layer must be 2
- if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
- # Save network name
- $hcpNetName = $_;
-
- # Get network virtual address
- @words = split( ' ', $lines[$i] );
-
- # Get virtual address (channel)
- # Convert subchannel to decimal
- $channel = sprintf('%d', hex($words[1]));
-
- last;
- } else {
- # Go to next network available
- $hcpNetName = ''
- }
+ my $repo = $propVals->{'nfsserver'}; # Repository containing Linux ISO
+ my $xcatmaster = $propVals->{'xcatmaster'};
+ my $primaryNic = $propVals->{'primarynic'}; # NIC to use for OS installation
+
+ # If noderes.primarynic is not specified, find an acceptable NIC shared with the zHCP
+ if ($primaryNic) {
+ $layer = xCAT::zvmCPUtils->getNetworkLayer($::SUDOER, $hcp, $primaryNic);
+
+ # If DHCP is used and the NIC is not layer 2, then exit
+ if ($dhcp && $layer != 2) {
+ xCAT::zvmUtils->printLn( $callback, "$node: (Error) The template selected uses DHCP. A layer 2 VSWITCH or GLAN is required. None were found." );
+ xCAT::zvmUtils->printLn( $callback, "$node: (Solution) Modify the template to use static or --bootproto=static, or change the network device attached to virtual machine" );
+ return;
+ }
+
+ # Find device channel of NIC
+ my $userEntry = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Query_DM -T $userId" | sed '\$d'`;
+ $out = `echo "$userEntry" | grep "NICDEF" | grep "$primaryNic"`;
+
+ # Check user profile for device channel
+ if (!$out) {
+ my $profileName = `echo "$userEntry" | grep "INCLUDE"`;
+ if ($profileName) {
+ @words = split(' ', xCAT::zvmUtils->trimStr($profileName));
+
+ # Get user profile
+ my $userProfile = xCAT::zvmUtils->getUserProfile($::SUDOER, $hcp, $words[1]);
+
+ # Get the NICDEF statement containing the HCP network
+ $out = `echo "$userProfile" | grep "NICDEF" | grep "$primaryNic"`;
}
}
- }
+
+ # Grab the device channel from the NICDEF statement
+ my @lines = split('\n', $out);
+ @words = split(' ', $lines[0]);
+ $channel = sprintf('%d', hex($words[1]));
+ } else {
+ xCAT::zvmUtils->printLn( $callback, "$node: Searching for acceptable network device");
+ ($primaryNic, $channel, $layer) = xCAT::zvmUtils->findUsablezHcpNetwork($::SUDOER, $hcp, $userId, $dhcp);
- # If network device is not found
- if (!$hcpNetName) {
-
- # Check for user profile
- my $profileName = `echo "$userEntry" | grep "INCLUDE"`;
- if ($profileName) {
- @words = split( ' ', xCAT::zvmUtils->trimStr($profileName) );
-
- # Get user profile
- my $userProfile = xCAT::zvmUtils->getUserProfile($::SUDOER, $hcp, $words[1]);
-
- # Get the NICDEF statement containing the HCP network
- $out = `echo "$userProfile" | grep "NICDEF"`;
- @lines = split( '\n', $out );
-
- # Go through each line
- for ( $i = 0 ; $i < @lines ; $i++ ) {
- # Go through each network device attached to zHCP
- foreach (@hcpNets) {
-
- # If network device is found
- if ( $lines[$i] =~ m/ $_/i ) {
- # Get network layer
- $layer = xCAT::zvmCPUtils->getNetworkLayer($::SUDOER, $hcp, $_);
-
- # If template using DHCP, layer must be 2
- if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
- # Save network name
- $hcpNetName = $_;
-
- # Get network virtual address
- @words = split( ' ', $lines[$i] );
-
- # Get virtual address (channel)
- # Convert subchannel to decimal
- $channel = sprintf('%d', hex($words[1]));
-
- last;
- } else {
- # Go to next network available
- $hcpNetName = '';
- }
- }
- } # End of foreach
- } # End of for
- } # End of if
+ # If DHCP is used and not layer 2
+ if ($dhcp && $layer != 2) {
+ xCAT::zvmUtils->printLn( $callback, "$node: (Error) The template selected uses DHCP. A layer 2 VSWITCH or GLAN is required. None were found." );
+ xCAT::zvmUtils->printLn( $callback, "$node: (Solution) Modify the template to use static or change the network device attached to virtual machine" );
+ return;
+ }
}
-
+
# Exit if no suitable network found
- if (!$hcpNetName) {
- if ($dhcp) {
- xCAT::zvmUtils->printLn( $callback, "$node: (Error) The template selected uses DHCP. A layer 2 VSWITCH or GLAN is required. None were found." );
- xCAT::zvmUtils->printLn( $callback, "$node: (Solution) Modify the template to use static or change the network device attached to virtual machine" );
- } else {
- xCAT::zvmUtils->printLn( $callback, "$node: (Error) No suitable network device found in user directory entry" );
- xCAT::zvmUtils->printLn( $callback, "$node: (Solution) Verify that the node has one of the following network devices: @hcpNets" );
- }
-
+ if (!$primaryNic || !$channel || !$layer) {
+ xCAT::zvmUtils->printLn( $callback, "$node: (Error) No suitable network device found in user directory entry" );
return;
}
- xCAT::zvmUtils->printLn( $callback, "$node: Setting up networking on $hcpNetName (layer:$layer | DHCP:$dhcp)" );
+ xCAT::zvmUtils->printLn( $callback, "$node: Setting up networking on $primaryNic (layer:$layer | DHCP:$dhcp)" );
# Generate read, write, and data channels
- my $readChannel = "0.0." . ( sprintf('%X', $channel + 0) );
- if ( length($readChannel) < 8 ) {
+ my $readChannel = "0.0." . (sprintf('%X', $channel + 0));
+ if (length($readChannel) < 8) {
# Prepend a zero
- $readChannel = "0.0.0" . ( sprintf('%X', $channel + 0) );
+ $readChannel = "0.0.0" . (sprintf('%X', $channel + 0));
}
- my $writeChannel = "0.0." . ( sprintf('%X', $channel + 1) );
- if ( length($writeChannel) < 8 ) {
+ my $writeChannel = "0.0." . (sprintf('%X', $channel + 1));
+ if (length($writeChannel) < 8) {
# Prepend a zero
- $writeChannel = "0.0.0" . ( sprintf('%X', $channel + 1) );
+ $writeChannel = "0.0.0" . (sprintf('%X', $channel + 1));
}
- my $dataChannel = "0.0." . ( sprintf('%X', $channel + 2) );
- if ( length($dataChannel) < 8 ) {
+ my $dataChannel = "0.0." . (sprintf('%X', $channel + 2));
+ if (length($dataChannel) < 8) {
# Prepend a zero
- $dataChannel = "0.0.0" . ( sprintf('%X', $channel + 2) );
+ $dataChannel = "0.0.0" . (sprintf('%X', $channel + 2));
}
# Get MAC address (Only for layer 2)
my $mac = "";
my @propNames;
my $propVals;
- if ( $layer == 2 ) {
+ if ($layer == 2) {
# Search 'mac' table for node
@propNames = ('mac');
- $propVals = xCAT::zvmUtils->getTabPropsByKey( 'mac', 'node', $node, @propNames );
+ $propVals = xCAT::zvmUtils->getTabPropsByKey('mac', 'node', $node, @propNames);
$mac = $propVals->{'mac'};
# If no MAC address is found, exit
# MAC address should have been assigned to the node upon creation
- if ( !$mac ) {
- xCAT::zvmUtils->printLn( $callback, "$node: (Error) Missing MAC address of node" );
+ if (!$mac) {
+ xCAT::zvmUtils->printLn($callback, "$node: (Error) Missing MAC address of node");
return;
}
}