#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 1999,2007 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)83 1.109.1.2 src/avs/fs/mmfs/ts/admin/mmfsfuncs.sh, mmfs, avs_rgpfs24, rgpfs24s012a 3/29/07 13:07:03 ###################################################################### ###################################################################### # Pull in operating system dependent functions and declarations. ###################################################################### [[ -e ${mmcmdDir}/mmfsfuncs.$osName ]] && \ . ${mmcmdDir}/mmfsfuncs.$osName ################################################################## # # Function: Given a disk name, find the file system to which # the disk belongs. # # Input: $1 - Name of disk # $2 - Name of mmsdrfs file # # Output: $1 - File system name # # Returns: 0 - file system found # 1 - file system not found # ################################################################## function findFSforDisk # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGfindFSforDisk ]] && set -x $mmTRACE_ENTER "$*" typeset diskName=$1 typeset sdrfs=$2 typeset rc fsName # The awk script looks at all SG_DISKS lines. # If the disk name field matches the value in $diskName, # we have located the line that we are looking for. # Print the file system device name and stop. fsName=$($awk -F: ' \ /':$SG_DISKS:'/ { \ if ($'$DISK_NAME_Field' == "'$diskName'" && \ $'$DEV_NAME_Field' != "'$NO_DEVICE'") { \ { print $'$DEV_NAME_Field' } \ { exit 0 } \ } \ } \ ' $sdrfs) checkForErrors awk $? if [[ -n $fsName ]] then print -- $fsName return 0 else return 1 fi } #----- end of function findFSforDisk ------------------ ################################################################## # # Function: Given a disk name, find the corresponding SG_DISKS # line and return the value of the specified field. # # Input: $1 - field whose value should be returned # $2 - name of disk for which info is sought # $3 - name of mmsdrfs file to search # # Output: $1 - value of the requested field # # Returns: 0 - disk found and requested value returned # 1 - disk not found # ################################################################## function getDiskInfo # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetDiskInfo ]] && set -x $mmTRACE_ENTER "$*" typeset returnField=$1 typeset diskName=$2 typeset sdrfs=$3 typeset rc result # The awk script looks at SG_DISKS lines. # If the diskname field matches the value in $diskName, # we have located the line that we are looking for. # Print the value of the requested field and stop. result=$($awk -F: ' \ /':$SG_DISKS:'/ { \ if ($'$DISK_NAME_Field' == "'$diskName'") { \ { print $'$returnField' } \ { exit 0 } \ } \ } \ ' $sdrfs) checkForErrors awk $? if [[ -n $result ]] then print -- $result return 0 else return 1 fi } #----- end of function getDiskInfo -------------------- ############################################################################ # # Function: Given an mm disk descriptor and its corresponding free # SG_DISKS line, this routine validates the parameters, # converts the descriptor to ts format, and generates # an updated SG_DISKS line. # # Input: $1 - disk descriptor in mm format # $2 - the current (free) SG_DISKS line for the disk # $3 - file system to which the disk will be assigned # or $NO_DEVICE if invoked from mmcrnsd # or $CHANGE_NSD if invoked from mmchnsd # $4 - nodeset to which the file system belongs # or $FREE_DISK if invoked from mmcrnsd # $5 - status string with which to update DISK_STATUS_Field # when a match is found; NULL if no value # $6 - (optional) Default disk usage if usage is not # specified in the mm disk descriptor. # "oldDiskUsage" is used when replacing a disk. # # Output: $1 - updated SG_DISKS line for the disk # $2 - Disk descriptor in TS format # $3 - Disk usage # # Returns: 0 - valid descriptor # 1 - invalid descriptor # ############################################################################ function validateAndConvertNsdDescriptor # # # [] { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGvalidateAndConvertNsdDescriptor ]] && set -x $mmTRACE_ENTER "$*" typeset mmDiskDesc=$1 typeset freeDiskLine=$2 typeset deviceName=$3 typeset nodesetId=$4 typeset statusString=$5 typeset defaultUsage=$6 typeset updatedDiskLine diskName diskUsage failureGroup ipa storagePool typeset primaryNsdAdminNode newPrimaryNsdAdminNode typeset primaryNsdDaemonNode newPrimaryNsdDaemonNode typeset backupNsdAdminNode newBackupNsdAdminNode typeset backupNsdDaemonNode newBackupNsdDaemonNode typeset -i primaryNodeNumber defaultFailureGroup typeset driverType="nsd" typeset sectorSize="" typeset hasMetaData=1 typeset hasData=1 typeset addingDiskToFS="" typeset replacingDisk="" [[ $statusString = NULL ]] && statusString="" [[ $defaultUsage = oldDiskUsage ]] && replacingDisk=yes ###################################################################### # Parse the mm descriptor and the current SG_DISKS line for the disk. ###################################################################### IFS=":" set -f ; set -- $mmDiskDesc ; set +f diskName=${1#+(/)dev+(/)} # name stripped of /dev/ prefix newPrimaryNsdAdminNode=$2 newBackupNsdAdminNode=$3 diskUsage=$4 failureGroup=$5 storagePool=$7 set -f ; set -A v -- - $freeDiskLine ; set +f IFS="$IFS_sv" ################################################################# # Determine who the caller is. The logic depends on whether # we are creating a new disk (mmcrnsd), adding an already # existing disk to a file system (mmcrfs, mmadddisk, mmrpldisk) # or changing some of the disk attributes (mmchnsd). ################################################################# if [[ $deviceName = $NO_DEVICE ]] then # Creating a new disk. Verify that the disk name is specified. deviceName="" if [[ -z $diskName ]] then # The disk name must be specified in the disk descriptor. printErrorMsg 23 $mmcmd return 1 fi elif [[ $deviceName = $CHANGE_NSD ]] then # The caller is mmchnsd or mmimportfs. # The disk may or may not belong to a file system. deviceName=${v[$DEV_NAME_Field]} [[ $deviceName = $NO_DEVICE ]] && deviceName="" else # The caller is mmcrfs, mmadddisk, or mmrpldisk. # The file system is known. addingDiskToFS=yes fi ####################################################### # Verify the diskUsage parameter and set the ts flags. ####################################################### [[ -z $defaultUsage ]] && defaultUsage=dataAndMetadata [[ -z $diskUsage ]] && diskUsage=$defaultUsage if [[ $diskUsage = dataAndMetadata ]] then : # There is nothing to do; use default values. elif [[ $diskUsage = metadataOnly ]] then hasData=0 elif [[ $diskUsage = dataOnly ]] then hasMetaData=0 elif [[ $diskUsage = descOnly ]] then hasData=0 hasMetaData=0 elif [[ $diskUsage = oldDiskUsage ]] then hasData="" hasMetaData="" diskUsage=${v[$DISK_USAGE_Field]} else # The disk usage parameter is invalid. printErrorMsg 24 $mmcmd return 1 fi ####################################################### # Verify the NSD server node values. ####################################################### # If a server node was specified, make sure that it is valid # and convert it if necessary to an admin node adapter name. if [[ -n $newPrimaryNsdAdminNode ]] then newPrimaryNsdAdminNode=$(checkAndConvertNodeValue \ $newPrimaryNsdAdminNode $REL_HOSTNAME_Field) [[ $? -ne 0 ]] && return 1 newPrimaryNsdDaemonNode=$(checkAndConvertNodeValue \ $newPrimaryNsdAdminNode $DAEMON_NODENAME_Field) [[ $? -ne 0 ]] && return 1 fi if [[ -n $newBackupNsdAdminNode ]] then newBackupNsdAdminNode=$(checkAndConvertNodeValue \ $newBackupNsdAdminNode $REL_HOSTNAME_Field) [[ $? -ne 0 ]] && return 1 newBackupNsdDaemonNode=$(checkAndConvertNodeValue \ $newBackupNsdAdminNode $DAEMON_NODENAME_Field) [[ $? -ne 0 ]] && return 1 fi # Are we adding disks to a file system? if [[ -n $addingDiskToFS ]] then # If adding an existing disk to some file system, # the descriptor cannot have NSD server nodes that # are different than the ones already defined. # Note: Under normal circumstances, the server fields # in the disk descriptor should be null. primaryNsdAdminNode=${v[$NSD_PRIMARY_NODE_Field]} primaryNsdDaemonNode=${v[$DAEMON_NSD_PRIMARY_Field]} backupNsdAdminNode=${v[$NSD_BACKUP_NODE_Field]} backupNsdDaemonNode=${v[$DAEMON_NSD_BACKUP_Field]} if [[ -n $newPrimaryNsdAdminNode && \ $newPrimaryNsdAdminNode != $primaryNsdAdminNode ]] then # The server node in the disk descriptor is not valid. printErrorMsg 201 $mmcmd $newPrimaryNsdAdminNode return 1 fi if [[ -n $newBackupNsdAdminNode && \ $newBackupNsdAdminNode != $backupNsdAdminNode ]] then # The server node in the disk descriptor is not valid. printErrorMsg 201 $mmcmd $newBackupNsdAdminNode return 1 fi else # If creating a new disk or changing an existing one, # accept the server node values from the descriptor. primaryNsdAdminNode=$newPrimaryNsdAdminNode primaryNsdDaemonNode=$newPrimaryNsdDaemonNode backupNsdAdminNode=$newBackupNsdAdminNode backupNsdDaemonNode=$newBackupNsdDaemonNode if [[ -n $backupNsdAdminNode && -z $primaryNsdAdminNode ]] then # The primary NSD node is not specified. printErrorMsg 491 $mmcmd $diskName return 1 fi fi # end of if [[ -n $addingDiskToFS ]] # If a primary NSD node was specified, find its node number # in order to compute the default failure group value. if [[ -n $primaryNsdAdminNode ]] then if [[ $backupNsdAdminNode = $primaryNsdAdminNode ]] then # The primary and backup NSD servers must be different nodes. printErrorMsg 492 $mmcmd return 1 fi primaryNodeNumber=$(checkAndConvertNodeValue $primaryNsdAdminNode $NODE_NUMBER_Field) [[ $? -ne 0 ]] && return 1 # The default failure group is the primary server number + 4000. defaultFailureGroup=$primaryNodeNumber+4000 fi # end of if [[ -n $primaryNsdAdminNode ]] ############################## # Failure group verification ############################## if [[ -n $replacingDisk ]] then : # Let tsrpldisk handle the failure group. elif [[ -n $failureGroup ]] then # Validate the user-supplied value. if [[ $failureGroup != ?(-)+([0-9]) ]] then # Invalid integer printErrorMsg 199 $mmcmd $failureGroup return 1 fi if [[ $failureGroup -ge -1 && $failureGroup -le 4000 || -n $primaryNsdAdminNode && $failureGroup -eq $defaultFailureGroup ]] then : # The user-specified failure group looks reasonable. else # Invalid failure group range. printErrorMsg 30 $mmcmd return 1 fi elif [[ -n $primaryNsdAdminNode ]] then # Set the failure group to the server node number + 4000. failureGroup=$defaultFailureGroup else # If all else fails, go with negative one. failureGroup="-1" fi # end of if [[ -n $replacingDisk ]] ############################# # Storage pool verification ############################# # Check the storage pool name if one was specified. if [[ -n $storagePool && $storagePool != "system" ]] then # Check whether the disk is to be used for metadata. if [[ $hasMetaData = 1 || $diskUsage = descOnly ]] then # The disk usage is not compatible with the storage pool. printErrorMsg 239 $mmcmd $diskUsage $storagePool return 1 fi # Check whether the storage pool name conforms to naming rules. # If it does not, issue an error message and exit with a non-zero rc. checkName poolName 255 "$storagePool" [[ $? -ne 0 ]] && return 1 fi ############################################################## # Everything seems to be OK. Generate the output and return. ############################################################## # Build the ts version of the descriptor. tsDiskDesc="$diskName:$driverType:$sectorSize:$failureGroup:" tsDiskDesc="${tsDiskDesc}$hasMetaData:$hasData:$storagePool" # Update fields in the SG_DISKS line as necessary. [[ -z $deviceName ]] && deviceName=$NO_DEVICE v[$NODESETID_Field]=$nodesetId v[$DEV_NAME_Field]=$deviceName v[$FAILURE_GROUP_Field]=$failureGroup v[$DISK_USAGE_Field]=$diskUsage v[$DISK_TYPE_Field]=$driverType v[$DISK_STATUS_Field]=$statusString v[$NSD_PRIMARY_NODE_Field]=$primaryNsdAdminNode v[$NSD_BACKUP_NODE_Field]=$backupNsdAdminNode v[$DAEMON_NSD_PRIMARY_Field]=$primaryNsdDaemonNode v[$DAEMON_NSD_BACKUP_Field]=$backupNsdDaemonNode v[$STORAGE_POOL_Field]=$storagePool updatedDiskLine=$(print_newLine) # Print the results. print -- "$updatedDiskLine $tsDiskDesc $diskUsage" return 0 } #----- end of function validateAndConvertNsdDescriptor --------- ######################################################################## # # Function: Invoke tspreparedisk to generate an unique identifier # and record it on the disk. If invoked by mmimportfs, # move the sg descriptor to sector 8 if necessary. # # Input: $1 - name of the underlying disk to use # $2 - value of verification flag (-v option of mmcrnsd) # $3 - invoking command # $4 - nsd subtype # (if "NULL" is passed, createNsd will determine it) # # Output: NSD disk type followed by the output from tspreparedisk # # Returns: 0 - success # non-zero - unexpected error # ######################################################################## function createNsd # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGcreateNsd ]] && set -x $mmTRACE_ENTER "$*" typeset diskName=$1 typeset vflag=$2 typeset invokingCommand=$3 typeset nsdSubtype=$4 typeset device tscmdParms tspreparediskOutput typeset unfenceAttempted="" typeset rc=0 typeset ec=0 if [[ $nsdSubtype = NULL ]] then # Determine the type of the underlying disk. nsdSubtype=$(determineNsdSubtype $diskName) rc=$? if [[ $rc -ne 0 || -z $nsdSubtype ]] then # Print result and return. print error tspreparedisk:0:0:0:0:3901:0:0 [[ $rc -eq 0 ]] && rc=1 return $rc fi fi # end of if [[ $nsdSubtype = NULL ]] # Ensure the sg descriptor starts in sector 8. if [[ $invokingCommand = mmimportfs ]] then tspreparediskOutput=$($tspreparedisk -m $diskName 2>$errMsg) rc=$? # If we fail because this is a fenced-out VSD, # unfence the disk and retry the tspreparedisk. if [[ $rc -eq 50 && $nsdSubtype = vsd ]] then $rm -f $errMsg unfenceVSDdisk $diskName ec=$? unfenceAttempted=yes if [[ $ec -eq 0 ]] then tspreparediskOutput=$($tspreparedisk -m $diskName 2>$errMsg) rc=$? fi fi # end of if [[ $rc -eq 50 && $nsdSubtype = vsd ]] # Check the result from the tspreparedisk command. if [[ $rc -ne 0 || -z $tspreparediskOutput ]] then # Print result and return. [[ -s $errMsg ]] && $cat $errMsg 1>&2 $rm -f $errMsg print error tspreparedisk:$rc:0:0:0:3902:0:0 [[ $rc -eq 0 ]] && rc=1 return $rc fi $rm -f $errMsg fi # end of if [[ $invokingCommand = mmimportfs ]] # Construct the fully-qualified device name. # Note that this is required for the -n and -N options # of tspreparedisk, but not for the -m option. if [[ $diskName = /* ]] then device=$diskName elif [[ $osName = AIX ]] then device=/dev/r$diskName else device=/dev/$diskName fi # Determine the parameters to specify on the tspreparedisk command. # If the -v flag on the mmcrnsd command was set to yes, do not # overwrite an existing pvid. Otherwise, unconditionally generate # a new pvid. if [[ $vflag = yes ]] then tscmdParms="-n $device -t $nsdSubtype" else tscmdParms="-N $device -t $nsdSubtype" fi # Invoke tspreparedisk to generate and write a unique pvid on the disk. tspreparediskOutput=$($tspreparedisk $tscmdParms) rc=$? # If there is failure because this is a fenced-out VSD, # unfence the disk and retry the tspreparedisk. if [[ $rc -eq 50 && $nsdSubtype = vsd && -z $unfenceAttempted ]] then unfenceVSDdisk $diskName ec=$? if [[ $ec -eq 0 ]] then tspreparediskOutput=$($tspreparedisk $tscmdParms) rc=$? fi fi # end of if [[ $rc -eq 50 && $nsdSubtype = vsd && -z $unfenceAttempted ]] # Output the NSD subtype and the result from tspreparedisk. print $nsdSubtype $tspreparediskOutput return $rc } #----- end of function createNsd ---------------------- ############################################################################## # # Function: Invoke tspreparedisk to configure disks for use as quorum disks. # # Input: $1 - file with the SG_DISK lines for the disks # $2 - comma-separated list of quorum node numbers # $3 - comma-separated list of quorum node names # $4 - invoking command # # Output: None # # Returns: 0 - success # non-zero - unexpected error # ############################################################################## function formatPaxosDisks # # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGformatPaxosDisks ]] && set -x $mmTRACE_ENTER "$*" typeset diskLines=$1 typeset quorumNodeNumbers=$2 typeset quorumNodeNames=$3 typeset invokingCommand=$4 typeset rc=0 typeset formatPaxosDisks_rc=0 typeset wOpt="" typeset sdrfsLine diskName pvid nsdSubtype fOpt rc2 typeset magicWord fsName nodeName invokedNode result [[ $invokingCommand = mmaddnode ]] && wOpt="-w" # Read the SG_DISK lines and process the disks one by one. $rm -f $errMsg IFS=":" exec 3<&- exec 3< $diskLines while read -u3 sdrfsLine do # Parse the line. set -f ; set -A v -- - $sdrfsLine ; set +f IFS="$IFS_sv" diskName=${v[$DISK_NAME_Field]} pvid=${v[$PVID_Field]} nsdSubtype=${v[$NSD_SUBTYPE_Field]} if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] then fOpt="" else fOpt="-f" fi # Loop through the list of nodes, invoking the tspreparedisk command # to format the disk. We continue looping until we succeed on some node. IFS="," for nodeName in $quorumNodeNames do IFS="$IFS_sv" if [[ $nodeName = $ourNodeName ]] then # Execute the command locally. result=$($mmremote adminCmd tspreparedisk \ -p $pvid -t $nsdSubtype -q $quorumNodeNumbers $fOpt $wOpt) rc=$? invokedNode=$ourNodeName tspreparediskOutput="$result" else # Check whether the node can be reached. isNodeReachable $nodeName if [[ $? -eq 0 ]] then # Invoke mmdsh to execute the command on the node. result=$($mmdsh -vL $nodeName $mmremote adminCmd tspreparedisk \ -p $pvid -t $nsdSubtype -q $quorumNodeNumbers $fOpt $wOpt) rc=$? invokedNode=${result%%: *} tspreparediskOutput=${result#* } tspreparediskOutput=${tspreparediskOutput## } else rc=$MM_HostDown fi # end of if [[ $? -eq 0 ]] fi # end of if [[ $nodeName = $ourNodeName ]] # Parse the result from tspreparedisk. IFS=":" set -f ; set -- $tspreparediskOutput ; set +f magicWord=$1 rc2=$2 IFS="$IFS_sv" # Issue an appropriate message if the node was unable # to execute tspreparedisk successfully. if [[ $rc -ne 0 || $magicWord != tspreparedisk || $rc2 -ne 0 ]] then # Something went wrong with this disk. # Try to make sense of the error. if [[ $rc -eq $MM_HostDown ]] then # The node is not reachable. printErrorMsg 340 $mmcmd $nodeName 2>> $errMsg elif [[ $magicWord = tspreparedisk ]] then # tspreparedisk executed but it was not happy about something. if [[ $rc2 = 1 ]] # E_PERM then # Permission was denied for disk. printErrorMsg 523 "$invokedNode: $mmcmd" "$diskName" 2>> $errMsg elif [[ $rc2 = 2 ]] # E_NOENT then # The disk was not found. printErrorMsg 524 "$invokedNode: $mmcmd" "$diskName" 2>> $errMsg elif [[ $rc2 = 5 ]] # E_IO then # I/O error printErrorMsg 525 "$invokedNode: $mmcmd" "$diskName" 2>> $errMsg elif [[ $rc2 = 19 ]] # E_NODEV then # A return code of ENODEV was returned for the disk. printErrorMsg 187 $mmcmd $invokedNode "$diskName" 2>> $errMsg elif [[ $rc2 = 50 ]] # E_NOCONNECT then # The disk is fenced out. printErrorMsg 395 $mmcmd $invokedNode "$diskName" 2>> $errMsg elif [[ $rc2 = 214 ]] # E_VALIDATE then # Disk validation error. printErrorMsg 539 "$invokedNode: $mmcmd" "$diskName" $rc2 2>>$errMsg elif [[ $rc2 = 221 ]] # E_BALSPACE then # There is no space in the descriptor for the paxos sectors. printErrorMsg 531 "$invokedNode: $mmcmd" "$diskName" 2>> $errMsg elif [[ $rc2 = 236 ]] # E_FORMAT_INCOMPAT then # The disk belongs to a back level file system or # it is not in ready state. fsName=$(findFSforDisk "$diskName" $mmsdrfsFile) printErrorMsg 528 "$invokedNode: $mmcmd" "$diskName" $fsName 2>> $errMsg else # Show the result from tspreparedisk. print -u2 "$tspreparediskOutput" 2>> $errMsg # There was an unexpected error from tspreparedisk. printErrorMsg 171 "$invokedNode: $mmcmd" \ "tspreparedisk -p $pvid -t $nsdSubtype -q $quorumNodeNumbers $fOpt $wOpt" $rc2 2>> $errMsg fi # end of if [[ $rc2 = 1 ]] else # Something is really wrong. Output error information if any. [[ -n $result ]] && print -u2 "$nodeName: $result" 2>> $errMsg fi # end of if [[ $magicWord = tspreparedisk ]] fi # end of if [[ $rc -ne 0 || $magicWord != tspreparedisk || $rc2 -ne 0 ]] # Exit the loop if tspreparedisk succeeded. [[ $rc -eq 0 && $magicWord = tspreparedisk && $rc2 -eq 0 ]] && break IFS="," # Change the field separator back to "," for the next iteration. done # end of for nodeName in $quorumNodeNames IFS="$IFS_sv" # If no node was able to run tspreparedisk successfully, # show all of the error messages and set a failure return code. if [[ $rc -ne 0 || $magicWord != tspreparedisk || $rc2 -ne 0 ]] then $cat $errMsg 1>&2 # Failed while processing the disk. printErrorMsg 529 $mmcmd "$diskName" formatPaxosDisks_rc=1 fi # end of if [[ $rc -ne 0 || $magicWord != tspreparedisk || $rc2 -ne 0 ]] # Reset things needed for the next iteration. $rm -f $errMsg IFS=":" done # end of while read -u3 sdrfsLine IFS="$IFS_sv" return $formatPaxosDisks_rc } #----- end of function formatPaxosDisks -------------------- ############################################################################ # # Function: Send nsd data obtained from the tspreparedisk -s command # (and other sources) for all nsds on this node to stdout. # # Input: X flag (optional; if set, it specifies that eXtra information # should be returned in the remarks field) # # Output: colon-separated nsd information from the "tspreparedisk -s" # command (and other sources if the X flag was specified) # # Returns: 0 - success # ############################################################################ function getLocalNsdData # [] { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetLocalNsdData ]] && set -x $mmTRACE_ENTER "$*" typeset Xflag=$1 typeset tspreparediskLine nsid deviceName localDevice deviceType vgname typeset vsdDataNeeded=yes # Obtain the output of the tspreparedisk -s command. $tspreparedisk -s > $tsOutputFile 2> $errMsg # Read and process the output. exec 4<&- exec 4< $tsOutputFile while read -u4 tspreparediskLine do # Parse the tspreparedisk output line. set -f ; set -- $tspreparediskLine ; set +f nsid=$1 localDevice=$2 deviceType=$3 # If this is an AIX environment, replace the /dev/r prefix with /dev/. if [[ $osName = AIX && $localDevice = +(/)dev+(/)r* ]] then deviceName=${localDevice##+(/)dev+(/)r} localDevice=/dev/$deviceName fi if [[ -z $Xflag ]] then # Here if -m or -M was specified. # If this is not an error line, print the data. [[ $nsid != tspreparedisk* ]] && \ print "getLocalNsdData:$nsid:$localDevice:$deviceType::" >> $nsdDataFile else # Here if -X was specified. # Obtain information for the remarks field for certain types of disks. remarks="" if [[ $osName = AIX ]] then if [[ $deviceType = vsd ]] then # Obtain VSD information for the remarks field. if [[ $vsdDataNeeded = yes ]] then getVsdRpdNodeData $tmpNodes LC_ALL=C $lsvsd -l > $vsdNamesFile 2>/dev/null LC_ALL=C $vsdatalst -v > $diskfile 2>/dev/null LC_ALL=C $vsdatalst -g > $volGroupFile 2>/dev/null $touch $tmpNodes $vsdNamesFile $diskfile $volGroupFile vsdDataNeeded=no fi remarks=$(obtainVsdInfo $deviceName $tmpNodes $vsdNamesFile $diskfile $volGroupFile) elif [[ $deviceType = lv ]] then # Obtain logical volume information for the remarks field. vgname=$(LC_ALL=C $lslv -L $deviceName 2>/dev/null | $awk '/VOLUME GROUP:/ {print $6}') [[ -z vgname ]] && vgname=unknown remarks="lv=$deviceName,vg=$vgname" fi # end of if [[ $deviceType = vsd ]] fi # end of if [[ $osName = AIX ]] # If this is not an error line, print the data. [[ $nsid != tspreparedisk* ]] && \ print "getLocalNsdData:$nsid:$localDevice:$deviceType:$remarks:" >> $nsdDataFile fi # end of if [[ -z $Xflag ]] done # end of while read -u4 tspreparediskLine # Send the colon-separated output and any error messages to stdout. $touch $nsdDataFile # Make sure the file exists even if empty. cat $nsdDataFile $errMsg return 0 } #----- end of function getLocalNsdData --------------------- #################################################################### # # Function: Find out the local device name for the disk with # the specified pvid. # # Input: $1 - pvid of the disk being looked up # $2 - nsd subtype of the disk being looked up # # Output: A line with the following ':' separated fields: # - magic word 'getLocalDiskName' # - local disk name # - return code from tspreparedisk -p # - always 0 (used to be return code from tsnsdreset -q) # # Returns: 0 - success # 1 - unexpected error # #################################################################### function getLocalDiskName # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetLocalDiskName ]] && set -x $mmTRACE_ENTER "$*" typeset pvid=$1 typeset nsdSubtype=$2 typeset tspreparediskOutput magicWord pvid typeset localDiskName="" typeset rc=0 typeset rc1=0 typeset rc2=0 # Use the nsd commands to determine the local device name. # Find out the local device name. tspreparediskOutput=$($tspreparedisk -p $pvid -t $nsdSubtype 2>$errMsg2) rc=$? # Parse the output from the tspreparedisk command. IFS=":" set -f ; set -- $tspreparediskOutput ; set +f magicWord=$1 rc1=$2 pvid=$3 localDiskName=$4 IFS="$IFS_sv" if [[ $magicWord != tspreparedisk ]] then # Unexpected error. Print error messages and give up. [[ -s $errMsg2 ]] && $cat $errMsg2 1>&2 $rm -f $errMsg2 [[ $rc -eq 0 ]] && rc=1 printErrorMsg 171 \ "getLocalDiskName" "tspreparedisk -p $pvid -t $nsdSubtype" $rc return 1 fi $rm -f $errMsg2 # If this is an AIX environment, replace the /dev/r prefix with /dev/. if [[ $osName = AIX && $localDiskName = +(/)dev+(/)r* ]] then localDiskName=${localDiskName##+(/)dev+(/)r} localDiskName=/dev/$localDiskName fi if [[ $rc -eq 0 && -n $localDiskName ]] then # tspreparedisk worked and we have a good answer. print -- "getLocalDiskName:$localDiskName:$rc1:$rc2" return 0 fi if [[ $MMMODE = single ]] then # If in single mode, there is nothing more to try; give up. print -- "getLocalDiskName:$UNRESOLVED:$rc1:$rc2" return 0 fi # If we are here, tspreparedisk failed to find out the local disk name. # There may be many reasons for this, one of which is that the disk is # being reserved by some other node and we cannot verify the pvid. # Assuming this is the case, we will look at the nsd map file and will # attempt to determine the mapping from there keeping in mind that the # answer is not 100% guaranteed to be correct anymore. # Search the nsd map file for an entry with our pvid. if [[ -s $nsdmap ]] then localDiskName=$($awk ' { \ if ($1 == "'$pvid'") { \ { print $2 } \ { exit 0 } \ } \ } ' $nsdmap) checkForErrors "awk $nsdmap" $? fi # end of if [[ -s $nsdmap ]] # If no matching pvid found in the hints file, give up. if [[ -z $localDiskName ]] then print -- "getLocalDiskName:$UNRESOLVED:$rc1:$rc2" return 0 fi # tspreparedisk should have been able to verify the pvid; # most likely this is a different disk. print -- "getLocalDiskName:$UNRESOLVED:$rc1:$rc2" return 0 } #----- end of function getLocalDiskName --------------- ############################################################# # # Function: Select an unused device minor number. # # Input: $1 - list of currently-assigned minor numbers. # # Output: A minor number for the /dev entry. # # Returns: Zero if successful, non-zero otherwise. # ############################################################# function assignDevMinor # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGassignDevMinor ]] && set -x $mmTRACE_ENTER "$*" typeset existingMinorNumbers="$1" typeset x devMinor typeset rc=0 # Set the initial devMinor number. The first 50 numbers # are reserved for existing file systems that do not play # by the new rules yet. devMinor=$((minMinorNumber + 50)) # Keep looping until we either find an unused minor number, # or we run out of numbers. while ((devMinor <= maxMinorNumber)) do # Scan the currently-assigned minor numbers. for x in $existingMinorNumbers do # If the number that we want is already in use, # get out of the for loop. [[ $x = $devMinor ]] && break done # If the number that we want is free, we are done. [[ $x != $devMinor ]] && break # No luck so far, try the next number. devMinor=$((devMinor + 1)) done # end of while ((devMinor <= maxMinorNumber)) # If the number is out of range, return null and let # mmfsmknod worry about it. This should never happen # since we do not support more than 32 file systems. if [[ $devMinor -gt $maxMinorNumber ]] then rc=1 devMinor="" fi # Return the result. print -- $devMinor return $rc } #----- end of function assignDevMinor ----------------- ############################################################# # # Function: Find the disk info (pvid, vgname, lvname) that # corresponds to the raw disk name. # # Input: $1 - raw disk name (eg: hdisk7, sda2). # # Output: The disk information: pvid, vgname, lvname. # # Returns: Zero if successful, non-zero otherwise. # ############################################################# function getRawDiskInfo # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetRawDiskInfo ]] && set -x $mmTRACE_ENTER "$*" typeset rawDiskName=$1 typeset pvid vgname lvname lspvOutput integer rc=0 # Find out the disks pvid and local volume group. lspvOutput=$($lspv | $grep -w $rawDiskName) rc=$? set -f ; set -- $lspvOutput ; set +f pvid=$2 vgname=$3 if [[ $rc -ne 0 || -z $pvid || -z $vgname ]] then printErrorMsg 232 $mmcmd $rawDiskName lspv return $rc fi if [[ $vgname != None && $vgname != gpfs ]] then # Determine the name of the logical volume that corresponds to this # volume group. If there is more than one lv ...? lvname=$(LC_ALL=C $lsvg -l $vgname 2>/dev/null | $grep mmfs | $awk '{ print $1 }') rc=$? if [[ $rc -ne 0 || -z $lvname ]] then printErrorMsg 104 "$mmcmd" "lsvg -l $vgname" return 1 fi else # We come here if vgname = None or vgname = gpfs (the latter being # indicative of an old, no-longer-used nsd for which mmdelnsd was not run). # Tell the user no disks were found. printErrorMsg 418 $mmcmd return 1 fi print -- $pvid $vgname $lvname return 0 } #----- end of function getRawDiskInfo ----------------- ############################################################# # # Function: Find the VSD name corresponding to the vgname. # # Input: $1 - vg name # # Output: The VSD name. # # Returns: Zero if successful, non-zero otherwise. # ############################################################# function getVSDName # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetVSDName ]] && set -x $mmTRACE_ENTER "$*" typeset vgname=$1 typeset vsdname gvg integer rc=0 gvg=$($vsdatalst -g | $awk '{ if ($2 == "'"$vgname"'") print $1 }') if [[ -z $gvg ]] then printErrorMsg 232 $mmcmd $vgname "vsdatalst -g" print -- "" return 1 else vsdname=$($vsdatalst -v | \ $awk '{if ($3 == "'"$gvg"'") print $1}') rc=$? if [[ $rc -ne 0 || -z $vsdname ]] then printErrorMsg 232 $mmcmd $vgname "vsdatalst -v" print -- "" return 1 fi fi print -- $vsdname return 0 } #----- end of function getVSDName --------------------- ############################################################# # # Function: Find the NSD disk name. # # Input: $1 - rawdisk, lv, or vsdname # # Output: the NSD disk name # # Returns: zero if successful, non-zero otherwise # ############################################################# function getNSDName # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetNSDName ]] && set -x $mmTRACE_ENTER "$*" rawName=$1 typeset rc=0 typeset gpfsDiskName tspreparediskOutput pvid if [[ $osName = AIX ]] then rawName="r$rawName" fi tspreparediskOutput=$($tspreparedisk -s | $grep -w "/dev/$rawName") rc=$? # Parse the output from the tspreparedisk command. IF=":" set -f ; set -- $tspreparediskOutput ; set +f pvid=$1 [[ $rc -ne 0 || -z $pvid ]] && return 1 # Search for the nsd disk name in the mmsdrfs file. gpfsDiskName=$($awk -F: ' \ /':$SG_DISKS:'/ { \ if ($'$PVID_Field' == "'$pvid'") { \ { print $'$DISK_NAME_Field' } \ { exit 0 } \ } \ } ' $mmsdrfsFile) checkForErrors awk $? if [[ -n $gpfsDiskName ]] then print -- $gpfsDiskName return 0 else return 1 fi } #----- end of function getNSDName --------------------- ############################################################### # # Function: Find the GPFS disk name given the raw disk name. # # Input: $1 - raw disk name (eg: hdisk, sda) # # Output: the GPFS disk name # # Returns: zero if successful, non-zero otherwise # ############################################################### function getGpfsDiskName # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGgetGpfsDiskName ]] && set -x $mmTRACE_ENTER "$*" typeset rawDiskName=$1 typeset rawDiskInfo pvid vgname lvname vsdname gpfsDiskName # Check the GPFS cluster type. [[ -z $MMMODE ]] && determineMode # Call routine to obtain the name of the NSD. gpfsDiskName=$(getNSDName $rawDiskName) # If the NSD was not found and this is a Linux node, # return with a failure rc; there is nothing more we can do. [[ -z $gpfsDiskName && $osName = Linux ]] && return 1 # Did we get the name of the NSD? if [[ -z $gpfsDiskName ]] then # We did not get the name of the NSD. # Check whether this is an AIX logical volume. rawDiskInfo=$(getRawDiskInfo $rawDiskName) set -f ; set -- $rawDiskInfo ; set +f pvid=$1 vgname=$2 lvname=$3 # If we did not find an lv, return with a failing rc; # the disk is not known. [[ -z $lvname ]] && return 1 # Check for an NSD name corresponding to the lv. gpfsDiskName=$(getNSDName $lvname) if [[ -z $gpfsDiskName ]] then # If still no NSD was found, check whether this is a VSD. vsdname=$(getVSDName $vgname) if [[ -n $vsdname ]] then # Check for an NSD name corresponding to the vsd. gpfsDiskName=$(getNSDName $vsdname) [[ -z $gpfsDiskName ]] && return 1 else # We did not find the NSD. Return with a failing rc. return 1 fi fi fi # end of if [[ -z $gpfsDiskName ]] # Output the GPFS disk name and return. print -- $gpfsDiskName return 0 } #----- end of function getGpfsDiskName ----------------------- ########################################################################### # # Function: Reset (i.e., set to the null string) the status field # of SG_DISKS lines for the specified filesystem if their # disk status value matches the passed status string, # thus causing the disk to be reported to the GPFS daemon # by future invocations of the getEFOptions routine. # # This routine is called after a ts disk command has completed # successfully. # # Input: $1 - file system name # $2 - passed sdrfs file # $3 - 1st status string used to identify SG_DISK lines # whose disk status fields need to be reset; # the only acceptable values are "mmadd" and "mmdel" # $4 - optional 2nd status string used to identify SG_DISK # lines whose disk status fields need to be reset; # if specified, the only acceptable value is "mmdel"; # this option is used by mmrpldisk which does both # an add and a delete # # Output: The sdrfs file has been updated (the DISK_STATUS field # of any SG_DISKS line for the specified filesystem is # reset if the disk status matches the passed values) # # Returns: 0 - the passed sdrfs file was successfully updated # ########################################################################### function resetDiskStatus # [] { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGresetDiskStatus ]] && set -x $mmTRACE_ENTER "$*" typeset fsname=$1 typeset sdrfsFile=$2 typeset status1=$3 typeset status2=$4 typeset oddState typeset outfile=${sdrfs}tmp $rm -f $outfile oddState=$($awk -F: ' \ BEGIN { \ { oddstate = "no" } \ { c = ":" } \ } \ # If this is the global header line, increment the gen number. \ /^'$GLOBAL_ID:$VERSION_LINE:'/ { \ { $'$SDRFS_GENNUM_Field' = $'$SDRFS_GENNUM_Field' + 1 } \ { print $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":" \ $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":" \ $21":"$22":"$23":"$24":"$25":"$26":"$27":" >> "'$outfile'" } \ { next } \ } \ # Save the SG_HEADR line for the specified filesystem as two \ # strings - the parts before and after ODD_STATE_Field ($6). \ /':$SG_HEADR:$fsname:'/ { \ { sgh1 = $1 c $2 c $3 c $4 c $5 } \ { sgh2 = $7 c $8 c $9 c $10 c $11 c $12 c $13 c $14 c $15 c $16 c $17 c } \ { sgh2 = sgh2 $18 c $19 c $20 c $21 c $22 c $23 c $24 c $25 c $26 c $27 c } \ { next } \ } \ # Check for SG_DISKS lines for the specified filesystem. \ /':$SG_DISKS:$fsname:'/ { \ # Does the disk status value match the first passed value? \ if ( $'$DISK_STATUS_Field' == "'$status1'" ) { \ # The disk status value matches. Process the line. \ if ( "'$status1'" == "mmadd" ) { \ # For mmadd, we simply reset the disk status field. \ { $'$DISK_STATUS_Field' = "" } \ { print $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":" \ $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":" \ $21":"$22":"$23":"$24":"$25":"$26":"$27":" >> "'$outfile'" } \ } else { \ if ( "'$status1'" == "mmdel" ) { \ # For mmdel, we change the disk into a free disk \ # and reset the disk status field. \ { $'$NODESETID_Field' = "'$FREE_DISK'" } \ { $'$DEV_NAME_Field' = "'$NO_DEVICE'" } \ { $'$LINE_NUMBER_Field' = "0" } \ { $'$DISK_STATUS_Field' = "" } \ { print $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":" \ $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":" \ $21":"$22":"$23":"$24":"$25":"$26":"$27":" >> "'$outfile'" } \ } \ } \ { next } \ } else { \ # Does the disk status value match a second passed value of mmdel? \ if ( "'$status2'" == "mmdel" && $'$DISK_STATUS_Field' == "'$status2'" ) { \ # The disk status value matches and is mmdel. \ # We change the disk into a free disk and reset the status field. \ { $'$NODESETID_Field' = "'$FREE_DISK'" } \ { $'$DEV_NAME_Field' = "'$NO_DEVICE'" } \ { $'$LINE_NUMBER_Field' = "0" } \ { $'$DISK_STATUS_Field' = "" } \ { print $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":" \ $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":" \ $21":"$22":"$23":"$24":"$25":"$26":"$27":" >> "'$outfile'" } \ { next } \ } else { \ # The disk status value does not match anything. \ # Echo the line as is and check whether the disk is in an odd state. \ { print $0 >> "'$outfile'" } \ if ( $'$DISK_STATUS_Field' != "" && \ $'$DISK_STATUS_Field' != "ready" ) { \ { oddstate = "yes" } \ } \ { next } \ } \ } \ } \ # All other lines are echoed without change. \ { print $0 >> "'$outfile'" } \ END { \ { print sgh1 ":" oddstate ":" sgh2 >> "'$outfile'" } \ } \ ' $sdrfsFile) checkForErrors awk $? # Print a message for the user if any disks are in an odd state. [[ $oddState = yes ]] && printErrorMsg 103 $mmcmd $fsname $fsname # Sort the updated version of the sdrfs file. LC_ALL=C $SORT_MMSDRFS $outfile -o $outfile checkForErrors "sorting $outfile" $? # The file was updated successfully. Copy it to the input file. $mv $outfile $sdrfsFile checkForErrors "resetDiskStatus: mv $outfile $sdrfsFile " $? return 0 } #----- end of function resetDiskStatus ----------------------- ########################################################################## # # Function: Compare the daemon's list of disks for the file system # with that contained in the passed sdrfs file. # If they disagree, change the sdrfs file to agree # with the information returned by the daemon. # If any of the disks of the file system are in an # "odd state", the "odd state" flag is set to "yes" # in the SG_HEADR line for the file system (otherwise # it is set to "no"). # # Input: $1 - file system name # $2 - passed sdrfs file # # Output: The SG_DISKS lines in the sdrfs file for the specified # file system now agree with the daemon's view of the disks. # # Returns: 0 - the passed sdrfs file now agrees with the daemon # for the disks in the specified file system # Any other return code indicates an unexpected error. # ########################################################################## function reconcileSdrfsWithDaemon # { typeset sourceFile="mmfsfuncs.sh" [[ -n $DEBUG || -n $DEBUGreconcileSdrfsWithDaemon ]] && set -x $mmTRACE_ENTER "$*" typeset fsname=$1 typeset sdrfsFile=$2 typeset mmlsdiskLine sdrfsLine nodesetId diskName sgh1 sgh2 typeset failureGroup holdsMetadata holdsData diskStatus typeset oddState="no" typeset rc=0 integer nodeCount=0 integer seqNo=0 # Print message: "Verifying file system configuration information ..." printInfoMsg 473 # Determine the nodeset to which this filesystem belongs. nodesetId=$($awk -F: ' \ /':$SG_HEADR:'/ { \ if ( $'$DEV_NAME_Field' == "'$fsname'" ) { \ {print $'$NODESETID_Field'} \ { exit 0 } \ } \ } \ ' $sdrfsFile) checkForErrors awk $? # Obtain the daemon's list of disks for the filesystem. # If the nodeset to which this node belongs is the same as the nodeset # in which the file system resides, invoke the command directly. if [[ $nsId = $nodesetId ]] then ${mmcmdDir}/${links}/mmlsdisk $fsname >$tmpfile2 2>$errMsg rc=$(remapRC $?) # If the command failed in a way that a remote invocation will not # make a difference, display any error messages and get out. if [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait && $rc -ne 0 ]] then [[ -s $errMsg ]] && $cat $errMsg 1>&2 $rm -f $errMsg if [[ $rc -eq $MM_ConnectionReset ]] then # An internode connection was reset. printErrorMsg 257 $mmcmd fi return $rc fi else # Set rc to a non-zero value so we will try the mmlsdisk cmd remotely. rc=$MM_DaemonDown fi $rm -f $errMsg # If the mmlsdisk call has not succeeded yet, # issue the mmlsdisk command on a remote node. if [[ $rc -ne 0 ]] then # Create a file with the reliable names that form # the nodeset to which the file system belongs. nodeCount=$(getNodeFile $REL_HOSTNAME_Field $nodesetId $sdrfsFile $nodefile) if [[ $nodeCount -eq 0 ]] then # The nodeset is empty; there is nobody to run the command. printErrorMsg 171 $mmcmd "getNodeFile (nodeCount=0)" 1 return 1 fi # Try the nodes one by one until a node is able to execute the command. preferredNode=0 # We have no idea where to go first; let mmcommon decide. $mmcommon linkCommand $preferredNode $nodefile \ mmlsdisk $fsname >$tmpfile2 2>$errMsg rc=$? if [[ $rc -ne 0 ]] then [[ -s $errMsg ]] && $cat $errMsg 1>&2 $rm -f $errMsg if [[ $rc -eq $MM_ConnectionReset ]] then # An internode connection was reset. printErrorMsg 257 $mmcmd fi return $rc fi fi $rm -f $errMsg # Remove the header lines from the mmlsdisk output. $tail -n +4 $tmpfile2 > $tmpfile checkForErrors "tail -n +4 $tmpfile2 $tmpfile" $? # One more sanity check before we proceed. if [[ ! -s $tmpfile ]] then printErrorMsg 171 reconcileSdrfsWithDaemon "tslsdisk - missing disk information" 1 return 1 fi ########################################################################## # Go through the passed sdrfs file. Increment the generation number. # Make any needed changes to SG_DISKS lines for the specified filesystem. ########################################################################## # Delete the temporary file that will be created. $rm -f $sdrfs IFS=":" # Change the field separator to ':'. exec 3<&- exec 3< $sdrfsFile while read -u3 sdrfsLine do # Parse the line. set -f ; set -A v -- - $sdrfsLine ; set +f IFS="$IFS_sv" printLine=true # Selectively alter some of the fields in the line. case ${v[$LINE_TYPE_Field]} in $VERSION_LINE ) # This is the global header line. # Increment the generation number newGenNumber=${v[$SDRFS_GENNUM_Field]}+1 v[$SDRFS_GENNUM_Field]=$newGenNumber ;; $SG_HEADR ) # This is the header line for some file system. # If this is the header for the specified file system, # save the line's contents into two strings that will be used # later in creating the SG_HEADR line. We can't create the # line now because we don't know how to set the "odd state" # field for the file system yet. if [[ ${v[$DEV_NAME_Field]} = $fsname ]] then printLine=false sgh1=${v[1]}:${v[2]}:${v[3]}:${v[4]}:${v[5]} sgh2=${v[7]}:${v[8]}:${v[9]}:${v[10]}:${v[11]}:${v[12]}:${v[13]} sgh2=$sgh2:${v[14]}:${v[15]}:${v[16]}:${v[17]}:${v[18]}:${v[19]} sgh2=$sgh2:${v[20]}:${v[21]}:${v[22]}:${v[23]}:${v[24]} fi ;; $SG_DISKS ) # This line describes a disk. # If this disk belongs to the file system or is a free disk, # make the SG_DISKS line agree with the daemon's data about the disk. if [[ ${v[$DEV_NAME_Field]} = $fsname || ${v[$NODESETID_Field]} = $FREE_DISK ]] then # Locate the line for this disk in the mmlsdisk output file. $rm -f $tmpfile2 mmlsdiskLine=$($awk ' \ # If the line is for our disk, output it to $mmlsdiskLine \ # but do not append it to tmpfile2. \ $1 == "'${v[$DISK_NAME_Field]}'" { \ { print $0 } \ { next } \ } \ # If the line is for some other disk, append it to tmpfile2. \ { print $0 >> "'$tmpfile2'" } \ ' $tmpfile) checkForErrors awk $? # Prepare the mmlsdisk output file for the next iteration. # It will contain all of its prior lines except the line # for the disk that is currently being processed. $touch $tmpfile2 # Make sure the file exists even if empty. $mv $tmpfile2 $tmpfile checkForErrors "mv $tmpfile2 $tmpfile" $? if [[ -z $mmlsdiskLine ]] then # The daemon doesn't know about this disk. # If the SG_DISKS line indicates the disk belongs to the # filesystem, change the SG_DISKS line into a free disk line. if [[ ${v[$DEV_NAME_Field]} = $fsname ]] then v[$NODESETID_Field]=$FREE_DISK v[$DEV_NAME_Field]=$NO_DEVICE v[$LINE_NUMBER_Field]=0 v[$EXCLUDE_Field]=$includedDisk v[$DISK_STATUS_Field]="" fi else # The daemon says this disk is part of the filesystem. # Update the SG_DISKS line fields with the data from # mmlsdisk so that it is current. set -f ; set -- $mmlsdiskLine ; set +f failureGroup=$4 holdsMetadata=$5 holdsData=$6 diskStatus=$7 v[$FAILURE_GROUP_Field]=$failureGroup if [[ $holdsData = yes ]] then if [[ $holdsMetadata = yes ]] then v[$DISK_USAGE_Field]=dataAndMetadata else v[$DISK_USAGE_Field]=dataOnly fi else if [[ $holdsMetadata = yes ]] then v[$DISK_USAGE_Field]=metadataOnly else v[$DISK_USAGE_Field]=descOnly fi fi [[ $diskStatus = allocmap* || $diskStatus = being* || $diskStatus = removing* ]] && diskStatus=$diskStatus$8 v[$DISK_STATUS_Field]=$diskStatus [[ $diskStatus != ready && $diskStatus != "" ]] && oddState="yes" # If the disk is listed as a free disk, change the SG_DISKS # line to indicate that the disk is part of the filesystem. if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] then v[$NODESETID_Field]=$nodesetId v[$DEV_NAME_Field]=$fsname fi # Update the sequence number. seqNo=seqNo+1 v[$LINE_NUMBER_Field]=$seqNo fi # end of if [[ -z $mmlsdiskLine ]] fi # end of if [[ disk belongs to filesystem or disk is a free disk ]] ;; * ) # Pass all lines for other nodesets without a change. ;; esac # end Change some of the fields # Build and write the line to the new sdrfs file. if [[ $printLine = true ]] then print_newLine >> $sdrfs checkForErrors "writing to file $sdrfs" $? fi IFS=":" # Change the separator back to ":" for the next iteration. done # end while read -u3 sdrfsLine IFS="$IFS_sv" # Restore the default IFS settings. # Issue informational error messages for any active disks # reported by the daemon but not found in the sdrfs file. if [[ -s $tmpfile ]] then $rm -f $tmpfile2 exec 3<&- exec 3< $tmpfile while read -u3 mmlsdiskLine do # Parse the line. set -f ; set -- $mmlsdiskLine ; set +f diskStatus=$7 if [[ $diskStatus = "ready" ]] then print -- $mmlsdiskLine >> $tmpfile2 else oddState=yes # Set flag to let caller know he has odd-state disks. fi done # end of while read -u3 mmlsdiskLine if [[ -s $tmpfile2 ]] then # Active disks are missing from the GPFS configuration data. printErrorMsg 102 $mmcmd $cat $tmpfile2 1>&2 return 1 fi fi # end of if [[ -s $tmpfile ]] # Create/store the SG_HEADER line for the file system in the sdrfs file, # using the odd state flag that was set if any of the disks in the # file system were in an odd state. print -- "$sgh1:$oddState:$sgh2" >> $sdrfs checkForErrors "writing to file $sdrfs" $? # Print a message for the user if any disks are in an odd state. [[ $oddState = yes ]] && printErrorMsg 266 $mmcmd $fsname # Sort the reconciled version of the mmsdrfs file. LC_ALL=C $SORT_MMSDRFS $sdrfs -o $sdrfs checkForErrors "sorting $sdrfs" $? # Everything seems to have gone ok so far. # Rename the file so that the caller can find it. $mv $sdrfs $sdrfsFile checkForErrors "mv $sdrfs $sdrfsFile" $? # Return to the caller. return 0 } #----- end of function reconcileSdrfsWithDaemon --------------