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.
case "$1" in
# 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
if ! mount /dev/hdc /var/www || ! /etc/init.d/apache2 start ; then
echo "Can't mount /var/www" >&2
# 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
# 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
if ! grep -q /var/www /proc/mounts ; then
echo "filesystem not mounted" >&2
# 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
echo "HTTP not active" >&2