Using scriptlib2 to build failsafe resource action scripts: Note: Writing resource scripts with scriptlib2 is not fundamentally different from writing them using the original scriptlib documented in the Failsafe Programmer's Guide, which you should read. In the case where this textfile is incomplete or leaves things less than fully specified, you may wish to refer to said document for clarification. ---- In scriptlib2 as opposed to scriptlib, requires only one script for all actions: all actions are handled within a single script. The necessary actions are: exclusive - verifies resource has _not_ started start - starts resource stop - stops resource monitor - verifies resource is still running properly restart - restarts the resource 'in place'.. ie on the same node. Your script will supply a single function, process_resource(), which is handed an action as well as a resource and its attendant data. Whether you handle this within the single function, branch out to subfucntions for clarity, use external programs, etc. is your choice. ---- Boiler plate: You should begin your scriptlib2 script with a skeleton similar to the following: --------resource_script.skel----------- #!/bin/bash # Scriptlib2 location if [ ! "$FAILSAFE_DIR" ]; then FAILSAFE_DIR=/usr/lib/failsafe; fi if [ ! "$SCRIPTLIB" ]; then SCRIPTLIB=$FAILSAFE_DIR/common_scripts/scriptlib2.sh; fi process_resource() { action=$1 resource_name=$2 resource_attributes=$3 # Add code to process the resource here } # Source and initialize the script library . $SCRIPTLIB # Do the work s2_execute --------resource_script.skel----------- The elements of this script are as follows: - Determine the location of scriptlib2. In the future, Failsafe should pass this location as an environment variable, so we determine if this location is already known, before setting it to the current location as a default. - Provide the code to handle the resources as a single function or set of functions, one which will be named process_resource() - Source scriptlib. This sets up the environment, verifies arguments, provides functions, and other sundry tasks. - Launch the resource handling machinery of scriptlib. This walks the list of resources, contacts the resource information daemon, and calls process_resourc() once for every resource to take action on. Clearly, the only part which the script writer should be concerned about is the second, process_resources which will contain the meat of the script. ---- process_resources is a shell function which will be called successively for each resource to be processed. It receives three arguments: 1 - the action to take on the resource 2 - the name of the resource 3 - a list of attribute data It is important to recognize that the third argument is a whitespace seperated list, and thus must be quoted with double quotes when used in a command line. process_resources must take the following steps, though not necessarily in this order. - Obtain any necessary attribute data from the resource_attributes parameter. - Determine the action type being requested. - Run the necessary commands to satisfy the action. - Return the result of the action. ---- Obtaining attribute data: Attributes should be obtained from the attribute list with the function s2_get_attribute_value(), which takes the following arguments - name of the attribute to obtain - attribute list [OPTIONAL] - flag indicating all attributes of said name should be returned examples: first_address=`s2_get_attribute_value Address "$resource_attributes"` all_addresses=`s2_get_attribute_value Address "$resource_attributes" all` In the first case, first_address would be set to the the first Address in resource_attributes. In the second case, all_addressses would be set to the a list of all Address attributes in resource_attributes. As the script writer for a resource type, you will know what attributes your resource uses. ---- Determine the action type being requested: One way of doing this is with a simple case statement, such as: case $action in start) # start code ;; stop) # stop code ;; . . . esac If you intend to use subroutines for each action, another way is more direct: resource_$action $resource_name ... Which would simply call other functions such as resource_start() and resource_stop(). The arguments passed of course are whatever makes sense for the script. ---- Run the necessary commands to satisfy the action: These commands are primarily resource-specific of course, but there are three functions worth bringing up here. s2_run_command() Arguments COMMAND - the actual text to run Command Description - a textual description of the action This function will run the command for you, logging the output in case of error, and logging the action when the loglevel is set to DEBUG or higher. Standard error and standard out of COMMAND are sent to standard error and out of of s2_run_command. Likewise the exit code of s2_run_command will be the exit code of COMMAND. As a special option, a switch '-u ' may be passed to s2_run_command which instructs it to run the command as the user specified. In thise case, the exit code of s2_run_command will be HA_CMD_FAILED if the attempt to become the splecified user fails. example: s2_run_command "ifconfig down $interface" "Shutting down interface $interface" s2_log() Writes a message, with timestamping etc. to the logging facility example: s2_log "Determined the frobnicator is broken, autocorrecting" s2_log_debug() Writes a message, with timestamping etc. to the logging facility if the loglevel is set to DEBUG example: s2_log_debug "frobnicator level: $frob_level" There are other executable commands provided by the Failsafe environment which you may find useful. Refer to other Failsafe docs for this information. ---- Return the result: The results of the action are returned to failsafe through another provided shell function: s2_write_resource_status() Arguments: Status - resulting status of the action Names - a list of resouces for which this status applies Usually 'Names' will have a single resource name, but multiples can be used. In the case of almost every command, Status will be one of: $HA_SUCCESS - for success $HA_CMD_FAILED - for failure except for the `exclusive` action, in which case you should one of: $HA_NOT_RUNNING - when it is not running $HA_RUNNING - when it is running example: s2_write_resource_status $HA_SUCCESS $resource_name ---------------------- Packaging the resource type and making it available to FailSafe. The failsafe interface specifies the following things about a resource type: - It will be in a directory named for the resource type. - It will have files for each action: start, stop, exclusive, monitor, restart - It will have a create_resource script which runs the appropriate commands to add the resource to the cluster configuration database. If you know your resource type name, step one is easy. Eg. if your resource is called 'oracle_database', create a directory called 'oracle_database'. Place your script in this directory. It need not have any particular name. In this case I will pretend the name is 'action_script' Create symbolic links to your script from each of the action names. eg: cd oracle_database ln -s action_script start ln -s action_script stop ln -s action_script exclusive ln -s action_script monitor ln -s action_script restart The create_resource script is not strictly necessary, as you can manually add a definition of the resource to FailSafe, but if it exists it will be manually run when the FailSafe configuration database is rebuilt, so is a good idea. Unfortunately, I don't currently know how to do this properly. Consider copying this script from another resource and modifying it. Or ask on the failsafe mailing list, etc.