mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	zVM specific files
This commit is contained in:
		@@ -611,25 +611,39 @@ sub punch2Reader {
 | 
			
		||||
            
 | 
			
		||||
    # Punch to reader
 | 
			
		||||
    # VMUR located in different directories on RHEL and SLES
 | 
			
		||||
    my $out;
 | 
			
		||||
    my $vmur;
 | 
			
		||||
    if ( $os =~ m/sles10/i ) {
 | 
			
		||||
        $out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
 | 
			
		||||
    } elsif ( $os =~ m/sles11/i ) {
 | 
			
		||||
        $out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
 | 
			
		||||
    } elsif ( $os =~ m/rhel/i ) {
 | 
			
		||||
    	$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
 | 
			
		||||
        $vmur = "/sbin/vmur";
 | 
			
		||||
    } else {
 | 
			
		||||
    	$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
 | 
			
		||||
        $vmur = "/usr/sbin/vmur";
 | 
			
		||||
    }
 | 
			
		||||
    my $out;
 | 
			
		||||
    my $done = 0;
 | 
			
		||||
    
 | 
			
		||||
    until ( $done ) {
 | 
			
		||||
        $out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo $vmur punch $options -u $userId -r $srcFile -N $tgtFile" 2>&1`;
 | 
			
		||||
        my $rc = $? >> 8;
 | 
			
		||||
        if ( $rc == 255 ) {
 | 
			
		||||
            $out = "(Error) Unable to communicate with the zHCP system: $hcp";
 | 
			
		||||
            $done = 1;
 | 
			
		||||
        } elsif ( $out =~ m/A concurrent instance of vmur is already active/i ) {
 | 
			
		||||
            # Recoverable error: retry the command after a delay
 | 
			
		||||
            xCAT::zvmUtils->printSyslog( "punch2Reader() Punch in use on $hcp, retrying in 15 seconds" );
 | 
			
		||||
            sleep( 15 );
 | 
			
		||||
        } else {
 | 
			
		||||
            # Punch appears successful -- Look for the completion string
 | 
			
		||||
            my $searchStr = "created and transferred";
 | 
			
		||||
            if ( !( $out =~ m/$searchStr/i ) ) {
 | 
			
		||||
                chomp( $out );
 | 
			
		||||
                $out = "Failed, punch info: '$out'\n";
 | 
			
		||||
                xCAT::zvmUtils->printSyslog( "punch2Reader() Failed punching $srcFile to $userId from $hcp, info: '$out'" );
 | 
			
		||||
            } else {
 | 
			
		||||
                $out = "Done\n";
 | 
			
		||||
            }
 | 
			
		||||
            $done = 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # If punch is successful -- Look for this string
 | 
			
		||||
    my $searchStr = "created and transferred";
 | 
			
		||||
    if ( !( $out =~ m/$searchStr/i ) ) {
 | 
			
		||||
        $out = "Failed\n";
 | 
			
		||||
    } else {
 | 
			
		||||
        $out = "Done\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -289,7 +289,7 @@ sub printLn {
 | 
			
		||||
    # Print string
 | 
			
		||||
    my $rsp;
 | 
			
		||||
    my $type = "I";
 | 
			
		||||
    if ($str =~ m/error/i) {  # Set to print error if the string contains error
 | 
			
		||||
    if ($str =~ m/(\(error\)|\sfailed)/i) {  # Set to print error if the string contains error
 | 
			
		||||
        $type = "E";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -1246,7 +1246,7 @@ sub getArch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # Get host using VMCP
 | 
			
		||||
    my $arch = `ssh $user\@$node "$sudo uname -p"`;
 | 
			
		||||
    my $arch = `ssh $user\@$node "$sudo uname -m"`;
 | 
			
		||||
 | 
			
		||||
    return ( xCAT::zvmUtils->trimStr($arch) );
 | 
			
		||||
}
 | 
			
		||||
@@ -2308,19 +2308,20 @@ sub getUsedFcpDevices {
 | 
			
		||||
    Arguments   : Sudoer user name
 | 
			
		||||
                  Sudo keyword
 | 
			
		||||
                  zHCP hostname
 | 
			
		||||
                  Install root directory
 | 
			
		||||
                  Local directory to remotely mount
 | 
			
		||||
                  Mount access ('ro' for read only, 'rw' for read write)
 | 
			
		||||
                  Directory as known to zHCP (out)
 | 
			
		||||
    Returns     : 0 - Mounted, or zHCP and MN are on the same system
 | 
			
		||||
                  1 - Mount failed
 | 
			
		||||
    Example     : establishMount( $callback, $::SUDOER, $::SUDO, $hcp, "$installRoot/$provMethod", "ro", \$remoteDeployDir );
 | 
			
		||||
    Example     : establishMount( $callback, $::SUDOER, $::SUDO, $hcp, $installRoot, $provMethod, "ro", \$remoteDeployDir );
 | 
			
		||||
    
 | 
			
		||||
=cut
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------
 | 
			
		||||
sub establishMount {
 | 
			
		||||
    # Get inputs
 | 
			
		||||
    my ($class, $callback, $sudoer, $sudo, $hcp, $localDir, $access, $mountedPt) = @_;    
 | 
			
		||||
    my ($class, $callback, $sudoer, $sudo, $hcp, $installRoot, $localDir, $access, $mountedPt) = @_;    
 | 
			
		||||
    my $out;
 | 
			
		||||
 | 
			
		||||
    # If the target system is not on this system then establish the NFS mount point.
 | 
			
		||||
@@ -2338,7 +2339,7 @@ sub establishMount {
 | 
			
		||||
    
 | 
			
		||||
    if ($masterIp eq $hcpIP) {
 | 
			
		||||
        # xCAT MN and zHCP are on the same box and will use the same directory without the need for an NFS mount.
 | 
			
		||||
        $$mountedPt = $localDir;
 | 
			
		||||
        $$mountedPt = "$installRoot/$localDir";
 | 
			
		||||
    } else {
 | 
			
		||||
        # Determine the hostname for this management node
 | 
			
		||||
        my $masterHostname = Sys::Hostname::hostname();
 | 
			
		||||
@@ -2347,15 +2348,23 @@ sub establishMount {
 | 
			
		||||
            $masterHostname = $masterIp;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $$mountedPt = "/mnt/$masterHostname$installRoot/$localDir";
 | 
			
		||||
        
 | 
			
		||||
        # If the mount point already exists then return because we are done.
 | 
			
		||||
        my $rc = `ssh $sudoer\@$hcp "$sudo mount | grep $$mountedPt > /dev/null; echo \\\$?"`;
 | 
			
		||||
        if ($rc == 0) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        xCAT::zvmUtils->printSyslog( "establishMount() Preparing the NFS mount point on zHCP ($hcpIP) to xCAT MN $masterHostname($masterIp) for $localDir" );
 | 
			
		||||
        
 | 
			
		||||
        # Prepare the staging mount point on zHCP, if they need to be established
 | 
			
		||||
        $$mountedPt = "/mnt/$masterHostname$localDir";
 | 
			
		||||
        my $rc = `ssh $sudoer\@$hcp "$sudo mkdir -p $$mountedPt && mount -t nfs -o $access $masterIp:$localDir $$mountedPt; echo \\\$?"`;
 | 
			
		||||
        $rc = `ssh $sudoer\@$hcp "$sudo mkdir -p $$mountedPt && mount -t nfs -o $access $masterIp:/$localDir $$mountedPt; echo \\\$?"`;
 | 
			
		||||
        
 | 
			
		||||
        # Return code = 0 (mount succeeded) or 32 (mount already exists)
 | 
			
		||||
        if ($rc != '0' && $rc != '32') {
 | 
			
		||||
        # Return code = 0 (mount succeeded)
 | 
			
		||||
        if ($rc != '0') {
 | 
			
		||||
            xCAT::zvmUtils->printLn( $callback, "$hcp: (Error) Unable to establish zHCP mount point: $$mountedPt" );
 | 
			
		||||
            xCAT::zvmUtils->printSyslog( "establishMount() Unable to establish zHCP mount point: $$mountedPt, rc: $rc" );
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -2367,9 +2376,12 @@ sub establishMount {
 | 
			
		||||
 | 
			
		||||
=head3   getFreeRepoSpace
 | 
			
		||||
 | 
			
		||||
    Description : Get the free space of image repository under /install
 | 
			
		||||
    Description : Get the free space of image repository under /install.
 | 
			
		||||
    Arguments   : Node
 | 
			
		||||
    Returns     : The available space for /install
 | 
			
		||||
    Returns     : The available space for /install (e.g. "2.1G ").  
 | 
			
		||||
                  The value is returned as a perl string (e.g. "0 ") to 
 | 
			
		||||
                  avoid perl returning null instead of "0" in the case
 | 
			
		||||
                  of no space available.
 | 
			
		||||
    Example     : my $free = getFreeRepoSpace($callback, $node);
 | 
			
		||||
    
 | 
			
		||||
=cut
 | 
			
		||||
@@ -2395,7 +2407,10 @@ sub getFreeRepoSpace {
 | 
			
		||||
        my $out = `$sudo /bin/df -h /install | sed 1d`;
 | 
			
		||||
        $out =~ s/\h+/ /g;
 | 
			
		||||
        my @results = split(' ', $out);
 | 
			
		||||
        return ($results[3]);
 | 
			
		||||
        if ( $results[3] eq "0" ) {
 | 
			
		||||
            $results[3] = "0M";
 | 
			
		||||
        }
 | 
			
		||||
        return $results[3];
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
@@ -2475,12 +2490,12 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
        return \%results;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # Check WWPN and LUN syntax
 | 
			
		||||
    if ( $wwpn && ($wwpn =~ /[^0-9a-f;"]/i) ) {
 | 
			
		||||
        xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid world wide portname $wwpn." );
 | 
			
		||||
    # Owner must be specified if status is used
 | 
			
		||||
    if ($status =~ m/used/i && !$owner) {
 | 
			
		||||
        xCAT::zvmUtils->printLn( $callback, "$header: (Error) Owner must be specified if status is used." );
 | 
			
		||||
        return \%results;
 | 
			
		||||
    } if ( $lun && ($lun =~ /[^0-9a-f]/i) ) {
 | 
			
		||||
        xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid logical unit number $lun." );
 | 
			
		||||
    } elsif ($status =~ m/free/i && $owner) {
 | 
			
		||||
        xCAT::zvmUtils->printLn( $callback, "$header: (Error) Owner must not be specified if status is free." );
 | 
			
		||||
        return \%results;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
@@ -2509,6 +2524,15 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
        # Make sure WWPN and LUN do not have 0x prefix
 | 
			
		||||
        $wwpn = xCAT::zvmUtils->replaceStr($wwpn, "0x", "");
 | 
			
		||||
        $lun = xCAT::zvmUtils->replaceStr($lun, "0x", "");
 | 
			
		||||
        
 | 
			
		||||
        # Check WWPN and LUN syntax
 | 
			
		||||
        if ( $wwpn && ($wwpn =~ /[^0-9a-f;"]/i) ) {
 | 
			
		||||
            xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid world wide portname $wwpn." );
 | 
			
		||||
            return \%results;
 | 
			
		||||
        } if ( $lun && ($lun =~ /[^0-9a-f]/i) ) {
 | 
			
		||||
            xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid logical unit number $lun." );
 | 
			
		||||
            return \%results;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # Find disk pool (create one if non-existent)
 | 
			
		||||
@@ -2569,15 +2593,19 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        # Do not continue if no devices can be found
 | 
			
		||||
        if (!$wwpn && !$lun) {
 | 
			
		||||
        if (!$wwpn || !$lun) {
 | 
			
		||||
            xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable device of $size" . "M or larger could not be found");
 | 
			
		||||
            return \%results;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
    	# Find given WWPN and LUN. Do not continue if device is used
 | 
			
		||||
        # Find given WWPN and LUN. Do not continue if device is used
 | 
			
		||||
        my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$wwpn,$lun"`;
 | 
			
		||||
        chomp($select);
 | 
			
		||||
        
 | 
			
		||||
        if (!$select) {
 | 
			
		||||
            xCAT::zvmUtils->printLn($callback, "$header: (Error) zFCP device 0x$wwpn/0x$lun could not be found in zFCP pool $pool");
 | 
			
		||||
            return \%results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @info = split(',', $select);
 | 
			
		||||
        
 | 
			
		||||
        if ($size) {
 | 
			
		||||
@@ -2585,13 +2613,11 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
                # Convert to MegaBytes
 | 
			
		||||
                $info[3] =~ s/\D//g;
 | 
			
		||||
                $info[3] = int($info[3]) * 1024
 | 
			
		||||
            } elsif ($info[3] =~ m/M/i) {
 | 
			
		||||
            } else {
 | 
			
		||||
                # Do nothing
 | 
			
		||||
                $info[3] =~ s/\D//g;
 | 
			
		||||
            } else {
 | 
			
		||||
                next;
 | 
			
		||||
            }
 | 
			
		||||
                
 | 
			
		||||
            
 | 
			
		||||
            # Do not continue if specified device does not have enough capacity
 | 
			
		||||
            if ($info[3] < $size) {
 | 
			
		||||
                xCAT::zvmUtils->printLn($callback, "$header: (Error) FCP device $wwpn/$lun is not large enough");
 | 
			
		||||
@@ -2602,7 +2628,7 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
        # Find range of the specified disk
 | 
			
		||||
        $range = $info[4];
 | 
			
		||||
    }
 | 
			
		||||
       
 | 
			
		||||
    
 | 
			
		||||
    # If there are multiple paths, take the 1st one
 | 
			
		||||
    # Handle multi-pathing in postscript because autoyast/kickstart does not support it.
 | 
			
		||||
    my $origWwpn = $wwpn;
 | 
			
		||||
@@ -2612,117 +2638,23 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    xCAT::zvmUtils->printLn($callback, "$header: Found FCP device 0x$wwpn/0x$lun");
 | 
			
		||||
        
 | 
			
		||||
    # Find a free FCP device based on the given range
 | 
			
		||||
    if ($fcpDevice =~ m/^auto/i) {
 | 
			
		||||
        my @ranges;
 | 
			
		||||
        my $min;
 | 
			
		||||
        my $max;
 | 
			
		||||
        my $found = 0;
 | 
			
		||||
                
 | 
			
		||||
        if ($range =~ m/;/i) {
 | 
			
		||||
            @ranges = split(';', $range);
 | 
			
		||||
        } else {
 | 
			
		||||
            push(@ranges, $range);
 | 
			
		||||
        }
 | 
			
		||||
                    
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            # If the node has an eligible FCP device, use it
 | 
			
		||||
            my @deviceList = xCAT::zvmUtils->getDedicates($callback, $user, $owner);
 | 
			
		||||
            foreach (@deviceList) {
 | 
			
		||||
                # Check if this devide is eligible (among the range specified for disk $lun)
 | 
			
		||||
                @info = split(' ', $_);
 | 
			
		||||
                my $candidate = $info[2];
 | 
			
		||||
                foreach (@ranges) {
 | 
			
		||||
                    ($min, $max) = split('-', $_);
 | 
			
		||||
                    if (hex($candidate) >= hex($min) && hex($candidate) <= hex($max)) {
 | 
			
		||||
                        $found = 1;
 | 
			
		||||
                        $fcpDevice = uc($candidate);
 | 
			
		||||
                        
 | 
			
		||||
                        last;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if ($found) {
 | 
			
		||||
                	xCAT::zvmUtils->printLn($callback, "$header: Found eligible FCP channel $fcpDevice");
 | 
			
		||||
                    last;
 | 
			
		||||
                }       
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            # If the node has no eligible FCP device, find a free one for it.
 | 
			
		||||
            my %usedDevices = xCAT::zvmUtils->getUsedFcpDevices($user, $hcp);
 | 
			
		||||
            
 | 
			
		||||
            my $hcpUserId = xCAT::zvmCPUtils->getUserId($user, $hcp);
 | 
			
		||||
            $hcpUserId =~ tr/a-z/A-Z/;
 | 
			
		||||
        
 | 
			
		||||
            # Find a free FCP channel
 | 
			
		||||
            $out = `ssh $user\@$hcp "$sudo $dir/smcli System_WWPN_Query -T $hcpUserId" | egrep -i "FCP device number|Status"`;
 | 
			
		||||
            my @devices = split( "\n", $out );
 | 
			
		||||
            for (my $i = 0; $i < @devices; $i++) {
 | 
			
		||||
                # Extract the device number and status
 | 
			
		||||
                $fcpDevice = $devices[$i];
 | 
			
		||||
                $fcpDevice =~ s/^FCP device number:(.*)/$1/;
 | 
			
		||||
                $fcpDevice =~ s/^\s+//;
 | 
			
		||||
                $fcpDevice =~ s/\s+$//;
 | 
			
		||||
                        
 | 
			
		||||
                $i++;
 | 
			
		||||
                my $fcpStatus = $devices[$i];
 | 
			
		||||
                $fcpStatus =~ s/^Status:(.*)/$1/;
 | 
			
		||||
                $fcpStatus =~ s/^\s+//;
 | 
			
		||||
                $fcpStatus =~ s/\s+$//;                    
 | 
			
		||||
                        
 | 
			
		||||
                # Only look at free FCP devices
 | 
			
		||||
                if ($fcpStatus =~ m/free/i) {                    
 | 
			
		||||
                    # If the device number is within the specified range, exit out of loop
 | 
			
		||||
                    # Range: 3B00-3C00;4B00-4C00;5E12-5E12
 | 
			
		||||
                    foreach (@ranges) {
 | 
			
		||||
                        ($min, $max) = split('-', $_);
 | 
			
		||||
                        if (hex($fcpDevice) >= hex($min) && hex($fcpDevice) <= hex($max)) {
 | 
			
		||||
                            $fcpDevice = uc($fcpDevice);
 | 
			
		||||
                
 | 
			
		||||
                            # Used found FCP channel if not in use or allocated                        
 | 
			
		||||
                            if (!$usedDevices{$fcpDevice}) {
 | 
			
		||||
                                $found = 1;
 | 
			
		||||
                                last;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                # Break out of loop if FCP channel is found
 | 
			
		||||
                if ($found) {
 | 
			
		||||
                	xCAT::zvmUtils->printLn($callback, "$header: Found FCP channel within acceptable range $fcpDevice");
 | 
			
		||||
                    last;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        # Do not continue if no FCP channel is found
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable FCP channel could not be found");
 | 
			
		||||
    
 | 
			
		||||
    if ( ($status =~ m/used/i) && ($fcpDevice =~ /^auto/i) ) {
 | 
			
		||||
        # select an eligible FCP device
 | 
			
		||||
        $fcpDevice = xCAT::zvmUtils->selectFcpDevice($callback, $header, $user, $hcp, $fcpDevice, $range, $owner);
 | 
			
		||||
        if (!$fcpDevice) {
 | 
			
		||||
            return \%results;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # If there are multiple devices (multipathing), take the 1st one
 | 
			
		||||
    if ($fcpDevice) {
 | 
			
		||||
        if ($fcpDevice =~ m/;/i) {
 | 
			
		||||
            @info = split(';', $fcpDevice);
 | 
			
		||||
            $fcpDevice = xCAT::zvmUtils->trimStr($info[0]);
 | 
			
		||||
        }
 | 
			
		||||
                    
 | 
			
		||||
        # Make sure channel has a length of 4
 | 
			
		||||
        while (length($fcpDevice) < 4) {
 | 
			
		||||
            $fcpDevice = "0" . $fcpDevice;
 | 
			
		||||
        }
 | 
			
		||||
    } elsif ($status =~ m/free/i) {
 | 
			
		||||
        # Owner and FCP channel make no sense when status is free
 | 
			
		||||
        $fcpDevice = "";
 | 
			
		||||
        $owner = "";
 | 
			
		||||
    }
 | 
			
		||||
            
 | 
			
		||||
    # Mark WWPN and LUN as used, free, or reserved and set the owner/channel appropriately
 | 
			
		||||
    # This config file keeps track of the owner of each device, which is useful in nodeset
 | 
			
		||||
    $size = $size . "M";
 | 
			
		||||
    my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$lun" | grep -i "$wwpn"`;
 | 
			
		||||
    my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$lun"`;
 | 
			
		||||
    chomp($select);
 | 
			
		||||
    if ($select) {
 | 
			
		||||
        @info = split(',', $select);
 | 
			
		||||
@@ -2759,6 +2691,156 @@ sub findAndUpdatezFcpPool {
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
=head3   selectFcpDevice
 | 
			
		||||
 | 
			
		||||
    Description : Select an eligible FCP device for attaching a zFCP device to a node
 | 
			
		||||
    Arguments   :   Message header
 | 
			
		||||
                    User (root or non-root)
 | 
			
		||||
                    zHCP
 | 
			
		||||
                    candidate FCP devices or auto
 | 
			
		||||
                    FCP device range
 | 
			
		||||
                    zFCP device owner
 | 
			
		||||
    Returns     : selected FCP device or empty if no one is selected
 | 
			
		||||
    Example     : my $fcpDevice = xCAT::zvmUtils->selectFcpDevice($callback, $header, $user, $hcp, $fcpDevice, $range, $owner);
 | 
			
		||||
    
 | 
			
		||||
=cut
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------
 | 
			
		||||
sub selectFcpDevice {
 | 
			
		||||
    # Get inputs
 | 
			
		||||
    my ($class, $callback, $header, $user, $hcp, $fcpDevice, $range, $owner) = @_;
 | 
			
		||||
        
 | 
			
		||||
    # Determine if sudo is used
 | 
			
		||||
    my $sudo = "sudo";
 | 
			
		||||
    if ($user eq "root") {
 | 
			
		||||
        $sudo = "";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # Directory where executables are on zHCP
 | 
			
		||||
    my $dir = "/opt/zhcp/bin";
 | 
			
		||||
        
 | 
			
		||||
    # Directory where FCP disk pools are on zHCP
 | 
			
		||||
    my $zfcpDir = "/var/opt/zhcp/zfcp";
 | 
			
		||||
    
 | 
			
		||||
    my %results = ('rc' => -1);  # Default to error
 | 
			
		||||
    
 | 
			
		||||
    # Check FCP device syntax
 | 
			
		||||
    if ($fcpDevice && ($fcpDevice !~ /^auto/i) && ($fcpDevice =~ /[^0-9a-f]/i)) {
 | 
			
		||||
        xCAT::zvmUtils->printLn($callback, "$header: (Error) Invalid FCP channel address $fcpDevice.");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # Find a free FCP device based on the given range
 | 
			
		||||
    if ($fcpDevice =~ m/^auto/i) {
 | 
			
		||||
        my @ranges;
 | 
			
		||||
        my $min;
 | 
			
		||||
        my $max;
 | 
			
		||||
        my $found = 0;
 | 
			
		||||
                
 | 
			
		||||
        if ($range =~ m/;/i) {
 | 
			
		||||
            @ranges = split(';', $range);
 | 
			
		||||
        } else {
 | 
			
		||||
            push(@ranges, $range);
 | 
			
		||||
        }
 | 
			
		||||
                    
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            # If the node has an eligible FCP device, use it
 | 
			
		||||
            my @deviceList = xCAT::zvmUtils->getDedicates($callback, $user, $owner);
 | 
			
		||||
            foreach (@deviceList) {
 | 
			
		||||
                # Check if this devide is eligible (among the range specified for disk $lun)
 | 
			
		||||
                my @info = split(' ', $_);
 | 
			
		||||
                my $candidate = $info[2];
 | 
			
		||||
                foreach (@ranges) {
 | 
			
		||||
                    ($min, $max) = split('-', $_);
 | 
			
		||||
                    if (hex($candidate) >= hex($min) && hex($candidate) <= hex($max)) {
 | 
			
		||||
                        $found = 1;
 | 
			
		||||
                        $fcpDevice = uc($candidate);
 | 
			
		||||
                        
 | 
			
		||||
                        last;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if ($found) {
 | 
			
		||||
                    xCAT::zvmUtils->printLn($callback, "$header: Found eligible FCP channel $fcpDevice");
 | 
			
		||||
                    last;
 | 
			
		||||
                }       
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            # If the node has no eligible FCP device, find a free one for it.
 | 
			
		||||
            my %usedDevices = xCAT::zvmUtils->getUsedFcpDevices($user, $hcp);
 | 
			
		||||
            
 | 
			
		||||
            my $hcpUserId = xCAT::zvmCPUtils->getUserId($user, $hcp);
 | 
			
		||||
            $hcpUserId =~ tr/a-z/A-Z/;
 | 
			
		||||
        
 | 
			
		||||
            # Find a free FCP channel
 | 
			
		||||
            my $out = `ssh $user\@$hcp "$sudo $dir/smcli System_WWPN_Query -T $hcpUserId" | egrep -i "FCP device number|Status"`;
 | 
			
		||||
            my @devices = split( "\n", $out );
 | 
			
		||||
            for (my $i = 0; $i < @devices; $i++) {
 | 
			
		||||
                # Extract the device number and status
 | 
			
		||||
                $fcpDevice = $devices[$i];
 | 
			
		||||
                $fcpDevice =~ s/^FCP device number:(.*)/$1/;
 | 
			
		||||
                $fcpDevice =~ s/^\s+//;
 | 
			
		||||
                $fcpDevice =~ s/\s+$//;
 | 
			
		||||
                        
 | 
			
		||||
                $i++;
 | 
			
		||||
                my $fcpStatus = $devices[$i];
 | 
			
		||||
                $fcpStatus =~ s/^Status:(.*)/$1/;
 | 
			
		||||
                $fcpStatus =~ s/^\s+//;
 | 
			
		||||
                $fcpStatus =~ s/\s+$//;                    
 | 
			
		||||
                        
 | 
			
		||||
                # Only look at free FCP devices
 | 
			
		||||
                if ($fcpStatus =~ m/free/i) {                    
 | 
			
		||||
                    # If the device number is within the specified range, exit out of loop
 | 
			
		||||
                    # Range: 3B00-3C00;4B00-4C00;5E12-5E12
 | 
			
		||||
                    foreach (@ranges) {
 | 
			
		||||
                        ($min, $max) = split('-', $_);
 | 
			
		||||
                        if (hex($fcpDevice) >= hex($min) && hex($fcpDevice) <= hex($max)) {
 | 
			
		||||
                            $fcpDevice = uc($fcpDevice);
 | 
			
		||||
                
 | 
			
		||||
                            # Use found FCP channel if not in use or allocated                        
 | 
			
		||||
                            if (!$usedDevices{$fcpDevice}) {
 | 
			
		||||
                                $found = 1;
 | 
			
		||||
                                last;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                # Break out of loop if FCP channel is found
 | 
			
		||||
                if ($found) {
 | 
			
		||||
                    xCAT::zvmUtils->printLn($callback, "$header: Found FCP channel within acceptable range $fcpDevice");
 | 
			
		||||
                    last;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        # Do not continue if no FCP channel is found
 | 
			
		||||
        if (!$found) {
 | 
			
		||||
            xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable FCP channel could not be found");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # If there are multiple devices (multipathing), take the 1st one
 | 
			
		||||
    if ($fcpDevice) {
 | 
			
		||||
        if ($fcpDevice =~ m/;/i) {
 | 
			
		||||
            my @info = split(';', $fcpDevice);
 | 
			
		||||
            $fcpDevice = xCAT::zvmUtils->trimStr($info[0]);
 | 
			
		||||
        }
 | 
			
		||||
                    
 | 
			
		||||
        # Make sure channel has a length of 4
 | 
			
		||||
        while (length($fcpDevice) < 4) {
 | 
			
		||||
            $fcpDevice = "0" . $fcpDevice;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return $fcpDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
=head3   findzFcpDevicePool
 | 
			
		||||
 | 
			
		||||
    Description : Find the zFCP storage pool that contains the given zFCP device
 | 
			
		||||
@@ -2807,7 +2889,7 @@ sub findzFcpDevicePool {
 | 
			
		||||
                    WWPN
 | 
			
		||||
                    LUN
 | 
			
		||||
    Returns     : Architecture of node
 | 
			
		||||
    Example     : my $deviceRef = xCAT::zvmUtils->findzFcpDeviceAttr($user, $hcp, $wwpn, $lun);
 | 
			
		||||
    Example     : my $deviceRef = xCAT::zvmUtils->findzFcpDeviceAttr($user, $hcp, $pool, $wwpn, $lun);
 | 
			
		||||
    
 | 
			
		||||
=cut
 | 
			
		||||
 | 
			
		||||
@@ -2827,7 +2909,7 @@ sub findzFcpDeviceAttr {
 | 
			
		||||
 | 
			
		||||
    # Find the SCSI/FCP device
 | 
			
		||||
    # Entry order: status,wwpn,lun,size,range,owner,channel,tag
 | 
			
		||||
    my @info = split("\n", `ssh $user\@$hcp "$sudo grep \"$wwpn,$lun\" $zfcpDir/$pool.conf"`);
 | 
			
		||||
    my @info = split("\n", `ssh $user\@$hcp "$sudo grep -i \"$wwpn,$lun\" $zfcpDir/$pool.conf"`);
 | 
			
		||||
    my $entry = $info[0];
 | 
			
		||||
    chomp($entry);
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -2664,9 +2664,9 @@ zvmPlugin.prototype.loadLogPage = function(node) {
 | 
			
		||||
 | 
			
		||||
            // If a value is given for every input
 | 
			
		||||
            if (ready) {
 | 
			
		||||
                // Disable all inputs
 | 
			
		||||
                var inputs = $('#' + newTabId + ' input');
 | 
			
		||||
                inputs.attr('disabled', 'disabled');
 | 
			
		||||
                // Do not disable all inputs
 | 
			
		||||
                //var inputs = $('#' + newTabId + ' input');
 | 
			
		||||
                //inputs.attr('disabled', 'disabled');
 | 
			
		||||
                
 | 
			
		||||
                /**
 | 
			
		||||
                 * (1) Retrieve, clear, or set options for event logs
 | 
			
		||||
@@ -2688,8 +2688,8 @@ zvmPlugin.prototype.loadLogPage = function(node) {
 | 
			
		||||
                $('#' + statBarId).find('div').append(createLoader());
 | 
			
		||||
                $('#' + statBarId).show();
 | 
			
		||||
 | 
			
		||||
                // Disable run button
 | 
			
		||||
                $(this).attr('disabled', 'true');
 | 
			
		||||
                // Do not disable run button
 | 
			
		||||
                //$(this).attr('disabled', 'true');
 | 
			
		||||
            } else {
 | 
			
		||||
                // Show warning message
 | 
			
		||||
                var warn = createWarnBar(errMsg);
 | 
			
		||||
 
 | 
			
		||||
@@ -400,9 +400,8 @@ function updateZProvisionNewStatus(data) {
 | 
			
		||||
                            + ';' + size + ';' + mode + ';' + password + ';'
 | 
			
		||||
                            + password + ';' + password;
 | 
			
		||||
                    } else if (type == '9336') {
 | 
			
		||||
                        var blkSize = '512';
 | 
			
		||||
                        args = '--add' + type + ';' + pool + ';' + address + ';' 
 | 
			
		||||
                            + blkSize + ';' + size + ';' + mode + ';' + password + ';'
 | 
			
		||||
                            + size + ';' + mode + ';' + password + ';'
 | 
			
		||||
                            + password + ';' + password;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
@@ -1413,7 +1412,6 @@ function openAddDiskDialog(node, hcp) {
 | 
			
		||||
                        $('#' + statusId).show();
 | 
			
		||||
                    } else if (type == '9336') {
 | 
			
		||||
                        // Default block size for FBA volumes = 512
 | 
			
		||||
                        var blkSize = '512';
 | 
			
		||||
                        
 | 
			
		||||
                        $.ajax( {
 | 
			
		||||
                            url : 'lib/cmd.php',
 | 
			
		||||
@@ -1421,7 +1419,7 @@ function openAddDiskDialog(node, hcp) {
 | 
			
		||||
                            data : {
 | 
			
		||||
                                cmd : 'chvm',
 | 
			
		||||
                                tgt : node,
 | 
			
		||||
                                args : '--add9336;' + pool + ';' + address + ';' + blkSize + ';' + size
 | 
			
		||||
                                args : '--add9336;' + pool + ';' + address + ';' + size
 | 
			
		||||
                                    + ';' + mode + ';' + password + ';' + password + ';' + password,
 | 
			
		||||
                                msg : node
 | 
			
		||||
                            },
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user