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; } }