#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2000,2006 # 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 # @(#)14 1.44.1.1 src/avs/fs/mmfs/ts/admin/mmglobfuncs.Linux.sh, mmfs, avs_rgpfs24, rgpfs24s007a 9/20/06 11:22:24 ############################################################# # # This file contains declarations and functions that are # unique to the Linux operating system environment. # ############################################################# sourceFile="mmglobfuncs.Linux.sh" [[ -n $DEBUGmmglobfuncsLinux ]] && set -x #----------------------------------------------------------- # Constants and global variables for internal mm command use. #----------------------------------------------------------- fsDeviceType='b' defaultMajorNumber=239 minMinorNumber=100 maxMinorNumber=255 currentMajorNumber=$defaultMajorNumber neededMajorNumber=$defaultMajorNumber # Find out if this is 2.4 or earlier version. [[ $(/bin/uname -r) = 2.[0-4].* ]] && version24=yes || version24="" #----------------------------------------------------------- # Return codes and constants for internal mm command use. #----------------------------------------------------------- MM_Remotefs2=66 # remote file system (EREMOTE) MM_UnknownCluster2=101 # unknown cluster (ENETUNREACH) MM_ConnAborted=103 # connection aborted (ECONNABORTED) MM_ConnectionReset2=104 # connection reset (ECONNRESET) MM_TimedOut2=110 # connection timed out (ETIMEDOUT) MM_HostDown2=112 # host is down (EHOSTDOWN) MM_DaemonDown2=127 # daemon not running (second value) #----------------------------------------------------------- # Full path names for Linux system commands #----------------------------------------------------------- automount=/usr/sbin/automount awk=/bin/awk cat=/bin/cat chmod=/bin/chmod chown=/bin/chown cp=/bin/cp cut=cut # /bin/cut or /usr/bin/cut depending on the RH release date=/bin/date dd=/bin/dd df=/bin/df diff=/usr/bin/diff egrep=/bin/egrep find=/usr/bin/find fgrep=/bin/fgrep grep=/bin/grep head=/usr/bin/head # host=/usr/bin/host host="host_aixformat" # internal function to convert the host output hostname=/bin/hostname id=/usr/bin/id ifconfig=/sbin/ifconfig insmod=/sbin/insmod join=/usr/bin/join kill=/bin/kill locale=/usr/bin/locale ln=/bin/ln ls=/bin/ls lsmod=/sbin/lsmod lssrc=/usr/bin/lssrc mkdir=/bin/mkdir mknod=/bin/mknod mount=/bin/mount mv=/bin/mv nm=/usr/bin/nm openssl=/usr/bin/openssl perl=/usr/bin/perl ping=/bin/ping ps=/bin/ps rcp=/usr/bin/rcp rm=/bin/rm rmdir=/bin/rmdir rmmod=/sbin/rmmod rpm=/bin/rpm rsh=/usr/bin/rsh sed=/bin/sed sleep=/bin/sleep sort=/bin/sort srcmstr=/sbin/srcmstr startsrc=/usr/bin/startsrc stopsrc=/usr/bin/stopsrc sum=/usr/bin/sum sync=/bin/sync tail=/usr/bin/tail tee=/usr/bin/tee touch=/bin/touch tr=/usr/bin/tr umount=/bin/umount uname=/bin/uname unmount=/bin/umount # synonym for umount wc=/usr/bin/wc #----------------------------------------------------------- # Well-known file names #----------------------------------------------------------- etcFilesystems="/etc/fstab" # Filesystem stanzas used by the mount command etcHosts="/etc/hosts" # Local host name resolution file etcHostConf="/etc/host.conf" # Resolver configuration file auto_master="/etc/auto_master" # master input for the automount daemon autoMaster="/etc/auto.master" # master input for the automount daemon #------------------------------- # Commands with common options #------------------------------- # Command to extract a specific field from a line. # Example: print -- $line | $GETVALUE $NODE_NAME_Field GETVALUE="$cut -d: -f " # Command to sort the mmsdrfs file prior to storing it. # Example: LC_ALL=C $SORT_MMSDRFS $sdrfs -o $sdrfs # The sorting is based on the following keys: # - the primary key is the nodeset id # - the secondary key is the stripe group id # - the next key is the line type # - the last key is the line number # The sorting is based on the ASCII collating sequence, # except for the fourth field, which is sorted in # arithmetic order. SORT_MMSDRFS="$sort -t: -k 1,1 -k 3,3 -k 2,2 -k 4,4n " #------------------------------- # Frequently used functions #------------------------------- #################################################################### # # Function: In the Linux environment, function host_aixformat # looks up a name using both /etc/hosts and the Linux # host command. This function determines the order # in which the name is resolved. # # Input: None. # # Output: "hosts" - check first the /etc/hosts file. # "bind" - start with the host command. # # Returns: Always zero. # #################################################################### function setHostResolveOrder { typeset sourceFile="mmglobfuncs.Linux.sh" [[ -n $DEBUG || -n $DEBUGsetHostResolveOrder ]] && set -x $mmTRACE_ENTER "$*" typeset order # Find out the host lookup order. Our rules are: # If 'hosts' is specified first on the order line in /etc/host.conf, # search for the name in /etc/hosts before issuing the host command. # Otherwise, start with the host command. if [[ -f $etcHostConf ]] then order=$($awk ' \ BEGIN { order = "bind" } \ $1 == "order" && $2 ~ /^hosts/ { order = "hosts" } \ END { print order } \ ' $etcHostConf 2>/dev/null) else order=bind fi print $order return 0 } #-------------- end of function setHostResolveOrder ------------------ #################################################################### # # Function: Issues the Linux host command and converts the output # to make it look as if it came from an AIX host command. # If the host command does not resolve the name, try # looking up the name in the local /etc/hosts file. # # Input: $1 - hostname or IP address # # Output: A line similar to the following: # esj.austin.ibm.com is 9.53.145.122 # # Returns: 0 - hostname resolved # non-zero - name not resolved # #################################################################### function host_aixformat # { typeset sourceFile="mmglobfuncs.Linux.sh" [[ -n $DEBUG || -n $DEBUGhost_aixformat ]] && set -x $mmTRACE_ENTER "$*" typeset inValue=$1 typeset nameResolved=no typeset etcHostsChecked=no typeset hostOutput=${tmpDir}hostOutput.${mmcmd}.$$ typeset hostErrMsg=${tmpDir}hostErrMsg.${mmcmd}.$$ typeset rc awkRc hostResult [[ -z $inValue ]] && return 1 # If still not known, determine the lookup order. [[ -z $resolveOrder ]] && \ resolveOrder=$(setHostResolveOrder) # If it is OK to do so, see if the host name appears in /etc/hosts. if [[ $resolveOrder = hosts && -f $etcHosts ]] then $awk ' \ BEGIN { entriesFound = 0 } \ # Skip comment, empty and short lines. \ $1 ~ /^#/ || NF <= 1 { next } \ # Compare the inValue to each of the fields. \ { for ( i = 1; i <= NF; i++ ) { \ if ( $i == "'$inValue'" ) { \ { print $2 " is " $1 } \ { entriesFound += 1 } \ { next } \ } \ # Ignore in-line comments. \ if ( $i ~ /^#/ ) { \ { break } \ } \ } \ { next } \ } \ END { \ if ( entriesFound == 1 ) { exit 0 } \ if ( entriesFound == 0 ) { exit 1 } \ { exit 2 } \ } \ ' $etcHosts awkRc=$? if [[ $awkRc -eq 0 ]] then # Name successfully resolved using /etc/hosts. nameResolved=yes rc=0 elif [[ $awkRc -eq 2 ]] then # There is more than one matching entry in /etc/hosts. # Give up - multiple names are not allowed. printErrorMsg 498 $mmcmd "$inValue ($etcHosts)" return 1 else # Name not found in /etc/hosts but keep going. etcHostsChecked=yes rc=1 fi # end of if [[ $awkRc -eq 0 ]] fi # end of if [[ $resolveOrder = hosts ]] # If the name is not resolved yet (because it is not in /etc/hosts # or because we have to start with the host command), try to resolve # the name using the Linux host command. if [[ $nameResolved = no ]] then # The output of the host command, and as a result the way we parse it, # depends on whether the input parameter is a hostname or an IP address. if [[ $inValue = +([0-9]).+([0-9]).+([0-9]).+([0-9])?(.) ]] then # We start with an IP address. The host command output looks like this: # 122.145.53.9.IN-ADDR.ARPA domain name pointer esj.austin.ibm.com hostResult=$(LC_ALL=C /usr/bin/host -t a $inValue 2>$hostErrMsg) rc=$? if [[ $rc -eq 0 ]] then set -f ; set -- $hostResult ; set +f if [[ -z $5 || -n $6 || $3 = not && $4 = found* ]] then # Something is wrong. Collect error information to be later # displayed to the user if the name cannot be resolved. # Note: Linux sends the 'not found' message to stdout and returns 0. # This forces us to do the funny test for $3 and $4 above. # Unexpected output from the host command. printErrorMsg 499 $mmcmd $inValue 2> $hostErrMsg /usr/bin/host -t a $inValue >>$hostErrMsg 2>&1 rc=1 else # Things seem to have worked. print -- "${5%.} is $inValue" nameResolved=yes fi fi else # We start with a hostname. The host command output looks like this: # esj.austin.ibm.com has address 9.53.145.122 # It is possible to have nickname line and more than one address line. LC_ALL=C /usr/bin/host -t a $inValue >$hostOutput 2>$hostErrMsg rc=$? if [[ $rc -eq 0 ]] then # Strip any nickname lines and eliminate duplicates hostResult=$($cat $hostOutput | $grep ' has address ' | $sort -u) set -f ; set -- $hostResult ; set +f if [[ -z $4 || -n $5 || $3 = not && $4 = found* ]] then # Something is wrong. Collect error information to be later # displayed to the user if the name cannot be resolved. # Note: Linux sends the 'not found' message to stdout and returns 0. # This forces us to do the funny test for $3 and $4 above. # Unexpected output from the host command. printErrorMsg 499 $mmcmd $inValue 2> $hostErrMsg /usr/bin/host -t a $inValue >>$hostErrMsg 2>&1 # Cannot handle multiple interfaces for host $inValue [[ -n $5 ]] && printErrorMsg 498 $mmcmd "$inValue" rc=1 else # Things seem to have worked. print -- "${1%.} is $4" nameResolved=yes fi fi fi # end of if [[ $inValue = +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] fi # end of if [[ $nameResolved = no ]] # If the name is still not resolved, and we haven't tried it yet, # try resolving the name by looking up /etc/hosts. if [[ $nameResolved = no ]] then if [[ $etcHostsChecked = no ]] then $awk ' \ BEGIN { entriesFound = 0 } \ # Skip comment, empty and short lines. \ $1 ~ /^#/ || NF <= 1 { next } \ # Compare the inValue to each of the fields. \ { for ( i = 1; i <= NF; i++ ) { \ if ( $i == "'$inValue'" ) { \ { print $2 " is " $1 } \ { entriesFound += 1 } \ { next } \ } \ # Ignore in-line comments. \ if ( $i ~ /^#/ ) { \ { break } \ } \ } \ { next } \ } \ END { \ if ( entriesFound == 1 ) { exit 0 } \ if ( entriesFound == 0 ) { exit 1 } \ { exit 2 } \ } \ ' $etcHosts awkRc=$? fi # end of if [[ $etcHostsChecked = no ]] if [[ $awkRc -eq 0 ]] then # Name successfully resolved using /etc/hosts. rc=0 elif [[ $awkRc -eq 2 ]] then # There is more than one matching entry in /etc/hosts. printErrorMsg 498 $mmcmd "$inValue ($etcHosts)" elif [[ -s $hostErrMsg ]] then # Name not found in /etc/hosts. Show the error information # from the Linux host command above. $cat $hostErrMsg 1>&2 else # Name not found in /etc/hosts and there is no other error information. printErrorMsg 500 $mmcmd $inValue fi # end of if [[ $awkRc -eq 0 ]] fi # end of if [[ $nameResolved = no ]] $rm -f $hostOutput $hostErrMsg return $rc } #-------------- end of function host_aixformat ------------------ ################################################################## # # Function: Remap ts return codes to OS-independent values. # # Input: $1 - the return code to be mapped. # # Output: the remapped input return code # # Returns: always zero # # Example: # tstatus -m fsname # rc=$(remapRC $?) # ################################################################## function remapRC # { typeset sourceFile="mmglobfuncs.Linux.sh" [[ -n $DEBUG || -n $DEBUGremapRC ]] && set -x $mmTRACE_ENTER "$*" typeset rcIn=$1 typeset rcOut case $rcIn in $MM_DaemonDown2 ) rcOut=$MM_DaemonDown ;; $MM_HostDown2 ) rcOut=$MM_HostDown ;; $MM_TimedOut2 ) rcOut=$MM_TimedOut ;; $MM_Remotefs2 ) rcOut=$MM_Remotefs ;; $MM_UnknownCluster2 ) rcOut=$MM_UnknownCluster ;; $MM_ConnectionReset2 ) rcOut=$MM_ConnectionReset ;; $MM_ConnAborted ) rcOut=$MM_DaemonDown ;; * ) rcOut=$rcIn ;; esac # end of case $rcIn in # Return the new value. print -- "$rcOut" return 0 } #------- end of function remapRC --------------------