Archives

Categories

Heartbeat service scripts

A service script for Heartbeat needs to support at least three operations, start, stop, and status. The operations will return 0 on success, 7 on failure (which in the case of the monitor script means that the service is not running) and any other value to indicate that something has gone wrong.

In the second half of this post (not in the feed) I have included an example service script. It is a very brief script and does not support some of the optional parameters (monitor, validate-all, and meta-data). So this script is not of a quality that would be accepted for inclusion in a Heartbeat release but is adequate to demonstrate the concepts.

The XML configuration for a service can have an arbitrary set of name-value pairs, and they are passed to the script as environment variables. For example the below script expects that the XML configuration item named ip will have the IP address used by the service, my script receives this as a variable named OCF_RESKEY_ip. My script doesn’t use the address, it merely allows it to be inherited by the IPaddr2 script (which is part of the Heartbeat distribution) and that script assigns the address to an Ethernet interface.

The script is for testing Heartbeat, it mounts a filesystem and starts Apache (which is configured to serve web pages from the filesystem in question on the IP address supplied by the ip parameter).

For test purposes the script looks for a file named /root/fail, if this file exists then the status check will always abort. An aborting status script means that Heartbeat can not be certain that the node in question has released all resources that it was using for the service. This means that Heartbeat will have to kill the node via the STONITH service. Such test scripts are the only way to test that STONITH works, and I believe that it’s a necessary part of pre-production testing of a Heartbeat cluster.

Update: Made it display error messages in all cases and also reformatted it for better cut/paste.

#!/bin/bash
case "$1" in
  start)
# the OCF_RESKEY_ip variable is passed in from Heartbeat and used by the
# IPaddr2 script to assign an address to an existing interface
    if ! /usr/lib/ocf/resource.d/heartbeat/IPaddr2 start ; then
      echo "Can't allocate IP address" >&2
      exit 7
    fi
    if ! mount /dev/hdc /var/www || ! /etc/init.d/apache2 start ; then
      umount /var/www
      echo "Can't mount /var/www" >&2
      exit 7
    fi
  ;;
  stop)
    /etc/init.d/apache2 stop
# fuser -km on the root filesystem kills everything, so check that
# something is mounted first
    if grep -q /var/www /proc/mounts ; then
      fuser -km /var/www
# sleep 250ms for the kill signals to be processed
      sleep 0.25
      umount /var/www
    fi
    /usr/lib/ocf/resource.d/heartbeat/IPaddr2 stop
    exit 0
  ;;
  status)
# as this is an example script if the file /root/fail exists then
# abort to trigger STONITH
    if [ -e /root/fail ]; then
      echo "forced failure" >&2
      exit 2
    fi
    if ! grep -q /var/www /proc/mounts ; then
      echo "filesystem not mounted" >&2
      exit 7
    fi
# www.example.com is in /etc/hosts – if this doesn't resolve then
# the service fails over so we don't want to use DNS
    if wget http://www.example.com/ -O /dev/null 2> /dev/null ; then
      exit 0
    else
      echo "HTTP not active" >&2
      exit 7
    fi
  ;;
esac

1 comment to Heartbeat service scripts