9.4. Specifying a master preference

Stateful (master/slave) resources must set their own master preference — they can thus provide hints to the cluster manager which is the the best instance to promote to the Master role.

[Important]Important

It is acceptable for multiple instances to have identical positive master preferences. In that case, the cluster resource manager will automatically select a resource agent to promote. However, if all instances have the (default) master score of zero, the cluster manager will not promote any instance at all. Thus, it is crucial that at least one instance has a positive master score.

For this purpose, crm_master comes in handy. This convenience wrapper around the crm_attribute sets a node attribute named master-$OCF_RESOURCE_INSTANCE for the node it is being executed on, and fills this attribute with the specified value. The cluster manager is then expected to translate this into a promotion score for the corresponding instance, and base its promotion preference on that score.

Stateful resource agents typically execute crm_master during the monitor and/or notify action.

The following example assumes that the foobar resource agent can test the application’s status by executing a binary that returns certain exit codes based on whether

foobar_monitor() {
    local rc

    # exit immediately if configuration is not valid
    foobar_validate_all || exit $?

    ocf_run frobnicate --test

    # This example assumes the following exit code convention
    # for frobnicate:
    # 0: running, and fully caught up with master
    # 1: gracefully stopped
    # 2: running, but lagging behind master
    # any other: error
    case "$?" in
        0)
            rc=$OCF_SUCCESS
            ocf_log debug "Resource is running"
            # Set a high master preference. The current master
            # will always get this, plus 1. Any current slaves
            # will get a high preference so that if the master
            # fails, they are next in line to take over.
            crm_master -l reboot -v 100
            ;;
        1)
            rc=$OCF_NOT_RUNNING
            ocf_log debug "Resource is not running"
            # Remove the master preference for this node
            crm_master -l reboot -D
            ;;
        2)
            rc=$OCF_SUCCESS
            ocf_log debug "Resource is lagging behind master"
            # Set a low master preference: if the master fails
            # right now, and there is another slave that does
            # not lag behind the master, its higher master
            # preference will win and that slave will become
            # the new master
            crm_master -l reboot -v 5
            ;;
        *)
            ocf_log err "Resource has failed"
            exit $OCF_ERR_GENERIC
    esac

    return $rc
}