#!/bin/ksh93 # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/usr/sbin/cluster/sa/nfs/sbin/clca_nfsutil.sh 1.9 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2007,2014 # 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 # @(#)65 1.9 src/43haes/usr/sbin/cluster/sa/nfs/sbin/clca_nfsutil.sh, hacmp.assist, 61haes_r714, 1449A_hacmp714 11/21/14 14:03:21 # Load the common clmgr/clvt functions library . /usr/es/lib/ksh93/func_include ## ## Name: clca_nfsutil ## ## Purpose: A generic utility script used by the NFS configuration assistant ## and various NFS related SMIT stanzas. ## ## Commands: ## ## addrg: ## ## Used by the configuration assistant to add a new RG with NFS exports. ## ## Usage: ## clca_nfsutil addrg -R -P ## -T -I ## -V -n ## -N -C ## -S ## -p ## ## Return: ## 0 - Success. ## non-zero - Failure ## ## ## modrg: ## ## Used by the configuration assistant to view/modify an existing RG ## with NFS exports. ## ## Usage: ## clca_nfsutil modrg -R -I ## -V -n ## -N -C ## -S ## -p ## ## Return: ## 0 - Success. ## non-zero - Failure ## ## ## delrg: ## ## Used by the configuration assistant to delete a RG with NFS exports. ## ## Usage: ## clca_nfsutil delrg ## ## Arguments: ## Resource Group Name. ## ## Return: ## 0 - Success. ## non-zero - Failure ## ## ## SMIT stanza helper commands. ## ## add_discover ## ## Used to discover SMIT screen entries for the configuration assistant's ## add screen. ## ## Usage: clca_nfsutil add_discover ## ## ## modify_discover ## ## Used to discover SMIT screen entries for the configuration assistant's ## view/change screen. ## Usage: clca_nfsutil modify_discover ## ## ## nfs_rgs ## List all the Resource Groups in that cluster that has any NFS exports. ## ## Usage: clca_nfsutil nfs_rgs ## function clca_nfs_usage { dspmsg -s 22 scripts.cat 13 "\nUsage:\n\tclca_nfsutil addrg -R -P -T -I -V -n -N -C -S -p \n\tclca_nfsutil modrg -R -I -V -n -N -C -S -p \n\tclca_nfsutil delrg \n\tclca_nfsutil add_discover\n\tclca_nfsutil modify_discover\n\tclca_nfsutil nfs_rgs\n\tclca_nfsutil list_ips\n" } # Function: # checkClusterNodes # # Purpose: # Is the node valid (exists as part of the HACMP cluster) # # Arguments: # (*) - list of nodes # # Returns: # 0 on success # 1 on failure # function checkClusterNodes { typeset nodelist="$@" typeset confNodes=$($CLVT query node) typeset missingNodes="" typeset -i rc=0 for a in $nodelist; do found=0 for b in $confNodes; do if [[ "$a" == "$b" ]]; then found=1 fi done if (( $found != 1 )); then missingNodes="$a $missingNodes" rc=1 fi done [[ $rc != "0" ]] && dspmsg -s 22 scripts.cat 8 "$PROGNAME: Following nodes are specified, but they are not part of the cluster. \n\t $missingNodes \nPlease check the cluster configuration.\n" $PROGNAME $missingNodes return $rc } # Function: # clca_list_ips # # Purpose: # To get the list of free service IPs or possible service IPs. # # Returns: # IP Labels. # function clca_list_ips { ExistingServiceIPs=$(KLIB_HACMP_get_unused_service_labels) typeset host tmp ip typeset -A labelXip for label in $ExistingServiceIPs; do /usr/bin/host "$label" | read host tmp ip ip=${ip//[\(\)]/} label=${label/\.*/} labelXip[$label]="$ip" done # # Print out discovered labels, if they're not already part of the # defined HACMP service labels # /usr/es/sbin/cluster/utilities/cl_harvestIP_scripts -a19 | grep -v none | sort -u | while read label ip; do ip=${ip//[\(\)]/} label=${label/\.*/} labelXip[$label]="$ip" done for label in $( for label in ${!labelXip[*]}; do echo $label done | sort); do ip=${labelXip[$label]} printf " %-35s (%s)\n" $label $ip done return 0 } # # Function: # createStableStorage # # Purpose: # Creates a filesystem for the stable storage # # Arguments: # List of volume groups associated with the resource group. # # Output: # Filesystem mount point that is just created. # # Return: # Success - 0 # Failure - non-zero exit # function createStableStorage { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset RG=$1 typeset SVGS=$2 typeset ret=1 MOUNT_HEAD="/.SS" # Go through the available VGs and create SS on the first possible one. for vg in $SVGS; do typeset MOUNT_POINT="$MOUNT_HEAD/$vg" # Bug in cl_crlvfs causing the first FS creation to fail partially. # Work around is to create a dummy, work-around FS, then our SS-FS, # after that delete the work-around FS. typeset WORK_AROUND_MOUNT_POINT="$MOUNT_HEAD/.work_around/$vg" # Check if there is a FS at this mnt point.. if so let us use it. vg_fs=$(/usr/sbin/lsvgfs "$vg") for fs in $vg_fs; do [[ "$fs" == "$MOUNT_POINT" ]] && { SSLOCATION="$MOUNT_POINT" return 0 } done # Save and clear any debug/verbose logging while calling cl_crlvfs. TMP_VERBOSE_LOGGING=$VERBOSE_LOGGING TMP_DEBUG=$_DEBUG unset VERBOSE_LOGGING unset _DEBUG # crfs expects size in the number of 512 blocks. # The intent here is to go for 512 MB. 512 * 1048576 = 512MB. export _CSPOC_CALLED_FROM_SMIT=true $CL_CRLVFS -cspoc "-g $RG" -v "jfs2" -g "$vg" -m "$WORK_AROUND_MOUNT_POINT" -p "rw" -a "size=1048576" ret="$?" unset _CSPOC_CALLED_FROM_SMIT if (( $ret == 0 )); then export _CSPOC_CALLED_FROM_SMIT=true $CL_CRLVFS -cspoc "-g $RG" -v "jfs2" -g "$vg" -m "$MOUNT_POINT" -p "rw" -a "size=1048576" # Save off the return value. ret="$?" unset _CSPOC_CALLED_FROM_SMIT # Now delete the work-around filesystem # It might have mounted, try to unmount it. # We don't want to fail the complete operation # even if we are not successful in getting rid of # this workaround FS, hence we won't check return values. /usr/sbin/umount "$WORK_AROUND_MOUNT_POINT" export _CSPOC_CALLED_FROM_SMIT=true $SMITLVM -9 "$RG" "$WORK_AROUND_MOUNT_POINT" -r unset _CSPOC_CALLED_FROM_SMIT fi # Restore debug/verbose logging. export VERBOSE_LOGGING=$TMP_VERBOSE_LOGGING export _DEBUG=$TMP_DEBUG if (( $ret == 0 )); then break; fi done # If ret is non-zero - we exhausted volume groups in trying to create # a new filesystem for stable storage. if [[ "$ret" != "0" ]]; then dspmsg -s 22 scripts.cat 2 "$PROGNAME: An attempt to create the Stable Storage Filesystem through cl_crlvfs failed. Please check cspoc.log for more information on the failure. If this failure is persistent, an explicit Stable Storage can be specified instead of opting for AUTO_SELECT.\n" $PROGNAME return 1 fi # Output the newly created Filesystem ; and return 0 SSLOCATION="$MOUNT_POINT" return 0 } # # Function: # getServiceNetwork # # Purpose: # Determine an appropriate network to place the service IP label # # Arguments: # (1) by reference - list of nodes to find interfaces for # # Output: # network name to place service IP label on # # Returns: # Success: Return 0 # Failure : Return non-zero value # function getServiceNetwork { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset NODES_ARG="$@" typeset NETWORKS=$($CLVT query network | sort -u) typeset validNetworks # List of valid networks in the cluster typeset -A netXnodeCount # Array to keep the count # Gather the list of valid networks. for network in $NETWORKS; do alias=$($CLVT query network $network | awk -F= '$1 ~ /ALIAS/ && $1 !~ /ALIAS_/ { print $2 }' | sed -e "s/\"//g") [[ "$alias" == "aliased" ]] && { # Add to the list validNetworks="$network $validNetworks" } done # Build a network_node array INTERFACES=$($CLVT query interface | sort -u) for interface in $INTERFACES; do node=$($CLVT query interface $interface | awk -F= '$1 ~ /NODE/ {print $2 }' | sed -e "s/\"//g") net=$($CLVT query interface $interface | awk -F= '$1 ~ /NETWORK/ {print $2 }' | sed -e "s/\"//g") [[ -n "$node" && -n "$net" ]] && { # Make the array. typeset -i count=${netXnodeCount[${net}_${node}]} (( count++ )) netXnodeCount[${net}_${node}]=$count } done typeset -i invalid=0 # Walk through the network_node array and findout the first network # for the nodes passed in. for network in $validNetworks; do invalid=0 for node in $NODES_ARG; do (( ${netXnodeCount[${network}_${node}]} == 0 )) && { invalid=1 } done (( $invalid == 0 )) && { echo $network return 0 } done return 1 } # Function: get_volume_groups # # Purpose: look up a list of all sharable volume groups # # Args: RG name # # Output: list of all VGs that could be shared by this group # # Return: # Success: Return 0 # Failure: Return Non-Zero # function get_volume_groups { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset GROUP="$1" typeset VGS typeset ret # clharvest_vg prints out additional debugging messages if _DEBUG is set. # clfind_shareable_vg does not parse these _DEBUG messages, so clear _DEBUG. typeset _DEBUG= # First harvest and populate the config dir. /usr/es/sbin/cluster/utilities/clharvest_vg -w >/dev/null 2>&1 || return 2 VGS=$(/usr/es/sbin/cluster/utilities/clfind_shareable_vg "$GROUP" -s) ret=$? # Exit if we can't find any VGs. if [[ "$ret" != "0" || -z "$VGS" ]]; then return 1 fi echo $VGS return 0 } # Function: # get_filesystems_for_export # # Purpose: # Return a list of filesystems on the specified VGs. Used for NFS exports. # # Args: List of VGs # # Output: list of non GEO Filesystems on those VGs # function get_filesystems_for_export { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset SS_PATH="$1" typeset VOLUME_GROUPS=$2 typeset FILE_SYSTEMS="" typeset TMP_LVs typeset ALL_LVs typeset LV typeset FS typeset gmd typeset PdDvLn for VG in $VOLUME_GROUPS; do TMP_LVs=$(odmget -q "name = $VG" CuDep | \ grep "dependency ="| awk -F= '{print $2}'|sed -e "s/\"//g") ALL_LVs="$ALL_LVs $TMP_LVs" done if (lslpp -l 'hageo.*' >/dev/null 2>&1 || lslpp -l 'geoRM.*' >/dev/null 2>&1) ; then # HAGEO is installed, take out HAGEO LVs. TMP_LVs="" for LV in $ALL_LVs; do PdDvLn="" gmd=$(odmget -q "attribute = local_device and value = /dev/r$LV" CuAt | grep 'name =' | cut -f3 -d' ' | tr -d '"') if [[ -n "$gmd" ]]; then PdDvLn=$(odmget -q "name = $gmd" CuDv |grep 'PdDvLn =' |cut -f3 -d' ' |tr -d '"') fi if [[ "$PdDvLn" != "geo_mirror/gmd/lgmd" ]]; then TMP_LVs="$TMP_LVs $LV" fi done ALL_LVs="$TMP_LVs" fi # Now get the filesystems on each LV for LV in $ALL_LVs; do FS=$(lslv -L ${LV} 2>/dev/null | awk '/^MOUNT POINT:/ {print $3}') if [[ $FS != "N/A" && -n $FS ]]; then case $SS_PATH in $FS) ;; # Exact match skip it. $FS/*) ;; #Stable storage is in this filesystem. Skip it. *) FILE_SYSTEMS="$FS $FILE_SYSTEMS";; esac fi done echo $FILE_SYSTEMS } # Function: # clca_addrg # # Purpose: # Add a resource group with NFS exports. # This is used by the NFS configuration assistant. # # Arguments: # R = '" # P = '' # T = '' # I = '' # V = '' # n = '' # N = '' # C = '' # S = '' # # Returns: # Success: Return 0 # Failure : exit non-zero value # function clca_addrg { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x # Get options from the command line. while getopts R:P:T:I:p:V:n:N:C:S: option do case $option in R ) RG_NAME=$OPTARG;; P ) PRIMARY=$OPTARG;; T ) TAKEOVER=$OPTARG;; I ) IP_LABEL=$OPTARG;; p ) PREFIX=$OPTARG;; V ) VGS=$OPTARG;; n ) NFSV2V3=$OPTARG;; N ) NFSV4=$OPTARG;; C ) CLNTMNT=$OPTARG;; S ) SSLOCATION=$OPTARG;; esac done # Basic Checks. # Check if the mandatory agruments are passed-in. if [[ -z $RG_NAME || -z $PRIMARY || -z $TAKEOVER || -z $IP_LABEL || -z $VGS ]]; then dspmsg -s 22 scripts.cat 4 "$PROGNAME: Essential arguments are missing.\n" $PROGNAME clca_nfs_usage exit 1 fi # Take care of value 'NONE' typeset -u TMP_NFSV4="$NFSV4" [[ "$TMP_NFSV4" == "NONE" ]] && NFSV4="" typeset -u TMP_NFSV2V3="$NFSV2V3" [[ "$TMP_NFSV2V3" == "NONE" ]] && NFSV2V3="" typeset -u TMP_CLNTMNT="$CLNTMNT" [[ "$TMP_CLNTMNT" == "NONE" ]] && CLNTMNT="" # IF NFSv4 exports are specified but no stable storage location; fail. if [[ "$NFSV4" && -z "$SSLOCATION" ]]; then dspmsg -s 22 scripts.cat 5 "$PROGNAME: Stable Storage is required for the NFSv4 exports.\n" $PROGNAME exit 2 fi # If stable storage location is specified but not the NFSv4 exports; ignore. if [[ -n "$SSLOCATION" && -z "$NFSV4" ]]; then # Ignore Stable Stoage and make it NULL SSLOCATION="" fi # If no NFS exports; We don't have any work to do - Exit. if [[ -z "$NFSV4" && -z "$NFSV2V3" ]]; then dspmsg -s 22 scripts.cat 6 "$PROGNAME: This configuration assistant is designed for adding NFS exports to the cluster. Exiting because, the user did not specify any NFS exports. \n" $PROGNAME exit 3 fi # # Check if the PRIMARY is present in SECONDARY, and if so take it out of # that list TMP_TAKEOVER=$TAKEOVER TAKEOVER="" for node in $TMP_TAKEOVER do [[ "$node" != "$PRIMARY" ]] && TAKEOVER="$TAKEOVER $node" done # Take out the leading space TAKEOVER=${TAKEOVER:1} # After cleaning, check if any nodes are left in TAKEOVER list. if [[ -z $TAKEOVER ]]; then dspmsg -s 22 scripts.cat 7 "$PROGNAME: Takeover list should have at least one node that is not the primary node.\n" $PROGNAME exit 4 fi # Determine if the cluster nodes entered are valid cluster nodes checkClusterNodes $PRIMARY $TAKEOVER if (( $? != 0 )); then exit 5 fi # Add a Resource Group to the cluster $CLVT add resource_group "$RG_NAME" \ PRIMARYNODES="$PRIMARY $TAKEOVER" \ STARTUP="OHN" \ FALLBACK="NFB" \ FALLOVER="FNPN" || { # ERROR: Failed to create resource group: $RG_NAME dspmsg -s 22 scripts.cat 9 "$PROGNAME: clvt add resource_group failed.\n" $PROGNAME exit 6 } # Process IP LABEL. serviceIP=$($CLVT query service_ip $IP_LABEL 2>/dev/null) [[ -z "$serviceIP" ]] && { # Create the service IP label, first find a network typeset nodes="$PRIMARY $TAKEOVER" network=$(getServiceNetwork "$nodes") [[ -z $network ]] && { dspmsg -s 22 scripts.cat 10 "$PROGNAME: Specified IP label is not a service IP label. Attempted to make it service IP label but, could not find an appropriate network to place it. Please check the network configuration.\n" $PROGNAME # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 7 } PREFIX_ARG="" [[ -n $PREFIX ]] && PREFIX_ARG="PREFIX=$PREFIX" $CLVT add service_ip $IP_LABEL NETWORK="$network" $PREFIX_ARG || { # ERROR: Unable to create service IP label: %s\n dspmsg -s 22 scripts.cat 11 "$PROGNAME: Specified IP label is not a service IP label. Attempted to make it service IP label but, clvt add service_ip failed.\n" $PROGNAME # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 8 } } # Process Volume Groups # If the user asked us to find "ALL" volume groups; get the list. # Otherwise, user should have given a list of VGs. # We will leave the validity checking job to the clvt. typeset -u VGS_UC="$VGS" if [[ $VGS_UC == 'ALL' ]]; then VGS=$( get_volume_groups "$RG_NAME" ) if (( $? != 0 )); then dspmsg -s 22 scripts.cat 3 "$PROGNAME: Could not detect any sharable volumes for the resource group : $RG_NAME\n" "$PROGNAME" "$RG_NAME" # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 9 fi fi # Make sure that rootvg is not part of the list. typeset TMP_VGS="$VGS" VGS="" for vg in $TMP_VGS; do [[ "$vg" != "rootvg" ]] && VGS="$VGS $vg" done # Takeout the leading space VGS=${VGS:1} # Add the list of VGs to the RG now. # We need to do this ahead of other resources, # as some of the VG related CSPOC # utilities depend on the fact that the VG is part of RG. $CLVT modify resource_group "$RG_NAME" \ VOLUME_GROUP="$VGS" \ VG_AUTO_IMPORT="false" \ FORCED_VARYON="false" || { typeset clvt_mod_ret=$? # Failed to modify the resource group $RG_NAME. dspmsg -s 22 scripts.cat 12 "$PROGNAME: clvt modify resource_group $RG_NAME failed.\n" $PROGNAME $RG_NAME # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 10 } # Process Stable Storage # If user asked us to create a Stable Storage through "AUTO_SELECT", # it is our job; or else user is expected to provide a stable storage path. # Validity/Sanity checks will be perofrmed in the later part of the # processing. typeset -u TMP_SSLOCATION=$SSLOCATION if [[ $TMP_SSLOCATION == 'AUTO_SELECT' ]]; then # The function createStableStorage creates and sets SSLOCATION variable. createStableStorage "$RG_NAME" "$VGS" if (( $? != 0 )); then # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 11 fi fi # Process export filesystems if [[ $TMP_NFSV2V3 == 'ALL' ]]; then NFSV2V3=$(get_filesystems_for_export "$SSLOCATION" "$VGS" ) fi if [[ $TMP_NFSV4 == 'ALL' ]]; then NFSV4=$(get_filesystems_for_export "$SSLOCATION" "$VGS" ) fi # Modify the resource group with additional attributes. $CLVT modify resource_group "$RG_NAME" \ SERVICE_LABEL="$IP_LABEL" \ VOLUME_GROUP="$VGS" \ VG_AUTO_IMPORT="false" \ FORCED_VARYON="false" \ FSCHECK_TOOL="fsck" \ FS_BEFORE_IPADDR="true" \ FILESYSTEM="" \ EXPORT_FILESYSTEM="$NFSV2V3" \ EXPORT_FILESYSTEM_V4="$NFSV4" \ MOUNT_FILESYSTEM="$CLNTMNT" \ STABLE_STORAGE_PATH="$SSLOCATION" || { typeset clvt_mod_ret=$? # Failed to modify the resource group $RG_NAME. dspmsg -s 22 scripts.cat 12 "$PROGNAME: clvt modify resource_group $RG_NAME failed.\n" $PROGNAME $RG_NAME # # We have failed. Delete the RG just created. # $CLVT delete resource_group $RG_NAME exit 12 } # Run verification. # clsapost -v equivallent. /usr/es/sbin/cluster/diag/clver -rt -C yes exit $? # Everything is good; let us go with dare. #/usr/es/sbin/cluster/utilities/cldare -rt -V 'normal' } # Function: # clca_modrg # # Purpose: # Modify a resource group with NFS exports. # This is used by the NFS configuration assistant. # # Arguments: # R = '" # I = '' # V = '' # n = '' # N = '' # C = '' # S = '' # # Returns: # Success: Return 0 # Failure : exit non-zero value # function clca_modrg { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x # Get options from the command line. while getopts R:P:T:I:p:V:n:N:C:S: option do case $option in R ) RG_NAME=$OPTARG;; P ) PRIMARY=$OPTARG;; T ) TAKEOVER=$OPTARG;; I ) IP_LABEL=$OPTARG;; p ) PREFIX=$OPTARG;; V ) VGS=$OPTARG;; n ) NFSV2V3=$OPTARG;; N ) NFSV4=$OPTARG;; C ) CLNTMNT=$OPTARG;; S ) SSLOCATION=$OPTARG;; esac done # Basic Checks. # Check if the mandatory agruments are passed-in. if [[ -z $RG_NAME || -z $IP_LABEL || -z $VGS ]]; then dspmsg -s 22 scripts.cat 4 "$PROGNAME: Essential arguments are missing.\n" $PROGNAME clca_nfs_usage exit 20 fi typeset -u TMP_NFSV4="$NFSV4" [[ "$TMP_NFSV4" == "NONE" ]] && NFSV4="" typeset -u TMP_NFSV2V3="$NFSV2V3" [[ "$TMP_NFSV2V3" == "NONE" ]] && NFSV2V3="" typeset -u TMP_CLNTMNT="$CLNTMNT" [[ "$TMP_CLNTMNT" == "NONE" ]] && CLNTMNT="" typeset -u TMP_SS_LOCATION="$SSLOCATION" [[ "$TMP_SS_LOCATION" == "NONE" ]] && SSLOCATION="" # Process Volume Groups # If the user asked us to find "ALL" volume groups; get the list. # Otherwise, user should have given a list of VGs. # We will leave the validity checking job to the clvt. typeset -u TMP_VGS=$VGS if [[ $TMP_VGS == 'ALL' ]]; then VGS=$( get_volume_groups "$RG_NAME" ) if (( $? != 0 )); then dspmsg -s 22 scripts.cat 3 "$PROGNAME: Could not detect any sharable volumes for the resource group : $RG_NAME\n" "$PROGNAME" "$RG_NAME" exit 21 fi fi # Make sure that rootvg is not part of the list. unset TMP_VGS typeset TMP_VGS=$VGS VGS="" for vg in $TMP_VGS; do [[ "$vg" != "rootvg" ]] && VGS="$VGS $vg" done # Takeout the leading space VGS=${VGS:1} # Process export filesystems if [[ $TMP_NFSV2V3 == 'ALL' ]]; then NFSV2V3=$(get_filesystems_for_export "$SSLOCATION" "$VGS" ) fi if [[ $TMP_NFSV4 == 'ALL' ]]; then NFSV4=$(get_filesystems_for_export "$SSLOCATION" "$VGS" ) fi eval $($CLVT query resource_group $RG_NAME | egrep $(echo $RESOURCES|tr ' ' '|')) EXPORT_FILESYSTEM_V4="$NFSV4" EXPORT_FILESYSTEM="$NFSV2V3" MOUNT_FILESYSTEM="$CLNTMNT" VOLUME_GROUP="$VGS" # Prepare arguments for clvt arg_resources="" for res in $RESOURCES; do eval value=\$$res [[ -z "$value" ]] && continue # Check and set value to NULL indicating all filesystems. [[ "$res" == "FILESYSTEM" && "$value" == "ALL" ]] && value="" tmp_string="$res=$value" arg_resources="$arg_resources $tmp_string" done # Modify the resource group. $CLVT modify resource_group "$RG_NAME" $arg_resources || { # ERROR: Failed to modify the resource group $RG_NAME. dspmsg -s 22 scripts.cat 12 "$PROGNAME: clvt modify resource_group $RG_NAME failed.\n" $PROGNAME $RG_NAME exit 22 } # # Run verification. /usr/es/sbin/cluster/diag/clver -rt -C yes exit $? } function clca_delrg { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x RG=$1 $CLVT delete resource_group "$RG" exit $? } # # Function: # clca_add_discover # # Input: # None # # Purpose: # Returns output suitable for NFS Configuration Assistant's Add screen. # # Output: # #primary # # function clca_add_discover { primary=$(/usr/es/sbin/cluster/utilities/get_local_nodename) echo '#primary' echo "$primary:" } # # Function: # clca_mod_discover # # Input: # None # # Purpose: # Returns output suitable for NFS Configuration Assistant's Change/Show # screen. # # Output # #rgname:primary:takeover:ip:vgs:v2_v3_exports:v4_exports:cmount:ss # < Corresponding values with : delimiter > # function clca_mod_discover { # Define local variables using typeset typeset primary takeover typeset RG SERVICE_LABEL VOLUME_GROUP typeset EXPORT_FILESYSTEM MOUNT_FILESYSTEM typeset MOUNT_FILESYSTEM STABLE_STORAGE_PATH # Automatically mark variables exported to the environment set -a RG=$1 eval $($CLVT query resource_group $RG | egrep $(echo $RESOURCES|tr ' ' '|')) set +a echo $NODES | read primary takeover [[ -z $EXPORT_FILESYSTEM ]] && EXPORT_FILESYSTEM="NONE" [[ -z $EXPORT_FILESYSTEM_V4 ]] && EXPORT_FILESYSTEM_V4="NONE" [[ -z $MOUNT_FILESYSTEM ]] && MOUNT_FILESYSTEM="NONE" [[ -z $STABLE_STORAGE_PATH ]] && STABLE_STORAGE_PATH="NONE" # Output in the format needed for the SMIT screen echo "#rgname:primary:takeover:ip:vgs:v2_v3_exports:v4_exports:cmount:ss" echo "$RG:$primary:$takeover:$SERVICE_LABEL:$VOLUME_GROUP:$EXPORT_FILESYSTEM:$EXPORT_FILESYSTEM_V4:$MOUNT_FILESYSTEM:$STABLE_STORAGE_PATH" } # # Function: # clca_list_nfs_rgs # # Input: # None # # Purpose: # Generates a list of resource groups in the system with NFS exports. # # Output: # List of resource groups with nfs exports. # function clca_list_nfs_rgs { typeset PS4_FUNC=$0 [[ "$VERBOSE_LOGGING" == "high" ]] && set -x odmget -q "name LIKE 'EXPORT_FILESYSTEM*'" HACMPresource | grep 'group = '| cut -d '"' -f2 | sort -u } #--------------------------------------------------------------------------- # Main Program #--------------------------------------------------------------------------- RESOURCES="DISK VOLUME_GROUP CONCURRENT_VOLUME_GROUP FILESYSTEM FSCHECK_TOOL \ RECOVERY_METHOD EXPORT_FILESYSTEM APPLICATIONS MOUNT_FILESYSTEM SERVICE_LABEL \ TAKEOVER_LABEL NFS_HOST \ AIX_CONNECTIONS_SERVICES COMMUNICATION_LINKS AIX_FAST_CONNECT_SERVICES \ SHARED_TAPE_RESOURCES FS_BEFORE_IPADDR FORCED_VARYON \ PRINCIPAL_ACTION ASSOCIATE_ACTION AUXILLIARY_ACTION VG_RR_ACTION \ SIBLING_NODES FOLLOWER_ACTION PPRC_REP_RESOURCE GMD_REP_RESOURCE \ ERCMF_REP_RESOURCE SVCPPRC_REP_RESOURCE VG_AUTO_IMPORT FS_BEFORE_IPADDR \ OEM_VOLUME_GROUP OEM_FILESYSTEM GMVG_REP_RESOURCE \ EXPORT_FILESYSTEM_V4 STABLE_STORAGE_PATH NODES WPAR_NAME" FPATH=/usr/es/lib/ksh93/hacmp CLVT=/usr/es/sbin/cluster/utilities/clvt CL_CRLVFS=/usr/es/sbin/cluster/sbin/cl_crlvfs SMITLVM=/usr/es/sbin/cluster/cspoc/smitlvm PROGNAME=$(basename $0) COMMAND=$1 export PS4='${GROUPNAME:-}:${PROGNAME:-}[${PS4_FUNC:-}+$LINENO] ' if [[ "$COMMAND" == "add_discover" || "$COMMAND" == "mod_discover" || "$COMMAND" == "nfs_rgs" ]]; then # These are SMIT commands, SMIT gets confused with the out put of set -x # So, explicitly disable the logging. VERBOSE_LOGGING="" fi [[ "$VERBOSE_LOGGING" == "high" ]] && set -x [[ "$VERBOSE_LOGGING" == "high" ]] && version='1.9' # Take care of no arguments case. if (( $# < 1 )) ; then clca_nfs_usage exit 1 fi shift case $COMMAND in addrg ) # # Add a new resource group with NFS exports. # clca_addrg "$@" ;; modrg ) # # Show/Change an existing resource group with NFS exports. # clca_modrg "$@" ;; delrg ) # # Delete a resource group with NFS exports. # clca_delrg "$@" ;; add_discover ) # # Fill-in the configuration assistant's add SMIT screen. # clca_add_discover ;; mod_discover ) # # Fill-in the configuration assistant's show/change SMIT screen. # clca_mod_discover "$@" ;; nfs_rgs ) # # Produce a list of resource groups with NFS exports. # clca_list_nfs_rgs ;; list_ips ) # # List IP LABELs. # clca_list_ips ;; * ) # Default clca_nfs_usage; exit 1; ;; esac exit 0 # End of script.