Using the SRM Script Library The /usr/lib/failsafe/common_scripts/scriptlib file contains the library of environment variables (beginning with uppercase HA_) and functions (beginning with lowercase ha_) available for use in your action scripts. script library scriptlib file Do not change the contents of the scriptlib file. This chapter describes functions that perform the following tasks, using samples from the scriptlib file: Linux FailSafe application interfaces Set global definitions Check arguments Read an input file Execute a command Write status for a resource Get the value for a field Get resource information Print exclusivity check messages Linux FailSafe application interfaces The Linux FailSafe application interface identifies resources by two strings: Resource name Resource type For example, a resource named vol1 of resource type volumes is identified by the following: vol1 volumes. Using the script library simplifies interaction with the interface. If you do not use the script library, you must understand the following file formats used by action scripts: Input file, which contains the list of resources that must be acted on by the executable; each resource must be specified on a separate line in the file. SRMD can also pass action flags for each resource in the input file. The format of a line in the input file is as follows (fields separated by white space): resource_name action_flags Output file, in which the executable writes the return the status of the each resource on a separate line using the following format (fields separated by white space): resource_name resource_status (optional) Input parameters file, which contains the name of the cluster: ClusterName clustername The following codes are defined in /usr/lib/failsafe/common_scripts/scriptlib : HA_SUCCESS HA_NOT_RUNNING HA_INVAL_ARGS HA_CMD_FAILED HA_RUNNING HA_NOTSUPPORTED HA_NOCFGINFO Set Global Definitions The ha_set_global_defs() function sets the global definitions for the environment variables environment variables shown in this section. global definition setting The HA_INFILE and HA_OUTFILE variables set the input and output files for a script. These variables do not have global definitions, and are not set by the ha_set_global_defs() function. Global Variable <literal>HA_HOSTNAME</literal> The output of the uname command with the -n option, which is the host name or nodename. The nodename is the name by which the system is known to communications networks. HA_HOSTNAME environment variable Default: `uname -n` Command Location Variables <literal>HA_CMDSPATH</literal> Path to user commands.HA_CMDSPATH environment variable path to user commands command path user command path uname command hostname nodename output Default: /usr/lib/failsafe/bin <literal>HA_PRIVCMDSPATH</literal> Path to privileged commands (those that can only be run by root).HA_PRIVCMDSPATH environment variable privileged command path root command path Default: /usr/lib/sysadm/privbin <literal>HA_LOGCMD</literal> Command used to log information. HA_LOGCMD environment variable Default: ha_cilog <literal>HA_RESOURCEQUERYCMD</literal> Resource query command. This is an internal command that is not meant for direct use in scripts; use the ha_get_info() function of scriptlib instead. HA_RESOURCEQUERYCMD environment variable resourcequery command Default: resourceQuery <literal>HA_SCRIPTTMPDIR</literal> Location of the script temporary directory. HA_SCRIPTTMPDIR environment variable Default: /var/run/failsafe/tmp Database Location Variables <literal>HA_CDB</literal> Location of the cluster configuration database. HA_CDB environment variable database location Default: /var/lib/failsafe/cdb/cdb.db Script Log Level Variables <literal>HA_NORMLVL</literal> Normal level of script logs. HA_NORMLVL environment variable Default: 1 <literal>HA_DBGLVL</literal> Debug level of script logs. HA_DBGLVL environment variable Default: 10 Script Log Variables <literal>HA_SCRIPTGROUP</literal> Log for the script group. HA_SCRIPTGROUP environment variable script group log Default: ha_script <literal>HA_SCRIPTSUBSYS</literal> Log for the script subsystem. HA_SCRIPTSUBSYS environment variable logs Default:script Script Logging Command Variables <literal>HA_DBGLOG</literal> Command used to log debug messages from the scripts. HA_DBGLOG environment variable debug script messages Default: ha_dbglog <literal>HA_CURRENT_LOGLEVEL</literal> The value of the current logging level. ha_log will only output messages if this value is greater than or equal to HA_NORMLVL . ha_dbglog will only output messages if this value is greater than or equal to HA_DBGLVL. Default: 2HA_CURRENT_LOGLEVEL environment variable <literal>HA_LOG</literal> Command used to log the scripts. HA_LOG environment variable Default: ha_log Script Error Value Variables <literal>HA_SUCCESS</literal> Successful execution of the script. This variable is used by the start, stop, restart, and monitor scripts. HA_SUCCESS environment variable Default: 0 <literal>HA_NOT_RUNNING</literal> The script is not running. This variable is used by exclusive scripts.HA_NOT_RUNNING environment variable Default: 0 <literal>HA_INVAL_ARGS</literal> HA_INVAL_ARGS environment variable An invalid argument was entered. This is used by all scripts. Default: 1 <literal>HA_CMD_FAILED</literal> A command called by the script has failed. his variable is used by the start, stop, restart, and monitor, scripts.HA_CMD_FAILED environment variable Default: 2 <literal>HA_RUNNING</literal> The script is running. This variable is used by exclusive scripts.HA_RUNNING environment variable Default: 2 <literal>HA_NOTSUPPORTED</literal> The specific action is not supported for this resource type. This is used by all scripts.HA_NOTSUPPORTED environment variable Default: 3 <literal>HA_NOCFGINFO</literal> No configuration information was found. This is used by all scripts.HA_NOCFGINFO environment variable Default: 4 Check Arguments An action script has the following arguments: an input file, HA_INFILE, an output file HA_OUTFILE, and an optional parameter file HA_PARAMFILE. These become the positional arguments to the script, $1, $2 and $3 parameter file is optional. check arguments The ha_check_args() function ha_check_args() function checks the arguments specified for a script and sets the $HA_INFILE and $HA_OUTFILE variables accordingly. If a parameter file exists, the ha_check_args() function reads the list of parameters from the file and sets the $HA_CLUSTERNAME variable. In the following, long lines use the continuation character ( \) for readability. ha_check_args()  { ${HA_DBGLOG} "$HA_SCRIPTNAME called with $1, $2 and $3" if ! [ $# -eq 2 -o $# -eq 3 ]; then ${HA_LOG} "Incorrect number of arguments" return 1; fi if [ ! -r $1 ]; then ${HA_LOG} "file $1 is not readable or does not exist" return 1; fi if [ ! -s $1 ]; then ${HA_LOG} "file $1 is empty" return 1; fi if [ $# -eq 3 ]; then HA_PARAMFILE=$3 if [ ! -r $3 ]; then ${HA_LOG} "file $3 is not readable or does not exist" return 1; fi HA_CLUSTERNAME=`/usr/bin/awk '{ if ( $1 == "ClusterName" ) \ print $2 }' ${HA_PARAMFILE}` fi HA_INFILE=$1 HA_OUTFILE=$2 return 0; } Read an Input File read an input file input file ha_read_infile() functionThe ha_read_infile() function reads the $HA_INFILE input file into the $HA_RES_NAMES variable, which specifies the list of resource names. ha_read_infile() { HA_RES_NAMES="";   for HA_RESOURCE in `cat ${HA_INFILE}` do HA_RES_NAMES="${HA_RES_NAMES} ${HA_RESOURCE}"; done } Execute a Command execute a command ha_execute_cmd() function command execution functionThe ha_execute_cmd() function executes the command specified by $HA_CMD, which is set in the action script. $1 is the string to be logged. The function returns 1 on error and 0 on success. On errors, the standard output and standard error of the command is redirected to the log file. ha_execute_cmd() { OUTFILE=${HA_SCRIPTTMPDIR}/script.$$ ${HA_DBGLOG} $1 eval ${HA_CMD} > ${OUTFILE} 2>&1; ha_exit_code=$?; if [ $ha_exit_code -ne 0 ]; then ${HA_LOG} "$1 failed" ${HA_LOG} `cat ${HA_SCRIPTTMPDIR}/script.$$` fi ${HA_DBGLOG} "${HA_CMD} exited with status $ha_exit_code"; rm ${OUTFILE} return $ha_exit_code; } ha_execute_cmd_ret() functionThe ha_execute_cmd_ret() function is similar to ha_execute_cmd, except that it places the command output in the string $HA_CMD_OUTPUT. ha_execute_cmd_ret() { ${HA_DBGLOG} $1 HA_CMD_OUTPUT=`${HA_CMD}`; ha_exit_code=$?; ${HA_DBGLOG} "${HA_CMD} exited with status $ha_exit_code"; return $ha_exit_code; } Write Status for a Resource write status for a resource ha_write_status_for_resource() functionThe ha_write_status_for_resource() function writes the status for a resource to the $HA_OUTFILE output file. $1 is the resource name, and $2 is the resource status. ha_write_status_for_resource() { echo $1 $2 >> $HA_OUTFILE; } ha_write_status_for_all_resources() functionSimilarly, the ha_write_status_for_all_resources() function writes the status for all resources. $HA_RES_NAMES is the list of resource names. ha_write_status_for_all_resources() { for HA_RES in $HA_RES_NAMES do echo $HA_RES $1 >> $HA_OUTFILE; done } Get the Value for a Field value for a field field value ha_get_field() functionThe ha_get_field() function obtains the field value from a string, where $1 is the string and $2 is the field name. The string format is a series of name-value field pairs, where a name field is followed by the value of the name, separated by whitespace. This appears as follows: ha_get_field() { HA_STR=$1 HA_FIELD_NAME=$2 ha_found=0; ha_field=1; for ha_i in $HA_STR do if [ $ha_field -eq 1 ]; then ha_field=0; if [ $ha_i = $HA_FIELD_NAME ]; then ha_found=1; fi else ha_field=1; if [ $ha_found -eq 1 ]; then HA_FIELD_VALUE=$ha_i return 0; fi fi done return 1; } Get the Value for Multiple Fields The ha_get_multi_fields() function obtains the field values from a string, where $1 is the string and $2 is the field name. The string format is a series of name-value field pairs, where a name field is followed by the value of the name, separated by whitespace. This function is typically used to extract dependency information. There may be multiple fields with the same name so the string returned in HA_FIELD_VALUE may contain multiple values separated by white space. This appears as follows: ha_get_multi_fields() { HA_STR=$1 HA_FIELD_NAME=$2 ha_found=0; ha_field=1; for ha_i in $HA_STR do if [ $ha_field -eq 1 ]; then ha_field=0; if [ $ha_i = $HA_FIELD_NAME ]; then ha_found=1; fi else ha_field=1; if [ $ha_found -eq 1 ]; then if [ -z "$HA_FIELD_VALUE" ]; then HA_FIELD_VALUE=$ha_i; else HA_FIELD_VALUE="$HA_FIELD_VALUE $ha_i"; fi; ha_found=0; fi fi done if [ -z "$HA_FIELD_VALUE" ]; then return 1; else return 0; fi } Get Resource Information resource information obtaining ha_get_info() functionThe ha_get_info() and ha_get_info_debug()functions read resource information. $1 is the resource type and $2 is the resource name, and $3 is an optional parameter of any value that specifies a request for resource dependency information . Resource information is stored in the HA_STRING variable. The return value of the query is passed back to the caller, 0 indicates success. All errors are logged. If the resourceQuery command fails, the HA_STRING is set to an invalid string, and future calls to ha_get_info() or ha_get_info_debug() return errors. The function ha_get_info_debug() differs from ha_get_info in that it will attempt the resource query a single time, instead of retrying as ha_get_info() would do. This is likely to be useful for testing due to faster returns and less complexity. You can call this function directly, or you can create the file /var/run/failsafe/resourceQuery.debug which will cause all invocations of ha_get_info() in all scripts on the node to be diverted to ha_get_info_debug() until the file is removed. ha_get_info() { if [ -f /var/run/failsafe/resourceQuery.debug ]; then ha_get_info_debug $1 $2 $3 return; fi if [ -n "$3" ]; then ha_doall="_ALL=true" else ha_doall="" fi # Retry resourceQuery command $HA_RETRY_CMD_MAX times if $HA_RETRY_CMD_ERR # is returned. ha_retry_count=1 while [ $ha_retry_count -le $HA_RETRY_CMD_MAX ]; do if [ -n "${HA_CLUSTERNAME}" ]; then HA_STRING=`${HA_PRIVCMDSPATH}/${HA_RESOURCEQUERYCMD} \ _CDB_DB=$HA_CDB _RESOURCE=$2 _RESOURCE_TYPE=$1 \ $ha_doall _NO_LOGGING=true _CLUSTER=${HA_CLUSTERNAME}` else HA_STRING=`${HA_PRIVCMDSPATH}/${HA_RESOURCEQUERYCMD} \ _CDB_DB=$HA_CDB _RESOURCE=$2 _RESOURCE_TYPE=$1 \ $ha_doall _NO_LOGGING=true` fi ha_exit_code=$? if [ $ha_exit_code -ne 0 ]; then ${HA_LOG} "${HA_RESOURCEQUERYCMD}: resource name $2 resource type $1" ${HA_LOG} "Failed with error: ${HA_STRING}"; fi if [ $ha_exit_code -ne $HA_RETRY_CMD_ERR ]; then break; fi ha_retry_count=`expr $ha_retry_count + 1` done if [ -n "$ha_doall" ]; then echo $HA_STRING \ | grep "No resource dependencies" > /dev/null 2>&1 if [ $? -eq 0 ]; then HA_STRING= else HA_STRING=`echo $HA_STRING | /bin/sed -e "s/^.*Resource dependencies //"` fi fi return ${ha_exit_code}; } ha_get_info_debug() { if [ -n "$3" ]; then ha_doall="_ALL=true" else ha_doall="" fi if [ -n "${HA_CLUSTERNAME}" ]; then HA_STRING=`${HA_PRIVCMDSPATH}/${HA_RESOURCEQUERYCMD} \ _CDB_DB=$HA_CDB _RESOURCE=$2 _RESOURCE_TYPE=$1 \ $ha_doall _CLUSTER=${HA_CLUSTERNAME}` else HA_STRING=`${HA_PRIVCMDSPATH}/${HA_RESOURCEQUERYCMD} \ _CDB_DB=$HA_CDB _RESOURCE=$2 _RESOURCE_TYPE=$1 $ha_doall` fi ha_exit_code=$? if [ $? -ne 0 ]; then ${HA_LOG} "${HA_RESOURCEQUERYCMD}: resource name $2 resource type $1" ${HA_LOG} "Failed with error: ${HA_STRING}"; fi if [ -n "$ha_doall" ]; then echo $HA_STRING \ | grep "No resource dependencies" > /dev/null 2>&1 if [ $? -eq 0 ]; then HA_STRING= else HA_STRING=`echo $HA_STRING | /bin/sed -e "s/^.*Resource dependencies //"` fi fi return ${ha_exit_code}; } Print Exclusivity Check Messages print exclusivity check messages ha_print_exclusive_status() functionThe ha_print_exclusive_status() function prints exclusivity check messages to the log file. $1 is the resource name and $2 is the exit status. ha_print_exclusive_status() { if [ $? -eq $HA_NOT_RUNNING ]; then ${HA_LOG} "resource $1 exclusive status: NOT RUNNING" else ${HA_LOG} "resource $1 exclusive status: RUNNING" fi } ha_print_exclusive_status_all_resources() functionThe ha_print_exclusive_status_all_resources() function is similar, but it prints exclusivity check messages for all resources. $HA_RES_NAMES is the list of resource names. ha_print_exclusive_status_all_resources() { for HA_RES in $HA_RES_NAMES do ha_print_exclusive_status ${HA_RES} $1 done }