#!/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 # @(#)84 1.473.1.23 src/avs/fs/mmfs/ts/admin/mmglobfuncs.sh, mmfs, avs_rgpfs24, rgpfs24s012a 4/18/07 15:05:42 ##################################################################### # # This file contains declarations and functions that are # common to most of the commands. All mm commands must # read this dot script before they do anything else. # # If a command needs additional dot scripts, they must # be read after this one. # ##################################################################### sourceFile="mmglobfuncs.sh" PS4='${0##*/}:${sourceFile}[$LINENO]> ' [[ -n $DEBUGmmglobfuncs ]] && set -x #----------------------------------------------------------- # Determine the operating system name. #----------------------------------------------------------- osName=$(/bin/uname -s) #----------------------------------------------------------- # Set environment and save input arguments. #----------------------------------------------------------- unset ENV umask 022 UMASK_sv=022 export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin" export PERL_BADLANG=0 integer argc=$# cmdline=$* mmcmd=${0##*/} if [[ $mmcmd = mmremote && "$1" = mmrpc* ]] then mmrpc="$1" shift 1 fi arg1="$1" arg2="$2" arg3="$3" arg4="$4" arg5="$5" arg6="$6" arg7="$7" arg8="$8" arg9="$9" #----------------------------------------------------------- # Global variables and constants #----------------------------------------------------------- primaryServer="" # primary server for cluster sdr files backupServer="" # backup server for cluster sdr files mmmode="" # mm mode (cluster type) environmentType="" # environment type gpfsObjectInfo="" # GPFS object info sdrLocked=no # If yes, the sdr is locked. gpfsLocked=no # If yes, the Gpfs object is locked. envLocked=no # If yes, the local env update lock is held. lockId=$$ # identifier for sdr locking getCredCalled=no # If yes, the getCred function was executed. new_krb5="" # newly-obtained DCE credentials old_krb5="$KRB5CCNAME" # DCE credentials prior to entering this script new_KRBTKFILE="/tmp/tktmmfs$$" # Kerberos ticket file for the command old_KRBTKFILE="$KRBTKFILE" # Kerberos file prior to entering this script nodesetId="" # the nodeset to which the command applies nsId="" # the nodeset to which this node belongs preferredNode=0 # the first node to try when shipping command noUsageMsg=0 # suppress the usage statement integer newGenNumber=0 # generation number for the mmsdrfs file integer sdrGenNumber=0 # most recent mmsdrfs generation number integer sdrGenTimestamp=0 # timestamp of the mmsdrfs generation number sdrfsFormatLevel=0 # the format level of the mmsdrfs file IFS_sv="$IFS" # value of the IFS environment variable ourNodeNumber="" # the node number of this node ourNodeName="" # the reliable node name of this node ourShortName="" # the unqualified node name of this node ourUid=$(/usr/bin/id -u) # the uid of the process invoking the command BLANKchar=" " TABchar=" " NO_MOUNT_CHECK="_NO_MOUNT_CHECK_" MOUNT_CHECK_ONLY="_MOUNT_CHECK_ONLY_" CHECK_ALL="_CHECK_ALL_" RESIGN_FSMGR="_RESIGN_FSMGR_" NO_FILE_COPY="_NO_FILE_COPY_" LINK="_LINK_" NO_LINK="_NO_LINK_" UNKNOWN="_UNKNOWN_" UNRESOLVED="-" #----------------------------------------------------------- # Return codes and constants for internal mm command use. #----------------------------------------------------------- # mm command unique values: MM_Version3=3 # node runs version 2.3 or later MM_IncompatibleCode=188 # installed GPFS code is not compatible MM_FsMounted=189 # file system mounted somewhere MM_KExtFailure=190 # kernel extension load/unload failure # Values based on the AIX errno.h constants: MM_RemoteNotFound=2 # remote cluster not found (ENOENT) MM_QuorumWait=11 # daemon waits for quorum (EAGAIN) MM_AccessDenied=13 # access denied (EACCES) MM_NotJoined=16 # node has not joined the cluster (EBUSY) MM_FsExists=17 # device already exists (EEXIST) MM_FsNotFound=19 # device does not exist (ENODEV) MM_DeviceNotFound=19 # device does not exist (ENODEV) MM_InvalidName=22 # invalid (device) name (EINVAL) MM_DaemonDown=50 # daemon not running (ENOCONNECT) MM_UnknownCluster=70 # unknown cluster (ENETUNREACH) MM_ConnectionReset=73 # connection reset (ECONNRESET) MM_TimedOut=78 # connection timed out (ETIMEDOUT) MM_HostDown=80 # host is down (EHOSTDOWN) MM_Remotefs=93 # remote file system (EREMOTE) # Values based on GPFS ShErrno.h constants modulo 256: MM_ConnectTimeout=107 # connection timeout or error (E_NOTCONN) MM_SecurityCfg=208 # failed to load security keys (E_SECURITY_CFG mod 256) MM_AuthorizationFailed=214 # authorization failed (E_AUTHORIZATION_FAILED mod 256) #----------------------------------------------------------- # Well-known directories #----------------------------------------------------------- # Set the directory with the mm commands. if [[ -n $MMFSDIR ]] then mmcmdDir="${MMFSDIR}/bin" elif [[ -z $mmcmdDir ]] then mmcmdDir="/usr/lpp/mmfs/bin" else : # mmcmdDir must have been set by the caller fi tscmdDir="$mmcmdDir" # directory with ts commands mmdataDir="/usr/lpp/mmfs/data/" # directory for various mm data files mmsdrfsDir="/var/mmfs/gen/" # directory for various mm system files mmfscfgDir="/var/mmfs/etc/" # directory for mmfs config files tmpDir="/var/mmfs/tmp/" # directory for temporary files mmbackupDir="/var/mmfs/mmbackup" # directory for use by mmbackup lockdir="/var/mmfs/etc/mmlock" # common lock directory mmfsEnvLockDir="/var/mmfs/gen/mmfsEnvLockDir" # local mmfsEnv lock directory links=".links" # directory with links to ts commands rasDir="/var/adm/ras/" # directory for daemon log files sslDir="/var/mmfs/ssl/" # directory for cluster security files sslStageDir="/var/mmfs/ssl/stage/" # directory for cluster security files defaultAutomountDir="/gpfs/automountdir" # default directory for automounts # Keep the following two items in sync with globcfg.C mmpmonDir="/var/mmfs/mmpmon/" # directory for use by mmpmon mmpmonSocket="mmpmonSocket" # name of mmpmon named socket # The env lock location can be altered with an environment variable. [[ -n $mmfsEnvLockLocation ]] && \ mmfsEnvLockDir="$mmfsEnvLockLocation/mmfsEnvLockDir" # If the user is not root, relocate files used by # mmls commands to /tmp instead of /var/mmfs/tmp. [[ $ourUid -ne 0 ]] && tmpDir="/tmp/" #----------------------------------------------------------- # Well-known file names #----------------------------------------------------------- if [[ $ourUid -eq 0 ]] then MULTIPLE_KEYS_5="${mmsdrfsDir}MULTIPLE_KEYS_5" #esjxx ifdef file # mkdir -p $mmsdrfsDir ; touch $MULTIPLE_KEYS_5 #esjxx ifdef file fi ignoreStartupMount=${mmfscfgDir}ignoreStartupMount # node-override for -A yes mounting localMountOptions=${mmfscfgDir}localMountOptions # node-specific mount options; # the suffix is the file system name mmfscfgFile=${mmfscfgDir}mmfs.cfg # mmfs.cfg file used by the daemon mmfscfg=${mmfscfgDir}mmfs.cfg # mmfs.cfg file used by the daemon haslock=${lockdir}/haslock # pid and node of command that has lock hasEnvLock=${mmfsEnvLockDir}/hasEnvLock # pid of cmd that has the mmfsEnv lock mmsdrfsFile=${mmsdrfsDir}mmsdrfs # cached copy of the mmsdrfs file mmsdrfsTmp=${mmsdrfsDir}mmsdrfs.tmp # uncommitted copy of the mmsdrfs file mmsdrfsPrev=${mmsdrfsDir}mmsdrfs.prev # previous version of the mmsdrfs file uncommitted=${mmsdrfsDir}uncommitted # empty file signifying commit in progress mmfsNodeData=${mmsdrfsDir}mmfsNodeData # local node data (hostname, ipa, etc.) mmfsEnvLevel=${mmsdrfsDir}mmfsEnvLevel # the suffix is equal to the gen number # of the local mmsdrfs file mmfsVfsNumber=${mmsdrfsDir}mmfsVfsNumber # the suffix is equal to the major number # assigned to /dev entries on this node exclDiskFile=${mmsdrfsDir}exclDiskFile # the suffix is equal to the file system # device name to which the disks belong mmsdrfsGen=${tmpDir}mmsdrfsGen # the suffix is the file's gen number mmauthKeyGen=${sslStageDir}mmauthKeyGen # mmauth genkey file (format 1) # the suffix is the key gen number genkeyData=${sslStageDir}genkeyData # mmauth genkey file (format 2) # the suffix is the key gen number mmfsNewKeyLevel=${mmsdrfsDir}mmfsNewKeyLevel # the suffix is equal to the gen number # of the uncommitted private key file mmfsCommittedKeyLevel=${mmsdrfsDir}mmfsCommittedKeyLevel # the suffix is the gen number # of the committed private key file newPrivateKey=${sslDir}id_rsa_new # uncommitted private key file committedPrivateKey=${sslDir}id_rsa_committed # committed private key file newPublicKey=${sslDir}id_rsa_new.pub # uncommitted public key file committedPublicKey=${sslDir}id_rsa_committed.pub # committed public key file newCertificate=${sslDir}id_rsa_new.cert # uncommitted self-signed certificate committedCertificate=${sslDir}id_rsa_committed.cert # committed self-signed certificate publicKey=${sslDir}id_rsa.pub # link to the current public key privateKey=${sslDir}id_rsa # private key file for the local cluster # the suffix is the key gen number mmSdrLockExp=${mmsdrfsDir}mmSdrLockExp # contains gen number and exp. timestamp nsdmap=${mmsdrfsDir}nsdmap # local disk name to pvid hints file nsdpvol=${mmsdrfsDir}nsdpvol # local disk name to nsd name file mmDirectMap=${mmsdrfsDir}mmDirectMap # list of automountable file systems startupMountFile=${mmsdrfsDir}automountFile # fs to mount at startup time automountFile=${mmsdrfsDir}automountFile # fs to mount at startup time authorizedKeys=${sslDir}authorized_keys # list of autorized keys knownCluster=${sslDir}known_cluster # public key file for a remote cluster; # the suffix is the cluster name. authorizedCertificates=${sslDir}authorized_certificates # list of autorized certificates knownCertificate=${sslDir}known_certificate # certificate file for a remote cluster; # the suffix is the cluster name. certConfigFile=${sslDir}openssl.conf # options for openssl certificate opensslConfFile=${mmdataDir}openssl.conf # template for openssl certificate rerunmmfsFile=${mmsdrfsDir}rerunmmfsFile # file telling runmmfs to respawn mmfsd respawnlog=${mmsdrfsDir}runmmfs.respawnlog # controls the rate of mmfsd respawn respawnlog2=${mmsdrfsDir}runmmfs.respawnlog.$$ # controls the rate of mmfsd respawn mmpmonNamedSocketFile=${mmpmonDir}${mmpmonSocket} # mmpmon named socket mmsdrservPid=${mmsdrfsDir}mmsdrservPid # contains pid of the mmsdrserv process # To get error messages from mmsdrserv, specify a file name in the mmsdrservLog # variable. If this variable is not defined, all error msgs will be discarded. #mmsdrservLog=${tmpDir}mmsdrservLog # log records from the mmsdrserv daemon [[ -z $mmsdrservLog ]] && mmsdrservLog="/dev/null" #----------------------------------------------------------- # Global working files #----------------------------------------------------------- adfile=${tmpDir}adapterFile.${mmcmd}.$$ # list of all node adapters rnfile=${tmpDir}relNamesFile.${mmcmd}.$$ # list of all reliable hostnames lslvOutput=${tmpDir}lslvOutput.${mmcmd}.$$ # lslv output sdrNodeFile=${tmpDir}sdrNodeFile.${mmcmd}.$$ # node-related information vsdNamesFile=${tmpDir}vsdNamesFile.${mmcmd}.$$ # list of all VSDs volGroupFile=${tmpDir}volGroupFile.${mmcmd}.$$ # list of all global volume groups allClusterNodes=${tmpDir}allClusterNodes.${mmcmd}.$$ # list of nodes in the cluster allQuorumNodes=${tmpDir}allQuorumNodes.${mmcmd}.$$ # list of all quorum nodes nodefile=${tmpDir}nodefile.${mmcmd}.$$ # list of nodes in the cluster diskfile=${tmpDir}diskfile.${mmcmd}.$$ # list of disks in the cluster newsdrfs=${tmpDir}newsdrfs.${mmcmd}.$$ # new version of mmsdrfs file tmpsdrfs=${tmpDir}tmpsdrfs.${mmcmd}.$$ # temp file for building the mmsdrfs mmsdrfsShadow=${mmsdrfsFile}.$$ # temp copy of the sdr version of mmsdrfs sdrfs=${tmpDir}sdrfs.${mmcmd}.$$ # local copy of the mmsdrfs file oldsdrfs=${tmpDir}oldsdrfs.${mmcmd}.$$ # local copy of the mmsdrfs file stanza=${tmpDir}stanza.${mmcmd}.$$ # /etc/filesystems stanza oldstanza=${tmpDir}oldstanza.${mmcmd}.$$ # old version of /etc/filesystems stanza newstanza=${tmpDir}newstanza.${mmcmd}.$$ # new version of /etc/filesystems stanza newcfg=${tmpDir}newcfg.${mmcmd}.$$ # new version of mmfs.cfg file remainingFs=${tmpDir}remainingFs.${mmcmd}.$$ # remaining file systems info tmpfile=${tmpDir}tmpfile.${mmcmd}.$$ # temp file for misc use tmpfile2=${tmpDir}tmpfile2.${mmcmd}.$$ # second temp file for misc use tmpCfg=${tmpDir}tmpCfg.${mmcmd}.$$ # temp mmfs.cfg file tmpNodes=${tmpDir}tmpNodes.${mmcmd}.$$ # temp file with node names tmpDirectMap=${mmsdrfsDir}tmpDirectMap # list of automountable file systems tmpPublicKey=${sslStageDir}tmpPublicKey.${mmcmd}.$$ # temp public key file tmpPrivateKey=${sslStageDir}tmpPrivateKey.${mmcmd}.$$ # temp private key file tmpCertificate=${sslStageDir}tmpCertificate.${mmcmd}.$$ # temp certificate file localAuthKeys=${tmpDir}localAuthKeys.${mmcmd}.$$ # local public keys localCertificates=${tmpDir}localCertificates.${mmcmd}.$$ # local certificates tmpAuthKeys=${tmpDir}tmpAuthKeys.${mmcmd}.$$ # temp authorized keys file tmpKnownCluster="${tmpDir}knownCluster.$$_" # temp known cluster key file # (suffix is the cluster name) tmpAuthCertificates=${tmpDir}tmpAuthCertificates.${mmcmd}.$$ # authorized certificates tmpKnownCertificate="${tmpDir}knownCertificate.$$_" # temp known certificate file # (suffix is the cluster name) unreachedNodes=${tmpDir}unreachedNodes.${mmcmd}.$$ # unreached nodes file sgDiskLines=${tmpDir}sgDiskLines.${mmcmd}.$$ # disk lines file diskNamesFile=${tmpDir}diskNamesFile.${mmcmd}.$$ # disk names file nsdDataFile=${tmpDir}nsdDataFile.${mmcmd}.$$ # NSD data file lqueryvgResult=${tmpDir}lqueryvgResult.${mmcmd}.$$ # lqueryvg output file lspvOutputFile=${tmpDir}lspvOutputFile.${mmcmd}.$$ # lspv output file tsOutputFile=${tmpDir}tsOutputFile.${mmcmd}.$$ # output file for a ts command errMsg=${tmpDir}errMsg.${mmcmd}.$$ # temp file for error messages # (erase as soon as not needed) errMsg2=${tmpDir}errMsg2.${mmcmd}.$$ # temp file for error messages # (erase as soon as not needed) GLOBAL_FILES=" $adfile $rnfile $sdrNodeFile $sdrfs $newsdrfs $volGroupFile \ $tmpfile $tmpfile2 $tmpsdrfs $vsdNamesFile $diskfile \ $oldstanza $stanza $newstanza $newcfg $tmpCfg $tmpNodes \ $oldsdrfs $nodefile $sgDiskLines $diskNamesFile $nsdDataFile \ $errMsg $errMsg2 $mmsdrfsShadow $lslvOutput $unreachedNodes \ $remainingFs $allClusterNodes $allQuorumNodes $lqueryvgResult \ $tmpAuthKeys ${tmpKnownCluster}* $tmpDirectMap $tmpPrivateKey \ $tmpPublicKey $tsOutputFile $lspvOutputFile \ $tmpCertificate $localCertificates \ $localAuthKeys $tmpAuthCertificates ${tmpKnownCertificate}* " #----------------------------------------------------------- # Full path names for GPFS commands #----------------------------------------------------------- daemonize=${mmcmdDir}/daemonize lxtrace=${mmcmdDir}/lxtrace mmchconfig=${mmcmdDir}/mmchconfig mmchecksubsys=${mmcmdDir}/mmchecksubsys mmclearfence=${mmcmdDir}/mmclearfence mmcommon=${mmcmdDir}/mmcommon mmcrclusterid=${mmcmdDir}/mmcrclusterid mmcrfsc=${mmcmdDir}/mmcrfsc mmdf=${mmcmdDir}/mmdf mmdsh=${mmcmdDir}/mmdsh mmdspmsg=${mmcmdDir}/mmdspmsg mmdynamicmap=${mmcmdDir}/mmdynamicmap mmexectsmcmd=${mmcmdDir}/mmexectsmcmd mmexportfs=${mmcmdDir}/mmexportfs mmfixcfg=${mmcmdDir}/mmfixcfg mmfsadm=${mmcmdDir}/mmfsadm mmfsenv=${mmcmdDir}/mmfsenv mmfskxgetwpid=${mmcmdDir}/mmfskxgetwpid mmfskxload=${mmcmdDir}/mmfskxload mmfskxunload=${mmcmdDir}/mmfskxunload mmfsmknod=${mmcmdDir}/mmfsmknod mmimportfs=${mmcmdDir}/mmimportfs mmkerninfo=${mmcmdDir}/mmkerninfo mmlsnsd=${mmcmdDir}/mmlsnsd mmmvfs=${mmcmdDir}/mmmvfs mmremote=${mmcmdDir}/mmremote mmsdrcli=${mmcmdDir}/mmsdrcli mmsdrserv=${mmcmdDir}/mmsdrserv mmsetrcmd=${mmcmdDir}/mmsetrcmd mmssaclearfence=${mmcmdDir}/mmssaclearfence mmstartup=${mmcmdDir}/mmstartup mmsync=${mmcmdDir}/mmsync mmtrace=${mmcmdDir}/mmtrace runmmfs=${mmcmdDir}/runmmfs tsadddisk=${tscmdDir}/tsadddisk tsauth=${tscmdDir}/tsauth tsaddrmap=${tscmdDir}/tsaddrmap tsbackup=${tscmdDir}/tsbackup tschfileset=${tscmdDir}/tschfileset tschfs=${tscmdDir}/tschfs tschmgr=${tscmdDir}/tschmgr tschpolicy=${tscmdDir}/tschpolicy tschpool=${tscmdDir}/tschpool tscrefresh=${tscmdDir}/tscrefresh tscrfileset=${tscmdDir}/tscrfileset tscrfs=${tscmdDir}/tscrfs tsctl=${tscmdDir}/tsctl tsctlfs=${tscmdDir}/tsctlfs tsdeldisk=${tscmdDir}/tsdeldisk tsdelfileset=${tscmdDir}/tsdelfileset tsdelfs=${tscmdDir}/tsdelfs tsdsh=${tscmdDir}/tsdsh tsfileid=${tscmdDir}/tsfileid tsfindinode=${tscmdDir}/tsfindinode tslinkfileset=${tscmdDir}/tslinkfileset tslsfs=${tscmdDir}/tslsfs tslsfileset=${tscmdDir}/tslsfileset tslspolicy=${tscmdDir}/tslspolicy tsmigrate=${tscmdDir}/tsmigrate tsnsdaccess=${tscmdDir}/tsnsdaccess tsremount=${tscmdDir}/tsremount tsrestripefs=${tscmdDir}/tsrestripefs tsstatus=${tscmdDir}/tsstatus tsprclear=${tscmdDir}/tsprclear tspreparedisk=${tscmdDir}/tspreparedisk tsunlinkfileset=${tscmdDir}/tsunlinkfileset nss_setmap=${tscmdDir}/nss_setmap #----------------------------------------------------------- # User exits #----------------------------------------------------------- mmsdrbackup=${mmfscfgDir}mmsdrbackup nsddevices=${mmfscfgDir}nsddevices remoteclusternodes=${mmfscfgDir}remoteclusternodes sslrandfile=${mmfscfgDir}sslrandfile syncfsconfig=${mmfscfgDir}syncfsconfig #----------------------------------------------------------- # RSCT peer domain commands #----------------------------------------------------------- export CT_MANAGEMENT_SCOPE=2 lsclcfg=/usr/bin/lsclcfg lsnodeid=/usr/sbin/rsct/bin/lsnodeid lsrsrcapi=/usr/bin/lsrsrc-api #----------------------------------------------------------- # Full path names for the GPFS daemon and kernel extension. # The mmcmdSubdir and mmcmdSuffix components, if they are to # have non-null values, must be set by the invoking module. #----------------------------------------------------------- mmfs=${mmcmdDir}/${mmcmdSubdir}/mmfs${mmcmdSuffix} mmfsd=${mmcmdDir}/${mmcmdSubdir}/mmfsd${mmcmdSuffix} #----------------------------------------------------------- # Global declarations for parsing the mmsdrfs file #----------------------------------------------------------- # Line type identifiers and other constants. VERSION_LINE='00_VERSION_LINE' COMMENT_LINE='03_COMMENT' NODESET_HDR='10_NODESET_HDR' MEMBER_NODE='20_MEMBER_NODE' SG_HEADR='30_SG_HEADR' SG_ETCFS='40_SG_ETCFS' SG_MOUNT='50_SG_MOUNT' SG_DISKS='60_SG_DISKS' MMFSCFG='70_MMFSCFG' REM_CLUSTER='80_REM_CLUSTER' REM_CLUSTER_KEY='82_REM_CLUSTER_KEY' AUTHORIZED_CLUSTER='90_AUTHORIZED_CLUSTER' AUTHORIZED_KEY='92_AUTHORIZED_KEY' AUTHORIZED_FS='94_AUTHORIZED_FS' HSMDATA='910_HSMDATA' HSMVERSION='920_HSMVERSION' CURRENT_SDRFS_FORMAT=1 CURRENT_SDRFS_VERSION=3 CURRENT_KEYFILE_FORMAT=2 COMPATIBLE_KEYFILE_FORMAT=2 GLOBAL_ID='%%9999%%' FREE_DISK='~%BBBB%%' DSM_DATA='~%DSM%%' NO_DEVICE='~/~' CHANGE_NSD='~/changeNsd/~' HOME_CLUSTER="%%home%%" availableField="" obsoleteField="" FREE_NODE='~%AAAA%%' # obsolete HA_SERVICES='~%HAS%%' # obsolete HA_CLUSTER_NAME='gpfs' # obsolete PRIMARY_NETWORK='gpfs' # obsolete SECONDARY_NETWORK='gpfs2' # obsolete # Global field definitions. NODESETID_Field=1 LINE_TYPE_Field=2 DEV_NAME_Field=3 LINE_NUMBER_Field=4 # Definitions for the VERSION_LINE. SDRFS_FORMAT_Field=4 SDRFS_VERSION_Field=5 SDRFS_GENNUM_Field=6 RUNNING_CMD_Field=7 CLUSTER_TYPE_Field=8 PRIMARY_SERVER_Field=9 BACKUP_SERVER_Field=10 HIGHEST_GPFS_DISK_NBR_Field=11 RSH_PATH_Field=12 RCP_PATH_Field=13 CLUSTERID_Field=14 CLUSTER_SUBTYPE_Field=15 GENNUM_TSTAMP_Field=16 GETOBJECT_PORT_Field=17 # obsolete CLUSTER_NAME_Field=18 NEW_KEY_Field=19 SECLEVEL_Field=20 COMMITTED_KEY_Field=21 KEYFILE_FORMAT_Field=22 initialDiskNumber=1000 # Definitions for COMMENT lines. COMMENT_TEXT_Field=5 warningText=" This is a machine generated file. Do not edit! " # Definitions for NODESET_HDR lines. NODE_COUNT_Field=5 COMM_PROTOCOL_Field=6 CIPHER_LIST_Field=7 TCP_PORT_Field=8 # obsolete_Field=9 # old CONVERSION_STATE_Field # obsolete_Field=10 # old EVENTS_PORT_Field # available_Field=11 MIN_DAEMON_VERSION_Field=12 # same as the maxFeatureLevel MAX_DAEMON_VERSION_Field=13 OS_ENVIRONMENT_Field=14 # available_Field=15 EVENTS_PORT_Field=16 GETOBJECT_PORT_Field=17 defaultTcpPort=1191 # Definitions for MEMBER_NODE lines. NODE_NUMBER_Field=5 NODE_NAME_Field=6 IPA_Field=7 REL_HOSTNAME_Field=8 DESIGNATION_Field=9 LAPI_ADAPTER_Field=10 # obsolete LAPI_WINDOW_Field=11 # obsolete SWITCH_NODE_NUMBER_Field=12 # obsolete ADDNODE_STATE_Field=13 ADAPTER_TYPE_Field=14 DAEMON_NODENAME_Field=15 ADMIN_SHORTNAME_Field=16 DAEMON_VERSION_Field=17 PRODUCT_VERSION_Field=18 OS_NAME_Field=19 CORE_QUORUM_Field=20 GS_NODE_NUMBER_Field=21 # obsolete noWindow="-1" noSwitch="-1" noNumber=0 DELETED_NODE="deleted" # obsolete QUORUM="quorum" NONQUORUM="nonquorum" MANAGER="manager" CLIENT="client" NEW_NODE="new" OLD_NODE="" quorumNode="Q" nonQuorumNode="N" maxQuorumNodes=128 maxRecQuorumNodes=7 # Definitions for SG_HEADR lines. DEV_MINOR_Field=5 ODD_STATE_Field=6 FS_TYPE_Field=7 REMOTE_DEV_NAME_Field=8 remotefs="R" localfs="" # Definitions for SG_ETCFS lines. ETCFS_TEXT_Field=5 MOUNT_POINT_Line=1 DEV_Line=2 VFS_Line=3 NODENAME_Line=4 MOUNT_Line=5 TYPE_Line=6 ACCOUNT_Line=7 OPTIONS_Line=8 DEV_Line_Prefix=" dev = " VFS_Line_Prefix=" vfs = " NODENAME_Line_Prefix=" nodename = " MOUNT_Line_Prefix=" mount = " TYPE_Line_Prefix=" type = " ACCOUNT_Line_Prefix=" account = " OPTIONS_Line_Prefix=" options = " # Definitions for SG_MOUNT lines. RW_OPT_Field=5 MTIME_OPT_Field=6 ATIME_OPT_Field=7 QUOTA_OPT_Field=8 OTHER_OPT_Field=9 QUOTA_ACTIVATED="userquota;groupquota;filesetquota" QUOTA_DISACTIVATED="" # Definitions for SG_DISKS lines. DISK_NAME_Field=5 DISK_SIZE_Field=6 FAILURE_GROUP_Field=7 DISK_USAGE_Field=8 PVID_Field=9 DISK_TYPE_Field=10 # disk type of the disk (e.g., vsd, lv, nsd-direct) NSD_PRIMARY_NODE_Field=11 NSD_BACKUP_NODE_Field=12 DISK_SUBTYPE_Field=13 # ssa, pr, other; used for fencing VPATH_FLAG_Field=14 # vpath or notvpath; used when deleting or importing # disks; SDD utilities may or may not be needed NSD_SUBTYPE_Field=15 # disk type of the disk underlying the nsd # (e.g., vsd, lv, hdisk, vpath, generic) NAME_SOURCE_Field=16 # disk name source (user-specified or cmd-generated) NSD_SUBTYPE_DISKNAME_Field=17 # disk name of the disk underlying the nsd EXCLUDE_Field=18 PAXOS_Field=19 DISK_STATUS_Field=20 AIX_PVID_Field=21 # PVID of the underlying AIX disk (if applicable). STORAGE_POOL_Field=22 DAEMON_NSD_PRIMARY_Field=23 DAEMON_NSD_BACKUP_Field=24 userSpecified="user" cmdGenerated="cmd" excludedDisk="excl" includedDisk="" PaxosDisk="quorumDisk" # Definitions for MMFSCFG lines. # # Since mmfs.cfg values can contain the ':' character, # everything past the first four fields, except trailing # null fields, is considered to be mmfs.cfg text. # Definitions for REM_CLUSTER lines. CONTACT_NODES_Field=5 # Definitions for REM_CLUSTER_KEY lines. # Definitions for AUTHORIZED_KEY lines. KEY_Field=5 # Definitions for AUTHORIZED_CLUSTER lines. GRANT_Field=5 # available_Field=6 CIPHER_LIST_Field=7 accessGranted="all" accessDenied="" # Definitions for AUTHORIZED_FS lines. ACCESS_TYPE_Field=5 ROOTSQUASH_UID_Field=6 ROOTSQUASH_GID_Field=7 # Definitions for HSMDATA and HSMVERSION lines. HSM_NODESET_Field=3 # Since these lines can contain the ':' character, # everything past the first four fields, except trailing # null fields, is considered to be free format text. #----------------------------------------------------------------------- # # Set up the internal mm trace facility. # # Tracing is controlled through the mmScriptTrace environment variable. # # - If the variable is not set, tracing is disabled. # # - If the variable is set, and its value starts with a slash, # it is assumed to be the full path name for the file which # is to contain the trace results. Otherwise, the trace results # are send to file /tmp/mmfs/mmScriptTrace. # # Examples: # # $mmTRACE_ENTER "$*" # # $mmTRACE "lock held by $lockHolderHostname $lockHolderPid" # # $mmTRACE_EXIT "rc=$rc" # #----------------------------------------------------------------------- if [[ -z $mmScriptTrace || $mmScriptTrace = "/dev/null" ]] then mmTRACE_ENTER=_mmTRACE_ENTER_disabled mmTRACE_EXIT=_mmTRACE_EXIT_disabled mmTRACE=_mmTRACE_disabled mmScriptTrace="/dev/null" else mmTRACE_ENTER=_mmTRACE_ENTER_enabled mmTRACE_EXIT=_mmTRACE_EXIT_enabled mmTRACE=_mmTRACE_enabled [[ $mmScriptTrace != /* ]] && \ mmScriptTrace=/tmp/mmfs/mmScriptTrace fi #----------------------------------------------------------- # Set release information. #----------------------------------------------------------- . /usr/lpp/mmfs/bin/mmprodname sourceFile="mmglobfuncs.sh" #------------------------------------------------------------------ # Pull in operating system dependent declarations and functions. #------------------------------------------------------------------ [[ -e ${mmcmdDir}/mmglobfuncs.$osName ]] && \ . ${mmcmdDir}/mmglobfuncs.$osName sourceFile="mmglobfuncs.sh" #------------------------------------------------------------------ # Check whether site changed the mmfs.log location. #------------------------------------------------------------------ if [[ -f $mmfscfg ]] then logDir=$($awk '$1 == "logDir" {value = $2} END {print value}' $mmfscfg) [[ -n $logDir ]] && rasDir="${logDir}/" fi #------------------------------------------------------------------ # Make sure required directories exist. #------------------------------------------------------------------ if [[ $ourUid -eq 0 ]] then $mkdir -p $mmsdrfsDir $mmfscfgDir $tmpDir $rasDir $mmbackupDir $mkdir -m 0700 -p $sslDir $sslStageDir $mmpmonDir fi #----------------------------------------------------------- # Frequently-used functions #----------------------------------------------------------- ####################################################################### # # Internal tracing functions. All of the functions interpret the # argument list with which they are invoked as being the trace record. # ####################################################################### _mmTRACE_ENTER_enabled() { typeset timestamp=$($perl -e 'print time') printf "%7s %7s %16s %-14s %-6s %s\n" \ $$ $PPID $timestamp $mmcmd "enter" "${0##*/}: $*" >> $mmScriptTrace } _mmTRACE_EXIT_enabled() { typeset timestamp=$($perl -e 'print time') printf "%7s %7s %16s %-14s %-6s %s\n" \ $$ $PPID $timestamp $mmcmd "EXIT " "${0##*/}: $*" >> $mmScriptTrace } _mmTRACE_enabled() { typeset timestamp=$($perl -e 'print time') printf "%7s %7s %16s %-14s %-6s %s\n" \ $$ $PPID $timestamp $mmcmd " " "${0##*/}: $*" >> $mmScriptTrace } _mmTRACE_ENTER_disabled() { return 0 } _mmTRACE_EXIT_disabled() { return 0 } _mmTRACE_disabled() { return 0 } #################################################################### # # Function: Prints the specified message to stdout # # Input: $1 - number of the message to print # $2, $3, ... - arguments to pass to dspmsg # #################################################################### function printInfoMsg # [ ... ] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGprintInfoMsg ]] && set -x msgNo=$1 typeset msgSet typeset printTimeStamp=no # Based on the message number, find the message text. case $msgNo in 12 ) msgTxt=\ "%s: %s nodes added to the cluster out of %s nodes specified." ;; 94 ) msgTxt=\ "Deleting disks ..." ;; 95 ) msgTxt=\ "Restriping %s ..." ;; 96 ) msgTxt=\ "Replacing %s ..." ;; 98 ) msgTxt=\ "%s: Processing disks that do not belong to any file system ..." ;; 99 ) msgTxt=\ "Done" ;; 143 ) msgTxt=\ "%s: %s: Processing user configuration file %s" ;; 179 ) msgTxt=\ "flag value description\n"\ "---- -------------- -----------------------------------------------------" ;; 180 ) msgTxt=\ "root allowed" ;; 181 ) msgTxt=\ "root remapped to" ;; 182 ) msgTxt=\ "%s: Granting cluster %s access to file system %s:\n"\ " access type %s; root credentials will not be remapped." ;; 183 ) msgTxt=\ "%s: Granting cluster %s access to file system %s:\n"\ " access type %s; root credentials will be remapped to %s:%s." ;; 231 ) msgTxt=\ "%s: %s already belongs to volume group %s.\n" ;; 241 ) msgTxt=\ "%s: %s: Starting force unmount of GPFS file systems" ;; 242 ) msgTxt=\ "%s: %s: Unmount not finished after %s seconds. Waiting %s more seconds" ;; 243 ) msgTxt=\ "%s: %s: Unmount not finished after %s seconds" ;; 244 ) msgTxt=\ "%s: %s: Shutting down GPFS daemons" ;; 245 ) msgTxt=\ "%s: %s: Finished" ;; 250 ) msgTxt=\ "%s: Processing file system %s ..." ;; 251 ) msgTxt=\ "%s: Processing disk %s" ;; 272 ) msgTxt=\ "%s: Command successfully completed" ;; 331 ) msgTxt=\ "Automatic mount option" ;; 332 ) msgTxt=\ "Exact mtime default mount option" ;; 333 ) msgTxt=\ "Suppress atime default mount option" ;; 339 ) msgTxt=\ "Verifying GPFS is stopped on all nodes ..." ;; 373 ) msgTxt=\ "%s: %s: Mounting file systems ..." ;; 392 ) msgTxt=\ "%s: %s: Starting GPFS ..." ;; 400 ) msgTxt=\ "GPFS cluster information" ;; 401 ) msgTxt=\ "GPFS cluster configuration servers:" ;; 402 ) msgTxt=\ " Primary server: %s" ;; 403 ) msgTxt=\ " Secondary server: %s" ;; 404 ) msgTxt=\ " Node Daemon node name IP address Admin node name Designation " ;; 405 ) msgTxt=\ " Summary information " ;; 406 ) msgTxt=\ "File system attributes for %s:" ;; 407 ) msgTxt=\ "Configuration data for cluster %s:" ;; 408 ) msgTxt=\ "File systems in cluster %s:" ;; 409 ) msgTxt=\ "(none)" ;; 414 ) msgTxt=\ "quorum-manager" ;; 416 ) msgTxt=\ "%s: %s: Processing node %s" ;; 426 ) msgTxt=\ "%s: %s: Unmounting file systems ..." ;; 427 ) msgTxt=\ "SHA digest (new):" ;; 430 ) msgTxt=\ " GPFS cluster name: %s" ;; 431 ) msgTxt=\ "quorum node" ;; 434 ) msgTxt=\ " GPFS cluster id: %s" ;; 435 ) msgTxt=\ " Remote shell command: %s" ;; 436 ) msgTxt=\ " Remote file copy command: %s" ;; 442 ) msgTxt=\ "Cluster name:" ;; 443 ) msgTxt=\ "Cipher list:" ;; 444 ) msgTxt=\ "SHA digest:" ;; 445 ) msgTxt=\ "File system access:" ;; 446 ) msgTxt=\ "Contact nodes:" ;; 447 ) msgTxt=\ "File systems:" ;; 451 ) msgTxt=\ " GPFS UID domain: %s" ;; 453 ) msgTxt=\ "Verifying GPFS is stopped on all affected nodes ..." ;; 473 ) msgTxt=\ "Verifying file system configuration information ..." ;; 475 ) msgTxt=\ "quorum" ;; 477 ) msgTxt=\ "File system %s %s is mounted on %s nodes in cluster %s:" ;; 478 ) msgTxt=\ "File system %s is mounted on %s nodes in cluster %s:" ;; 479 ) msgTxt=\ "File system %s %s is mounted on %s nodes in cluster %s." ;; 480 ) msgTxt=\ "File system %s is mounted on %s nodes in cluster %s." ;; 482 ) msgTxt=\ "manager" ;; 490 ) msgTxt=\ "Local Name Remote Name Cluster name Mount Point Mount Options Automount" ;; 496 ) msgTxt=\ " Node number Node name Quorum Nodes up Total nodes GPFS state Remarks " ;; 497 ) msgTxt=\ " Node number Node name GPFS state " ;; 501 ) msgTxt=\ " File system Disk name NSD volume ID Primary node Backup node " ;; 502 ) msgTxt=\ " Disk name NSD volume ID Device Node name Remarks " ;; 503 ) msgTxt=\ " File system Disk name Primary node Backup node " ;; 506 ) msgTxt=\ "Disk name IO performed on node Device Availability" ;; 512 ) msgTxt=\ " Disk name NSD volume ID Device Devtype Node name Remarks " ;; 519 ) msgTxt=\ "Additional mount options" ;; 521 ) msgTxt=\ "File system %s %s is mounted on %s nodes:" ;; 522 ) msgTxt=\ "File system %s is mounted on %s nodes:" ;; 527 ) msgTxt=\ "%s still running . . .\n" printTimeStamp=yes ;; 541 ) msgTxt=\ "File system %s %s is not mounted." ;; 542 ) msgTxt=\ "File system %s %s is not mounted on any remote cluster nodes." ;; 543 ) msgTxt=\ "File system %s %s is not mounted on any node in cluster %s." ;; 544 ) msgTxt=\ "File system %s is not mounted." ;; 545 ) msgTxt=\ "File system %s is not mounted on any remote cluster nodes." ;; 546 ) msgTxt=\ "File system %s is not mounted on any node in cluster %s." ;; 553 ) msgTxt=\ "File system %s %s is mounted on %s nodes." ;; 554 ) msgTxt=\ "File system %s is mounted on %s nodes." ;; 559 ) msgTxt=\ "Default mount point" ;; 586 ) msgTxt=\ "The %s subsystem is already active." ;; # Message numbers above 1000 are in message set 60 (ts/fencing/fencing.msg). 1018 ) msgTxt=\ "The disk specification must be in one of these formats:\n"\ " -l logicalVolumeName (e.g., '-l lv00')\n"\ " -v volumeGroupName (e.g., '-v vg00')\n"\ " -h physicalDiskName (e.g., '-h hdisk0')\n"\ " -p physicalVolumeIdentifier (e.g., '-p 0003366423ba4d39')\n" ;; 1019 ) msgTxt=\ "Usage: %s \n" ;; 1020 ) msgTxt=\ "Usage: %s " ;; 1021 ) msgTxt=\ "Usage: %s " ;; 1022 ) msgTxt=\ "Usage: %s " ;; 1023 ) msgTxt=\ "The node id list is a blank-separated list of one or more node ids." ;; * ) # unknown message, ignore it. return 0 ;; esac # Message numbers below 1000 are in message set 32 (ts/admin/admin.msg). # Message numbers above 1000 are in message set 60 (ts/fencing/fencing.msg). if [[ $msgNo -lt 1000 ]] then msgSet=32 else msgSet=60 fi if [[ $osName = AIX ]] then # Print the message - extra arguments are ignored. if [[ $printTimeStamp = yes ]] then print -- "$(date) $($dspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" else print -- "$($dspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" fi elif [[ $osName = Linux ]] then # Print the message - extra arguments are ignored. if [[ $printTimeStamp = yes ]] then print -- "$(date) $($mmdspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" else print -- "$($mmdspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" fi else checkForErrors "Unknown operating system $osName" 1 fi } #----- end of function printInfoMsg --------------------------- #################################################################### # # Function: Prints the specified message to stderr # # Input: $1 - number of the message to print # $2, $3, ... - arguments to pass to dspmsg # #################################################################### function printErrorMsg # [ ... ] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGprintErrorMsg ]] && set -x msgNo=$1 typeset msgSet typeset printTimeStamp=no # Based on the message number, find the message text case $msgNo in 13 ) msgTxt=\ "%s: Incorrect option: %s" ;; 19 ) msgTxt=\ "%s: Obsolete option: %s" ;; 20 ) msgTxt=\ "%s: Interrupt received: No changes made." ;; 23 ) msgTxt=\ "%s: Disk name must be specified in disk descriptor." ;; 24 ) msgTxt=\ "%s: Disk usage must be dataOnly, metadataOnly, descOnly, or dataAndMetadata." ;; 30 ) msgTxt=\ "%s: User specified failure group must be in the range from -1 to 4000." ;; 32 ) msgTxt=\ "%s: Interrupt received: changes not propagated." ;; 33 ) msgTxt=\ "%s: Interrupt received. Only -A, -Q, and -T were changed." ;; 34 ) msgTxt=\ "Usage: %s Device" ;; 35 ) msgTxt=\ "%s: Restriping may not have finished." ;; 36 ) msgTxt=\ "%s: %s option specified twice." ;; 37 ) msgTxt=\ "%s: %s value must be yes or no." ;; 38 ) msgTxt=\ "%s: Incorrect extra argument: %s" ;; 39 ) msgTxt=\ "Usage: %s QueryType ItemList [Scope [norefresh]]" ;; 40 ) msgTxt=\ "%s: Incorrect integer for %s: %s" ;; 41 ) msgTxt=\ "%s: No disk descriptor file specified" ;; 42 ) msgTxt=\ "%s: File %s already exists." ;; 43 ) msgTxt=\ "%s: Cannot open %s" ;; 44 ) msgTxt=\ "%s: Incompatible cluster types. You cannot move file systems that were\n"\ "created by GPFS cluster type %s into GPFS cluster type %s." ;; 45 ) msgTxt=\ "%s: %s must be greater than 0: %s" ;; 47 ) msgTxt=\ "%s: Error converting %s into an NSD." ;; 48 ) msgTxt=\ "%s: File system %s already exists in the cluster.\n"\ " Use mmchfs -W to assign a new device name for the existing file system." ;; 49 ) msgTxt=\ "%s: %s is defined to have mount point %s.\n"\ " There is already such a mount point in the cluster.\n"\ " Use mmchfs -T to assign a new mount point to the existing file system." ;; 50 ) msgTxt=\ "%s: Error encountered while importing disk %s." ;; 51 ) msgTxt=\ "%s: Disk %s already exists in the cluster." ;; 53 ) msgTxt=\ "%s: At least one node in the cluster must be defined as a quorum node." ;; 54 ) msgTxt=\ "%s: Incorrect node %s specified for command." ;; 61 ) msgTxt=\ "%s: Use the dash character (-) to separate multiple node designations." ;; 62 ) msgTxt=\ "%s: Use the semi-colon character (;) to separate the disk names." ;; 63 ) msgTxt=\ "%s: GPFS is still active on %s" ;; 78 ) msgTxt=\ "%s: %s must be from %s to %s: %s" ;; 79 ) msgTxt=\ "%s: mmfixcfg failed while changing %s" ;; 88 ) msgTxt=\ "%s: Duplicate disk specified: %s" ;; 89 ) msgTxt=\ "%s: You cannot delete all disks" ;; 97 ) msgTxt=\ "%s: %s must be greater than %s: %s" ;; 100 ) msgTxt=\ "%s: tscrfs failed. Cannot create %s" ;; 101 ) msgTxt=\ "%s: Disk %s does not belong to file system %s." ;; 102 ) msgTxt=\ "%s: Active disks are missing from the GPFS configuration data:" ;; 103 ) msgTxt=\ "%s: Attention: File system %s may have some disks\n"\ "that are in a non-ready state. Issue the command:\n"\ " mmcommon recoverfs %s" ;; 104 ) msgTxt=\ "%s: %s failed." ;; 105 ) msgTxt=\ "%s: Failed to connect to remote cluster %s" ;; 106 ) msgTxt=\ "%s: File system %s belongs to cluster %s.\n"\ " Command is not allowed for remote file systems." ;; 107 ) msgTxt=\ "%s: There is already an existing file system using %s" ;; 108 ) msgTxt=\ "%s: File system %s not found in cluster %s" ;; 109 ) msgTxt=\ "%s: GPFS is down on this node." ;; 110 ) msgTxt=\ "%s: GPFS is not ready to handle commands yet." ;; 111 ) msgTxt=\ "%s: %s refers to file system %s in cluster %s" ;; 112 ) msgTxt=\ "%s: File system %s does not belong to cluster %s" ;; 113 ) msgTxt=\ "%s: %s failed. Error code %s." ;; 127 ) msgTxt=\ "%s: The main GPFS cluster configuration file is locked. Retrying..." ;; 128 ) msgTxt=\ "%s: Lock creation successful." ;; 129 ) msgTxt=\ "%s: Timed out waiting for lock. Try again later." ;; 130 ) msgTxt=\ "%s: Disk %s is a tiebreaker disk and cannot be deleted." ;; 131 ) msgTxt=\ "%s: GPFS detected more than eight quorum nodes while\n"\ "node quorum with tiebreaker disks is in use." ;; 132 ) msgTxt=\ "%s: GPFS failed to initialize the tiebreaker disks." ;; 133 ) msgTxt=\ "%s: Incorrect keyword: %s" ;; 134 ) msgTxt=\ "%s: Adding node %s to the cluster will exceed\n"\ "the quorum node limit." ;; 135 ) msgTxt=\ "%s: The %s kernel extension does not exist." ;; 136 ) msgTxt=\ "%s: Unable to verify kernel/module configuration." ;; 137 ) msgTxt=\ "%s: The GPFS daemon is still running; use the mmshutdown command." ;; 138 ) msgTxt=\ "%s: Module %s is still in use.\n"\ "Unmount all GPFS file systems and issue the command:\n"\ " mmfsadm cleanup" ;; 139 ) msgTxt=\ "%s: Error unloading module %s." ;; 140 ) msgTxt=\ "%s: Module %s is already loaded." ;; 141 ) msgTxt=\ "%s: %s was not found in /proc/partitions." ;; 142 ) msgTxt=\ "%s: GPFS is waiting for %s" printTimeStamp=yes ;; 144 ) msgTxt=\ "%s: \"%s\" is set by the mmcrcluster processing.\n"\ " Line in error: %s\n"\ " The line is ignored; processing continues." ;; 145 ) msgTxt=\ "%s: \"%s\" must be set with the %s command.\n"\ " Line in error: %s\n"\ " The line is ignored; processing continues." ;; 146 ) msgTxt=\ "%s: \"%s\" is an obsolete parameter.\n"\ " Line in error: %s\n"\ " The line is ignored; processing continues." ;; 147 ) msgTxt=\ "%s: \"%s\" cannot appear in a node-override section.\n"\ " Line in error: %s\n"\ " The line is ignored; processing continues." ;; 148 ) msgTxt=\ "%s: Mount point can not be a relative path name: %s" ;; 149 ) msgTxt=\ "%s: %s can not be a relative path name: %s" ;; 150 ) msgTxt=\ "%s: Key file is not valid." ;; 151 ) msgTxt=\ "%s: Key file mismatch." ;; 152 ) msgTxt=\ "%s: Node %s already belongs to the GPFS cluster." ;; 153 ) msgTxt=\ "%s: Incorrect value for %s option" ;; 154 ) msgTxt=\ "%s: Adapter port name %s is not known on node %s." ;; 155 ) msgTxt=\ "%s: There is nothing to commit. You must first run:\n %s" ;; 156 ) msgTxt=\ "%s: The current authentication files are already committed." ;; 157 ) msgTxt=\ "%s: There are uncommitted authentication files. You must first run:\n %s" ;; 158 ) msgTxt=\ "%s: You must establish a cipher list first. Run:\n %s" ;; 159 ) msgTxt=\ "%s: %s not found. Ensure the OpenSSL code is properly installed." ;; 160 ) msgTxt=\ "%s: For the logical volume specification \"-l %s\" to be valid\n"\ "%s must be the only logical volume in the volume group.\n"\ "However, volume group %s contains the following logical volumes:" ;; 161 ) msgTxt=\ "%s: %s is not a valid logical volume." ;; 162 ) msgTxt=\ "%s: %s is not a valid volume group name." ;; 163 ) msgTxt=\ "%s: For the hdisk specification \"-h %s\" to be valid\n"\ "%s must be the only disk in the volume group.\n"\ "However, volume group %s contains the following disks:" ;; 164 ) msgTxt=\ "%s: %s is not a valid physical volume name." ;; 165 ) msgTxt=\ "%s: %s is not a valid physical volume id." ;; 166 ) msgTxt=\ "Usage: %s \n" ;; 167 ) msgTxt=\ "The disk specification must be in one of these formats:\n"\ " -l logicalVolumeName (e.g., '-l lv00')\n"\ " -v volumeGroupName (e.g., '-v vg00')\n"\ " -h physicalDiskName (e.g., '-h hdisk0')\n"\ " -p physicalVolumeIdentifier (e.g., '-p 0003366423ba4d39')\n" ;; 168 ) msgTxt=\ "%s: Missing arguments" ;; 169 ) msgTxt=\ "%s: The device name %s starts with a slash, but not /dev/." ;; 170 ) msgTxt=\ "%s: The device name %s contains a slash, but not as its first character." ;; 171 ) msgTxt=\ "%s: Unexpected error from %s. Return code: %s" ;; 172 ) msgTxt=\ "%s: Unknown user name %s" ;; 173 ) msgTxt=\ "%s: Unknown group name %s" ;; 174 ) msgTxt=\ "%s: The administrative adapter port name was not defined\n"\ "for nodes:\n\t %s\n"\ "Correct the problems and run mmchcluster -N again." ;; 175 ) msgTxt=\ "%s: Daemon node adapter %s was not found on admin node %s." ;; 176 ) msgTxt=\ "%s: Command failed for disks: %s" ;; 177 ) msgTxt=\ "%s: No contact nodes were provided for cluster %s" ;; 178 ) msgTxt=\ "%s: None of the contact nodes in cluster %s can be reached." ;; 184 ) msgTxt=\ "Usage: %s [-a | -n NodeName]" ;; 185 ) msgTxt=\ "Usage: %s Device [-W NewDeviceName]" ;; 186 ) msgTxt=\ "Usage: %s [-d IntegerDelayValue] [-i CommandFile] [-p]\n"\ " [-r IntegerRepeatValue] [-s] [-t IntegerTimeoutValue]" ;; 187 ) msgTxt=\ "%s: Node %s returned ENODEV for disk %s." ;; 188 ) msgTxt=\ "%s: Remote cluster %s was not found." ;; 189 ) msgTxt=\ "%s: Name %s is not allowed.\n"\ "It contains the following invalid special character: %s" ;; 190 ) msgTxt=\ "%s: GPFS configuration data for file system %s\n"\ "may not be in agreement with the on-disk data for the file system.\n"\ "Issue the command:\n"\ " mmcommon recoverfs %s" ;; 191 ) msgTxt=\ "%s: Options %s and %s cannot be specified at the same time." ;; 192 ) msgTxt=\ "%s: cannot be used with attribute %s" ;; 193 ) msgTxt=\ "%s: There are no remote file systems." ;; 194 ) msgTxt=\ "%s: Remote file system %s is not defined." ;; 195 ) msgTxt=\ "%s: The GPFS configuration information is incorrect or not available." ;; 196 ) msgTxt=\ "%s: Device name cannot be 'all'." ;; 197 ) msgTxt=\ "%s: Each device specifies metadataOnly for disk usage.\n"\ "This file system could not store data." ;; 198 ) msgTxt=\ "%s: Each device specifies dataOnly for disk usage.\n"\ "This file system could not store metadata." ;; 199 ) msgTxt=\ "%s: Incorrect integer %s specified for failure group." ;; 200 ) msgTxt=\ "%s: No file systems were found." ;; 201 ) msgTxt=\ "%s: Incorrect server node %s in disk descriptor." ;; 202 ) msgTxt=\ "%s: %s is the name of the local cluster." ;; 204 ) msgTxt=\ "%s: Missing argument after %s option" ;; 229 ) msgTxt=\ "Usage: %s [-CIVOSPDH] [-c] [-u] [-d disk] [-g volumeGroup]\n"\ " [-l logicalVolume] [-G globalVolumeGroup] [-L globalLogicalVolume]\n"\ " [-p physicalVolumeID ]\n" ;; 230 ) msgTxt=\ "%s: %s is already in volume group %s and cannot be added to %s.\n" ;; 232 ) msgTxt=\ "%s: Cannot find %s with %s.\n" ;; 233 ) msgTxt=\ "%s: %s requires a value.\n" ;; 234 ) msgTxt=\ "%s: Incorrect option: %s\n" ;; 235 ) msgTxt=\ "%s: Interrupt received.\n" ;; 236 ) msgTxt=\ "%s: Volume group %s cannot be imported on node\n"\ "%s because the disk with physical volume ID %s\n"\ "cannot be found." ;; 237 ) msgTxt=\ "%s: Failed to obtain DCE credentials; dsrvtgt %s command rc=%s. Continuing." ;; 238 ) msgTxt=\ "%s: Command is not allowed for remote file systems." ;; 239 ) msgTxt=\ "%s: Disk usage %s is incompatible with storage pool %s." ;; 240 ) msgTxt=\ "%s: File %s not found. Recover the file or run mmauth genkey." ;; 246 ) msgTxt=\ "Usage:\n"\ " %s [-t UnmountTimeout]\n"\ " [-a | -N {Node[,Node...] | NodeFile | NodeClass}]" ;; 247 ) msgTxt=\ "%s: Disk with NSD volume id %s no longer\n"\ " exists in the GPFS cluster configuration data but the NSD volume id\n"\ " was not erased from the disk. To remove the NSD volume id, issue\n"\ " mmdelnsd -p %s" ;; 248 ) msgTxt=\ "%s: Disk with NSD volume id %s no longer\n"\ " exists in the GPFS cluster configuration data but the NSD volume id\n"\ " was not erased from the disk. To remove the NSD volume id, issue\n"\ " mmdelnsd -p %s -N %s" ;; 249 ) msgTxt=\ "Usage:\n"\ " %s genkey {new | commit}\n"\ " or\n"\ " %s add RemoteClusterName -k KeyFile [-l CipherList]\n"\ " or\n"\ " %s update RemoteClusterName {[-C NewClusterName] [-k KeyFile] [-l CipherList]}\n"\ " or\n"\ " %s delete {RemoteClusterName | all}\n"\ " or\n"\ " %s grant {RemoteClusterName | all} -f {Device | all} [-a {rw | ro}] [-r {uid:gid | no}]\n"\ " or\n"\ " %s deny {RemoteClusterName | all} -f {Device | all}\n"\ " or\n"\ " %s show [RemoteClusterName | all]\n" ;; 252 ) msgTxt=\ "%s: %s is not a remote file system known to GPFS." ;; 257 ) msgTxt=\ "%s: An internode connection between GPFS nodes was disrupted." ;; 258 ) msgTxt=\ "%s: No clusters are authorized to access this cluster." ;; 259 ) msgTxt=\ "%s: Cluster %s is not authorized to access this cluster." ;; 260 ) msgTxt=\ "Usage: %s %s %s" ;; 261 ) msgTxt=\ "%s: Attention: There are no available valid VFS type values for mmfs in /etc/vfs." ;; 262 ) msgTxt=\ "%s: There are no remote cluster definitions." ;; 263 ) msgTxt=\ "%s: Remote cluster %s is not defined." ;; 264 ) msgTxt=\ "%s: No disks specified" ;; 265 ) msgTxt=\ "%s: Disk %s already belongs to file system %s." ;; 266 ) msgTxt=\ "%s: File system %s has some disks that are in a non-ready state." ;; 267 ) msgTxt=\ "%s: Attention: Not all disks were marked as available." ;; 268 ) msgTxt=\ "%s: This GPFS cluster contains declarations for remote file systems and clusters.\n"\ " You cannot delete the last node." ;; 270 ) msgTxt=\ "%s: The following nodes could not be reached:\n" ;; 271 ) msgTxt=\ "%s: Propagating the cluster configuration data to all\n"\ " affected nodes. This is an asynchronous process." ;; 272 ) msgTxt=\ "%s: Command successfully completed" ;; 273 ) msgTxt=\ "%s: There is no file system information in input file %s." ;; 274 ) msgTxt=\ "%s: File system %s was not found in input file %s." ;; 275 ) msgTxt=\ "%s: The following file systems were not imported:%s" ;; 277 ) msgTxt=\ "%s: Attention: Unknown attribute specified: %s. Press the ENTER key to continue." ;; 278 ) msgTxt=\ "%s: Incorrect record found in the mmsdrfs file (code %s):" ;; 279 ) msgTxt=\ "%s: There is no file system with mount point %s." ;; 280 ) msgTxt=\ "%s: File system %s is already mounted at %s." ;; 281 ) msgTxt=\ "%s: Mount point cannot be specified when mounting all file systems." ;; 282 ) msgTxt=\ "%s: This node does not belong to a GPFS cluster." ;; 283 ) msgTxt=\ "%s: There is no record for this node in file %s.\n"\ " Either the node is not part of the cluster, or the file is for a different cluster,\n"\ " or not all of the node's adapter interfaces have been activated yet." ;; 284 ) msgTxt=\ "Usage:\n"\ " %s [-p NodeName] [-F mmsdrfsFile] [-R RemoteFileCopyCommand]" ;; 285 ) msgTxt=\ "%s: Node %s successfully restored." ;; 286 ) msgTxt=\ "%s: Unexpected value for Gpfs object: %s" ;; 287 ) msgTxt=\ "Usage:\n"\ " %s Device {resume | start} -a\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]\n"\ " or\n"\ " %s Device {suspend | resume | stop | start | change}\n"\ " -d \"DiskDesc[;DiskDesc...]\"\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 288 ) msgTxt=\ "%s: File system %s is not known to the GPFS cluster." ;; 289 ) msgTxt=\ "Usage:\n"\ " %s Attribute=value[,Attribute=value...] [-i | -I]\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 290 ) msgTxt=\ "%s: Node %s does not belong to the GPFS cluster,\n"\ " or is represented multiple times on the command line." ;; 291 ) msgTxt=\ "Usage:\n"\ " %s Device {\"DiskDesc[;DiskDesc...]\" | -F DescFile} [-a] [-c]\n"\ " [-r] [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 292 ) msgTxt=\ "Usage: %s Device [-p]" ;; 293 ) msgTxt=\ "%s: Invalid node designation specified: %s" ;; 294 ) msgTxt=\ "%s: Operation not allowed for the local cluster." ;; 295 ) msgTxt=\ "Usage:\n"\ " %s Device DiskName {DiskDesc | -F DescFile} [-v {yes | no}]\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 296 ) msgTxt=\ "Usage:\n"\ " %s Device {\"DiskDesc[;DiskDesc...]\" | -F DescFile} [-a] [-r]\n"\ " [-v {yes | no}] [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 298 ) msgTxt=\ "Usage: %s Device [-d | -F | -m] [-P PoolName] [-q]" ;; 299 ) msgTxt=\ "Usage: %s Device [-i] [-u BlkUtilPct] [-v]" ;; 300 ) msgTxt=\ "Usage:\n"\ " %s Device [-n | -y] [-v | -V] [-c | -o] [-t Directory]\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 301 ) msgTxt=\ "Usage:\n"\ " %s Device [-d \"DiskName[;DiskName...]\"] [-e] [-L]\n"\ " or\n"\ " %s Device [-d \"DiskName[;DiskName...]\"] {-m | -M}" ;; 302 ) msgTxt=\ "Usage:\n"\ " %s Device {-m | -r | -b | -p | -R} [-P PoolName]\n"\ " [-N {Node[,Node...] | NodeFile | NodeClass}]" ;; 303 ) msgTxt=\ "Usage: %s [Device[ Device...]] | [-C ClusterName]" ;; 304 ) msgTxt=\ "Usage: %s Device [Node]" ;; 305 ) msgTxt=\ "%s: Mount point and device name cannot be equal: %s" ;; 306 ) msgTxt=\ "%s: Interrupt received." ;; 307 ) msgTxt=\ "%s: You must first generate an authentication key file. Run:\n"\ " mmauth genkey new" ;; 309 ) msgTxt=\ "%s: The -i option failed. Changes will take effect after GPFS is restarted." ;; 310 ) msgTxt=\ "%s: This GPFS cluster contains file systems. You cannot delete the last node." ;; 311 ) msgTxt=\ "%s: Attention: Failed to remove node-specific changes." ;; 312 ) msgTxt=\ "%s: %s command cannot be executed. Either none of the\n"\ " nodes in the cluster are reachable, or GPFS is down on all of the nodes." ;; 313 ) msgTxt=\ "%s: Attention: The file system may no longer be properly balanced" ;; 314 ) msgTxt=\ "%s: To change the authentication key for the local cluster, run:\n"\ " mmauth genkey" ;; 315 ) msgTxt=\ "%s: %s not found in file system %s" ;; 316 ) msgTxt=\ "%s: Remote cluster %s is already defined." ;; 317 ) msgTxt=\ "%s: File system %s from cluster %s is already defined." ;; 318 ) msgTxt=\ "%s: %s command failed. Only %s changed." ;; 319 ) msgTxt=\ " The volume group %s exists, but partition\n"\ "information cannot be determined. Perhaps it needs to be varied on?\n" ;; 321 ) msgTxt=\ "%s: %s does not exist or failed; automount mounting may not work." ;; 322 ) msgTxt=\ "%s: The command must run on a node that is part of the cluster." ;; 323 ) msgTxt=\ "%s: Command completed: No changes made" ;; 324 ) msgTxt=\ "%s: Permission failure. The command requires root authority to execute." ;; 328 ) msgTxt=\ "%s: File %s does not contain node names." ;; 329 ) msgTxt=\ "%s: File %s does not contain data." ;; 330 ) msgTxt=\ "%s: Failed to obtain Kerberos credentials; ksrvtgt %s command rc=%s. Continuing." ;; 334 ) msgTxt=\ "Usage:\n"\ " %s {Device | all} [-a] [-A] [-B] [-d] [-D] [-E] [-f] [-F] [-i]\n"\ " [-I] [-j] [-k] [-K] [-m] [-M] [-n] [-o] [-P]\n"\ " [-Q] [-r] [-R] [-s] [-S] [-T] [-u] [-V] [-z]\n" ;; 337 ) msgTxt=\ "%s: Unable to determine the local device name for disk %s on node %s." ;; 338 ) msgTxt=\ "%s: Unknown GPFS execution environment %s" ;; 340 ) msgTxt=\ "%s: %s cannot be reached." ;; 341 ) msgTxt=\ "%s: Attention: Unable to retrieve GPFS cluster files from node %s" ;; 342 ) msgTxt=\ "%s: Unable to retrieve GPFS cluster files from node %s" ;; 343 ) msgTxt=\ "Usage:\n"\ " %s -N {NodeDesc[,NodeDesc...] | NodeFile}\n"\ " -p PrimaryServer [-s SecondaryServer]\n"\ " [-r RemoteShellCommand] [-R RemoteFileCopyCommand]\n"\ " [-C ClusterName] [-U DomainName] [-A] [-c ConfigFile]" ;; 344 ) msgTxt=\ "%s: Run the %s command until successful." ;; 345 ) msgTxt=\ "%s: No nodes were found that matched the input specification." ;; 346 ) msgTxt=\ "%s: The same node was specified for both the primary and the secondary server." ;; 347 ) msgTxt=\ "%s: Node %s is specified more than once." ;; 348 ) msgTxt=\ "%s: Node %s was not added to the cluster.\n"\ " The node appears to already belong to a GPFS cluster." ;; 349 ) msgTxt=\ "%s: The level of GPFS on node %s does not support the requested action." ;; 350 ) msgTxt=\ "%s: Make sure that the following nodes are available: %s" ;; 351 ) msgTxt=\ "%s: Removing GPFS cluster files from the nodes in the cluster . . . " ;; 352 ) msgTxt=\ "%s: %s is not a member of this cluster." ;; 353 ) msgTxt=\ "%s: The following nodes could not be added to the GPFS cluster:%s\n"\ " Correct the problems and use the mmaddnode command to add these nodes\n"\ " to the cluster." ;; 354 ) msgTxt=\ "%s: Information cannot be displayed. Either none of the\n"\ " nodes in the cluster are reachable, or GPFS is down on all of the nodes." ;; 355 ) msgTxt=\ "Usage:\n"\ " %s -N {NodeDesc[,NodeDesc...] | NodeFile}" ;; 356 ) msgTxt=\ "Usage:\n"\ " %s {-a | -N {Node[,Node...] | NodeFile | NodeClass}}" ;; 357 ) msgTxt=\ "Usage: %s " ;; 358 ) msgTxt=\ "Usage: %s Device [-L]" ;; 359 ) msgTxt=\ "Usage: %s {[-p PrimaryServer] [-s SecondaryServer]}\n"\ " or\n"\ " %s -p LATEST\n"\ " or\n"\ " %s {[-r RemoteShellCommand] [-R RemoteFileCopyCommand]}\n"\ " or\n"\ " %s -C ClusterName\n"\ " or\n"\ " %s -N {NodeDesc[,NodeDesc...] | NodeFile}" ;; 360 ) msgTxt=\ "%s: Disk %s is the only disk in file system %s.\n"\ "You cannot replace a disk when it is the only remaining disk in the file system." ;; 361 ) msgTxt=\ "Usage: %s Device PolicyFilename [-t DescriptiveName] [-I {yes|test}]" ;; 367 ) msgTxt=\ "%s: There are no available nodes on which to run the command." ;; 370 ) msgTxt=\ "Usage: %s" ;; 371 ) msgTxt=\ "Usage: %s Device Directory" ;; 372 ) msgTxt=\ "Usage: %s Device Directory" ;; 374 ) msgTxt=\ "Usage:\n"\ " %s [-f] [-a | -N {Node[,Node...] | NodeFile | NodeClass}]" ;; 375 ) msgTxt=\ "%s: %s cannot be used with attribute %s" ;; 376 ) msgTxt=\ "%s: Command is not supported in the %s environment." ;; 377 ) msgTxt=\ "%s: Command failed on nodes: %s" ;; 378 ) msgTxt=\ "%s: Cannot determine basic environment information.\n"\ " Not enough nodes are available." ;; 379 ) msgTxt=\ "%s: Error retrieving data from %s to %s." ;; 380 ) msgTxt=\ "%s: The GPFS cluster data on %s is back level." ;; 381 ) msgTxt=\ "%s: The commit process failed." ;; 382 ) msgTxt=\ "%s: The GPFS cluster configuration data on %s\n"\ "is different from the data on %s." ;; 383 ) msgTxt=\ "%s: Failed to create a backup copy of the GPFS cluster data on %s." ;; 384 ) msgTxt=\ "%s: GPFS cluster configuration server node %s cannot be removed." ;; 385 ) msgTxt=\ "Usage:\n"\ " %s add Device -f RemoteDevice -C RemoteClusterName\n"\ " -T Mountpoint [-o MountOptions] [-A {yes | no | automount}]\n"\ " or\n"\ " %s update Device [-f RemoteDevice] [-C RemoteClusterName]\n"\ " [-T Mountpoint] [-o MountOptions] [-A {yes | no | automount}]\n"\ " or\n"\ " %s delete {Device | all | -C RemoteClusterName}\n"\ " or\n"\ " %s show [Device | all | -C RemoteClusterName]\n" ;; 386 ) msgTxt=\ "%s: Error found while checking disk descriptor %s" ;; 387 ) msgTxt=\ "%s: %s quitting. None of the specified nodes are valid." ;; 388 ) msgTxt=\ "Usage:\n"\ " %s add RemoteClusterName -k KeyFile -n ContactNodes\n"\ " or\n"\ " %s update RemoteClusterName {[-C NewClusterName] [-k KeyFile] [-n ContactNodes]}\n"\ " or\n"\ " %s delete {RemoteClusterName | all}\n"\ " or\n"\ " %s show [RemoteClusterName | all]\n" ;; 389 ) msgTxt=\ "%s: Command failed. Examine previous error messages to determine cause." ;; 390 ) msgTxt=\ "Usage:\n"\ " %s {Device | DefaultMountPoint | all | all_local | all_remote} [-o MountOptions]\n"\ " [-a | -N {Node[,Node...] | NodeFile | NodeClass}]\n"\ " or\n"\ " %s Device MountPoint [-o MountOptions]\n"\ " [-a | -N {Node[,Node...] | NodeFile | NodeClass}]" ;; 391 ) msgTxt=\ "Usage:\n"\ " %s [-a | -N {Node[,Node...] | NodeFile | NodeClass}]\n"\ " [-E EnvVar=value...]" ;; 393 ) msgTxt=\ "%s: The number of quorum nodes exceeds the maximum (%s) allowed." ;; 394 ) msgTxt=\ "%s: Warning: The number of quorum nodes exceeds the suggested maximum (%s)." ;; 395 ) msgTxt=\ "%s: Node %s is fenced out from disk %s." ;; 396 ) msgTxt=\ "Usage:\n"\ " %s {Device | MountPoint | all | all_local | all_remote} [-f]\n"\ " [-a | -N {Node[,Node...] | NodeFile | NodeClass}]\n"\ " or\n"\ " %s Device -f -C {all_remote | ClusterName} [-N Node[,Node...]]" ;; 397 ) msgTxt=\ "%s: Unable to find disk with NSD volume id %s." ;; 398 ) msgTxt=\ "%s: GPFS was unable to obtain a lock from node %s." ;; 399 ) msgTxt=\ "%s: Remount failed for file system %s. Error code %s." ;; 410 ) msgTxt=\ "Usage: %s -F DescFile [-v {yes | no}]\n" ;; 411 ) msgTxt=\ "%s: Failed while processing disk descriptor %s on node %s." ;; 412 ) msgTxt=\ "%s: Disk descriptor %s refers to an existing NSD %s" ;; 413 ) msgTxt=\ "Usage:\n"\ " %s {\"DiskName[;DiskName...]\" | -F DiskFile}\n"\ " or\n"\ " %s -p NSDId [-N Node[,Node]]" ;; 415 ) msgTxt=\ "%s: Disk descriptor %s should refer to an existing NSD.\n"\ "Use mmcrnsd to create the NSD." ;; 417 ) msgTxt=\ "%s: Issue the command from a node that remains in the cluster." ;; 418 ) msgTxt=\ "%s: No disks were found." ;; 419 ) msgTxt=\ "Usage: %s Device Directory [-c]" ;; 420 ) msgTxt=\ "Usage:\n"\ " %s Mountpoint Device {\"DiskDesc[;DiskDesc...]\" | -F DescFile}\n"\ " [-A {yes | no | automount}] [-B BlockSize] [-D {posix | nfs4}]\n"\ " [-E {yes | no}] [-j {cluster | scatter}]\n"\ " [-k {posix | nfs4 | all}] [-K {no | whenpossible | always}]\n"\ " [-m DefaultMetadataReplicas] [-M MaxMetadataReplicas]\n"\ " [-n NumNodes] [-N NumInodes[:NumInodesToPreallocate]] [-Q {yes | no}]\n"\ " [-r DefaultDataReplicas] [-R MaxDataReplicas]\n"\ " [-S {yes | no}] [-v {yes | no}] [-z {yes | no}]\n" ;; 421 ) msgTxt=\ "Usage:\n"\ " %s Device [-A {yes | no | automount}] [-D {posix | nfs4}] [-E {yes | no}]\n"\ " [-F MaxNumInodes[:NumInodesToPreallocate]]\n"\ " [-k {posix | nfs4 | all}] [-K {no | whenpossible | always}]\n"\ " [-m DefaultMetadataReplicas] [-o MountOptions]\n"\ " [-Q {yes | no}] [-r DefaultDataReplicas] [-S {yes | no}]\n"\ " [-T Mountpoint] [-V] [-z {yes | no}]\n"\ " or\n"\ " %s Device [-W NewDeviceName]" ;; 422 ) msgTxt=\ "%s: Incorrect or missing remote shell command: %s" ;; 423 ) msgTxt=\ "%s: Incorrect or missing remote file copy command: %s" ;; 424 ) msgTxt=\ "%s: %s %s parameter must be an absolute pathname." ;; 425 ) msgTxt=\ "Usage:\n"\ " %s {[-r RemoteShellCommand] [-R RemoteFileCopyCommand]} [-f]\n"\ " or\n"\ " %s -C ClusterName" ;; 428 ) msgTxt=\ "Usage:\n"\ " %s [-a | -F | -f Device | -d \"DiskName[;DiskName...]\"]\n"\ " [-L | -m | -M | -X] [-v]" ;; 429 ) msgTxt=\ "%s: Disk %s is of an unknown type." ;; 432 ) msgTxt=\ "%s: Disk name %s is already registered for use by GPFS." ;; 433 ) msgTxt=\ "%s: Node %s is being used as a primary or backup NSD server." ;; 437 ) msgTxt=\ "%s: Processing continues without lock protection." ;; 438 ) msgTxt=\ "Usage: %s {\"DiskDesc[;DiskDesc...]\" | -F DescFile}\n" ;; 439 ) msgTxt=\ "Usage: %s Device [-d] [-Q]" ;; 440 ) msgTxt=\ "%s: Command was unable to obtain the lock for the GPFS system data.\n"\ " Unable to reach the holder of the lock %s.\n"\ " Check the preceding messages, if any. Follow the procedure outlined\n"\ " in the GPFS Problem Determination Guide." ;; 441 ) msgTxt=\ "vpath disk %s is not recognized as an IBM SDD device.\n" ;; 448 ) msgTxt=\ "Usage: %s " ;; 449 ) msgTxt=\ "Usage:\n"\ " %s [-L] [-s] [-v] [-a | -N {Node[,Node...] | NodeFile | NodeClass}]" ;; 450 ) msgTxt=\ "%s: Disk %s belongs to vpath %s.\n" ;; 452 ) msgTxt=\ "Usage:\n"\ " %s [-u User | -g Group | -j Fileset] [-v | -q] [-e]\n"\ " [-C ClusterName] [Device1 Device2 ...]\n"\ " or\n"\ " %s -d {-u | -g | -j} [-C ClusterName] [Device1 Device2 ...]\n" ;; 454 ) msgTxt=\ "%s: Failed to stat %s." ;; 455 ) msgTxt=\ "%s: %s is not a GPFS file system object." ;; 456 ) msgTxt=\ "%s: The policy file cannot be determined." ;; 457 ) msgTxt=\ "Usage:\n"\ " %s {Device|Directory} [-P PolicyFile] [-I {yes|defer|test}]\n"\ " [-L n] [-D yyyy-mm-dd[@hh:mm[:ss]]] [-s WorkDirectory]\n" ;; 458 ) msgTxt=\ "Usage:\n"\ " %s Device -n ControlFile [-t {full | incremental}] [-s SortDir]\n"\ " or\n"\ " %s Device -R [-s SortDir]\n" ;; 459 ) msgTxt=\ "Usage: %s Device {\"FileName[,FileName...]\" | -f FileNameFile}\n" ;; 460 ) msgTxt=\ "%s: \"%s\" must be a absolute path name." ;; 461 ) msgTxt=\ "%s: Device with major/minor numbers %s and %s already exists." ;; 462 ) msgTxt=\ "%s: %s was not created by GPFS or could not be refreshed." ;; 469 ) msgTxt=\ "%s: The %s option is not allowed for remote file systems." ;; 470 ) msgTxt=\ "%s: There are no available free disks.\n"\ "Disks must be prepared prior to invoking %s.\n"\ "Define the disks using the %s command." ;; 472 ) msgTxt=\ "%s: File system %s belongs to cluster %s.\n"\ " The %s option is not allowed for remote file systems." ;; 474 ) msgTxt=\ "%s: %s not active on nodes: %s" ;; 476 ) msgTxt=\ "%s: IP aliasing is not supported (%s). Specify the main device." ;; 481 ) msgTxt=\ "%s: The requested disks are not known to GPFS." ;; 483 ) msgTxt=\ "%s: %s is not a valid cipher list." ;; 484 ) msgTxt=\ "Usage:\n"\ " %s Device {suspend | resume}\n"\ " or\n"\ " %s Device {exclude | include}\n"\ " {-d \"DiskName[;DiskName...]\" | -F DiskFile | -G FailureGroup}\n"\ " or\n"\ " %s Device syncFSconfig\n"\ " {-n RemoteNodesFile | -C RemoteCluster} [-S SpecFile]\n" ;; 485 ) msgTxt=\ "%s: Disk %s belongs to file system %s." ;; 486 ) msgTxt=\ "%s: The following disks are not known to GPFS:\n%s" ;; 487 ) msgTxt=\ "%s: No disks were specified that could be deleted." ;; 488 ) msgTxt=\ "%s: Disk %s has been removed from the GPFS cluster\n"\ " configuration data but the NSD volume id was not erased from\n"\ " the disk. To remove the NSD volume id, issue\n"\ " mmdelnsd -p %s" ;; 489 ) msgTxt=\ "%s: Disk %s has been removed from the GPFS cluster data\n"\ " configuration data but the NSD volume id was not erased from\n"\ " the disk. To remove the NSD volume id, issue\n"\ " mmdelnsd -p %s -N %s" ;; 491 ) msgTxt=\ "%s: Disk %s is not assigned a primary NSD server node." ;; 492 ) msgTxt=\ "%s: The primary and backup NSD servers must be different nodes." ;; 498 ) msgTxt=\ "%s: Cannot handle multiple interfaces for host %s." ;; 499 ) msgTxt=\ "%s: Unexpected output from the 'host -t a %s' command:" ;; 500 ) msgTxt=\ "%s: Host %s not found." ;; 505 ) msgTxt=\ "%s: Disk name %s is not allowed.\n"\ "Names beginning with gpfs are reserved for use by GPFS." ;; 507 ) msgTxt=\ "%s: File %s not found.\n"\ " Recover the file, or generate and commit a new key using mmauth genkey." ;; 508 ) msgTxt=\ "%s: Disk %s is too large." ;; 509 ) msgTxt=\ "%s: Unexpected error obtaining the local environment update lock." ;; 510 ) msgTxt=\ "%s: Local update lock is busy." ;; 511 ) msgTxt=\ "%s: Failed to obtain the local environment update lock." ;; 513 ) msgTxt=\ "Usage:\n"\ " %s Device FilesetName [-t Comment]\n" ;; 514 ) msgTxt=\ "Usage:\n"\ " %s Device {FilesetName | -J JunctionPath}\n"\ " {[-j NewFileSetName] [-t Comment]}\n" ;; 515 ) msgTxt=\ "Usage:\n"\ " %s Device FilesetName [-J JunctionPath]\n" ;; 516 ) msgTxt=\ "Usage:\n"\ " %s Device {FilesetName | -J JunctionPath} [-f]\n" ;; 517 ) msgTxt=\ "Usage:\n"\ " %s Device FilesetName [-f]\n" ;; 518 ) msgTxt=\ "Usage:\n"\ " %s Device\n"\ " [[Fileset[,Fileset...]] [-J Junction[,Junction...]] | -F FileName]\n"\ " [-L] [-d] [-i]\n" ;; 520 ) msgTxt=\ "%s: %s: Volume group %s has been varied on." ;; 523 ) msgTxt=\ "%s: Permission denied for disk %s" ;; 524 ) msgTxt=\ "%s: Disk %s was not found." ;; 525 ) msgTxt=\ "%s: I/O error on %s" ;; 526 ) msgTxt=\ "%s: %s is not a valid logical volume." ;; 528 ) msgTxt=\ "%s: Disk %s belongs to back-level file system %s\n"\ " or the state of the disk is not ready.\n"\ " Use mmchfs -V to convert the file system to the latest format.\n"\ " Use mmchdisk to change the state of a disk." ;; 529 ) msgTxt=\ "%s: Failed while processing disk %s" ;; 530 ) msgTxt=\ "%s: Device %s already exists on node %s" ;; 531 ) msgTxt=\ "%s: Disk %s has no space for the quorum data structures.\n"\ " Specify a different disk as tiebreaker disk." ;; 532 ) msgTxt=\ "%s: Disk %s (pvid %s) is not known on node %s" ;; 533 ) msgTxt=\ "%s: Import of volume group %s on node %s failed." ;; 534 ) msgTxt=\ "%s: Volume group %s is not known on node %s." ;; 535 ) msgTxt=\ "%s: %s: Unable to varyon volume group %s." ;; 536 ) msgTxt=\ "%s: None of the quorum nodes can be reached." ;; 537 ) msgTxt=\ "%s: The descriptor file contains more than one descriptor." ;; 538 ) msgTxt=\ "%s: The descriptor file contains no descriptor." ;; 539 ) msgTxt=\ "%s: Failed validating disk %s. Error code %s." ;; 540 ) msgTxt=\ "Usage:\n"\ " %s {Device | all | all_local | all_remote} [-L]\n"\ " [-C {all | all_remote | ClusterName[,ClusterName...]}]" ;; 547 ) msgTxt=\ "%s: Skipping disk %s on node %s." ;; 548 ) msgTxt=\ "%s: Name %s is not allowed.\n"\ "It is longer than the maximum allowable length (%s)." ;; 549 ) msgTxt=\ "%s: mmfskxload: The format of the GPFS kernel extension\n"\ "is not correct for this version of AIX." ;; 550 ) msgTxt=\ "%s: %s does not resolve to a directory in %s.\n"\ " The junction must be within the specified file system." ;; 551 ) msgTxt=\ "%s: Name %s is not allowed." ;; 552 ) msgTxt=\ "%s: File system %s is not mounted." ;; 555 ) msgTxt=\ "Usage: %s Device [-q | -d | -s SnapLatestName]" ;; 556 ) msgTxt=\ "Usage: %s Device [-n | -f]" ;; 558 ) msgTxt=\ "%s: Vpath disk %s has an underlying hdisk that already belongs to a volume group." ;; 560 ) msgTxt=\ "Usage:\n"\ " %s Device\n"\ " {-d [NodeName]:{DiskName|DiskNum|BROKEN}:[PhysAddr1[PhysAddr2]] | -F DescFile}\n"\ " [-o OutputFile] [-f NumThreads] [-t Directory]" ;; 561 ) msgTxt=\ "%s: File %s either does not exist or has an incorrect format." ;; 562 ) msgTxt=\ "%s: did not find any match with the input disk address." ;; 563 ) msgTxt=\ "%s: Device %s is not mounted on node %s." ;; 564 ) msgTxt=\ "%s: Command was unable to determine whether file system %s is mounted." ;; 565 ) msgTxt=\ "%s: Backup control file %s from a previous backup does not exist." ;; 566 ) msgTxt=\ "Usage:\n"\ " %s Device {[-r | -a] [-s SnapDirName]} \n"\ " or\n"\ " %s Device [-q]" ;; 567 ) msgTxt=\ "%s: Line %d of file %s is incorrect:" ;; 568 ) msgTxt=\ "%s: Syntax error. The correct syntax is:\n %s" ;; 569 ) msgTxt=\ "%s: Incorrect range %s-%s specified." ;; 570 ) msgTxt=\ "Usage: %s {Device | all} -o ExportfsFile" ;; 571 ) msgTxt=\ "Usage:\n"\ " %s {Device | all} -i ImportfsFile [-S ChangeSpecFile]" ;; 572 ) msgTxt=\ "%s: Insufficient free space in %s (%s minimum required)." ;; 574 ) msgTxt=\ "%s: Directory %s does not exist." ;; 575 ) msgTxt=\ "%s: The GPFS release level could not be determined on nodes:\n%s" ;; 576 ) msgTxt=\ "%s: The GPFS release level could not be determined on any of the nodes." ;; 577 ) msgTxt=\ "%s: Ensure the nodes are available and run:\n%s" ;; 578 ) msgTxt=\ "%s: Upgrade the lower release level nodes and run:\n%s" ;; 579 ) msgTxt=\ "%s: The GPFS release level in effect for the cluster remains unchanged.\n"\ " Old level: %s (Release %s)" ;; 580 ) msgTxt=\ "%s: The GPFS release level in effect for the cluster cannot be determined.\n"\ " Assumed: %s (Release %s)" ;; 581 ) msgTxt=\ "%s: The GPFS release level in effect for the cluster will be changed.\n"\ " Old level: %s (Release %s) New level: %s (Release %s)" ;; 582 ) msgTxt=\ "%s: The cluster contains nodes that are at different GPFS release levels.\n"\ " Lowest level: %s (Release %s) Highest level: %s (Release %s)" ;; 583 ) msgTxt=\ "%s: -V option requires all nodes in the cluster to be at the same GPFS release level." ;; 585 ) msgTxt=\ "%s: Not able to associate %s on node %s with any known GPFS disk." ;; 587 ) msgTxt=\ "%s: Unable to resolve address range for disk %s on node %s." ;; # Message numbers above 1000 are in message set 60 (ts/fencing/fencing.msg). 1000 ) msgTxt=\ "%s: Could not clear fencing for disk %s." ;; 1001 ) msgTxt=\ "%s: tspreemptabort of disk %s for nodes %s failed." ;; 1002 ) msgTxt=\ "%s: Disk %s of type %s is not supported for fencing." ;; 1003 ) msgTxt=\ "%s: Unable to fence in node %s for disk %s." ;; 1004 ) msgTxt=\ "%s: None of the specified nodes belong to this GPFS cluster." ;; 1005 ) msgTxt=\ "%s: A node cannot fence itself in." ;; 1006 ) msgTxt=\ "%s: varyonLocalVolume: tsprregister was unable to unfence disk %s." ;; 1007 ) msgTxt=\ "%s: Unable to display fencing for disk %s." ;; 1008 ) msgTxt=\ "%s: For the logical volume specification \"-l %s\" to be valid\n"\ "%s must be the only logical volume in the volume group.\n"\ "However, volume group %s contains logical volumes." ;; 1009 ) msgTxt=\ "%s: %s is not a valid logical volume." ;; 1010 ) msgTxt=\ "%s: %s is not a valid volume group name." ;; 1011 ) msgTxt=\ "%s: For the hdisk specification \"-h %s\" to be valid\n"\ "%s must be the only disk in the volume group.\n"\ "However, volume group %s contains disks" ;; 1012 ) msgTxt=\ "%s: %s is not a valid physical volume name." ;; 1013 ) msgTxt=\ "%s: %s is not a valid physical volume id." ;; 1014 ) msgTxt=\ "%s: Node %s does not have access to disk %s." ;; 1015 ) msgTxt=\ "%s: Node %s does not hold a reservation for disk %s." ;; 1016 ) msgTxt=\ "%s: SSA fencing support is not present on this node." ;; 1017 ) msgTxt=\ "%s: Node ID %s is not a valid SSA node ID.\n"\ "SSA node IDs must be a number in the range of 1 to 128." ;; 1024 ) msgTxt=\ "%s: The SSA node id is not set." ;; 1025 ) msgTxt=\ "%s: Unable to retrieve the SSA node id." ;; 1026 ) msgTxt=\ "%s: Unable to set fencing for disk %s." ;; 1027 ) msgTxt=\ "%s: Unable to clear PR reservations for disk %s." ;; * ) # unknown message, ignore it. return 0 ;; esac # Message numbers below 1000 are in message set 32 (ts/admin/admin.msg). # Message numbers above 1000 are in message set 60 (ts/fencing/fencing.msg). if [[ $msgNo -lt 1000 ]] then msgSet=32 else msgSet=60 fi if [[ $osName = AIX ]] then # Print the message - extra arguments are ignored. if [[ $printTimeStamp = yes ]] then print -u2 -- "$(date) $($dspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" else print -u2 -- "$($dspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" fi elif [[ $osName = Linux ]] then # Print the message - extra arguments are ignored. if [[ $printTimeStamp = yes ]] then print -u2 -- "$(date) $($mmdspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" else print -u2 -- "$($mmdspmsg -s $msgSet mmfs.cat \ $msgNo "$msgTxt" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")" fi else checkForErrors "Unknown operating system $osName" 1 fi } #----- end of function printErrorMsg -------------------------- ########################################################################## # # Function: Prints a syntax-related message, optionally followed # by usage message, and terminates the command # # Input: $1 - indicator for the type of error # $2 - number of the usage message to issue; # if 0, usage message is not printed # $3, $4, etc. - substitute parameters for the message # # Output: Syntax-related message # # Returns: No return. The function invokes the cleanupAndExit routine. # # Note: The usage message is assumed to have only one substitute # parameter, the command name. The command name is allowed # to appear more than once in the usage statement. # ########################################################################## function syntaxError # [ [...]] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGsyntaxError ]] && set -x $mmTRACE_ENTER "$*" typeset reason=$1 typeset usageMsg=$2 typeset sub1="$3" typeset sub2="$4" typeset sub3="$5" typeset sub4="$6" typeset sub5="$7" # Print the appropriate message. case "$reason" in "multiple") # Parameter specified more than once. printErrorMsg 36 "$mmcmd" "$sub1" ;; "missingArgs") # Missing arguments. printErrorMsg 168 "$mmcmd" ;; "missingValue") # Missing required value after flag. printErrorMsg 204 "$mmcmd" "$sub1" ;; "missingFile") # Missing disk descriptor file. printErrorMsg 41 "$mmcmd" ;; "extraArg") # Unexpected extra argument. printErrorMsg 38 "$mmcmd" "$sub1" ;; "invalidOption") # Incorrect option. printErrorMsg 13 "$mmcmd" "$sub1" ;; "invalidCombination") # Invalid combination of options. printErrorMsg 191 "$mmcmd" "$sub1" "$sub2" ;; "YesNoValue") # Invalid yes|no parameter. printErrorMsg 37 "$mmcmd" "$sub1" ;; "keyword") # Invalid keyword specified. printErrorMsg 133 "$mmcmd" "$sub1" ;; "invalidInt") # Invalid parameter - must be an integer. printErrorMsg 40 "$mmcmd" "$sub1" "$sub2" ;; "cannotOpenFile") # unable to open file. printErrorMsg 43 "$mmcmd" "$sub1" ;; "negativeInt" ) # Invalid parameter - must be positive integer. printErrorMsg 45 "$mmcmd" "$sub1" "$sub2" ;; "invalidRange") # Invalid range. printErrorMsg 78 "$mmcmd" "$sub1" "$sub2" "$sub3" "$sub4" ;; "absolutePath") # Parameter must be an absolute path name. printErrorMsg 148 "$mmcmd" "$sub1" ;; "absolutePath_2") # Parameter must be an absolute path name. printErrorMsg 424 "$mmcmd" "$sub1" "$sub2" ;; "device1") # Device name starts with a slash, but not /dev/. printErrorMsg 169 "$mmcmd" "$sub1" ;; "device2") # Device name contains a slash, but not in column 1. printErrorMsg 170 "$mmcmd" "$sub1" ;; "invalidAttrValuePair") # Invalid attribute on mmchconfig. : # No special message, usage will be printed shortly. ;; "incorrectSyntax") # Incorrect syntax. printErrorMsg 568 "$mmcmd" "$sub1" ;; "incorrectRange") # Incorrect range. printErrorMsg 569 "$mmcmd" "$sub1" "$sub2" ;; "obsoleteOption") # Invalid (old) option specified. printErrorMsg 19 "$mmcmd" "$sub1" ;; "badSeparator_notSemicolon") # Must use semi-colon as a separator. printErrorMsg 62 "$mmcmd" ;; "badSeparator_notDash") # Must use dash as a separator. printErrorMsg 61 "$mmcmd" ;; "help") # Show the usage message only. : # Usage will be printed shortly. ;; *) # unexpected code : # do nothing ;; esac # end of case "$reason" # If necessary, print the usage statement. if [[ $usageMsg -ne 0 ]] then # Some usage messages put out the command name more than once. if [[ $usageMsg = 287 || $usageMsg = 301 || $usageMsg = 374 || $usageMsg = 390 || $usageMsg = 413 || $usageMsg = 421 || $usageMsg = 425 || $usageMsg = 452 || $usageMsg = 458 || $usageMsg = 566 ]] then printErrorMsg $usageMsg "$mmcmd" "$mmcmd" elif [[ $usageMsg = 484 ]] then printErrorMsg $usageMsg "$mmcmd" "$mmcmd" "$mmcmd" elif [[ $usageMsg = 385 || $usageMsg = 388 ]] then printErrorMsg $usageMsg "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" elif [[ $usageMsg = 359 ]] then printErrorMsg $usageMsg "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" elif [[ $usageMsg = 249 ]] then printErrorMsg $usageMsg "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" "$mmcmd" else printErrorMsg $usageMsg "$mmcmd" fi # end of if [[ $usageMsg = 287 || ... fi # end of if [[ $usageMsg -ne 0 ]] cleanupAndExit } #----- end of function syntaxError ---------------------------- ########################################################################### # # Function: Called if there is an interrupt before changes are committed. # Removes temporary files and unlocks the sdr if necessary. # # Input: None # # Output: None # # Returns: Exits with code 2 # ########################################################################### function pretrap { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGpretrap ]] && set -x $mmTRACE_ENTER "$*" typeset ec=0 trap "" HUP INT QUIT KILL # Disable traps so we won't get interrupted. [[ -z $MMMODE ]] && determineMode # We come here if an interrupt was received and # no changes have been made to the sdrfs file. # Display any buffered error messages that might be there. [[ -s $errMsg ]] && $cat $errMsg 1>&2 printErrorMsg 20 $mmcmd $rm -f $GLOBAL_FILES $LOCAL_FILES if [[ $gpfsLocked = yes ]] then setRunningCommand null $primaryServer ec=$? if [[ $ec -ne 0 ]] then printErrorMsg 171 $mmcmd "function setRunningCommand" $ec fi fi [[ $envLocked = yes ]] && \ freeEnvLock >/dev/null envLocked=no [[ $sdrLocked = yes ]] && \ freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no trap - HUP INT QUIT KILL # Restore interrupts. exit 2 } #----- end of function pretrap -------------------------------- #################################################################### # # Function: Called if there is an interrupt to a command that # does not change system files. Removes temporary files # and unlocks the sdr if necessary. # # Input: None # # Output: None # # Returns: Exits with code 2 # #################################################################### function pretrap2 { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGpretrap2 ]] && set -x $mmTRACE_ENTER "$*" trap "" HUP INT QUIT KILL # Disable traps so we can finish this. [[ -z $MMMODE ]] && determineMode # Interrupt received. # Display any buffered error messages that might be there. [[ -s $errMsg ]] && $cat $errMsg 1>&2 printErrorMsg 306 $mmcmd $rm -f $GLOBAL_FILES $LOCAL_FILES [[ $envLocked = yes ]] && \ freeEnvLock >/dev/null envLocked=no [[ $sdrLocked = yes ]] && \ freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no trap - HUP INT QUIT KILL # Restore interrupts. exit 2 } #----- end of function pretrap2 ------------------------------- ######################################################################## # # Function: Called if there is an interrupt to a command that # does not change system files. Removes temporary files # and unlocks the sdr if necessary. # # This silent trap routine is used by mmcommon and mmremote. # # Input: None # # Output: None # # Returns: Exits with code 2 # ######################################################################## function pretrap3 { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGpretrap3 ]] && set -x $mmTRACE_ENTER "$*" trap "" HUP INT QUIT KILL # Disable traps so we can finish this. [[ -z $MMMODE ]] && determineMode # Interrupt received. $rm -f $GLOBAL_FILES $LOCAL_FILES [[ $envLocked = yes ]] && \ freeEnvLock >/dev/null envLocked=no [[ $sdrLocked = yes ]] && \ freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no trap - HUP INT QUIT KILL # Restore interrupts. exit 2 } #----- end of function pretrap3 ------------------------------- ########################################################################### # # Function: Called if there is an interrupt after changes were committed. # Removes temporary files and unlocks the sdr if necessary. # # Input: None # # Output: None # # Returns: Exits with code 2 # ########################################################################### function posttrap { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGposttrap ]] && set -x $mmTRACE_ENTER "$*" typeset ec=0 trap "" HUP INT QUIT KILL # Disable traps so we can finish this. [[ -z $MMMODE ]] && determineMode # Interrupt received: changes not propagated. # Display any buffered error messages that might be there. [[ -s $errMsg ]] && $cat $errMsg 1>&2 printErrorMsg 32 $mmcmd $rm -f $GLOBAL_FILES $LOCAL_FILES if [[ $gpfsLocked = yes ]] then setRunningCommand null $primaryServer ec=$? if [[ $ec -ne 0 ]] then printErrorMsg 171 $mmcmd "function setRunningCommand" $ec fi fi [[ $envLocked = yes ]] && \ freeEnvLock >/dev/null envLocked=no [[ $sdrLocked = yes ]] && \ freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no trap - HUP INT QUIT KILL # Restore interrupts. exit 2 } #----- end of function posttrap ------------------------------- #################################################################### # # Function: This function must be called before a command exits, # either because of an unrecoverable error, or because # processing is completed. The caller must issue all # error messages prior to calling this function. # # This function does not return to its caller. # # Input: $1 (optional) return code value to be used # $2 (optional) indicator not to unlock the sdr # # Output: None # # Returns: Default exit code is 1 unless a different value # is passed as a first parameter. # #################################################################### function cleanupAndExit # [ ] [ doNotUnlock ] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGcleanupAndExit ]] && set -x $mmTRACE_ENTER "$*" typeset doNotUnlock=$2 typeset rc=1 typeset ec=0 [[ -n $1 ]] && rc=$1 trap "" HUP INT QUIT KILL # Disable traps so we can finish this. if [[ $gpfsLocked = yes && -z $doNotUnlock ]] then setRunningCommand null $primaryServer ec=$? if [[ $ec -ne 0 ]] then printErrorMsg 171 $mmcmd "function setRunningCommand" $ec fi fi if [[ $envLocked = yes && -z $doNotUnlock ]] then freeEnvLock > /dev/null envLocked=no fi if [[ $sdrLocked = yes && -z $doNotUnlock ]] then freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no fi [[ $getCredCalled = yes ]] && \ freeCred $rm -f $GLOBAL_FILES $LOCAL_FILES >/dev/null 2>&1 $mmTRACE_EXIT "rc=$rc" exit $rc } #----- end of function cleanupAndExit ------------------------- #################################################################### # # Function: Verifies that a command executed successfully. # If the return code from the command is not zero, # the function issues a message, performs cleanup, # and stops processing. # # Input: $1 - name of the command to check # $2 - return code from the execution of the command # # Output: None # # Returns: 0 - command finished successfully # If error, no return; processing is stopped. # #################################################################### function checkForErrors # { if [ $2 != "0" ] then # Unexpected error printErrorMsg 171 "$mmcmd" "$1" $2 cleanupAndExit fi } #----- end of function checkForErrors ------------------------- #################################################################### # # Function: Issue message 278 (corrupted mmsdrfs file). # Invoke cleanupAndExit to terminate the command. # # Input: $1 - point of failure code # $2 - (optional) mmsdrfs line in error # # Output: Message 278, followed by the line in error. # # Returns: No return # #################################################################### function corruptedSdrFileExit # [ ] { typeset errCode=$1 typeset lineInError=$2 printErrorMsg 278 $mmcmd $errCode [[ -n $lineInError ]] && \ print -u2 "$lineInError" cleanupAndExit $errCode } #----- end of function corruptedSdrFileExit ------------------- ##################################################################### # # Function: Verifies that the value of an attribute is an integer. # If the value ends with a suffix k, K, m, M, g or G, it is # converted to a simple integer. If min and max values # are specified, the function verifies that the attribute # value is within that range. # # Input: $1 - attribute name (needed for messages) # $2 - attribute value # $3 - minimum allowed value (optional) # $4 - maximum allowed value (optional) # # Output: The converted attribute value # # Returns: 0 - Attribute value is legitimate # 1 - (via cleanupAndExit) Attribute value is not valid # ##################################################################### function checkIntRange # [ ] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGcheckIntRange ]] && set -x $mmTRACE_ENTER "$*" typeset attribute=$1 typeset attrValue=$2 typeset minValue=$3 typeset maxValue=$4 typeset -l value=$attrValue typeset -l low=$minValue typeset -l high=$maxValue typeset rc=0 typeset -i result min max # Verify that the input value is an integer. # Convert if value has a k, K, m, M, g or G suffix. if [[ $value = k || $value = m || $value = g ]] then rc=1 elif [[ $value != ${value%g} ]] then [[ -z ${value%%*([0-9])g} ]] && result=${value%g}*1073741824 || rc=1 elif [[ $value != ${value%m} ]] then [[ -z ${value%%*([0-9])m} ]] && result=${value%m}*1048576 || rc=1 elif [[ $value != ${value%k} ]] then [[ -z ${value%%*([0-9])k} ]] && result=${value%k}*1024 || rc=1 else [[ -z ${value%%*([0-9])} ]] && result=$value || rc=1 fi if [[ $rc -ne 0 ]] then # Invalid integer printErrorMsg 40 $mmcmd "$attribute" "$attrValue" cleanupAndExit fi # If range checking required, account for any k, K, m, or M suffixes. if [[ -n $minValue ]] then # Account for any k, K, m, or M suffixes in minValue or maxValue. # Since these are not user input, there should be no errors. if [[ $low != ${low%m} ]] then [[ -z ${low%%*([0-9])m} ]] && min=${low%m}*1048576 || rc=1 elif [[ $low != ${low%k} ]] then [[ -z ${low%%*([0-9])k} ]] && min=${low%k}*1024 || rc=1 else [[ -z ${low%%*([0-9])} ]] && min=$low || rc=1 fi checkForErrors checkIntRange_min $rc fi # end if [[ -n $minValue ]] if [[ -n $maxValue ]] then if [[ $high != ${high%m} ]] then [[ -z ${high%%*([0-9])m} ]] && max=${high%m}*1048576 || rc=1 elif [[ $high != ${high%k} ]] then [[ -z ${high%%*([0-9])k} ]] && max=${high%k}*1024 || rc=1 else [[ -z ${high%%*([0-9])} ]] && max=$high || rc=1 fi checkForErrors checkIntRange_max $rc fi # end if [[ -n $maxValue ]] # Ensure that value is within the specified range. if [[ -n $maxValue ]] then # Make sure that value is within the specified range. if [[ $result -lt $min || $result -gt $max ]] then # Value is out of range. printErrorMsg 78 $mmcmd "$attribute" "$minValue" "$maxValue" "$attrValue" cleanupAndExit fi elif [[ -n $minValue ]] then # Make sure that value is greater than the minimum required. if [[ $result -lt $min ]] then # Value is out of range. printErrorMsg 97 $mmcmd "$attribute" "$minValue" "$attrValue" cleanupAndExit fi else : # nothing to do. fi # end if [[ -n $maxValue ]] # Everything looks OK, return the result. print -- "$result" return 0 } #----- end of function checkIntRange -------------------------- ############################################################################### # # Function: Check that a name does not violate any of the naming rules # about length or prohibited characters. # # Input: nameType - type of name being checked # maxLength - maximum length of the name # name - name to be checked # # Output: none # # Returns: 0 if the name is ok; non-zero otherwise # ############################################################################### function checkName # { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGcheckName ]] && set -x $mmTRACE_ENTER "$*" typeset nameType=$1 typeset maxLength=$2 typeset name="$3" typeset length typeset bannedFromAllNames=',:; "' # includes blank and a tab char typeset bannedFromDeviceNames=']/?$&*()' typeset bannedFromDiskNames='].<>{}/\?`~!@#$%^&*()+=\\-' typeset rc=0 # Return with success if the passed name is null. [[ -z $name ]] && return 0 # Return with a non-zero return code if the name is too long. length=${#name} if [[ length -gt maxLength ]] then # The name is too long. printErrorMsg 548 $mmcmd '"'"$name"'"' $maxLength return 1 fi # If only checking the length of the string, we are done. [[ $nameType = lengthCheckOnly ]] && return 0 # Check if any of the common banned characters are present in the name; # the single-quote character must be tested for explicitly. [[ "$name" = *+([${bannedFromAllNames}])* || "$name" = *"'"* ]] && rc=1 # Additional, name-specific checking. case $nameType in poolName | junctionName | filesetName ) [[ "$name" = *+([${bannedFromDeviceNames}])* || "$name" = *"["* ]] && \ rc=1 ;; deviceName ) [[ "${name##+(/)dev+(/)}" = *+([${bannedFromDeviceNames}])* || "$name" = *"["* ]] && \ rc=1 ;; diskName ) [[ "$name" = *+([${bannedFromDiskNames}])* || "$name" = *"["* ]] && \ rc=1 ;; * ) : # The name must be OK. ;; esac # end of case $nameType in # If a banned character was found, issue an appropriate message. if [[ $rc -ne 0 ]] then case $name in *\[* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '[' ;; *\]* ) printErrorMsg 189 $mmcmd '"'"$name"'"' ']' ;; *\.* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '.' ;; *\<* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '<' ;; *\>* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '>' ;; *\{* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '{' ;; *\}* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '}' ;; *\/* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '/' ;; *\?* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '?' ;; *\`* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '`' ;; *\~* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '~' ;; *\!* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '!' ;; *\@* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '@' ;; *\#* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '#' ;; *\$* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '$' ;; *\%* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '%' ;; *\^* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '^' ;; *\&* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '&' ;; *\** ) printErrorMsg 189 $mmcmd '"'"$name"'"' '*' ;; *\(* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '(' ;; *\)* ) printErrorMsg 189 $mmcmd '"'"$name"'"' ')' ;; *\+* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '+' ;; *\-* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '-' ;; *\=* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '=' ;; *\,* ) printErrorMsg 189 $mmcmd '"'"$name"'"' ',' ;; *\:* ) printErrorMsg 189 $mmcmd '"'"$name"'"' ':' ;; *\;* ) printErrorMsg 189 $mmcmd '"'"$name"'"' ';' ;; *\"* ) printErrorMsg 189 $mmcmd '"'"$name"'"' "\"" ;; *\'* ) printErrorMsg 189 $mmcmd '"'"$name"'"' "'" ;; *\\* ) printErrorMsg 189 $mmcmd '"'"$name"'"' '\' ;; *\ * ) printErrorMsg 189 $mmcmd '"'"$name"'"' 'blank character' ;; *\ * ) printErrorMsg 189 $mmcmd '"'"$name"'"' 'tab character' ;; esac # end of case $name in fi # end of if [[ $rc -ne 0 ]] return $rc } #----- end of function checkName ------------------------------ ######################################################################### # # Function: Verify that the user-supplied input file exists and # is not empty. Rewrite the file to ensure there are # no carriage-return characters and that it contains # a newline character at the end of the file. # # Input: $1 - name of the user-supplied input file # $2 - name of the file to create # # Output: None explicit. # # Returns: 0 - file is ok and successfully rewritten # non-zero - file does not exist, empty or unexpected error # ######################################################################### function checkUserFile # { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGcheckUserFile ]] && set -x typeset inputFile=$1 typeset newFile=$2 typeset operands # Verify input parameters. if [[ $# -lt 2 ]] then operands=" " printErrorMsg 260 checkIntRange "$operands" cleanupAndExit fi # Ensure the file exists and is not empty. if [[ ! -r $inputFile ]] then # We cannot open the file. printErrorMsg 43 $mmcmd $inputFile return 1 fi if [[ ! -s $inputFile ]] then # File is empty. printErrorMsg 329 $mmcmd $inputFile return 1 fi # Remove any carriage-return chareacters. # If the source and target file names are identical, # create a local working copy first. if [[ $inputFile = $newFile ]] then $cp $inputFile $tmpfile checkForErrors "checkUserFile: cp $inputFile $tmpfile" $? LC_ALL=C $tr -d "\r" < $tmpfile > $newFile checkForErrors "checkUserFile: tr -d <$tmpfile >$newFile" $? $rm -f $tmpfile else LC_ALL=C $tr -d "\r" < $inputFile > $newFile checkForErrors "checkUserFile: tr -d <$inputFile >$newFile" $? fi # If necessary, add a newline character at the end of the file. if [[ $(LC_ALL=C $tail -c 1 $newFile) != $(printf "\n") ]] then printf "\n" >> $newFile checkForErrors "writing to file $newFile" $? fi return 0 } #----- end of function checkUserFile ------------------ ############################################################################# # # Function: Determine what mode we are in (lc, single, ... ) and initialize # some global variables (primaryServer, backupServer, ... ). # # Input: none # # Output: The MMMODE environment variable is set to reflect mode. # The primaryServer and backupServer global variables are set. # The remote shell and file copy commands are reset to the user # specified path names. # # Returns: 0 in all cases # ############################################################################# function determineMode { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGdetermineMode ]] && set -x $mmTRACE_ENTER "$*" typeset versionLine="" typeset mmmode rshPath rcpPath if [[ -f $mmsdrfsFile ]] then # If the mmsdrfs file exists, parse the file's version line. versionLine=$($head -1 $mmsdrfsFile) IFS=':' set -f ; set -- $versionLine ; set +f IFS="$IFS_sv" # Perform a quick sanity check. [[ $2 != 00_VERSION_LINE ]] && \ corruptedSdrFileExit 127 "$versionLine" # Retrieve the cluster type and other values. mmmode=$8 primaryServer=$9 backupServer=${10} rshPath=${12} rcpPath=${13} if [[ -n $rshPath && $rshPath != "_DEFAULT_" ]] then rsh="$rshPath" export GPFS_rshPath="$rshPath" fi if [[ -n $rcpPath && $rcpPath != "_DEFAULT_" ]] then rcp="$rcpPath" export GPFS_rcpPath="$rcpPath" fi environmentType=${15} [[ -z $environmentType ]] && environmentType=$mmmode [[ $mmmode != $environmentType && $environmentType != lc2 ]] && \ environmentType="rpd" else # Otherwise, we have no idea what to do. mmmode="" environmentType="" # Unknown GPFS execution environment printErrorMsg 338 $mmcmd $mmmode cleanupAndExit fi # end if [[ -f $mmsdrfsFile ]] # Make the environment variables globally available. export MMMODE=$mmmode export environmentType=$environmentType return 0 } #----- end of function determineMode -------------------------- ############################################################################# # # Function: Determine the value of the specified mmfs.cfg parameter. # # Input: $1 - mmfs.cfg parameter name. # The rest of the parameters are optional. # $2 - check daemon indicator. If the value is "yes" or # "checkDaemon", the function will first make a tsctl # call to determine the value from the running daemon. # The default is not to check the daemon. # $3 - short node name. Default is $ourShortName. # $4 - mmfs.cfg file to use. Default is /var/mmfs/etc/mmfs.cfg. # # Output: The value of the mmfs.cfg parameter or null. # # Returns: 0 - worked # 1 - unexpected error # # Examples: autoload=$(showCfgValue autoload) # pagepool=$(showCfgValue pagepool checkDaemon $shortName $mmfscfg) # ############################################################################# function showCfgValue # [ [ []]] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGshowCfgValue ]] && set -x $mmTRACE_ENTER "$*" typeset parm=$1 typeset checkDaemon=$2 typeset node=$3 typeset cfgFile=$4 typeset parmValue rc # Set default values. [[ $checkDaemon != yes && $checkDaemon != checkDaemon ]] && checkDaemon="" [[ -z $node ]] && node=$ourShortName [[ -z $cfgFile ]] && cfgFile=$mmfscfgFile [[ ! -f $cfgFile ]] && return 1 # If we need to determine the value of the parameter from the currently # running GPFS daemon, use the tsctl showCfgValue command. If this fails, # for whatever reason, determine the value from the specified config file. # Note that boolean type parameters have different representation in the # daemon than in the mmfs.cfg file. It is the callers responsibility to # do the necessary translation. if [[ -n $checkDaemon && $node = $ourShortName ]] then parmValue=$($tsctl showCfgValue $parm 2>/dev/null) rc=$? if [[ -n $parmValue && $rc -eq 0 ]] then print -- "$parmValue" return 0 fi fi # end of if [[ -n $checkDaemon ]] # Find the setting of the parameter from the specified config file. parmValue=$($awk ' \ BEGIN { doNotIgnoreValue = 1 } \ # If this is the end of a node-override section, \ # set the flag to accept parameter values. \ $1 == "[common]" { \ { doNotIgnoreValue = 1 } \ { next } \ } \ # If this is the start of a node-override section, \ # see if this section applies to our node. \ # If yes, we will not ignore subsequent parameters. \ # If not, subsequent parameters will be ignored. \ /^\[.*]/ || /^[ ]*\[.*]/ { \ if ($1 == "['$node']" || $1 ~ /\['$node',/ || \ $1 ~ /,'$node']/ || $1 ~ /,'$node',/) { \ { doNotIgnoreValue = 1 } \ } else { \ { doNotIgnoreValue = 0 } \ } \ { next } \ } \ # If this line contains our parameter, save its \ # value, provided it is applicable to our node. \ $1 == "'$parm'" && doNotIgnoreValue { \ { parmValue = $2 } \ } \ END { print parmValue } \ ' $cfgFile) checkForErrors awk $? print -- "$parmValue" return 0 } #----- end of function showCfgValue --------------------------- ############################################################################## # # Function: Given a device name or a mount point, this routine # returns information about the file system. # # Input: $1 - file system device name or mount point. # $2 - name of mmsdrfs file # $3 - (optional) keyword indicating whether device or # mount point is used. The default is deviceName. # $4 - (optional) suppress messages flag # # Output: $1 - fully-qualified device name (/dev/...) # $2 - short device name (no /dev/ prefix) # $3 - cluster where the file system is defined # $4 - name of the remote device (no /dev/ prefix) # $5 - "odd state" flag indicating whether disks may be in # an odd state (this can happen when a disk command # did not complete normally); "yes" indicates there # may be disks in an odd state, "no" indicates no # $6 - default mount point for the file system # $7 - default options string for the mount command # # Returns: 0 - file system found # 19 - file system not found (ENODEV) # nn - some other unexpected error # ############################################################################## function findFS # [{deviceName|mountPoint} []] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGfindFS ]] && set -x $mmTRACE_ENTER "$*" typeset inputValue=$1 typeset sdrfs=$2 typeset inputType=$3 typeset suppressMsg=$4 typeset rc=0 typeset device deviceName fqDeviceName cluster result remoteDevice typeset oddState defaultOptions defaultMountPoint # Determine what type of search this is going to be: # by device name or by mount point. if [[ $inputType != mountPoint ]] then # Find the file system using its device name. inputType=deviceName device=$inputValue deviceName=${device##+(/)dev+(/)} # Verify the device name. if [[ $deviceName = /* ]] then # Name starts with a slash, but not /dev/. [[ -z $suppressMsg ]] && printErrorMsg 169 $mmcmd "$device" return 1 elif [[ $deviceName = */* ]] then # Name contains a slash. [[ -z $suppressMsg ]] && printErrorMsg 170 $mmcmd "$device" return 1 else : # The device name seems to be OK. fi else # Find the file system using its mount point. mountPoint=$inputValue # Verify the mount point. if [[ $mountPoint != /* ]] then # Mount point can not be a relative path name. [[ -z $suppressMsg ]] && printErrorMsg 148 $mmcmd "$mountPoint" return 1 fi fi # end of if [[ $inputType != mountpoint ]] # Retrieve the needed information for the file system. result=$($awk -F: ' \ BEGIN { \ # Assume the file system does not exist. \ { fsFound = 0 } \ } \ \ $'$LINE_TYPE_Field' == "'$SG_HEADR'" { \ # Starting a new file system. Save some values in case \ # this turns out to be the fs that we are looking for. \ if ( $'$REMOTE_DEV_NAME_Field' != "" ) { \ { remoteDevName = $'$REMOTE_DEV_NAME_Field' } \ } else { \ { remoteDevName = $'$DEV_NAME_Field' } \ } \ if ( $'$ODD_STATE_Field' == "" || $'$ODD_STATE_Field' == "no" ) { \ { oddStateField = "no" } \ } else { \ { oddStateField = "yes" } \ } \ { fsType = $'$FS_TYPE_Field' } \ { deviceName = "" } \ { next } \ } \ \ $'$LINE_TYPE_Field' == "'$SG_ETCFS'" && \ $'$LINE_NUMBER_Field' == "'$MOUNT_POINT_Line'" { \ # This line contains both the device name and the mount point. \ # Match one of the two fields based on the type of search. \ if ( search == "deviceName" && $'$DEV_NAME_Field' == "'$deviceName'" || \ search == "mountPoint" && $'$ETCFS_TEXT_Field' == "'$mountPoint'" ) { \ { homeCluster = $'$NODESETID_Field' } \ { deviceName = $'$DEV_NAME_Field' } \ { mountPoint = $'$ETCFS_TEXT_Field' } \ { fsFound = 1 } \ } \ { next } \ } \ \ $'$LINE_TYPE_Field' == "'$SG_MOUNT'" && \ $'$DEV_NAME_Field' == deviceName { \ { options = $'$RW_OPT_Field' } \ if ( $'$MTIME_OPT_Field' != "" ) { \ { options = options ","$'$MTIME_OPT_Field' } \ } \ if ( $'$ATIME_OPT_Field' != "" ) { \ { options = options ","$'$ATIME_OPT_Field' } \ } \ if ( $'$OTHER_OPT_Field' != "" ) { \ { options = options ","$'$OTHER_OPT_Field' } \ } \ if ( $'$QUOTA_OPT_Field' != "" ) { \ { options = options ",quota="$'$QUOTA_OPT_Field' } \ } \ if ( fsType == "'$remotefs'" ) { \ { options = options ",dev="homeCluster":"remoteDevName } \ { options = options ",ldev="deviceName } \ } else { \ { options = options ",dev="deviceName } \ } \ { exit } \ } \ \ END { \ # If the file system was found, print the result. \ if ( fsFound ) { \ { print homeCluster " " \ deviceName " " \ remoteDevName " " \ oddStateField " " \ mountPoint " " \ options } \ } \ } \ ' search=$inputType $sdrfs) checkForErrors awk $? # If nothing was found, print "not found" message (if not suppressed) # and return. if [[ -z $result ]] then if [[ -z $suppressMsg ]] then if [[ $inputType = mountPoint ]] then # There is no file system with the specified mount point. printErrorMsg 279 $mmcmd "$mountPoint" else # There is no file system with the specified device name. printErrorMsg 288 $mmcmd "$device" fi fi return $MM_FsNotFound fi # end of if [[ -z $result ]] # If we are here, the file system exists; # parse the results of the awk. set -f ; set -- $result ; set +f cluster=$1 deviceName=$2 remoteDevice=$3 oddState=$4 defaultMountPoint=$5 defaultOptions=$6 fqDeviceName="/dev/$deviceName" # Output the data. print -- $fqDeviceName $deviceName $cluster $remoteDevice \ $oddState $defaultMountPoint $defaultOptions return 0 } #----- end of function findFS --------------------------------- ############################################################################ # # Function: Determine which nodes have the specified file systems mounted. # # Input: $1 - file system to check or: all, all_local, or all_remote # $2 - scope of mount checking (list of cluster names) # $3 - show output for individual nodes: yes, no, unformatted # $4 - (optional) assume cached data is current # # Output: lists of nodes that have the specified file systems mounted # # Returns: 0 - command completed successfully # non-zero - error encountered # ############################################################################ function lsmount # [norefresh] { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGlsmount ]] && set -x $mmTRACE_ENTER "$*" typeset fsToShow="$1" typeset scope="$2" typeset showNodes="$3" typeset -l refreshArg=$4 typeset rc=0 typeset oneCluster=false typeset hdrlineStripClusterName=no typeset nodelineStripClusterName=yes typeset fsToCheck fqDeviceName localDevName deviceName typeset fsList homeCluster headerMsg clusterName Coption typeset hdrLine linePrefix localCluster integer numNodes # If more than one file system is requested or the file system name # is not fully-qualified, ensure the local environment is up-to-date # and generate a list of the file systems. # Process the file system parameter. if [[ $fsToShow = all || $fsToShow = all_local || $fsToShow = all_remote || $fsToShow != *:* ]] then # Either more than one file system is requested, # or the file system name is not fully-qualified. # Ensure the local environment is up-to-date. if [[ $refreshArg != "norefresh" ]] then gpfsInitOutput=$(gpfsInit nolock) setGlobalVar $? $gpfsInitOutput fi # Generate a list of the fully-qualified file system names. fsList=$($awk -F: ' \ $'$LINE_TYPE_Field' == "'$SG_HEADR'" { \ if ( $'$DEV_NAME_Field' == "'$fsToShow'" ) { \ # This is the file system that we want. \ # See if the fs is local or remote. \ if ( $'$FS_TYPE_Field' == "'$remotefs'" ) { \ { printf $'$NODESETID_Field' ":" \ $'$REMOTE_DEV_NAME_Field' ":" \ $'$DEV_NAME_Field' } \ } else { \ { printf ":" $'$DEV_NAME_Field' ":" } \ } \ # Nothing else to do. \ { exit 0 } \ } else if ( "'$fsToShow'" == "all" ) { \ # We want all file systems, local and remote. \ if ( $'$FS_TYPE_Field' == "'$remotefs'" ) { \ { printf $'$NODESETID_Field' ":" \ $'$REMOTE_DEV_NAME_Field' ":" \ $'$DEV_NAME_Field' "," } \ } else { \ { printf ":" $'$DEV_NAME_Field' ":," } \ } \ \ } else if ( "'$fsToShow'" == "all_local" ) { \ # We want all local file systems. \ if ( $'$FS_TYPE_Field' == "'$remotefs'" ) { \ { next } \ } else { \ { printf ":" $'$DEV_NAME_Field' ":," } \ } \ \ } else if ( "'$fsToShow'" == "all_remote" ) { \ # We want all remote file systems. \ if ( $'$FS_TYPE_Field' == "'$remotefs'" ) { \ { printf $'$NODESETID_Field' ":" \ $'$REMOTE_DEV_NAME_Field' ":" \ $'$DEV_NAME_Field' "," } \ } else { \ { next } \ } \ } else { \ { next } \ } \ } \ END { printf "\n" } \ ' $mmsdrfsFile) checkForErrors awk $? # Strip trailing commas, if any. fsList=${fsList%%,} else # Only one file system was specified using its fully-qualified name. fsList=$fsToShow fi # end of if [[ $fsToShow = all || $fsToShow = all_local ... # Return if no file systems were found. if [[ -z $fsList ]] then if [[ $fsToShow = all || $fsToShow = all_local ]] then # No file systems were found in the cluster. printErrorMsg 200 $mmcmd elif [[ $fsToShow = all_remote ]] then # There are no remote file systems. printErrorMsg 193 $mmcmd else # The specified file system was not found. printErrorMsg 288 $mmcmd "$fsToShow" fi # end of if [[ $fsToShow = all || $fsToShow = all_local ]] # Give up. return $MM_FsNotFound fi # #end of if [[ -z $fsList ]] # If the user did not specify the -C parameter on mmlsmount, # see if this cluster has knowledge of other clusters or if it # has granted access to its file systems to remote clusters. # If neither is true, suppress the cluster name in the output. if [[ $scope = NULL ]] then oneCluster=$($awk -F: ' \ $'$LINE_TYPE_Field' == "'$AUTHORIZED_CLUSTER'" || \ $'$LINE_TYPE_Field' == "'$REM_CLUSTER'" { \ { print "false" } \ { exit } \ } \ END { print "true" } \ ' $mmsdrfsFile) checkForErrors awk $? fi # end of if [[ $scope = NULL ]] if [[ $showNodes = unformatted ]] then # Generate and print the header line. hdrLine="mmlsmount::HEADER:version:reserved:reserved" hdrLine="${hdrLine}:localDevName:realDevName:owningCluster" hdrLine="${hdrLine}:totalNodes:nodeIP:nodeName:clusterName" print -- "${hdrLine}:" # Generate the prefix for the data lines. linePrefix="mmlsmount::0:1::" # Find our cluster name (needed for the unformatted output). localCluster=$($head -1 $mmsdrfsFile | $GETVALUE $CLUSTER_NAME_Field) fi # end of if [[ $showNodes = yes ]] # Process the list of file systems. IFS=',' for fsToCheck in $fsList do # Parse the information for the file system to be checked. IFS=':' set -f ; set -- $fsToCheck ; set +f homeCluster=$1 deviceName=$2 localDevName=$3 if [[ -z $homeCluster || $homeCluster = $HOME_CLUSTER ]] then fqDeviceName="$deviceName" else fqDeviceName="${homeCluster}:${deviceName}" fi # Process the mount check scope parameter. IFS=',' for clusterName in $scope do IFS="$IFS_sv" # Determine the value for the -C option on tsstatus. if [[ $clusterName = all || $clusterName = NULL || $clusterName = $CHECK_ALL ]] then Coption="" else [[ $clusterName = "." || $clusterName = all_local ]] && \ clusterName=$($head -1 $mmsdrfsFile | $GETVALUE $CLUSTER_NAME_Field) Coption="-C $clusterName" fi # Determine whether to strip the cluster name from the header line # or from the node lines for each of the possible scenarios. # The normal case is to have the cluster name on the header line # and not on the node lines, but the behavior is different if the # -C was not specified or if a value of all or all_remote was given. # If -C was not specified and there is only one cluster, we will not # output cluster names. If all or all_remote was specified for -C, # we will not output cluster names on the header line, but we will # show cluster names on the node lines. if [[ $clusterName = NULL && $oneCluster = true ]] then hdrlineStripClusterName=yes nodelineStripClusterName=yes elif [[ $clusterName = NULL || $clusterName = all || $clusterName = all_remote ]] then hdrlineStripClusterName=yes nodelineStripClusterName=no else hdrlineStripClusterName=no nodelineStripClusterName=yes fi # Determine whether anybody has the file system mounted. LC_ALL=C $tsstatus -m $fqDeviceName $Coption >$tmpfile 2>$errMsg rc=$(remapRC $?) if [[ $rc -eq 0 ]] then # The file system is mounted on at least one of the nodes that # we care about. The list of node names is returned by tsstatus. # # Note that the tsstatus output comes from the stripe group # manager node which always resides in the cluster that owns # the file system. In the case of remote file systems, the # manager node has no knowledge about the local name for the # file system. Therefore, we have to intercept the tsstatus # output and replace the header line with one that is more # meaningful for the local cluster. To keep the code simple, # we do this for both local and remote file systems. # if [[ -s $tmpfile ]] then # Determine the number of nodes that have the file system mounted. # We subtract 2 because tsstatus produces a blank line and a header. numNodes=$($awk 'END { print NR - 2 }' $tmpfile) # Generate the output for this file system. if [[ $showNodes = yes ]] then # We come here if a list of the nodes should be shown. # Construct a message to be used in place of the first line # in the tsstatus output. If checking a remote file system, # the local device name can be passed as a command argument. if [[ $hdrlineStripClusterName = yes ]] then if [[ -n $localDevName ]] then headerMsg=$(printInfoMsg 521 \ "$localDevName" "($fqDeviceName)" "$numNodes") else headerMsg=$(printInfoMsg 522 "$fqDeviceName" "$numNodes") fi else if [[ -n $localDevName ]] then headerMsg=$(printInfoMsg 477 \ "$localDevName" "($fqDeviceName)" "$numNodes" "$clusterName") else headerMsg=$(printInfoMsg 478 \ "$fqDeviceName" "$numNodes" "$clusterName") fi fi # Filter the result from the tsstatus command and replace # the header line with our own version. $awk ' \ /File system/ && /is managed by node/ && /and mounted on:/ { \ { print "'"$headerMsg"'" } \ { next } \ } \ { if (stripClusterName == "yes") { \ { printf (" %-15s %s \n", $1, $2) } \ } else { \ { print $0 } \ } \ } \ ' stripClusterName="$nodelineStripClusterName" $tmpfile elif [[ $showNodes = unformatted ]] then # We come here if the information should be presented in # colon separated fields (mmlsmount -Y). [[ -z $localDevName ]] && localDevName="$deviceName" [[ -z $homeCluster ]] && homeCluster="$localCluster" $awk ' \ NR > 2 { print "'$linePrefix':'$localDevName':'$deviceName':" \ "'$homeCluster':'$numNodes':"$1":"$2":"$3":" } \ ' $tmpfile else # We come here if a list of the nodes is not desired. # Construct the summary message to be used in place of # the tsstatus output. If checking a remote file system, # the local device name can be passed as a command argument. if [[ $hdrlineStripClusterName = yes ]] then if [[ -n $localDevName ]] then printInfoMsg 553 "$localDevName" "($fqDeviceName)" "$numNodes" else printInfoMsg 554 "$fqDeviceName" "$numNodes" fi else if [[ -n $localDevName ]] then printInfoMsg 479 \ "$localDevName" "($fqDeviceName)" "$numNodes" "$clusterName" else printInfoMsg 480 "$fqDeviceName" "$numNodes" "$clusterName" fi fi fi else # tstatus -m returned no data. This should not be the case here. # Show error output, if any, and return. [[ -s $errMsg ]] && $cat $errMsg 1>&2 $rm -f $errMsg # Unexpected error. printErrorMsg 171 $mmcmd "function lsmount - no tsstatus output" 1 return 1 fi # end of if [[ -s $tmpfile ]] elif [[ $rc -eq 2 ]] then # The file system is not mounted on any of the nodes that # we are interested in. That's OK, just put out a message. rc=0 if [[ $showNodes = unformatted ]] then # We come here if the information should be presented in # colon separated fields (mmlsmount -Y). [[ -z $localDevName ]] && localDevName="$deviceName" [[ -z $homeCluster ]] && homeCluster="$localCluster" print -- "${linePrefix}:${localDevName}:${deviceName}:${homeCluster}:0::::" elif [[ -n $localDevName ]] then if [[ -z $Coption ]] then # The file system is not mounted. printInfoMsg 541 "$localDevName" "($fqDeviceName)" else if [[ $clusterName = all_remote ]] then # The file system is not mounted in any remote cluster. printInfoMsg 542 "$localDevName" "($fqDeviceName)" else # The file system is not mounted in the specified cluster. printInfoMsg 543 "$localDevName" "($fqDeviceName)" "$clusterName" fi fi else if [[ -z $Coption ]] then # The file system is not mounted. printInfoMsg 544 "$fqDeviceName" else if [[ $clusterName = all_remote ]] then # The file system is not mounted in any remote cluster. printInfoMsg 545 "$fqDeviceName" else # The file system is not mounted in the specified cluster. printInfoMsg 546 "$fqDeviceName" "$clusterName" fi fi fi # end of if [[ -n $localDevName ]] elif [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait ]] then # Unexpected error. Show error output, if any, and continue looping. if [[ -s $errMsg ]] then $cat $errMsg 1>&2 else [[ $rc -ne 0 ]] && \ printErrorMsg 113 "$mmcmd" "tsstatus -m $fqDeviceName $Coption" $rc fi $rm -f $errMsg # Command was unable to determine whether the file system is mounted. if [[ -n $localDevName ]] then printErrorMsg 564 $mmcmd "$localDevName" else printErrorMsg 564 $mmcmd "$fqDeviceName" fi else # GPFS is not ready on this node (rc is MM_DaemonDown or MM_QuorumWait). # Return quietly. $rm -f $errMsg return $rc fi # end of if [[ $rc -eq 0 ]] # We were able to successfully determine whether the file # system is mounted on any node in the current cluster. # Move to the next cluster in the list. $rm -f $errMsg IFS=',' done # end of for clusterName in $scope # Move to the next file system. IFS=',' done # end of for fsTocheck in $fsList IFS="$IFS_sv" # Return to the caller. return $rc } #----- end of function lsmount -------------------------------- ############################################################################# # # Function: Determine if a remote node can be reached. # # Input: $1 - node name (may be null) # Note: Do not add more input parameters. # This function can be called w/o input. # # Output: None # # Returns: 0 - node can be reached # 1 - node can not be reached # ############################################################################# function isNodeReachable # { typeset sourceFile="mmglobfuncs.sh" [[ -n $DEBUG || -n $DEBUGisNodeReachable ]] && set -x $mmTRACE_ENTER "$*" typeset nodeName=$1 typeset maxPingCount=3 typeset -i pingTimeout=4 typeset -i pingCount=0 typeset pingRc=1 while [[ $pingRc -ne 0 && $pingCount -lt $maxPingCount ]] do (( pingCount += 1 )) (( pingTimeout += 1 )) $ping -w $pingTimeout -c 1 $nodeName >/dev/null 2>/dev/null pingRc=$? # [[ $pingRc -ne 0 ]] && \ # print -u2 "$mmcmd: ping $nodeName failed ($pingCount); pingRc=$pingRc" done return $pingRc } #----- end of function isNodeReachable ------------------------ #################################################################### # # Function: Exec the specified command with the given argv[0] # # Input: $1 - command path # $2 - argv[0] # $3, $4, ... - arguments to pass to the command # # Output: depends on the executed command # # Returns: No return if the exec call succeded. # #################################################################### function mmexecl # [ ... ] { # First, we attempt to execute the given command with naked exec, # without involving the shell. A successful exec never returns. # If it does return, it means it failed, in which case we attempt # to execute the program again, this time using sh, to produce an # error message and an appropriate return code. $perl -e "{\ \$arg0=\$ARGV[0]; \ shift; \ exec \$arg0 @ARGV; \ exec \"sh -c \$arg0\"; \ }" "$@" return $? } #----- end of function mmexecl --------------------------------