[Debian-ha-maintainers] Bug#858623: ocfs2-tools: Changed path to threshold file in /proc

Michal Svamberg svamberg at civ.zcu.cz
Fri Mar 24 15:40:27 UTC 2017


Package: ocfs2-tools
Version: 1.8.4-3
Severity: important

Dear Maintainer,

   * What led up to the situation?

Using package in Stretch to existing OCFS2 cluster with non-default hearbeat threshold.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?

Fixed path in /etc/init.d/o2cb script with this patch:

--- o2cb.orig   2016-10-21 18:39:00.000000000 +0200
+++ o2cb        2017-03-24 15:32:11.287654276 +0100
@@ -224,7 +224,7 @@
 set_timeouts_o2cb()
 {
     O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
-    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/dead_threshold
+    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/threshold
     if [ -n "$O2CB_HEARTBEAT_THRESHOLD" ]; then
         if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
             echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE"
@@ -259,7 +259,7 @@
 {
 
     O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
-    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/dead_threshold
+    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/threshold
     if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
         VAL=`cat "$O2CB_HEARTBEAT_THRESHOLD_FILE"`
         echo "  Heartbeat dead threshold: ${VAL}"


   * What was the outcome of this action?

Correct mounting ocfs2 volumes.


Thanks
Michal Svamberg

-- System Information:
Debian Release: 9.0
  APT prefers testing
  APT policy: (900, 'testing'), (400, 'unstable'), (350, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.9.0-2-amd64 (SMP w/8 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)

Versions of packages ocfs2-tools depends on:
ii  debconf [debconf-2.0]  1.5.60
ii  libaio1                0.3.110-3
ii  libc6                  2.24-9
ii  libcomerr2             1.43.4-2
ii  libdlm3                4.0.7-1
ii  libglib2.0-0           2.50.3-1
ii  libncurses5            6.0+20161126-1
ii  libreadline7           7.0-2
ii  libtinfo5              6.0+20161126-1
ii  libuuid1               2.29.1-1
ii  lsb-base               9.20161125
ii  psmisc                 22.21-2.1+b2

ocfs2-tools recommends no packages.

ocfs2-tools suggests no packages.

-- Configuration Files:
/etc/init.d/o2cb changed:
export LC_ALL=C
. /lib/lsb/init-functions
if [ $? != 0 ]
then
    echo "Unable to load LSB init functions" >&2
    exit 1
fi
CLUSTERCONF=/etc/ocfs2/cluster.conf
OCFS2_SYS_DIR="/sys/fs/ocfs2"
LOADED_PLUGINS_FILE="${OCFS2_SYS_DIR}/loaded_cluster_plugins"
CLUSTER_STACK_FILE="${OCFS2_SYS_DIR}/cluster_stack"
DLMFS_CAPABILITIES_FILE='/sys/module/ocfs2_dlmfs/parameters/capabilities'
DLMFS_DIR="/dlm"
DLMFS_MAGIC="76a9f425"
DEBUGFS_DIR="/sys/kernel/debug"
if [ -f /etc/sysconfig/o2cb ]
then
    # Red Hat and Novell
    CONFIGURATION=/etc/sysconfig/o2cb
elif [ -f /etc/default/o2cb ]
then
    # Debian
    CONFIGURATION=/etc/default/o2cb
    DPKGRECONF=yes
elif [ -d /etc/sysconfig ]
then
    CONFIGURATION=/etc/sysconfig/o2cb
else
    CONFIGURATION=/etc/default/o2cb
fi
BRINGUP_TIMEOUT=5
DEF_HEARTBEAT_THRESHOLD=31
DEF_IDLE_TIMEOUT_MS=30000
DEF_KEEPALIVE_DELAY_MS=2000
DEF_RECONNECT_DELAY_MS=2000
MIN_HEARTBEAT_THRESHOLD=7
MIN_IDLE_TIMEOUT_MS=5000
MIN_KEEPALIVE_DELAY_MS=1000
MIN_RECONNECT_DELAY_MS=2000
VERSION=1.8.4
[ -f "${CONFIGURATION}" ] && . "${CONFIGURATION}"
[ -z "$O2CB_STACK" ] && O2CB_STACK=o2cb
configfs_path()
{
    # Note that this is only valid *after* configfs is loaded
    if [ -d /sys/kernel/config ]
    then
        echo /sys/kernel/config
    else
        echo /config
    fi
}
touch_lockfile()
{
    if [ -d /var/lock/subsys ]
    then
        touch /var/lock/subsys/o2cb
    fi
}
remove_lockfile()
{
    if [ -e /var/lock/subsys/o2cb ]
    then
        rm /var/lock/subsys/o2cb
    fi
}
if_fail()
{
    RC="$1"
    REASON="$2"
    if [ "$RC" = "0" ]
    then
        echo "OK"
        return
    elif [ "$RC" = "2" ]
    then
        return
    fi
    echo "Failed"
    if [ -n "${REASON}" ]
    then
        echo "${REASON}" >&2
    fi
    exit 1
}
write_sysconfig()
{
    echo -n "Writing O2CB configuration: "
    cat >"${CONFIGURATION}" <<EOF
O2CB_ENABLED=${O2CB_ENABLED:-false}
O2CB_STACK=${O2CB_STACK}
O2CB_BOOTCLUSTER=${O2CB_BOOTCLUSTER}
O2CB_HEARTBEAT_THRESHOLD=${O2CB_HEARTBEAT_THRESHOLD}
O2CB_IDLE_TIMEOUT_MS=${O2CB_IDLE_TIMEOUT_MS}
O2CB_KEEPALIVE_DELAY_MS=${O2CB_KEEPALIVE_DELAY_MS}
O2CB_RECONNECT_DELAY_MS=${O2CB_RECONNECT_DELAY_MS}
EOF
    if [ $? != 0 ]
    then
        return 1
    fi
    return 0
}
read_timeout()
{
    if [ "$#" -lt "4" ]; then
        echo "read_timeout(): Requires more arguments" >&2
        exit 1
    fi
    ATTRIB_NAME=$1
    ATTRIB_VAL=$2
    MIN_ATTRIB_VAL=$3
    DEF_ATTRIB_VAL=$4
    RET_VAL=0
    while :
    do
        if [ -z $ATTRIB_VAL ]; then
            CUR=$DEF_ATTRIB_VAL
        else
            CUR=$ATTRIB_VAL
        fi
        echo -n "Specify ${ATTRIB_NAME} (>=$MIN_ATTRIB_VAL) [$CUR]: "
        read LINE
        case "$LINE" in
        "")
            RET_VAL="$ATTRIB_VAL"
            break
            ;;
        *[^0-9]*)
            echo "Invalid ${ATTRIB_NAME} value: $LINE" >&2
            ;;
        *)
            if [ $LINE -lt $MIN_ATTRIB_VAL ]; then
                echo "${ATTRIB_NAME} cannot be less than $MIN_ATTRIB_VAL" >&2
            else
                RET_VAL="$LINE"
                break
            fi
            ;;
        esac
    done
}
set_timeouts_o2cb()
{
    O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/threshold
    if [ -n "$O2CB_HEARTBEAT_THRESHOLD" ]; then
        if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
            echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE"
        elif [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD" ]; then
            echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD"
        fi
    fi
    O2CB_IDLE_TIMEOUT_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/idle_timeout_ms
    if [ -n "$O2CB_IDLE_TIMEOUT_MS" ]; then
        if [ -f "$O2CB_IDLE_TIMEOUT_MS_FILE" ]; then
            echo "$O2CB_IDLE_TIMEOUT_MS" > "$O2CB_IDLE_TIMEOUT_MS_FILE"
        fi
    fi
    O2CB_KEEPALIVE_DELAY_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/keepalive_delay_ms
    if [ -n "$O2CB_KEEPALIVE_DELAY_MS" ]; then
        if [ -f "$O2CB_KEEPALIVE_DELAY_MS_FILE" ]; then
            echo "$O2CB_KEEPALIVE_DELAY_MS" > "$O2CB_KEEPALIVE_DELAY_MS_FILE"
        fi
    fi
    O2CB_RECONNECT_DELAY_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/reconnect_delay_ms
    if [ -n "$O2CB_RECONNECT_DELAY_MS" ]; then
        if [ -f "$O2CB_RECONNECT_DELAY_MS_FILE" ]; then
            echo "$O2CB_RECONNECT_DELAY_MS" > "$O2CB_RECONNECT_DELAY_MS_FILE"
        fi
    fi
}
show_timeouts_o2cb()
{
    O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
    O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/threshold
    if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
        VAL=`cat "$O2CB_HEARTBEAT_THRESHOLD_FILE"`
        echo "  Heartbeat dead threshold: ${VAL}"
    elif [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD" ]; then
        VAL=`cat "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD"`
        echo "  Heartbeat dead threshold: ${VAL}"
    fi
    O2CB_IDLE_TIMEOUT_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/idle_timeout_ms
    if [ -f "$O2CB_IDLE_TIMEOUT_MS_FILE" ]; then
        VAL=`cat "$O2CB_IDLE_TIMEOUT_MS_FILE"`
        echo "  Network idle timeout: ${VAL}"
    fi
    O2CB_KEEPALIVE_DELAY_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/keepalive_delay_ms
    if [ -f "$O2CB_KEEPALIVE_DELAY_MS_FILE" ]; then
        VAL=`cat "$O2CB_KEEPALIVE_DELAY_MS_FILE"`
        echo "  Network keepalive delay: ${VAL}"
    fi
    O2CB_RECONNECT_DELAY_MS_FILE=$(configfs_path)/cluster/${CLUSTER}/reconnect_delay_ms
    if [ -f "$O2CB_RECONNECT_DELAY_MS_FILE" ]; then
        VAL=`cat "$O2CB_RECONNECT_DELAY_MS_FILE"`
        echo "  Network reconnect delay: ${VAL}"
    fi
}
global_heartbeat_enabled_o2cb()
{
    O2CB_HEARTBEAT_MODE_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/mode
    VAL="local"
    if [ -f "$O2CB_HEARTBEAT_MODE_FILE" ]; then
        VAL=$(cat "$O2CB_HEARTBEAT_MODE_FILE")
    fi
    if [ "${VAL}" = "global" ]; then
        return 1;
    fi
    return 0;
}
configure_ask()
{
    if [ -n "$DPKGRECONF" ]; then
	cat <<EOF
Configuring the O2CB driver.
Please configure this service in the Debian way:
 dpkg-reconfigure ocfs2-tools
EOF
	exit 0
    fi
    cat <<EOF
Configuring the O2CB driver.
This will configure the on-boot properties of the O2CB driver.
The following questions will determine whether the driver is loaded on
boot.  The current values will be shown in brackets ('[]').  Hitting
<ENTER> without typing an answer will keep that current value.  Ctrl-C
will abort.
EOF
    while :
    do
        if [ "$O2CB_ENABLED" = "true" ]
        then
            CUR=y
        else
            CUR=n
        fi
        echo -n "Load O2CB driver on boot (y/n) [$CUR]: "
        read LINE
        case "$LINE" in
        "")
            break
            ;;
        y|Y)
            O2CB_ENABLED=true
            break
            ;;
        n|N)
            O2CB_ENABLED=false
            break
            ;;
        *)
            echo "Invalid answer: $LINE" >&2
            ;;
        esac
    done
    while :
    do
        echo -n "Cluster stack backing O2CB [$O2CB_STACK]: "
        read LINE
        case "$LINE" in
        "")
            break
            ;;
        ????)
            O2CB_STACK="$LINE"
            break
            ;;
        *)
            echo "Invalid answer: $LINE" >&2
            ;;
        esac
    done
    while :
    do
        echo -n "Cluster to start on boot (Enter \"none\" to clear) [$O2CB_BOOTCLUSTER]: "
        read LINE
        case "$LINE" in
        "")
            break
            ;;
        none)
            O2CB_BOOTCLUSTER=
            break
            ;;
        *[^a-zA-Z0-9]*)
            echo "Invalid cluster name: $LINE" >&2
            ;;
        *)
            O2CB_BOOTCLUSTER="$LINE"
            break
            ;;
        esac
    done
    read_timeout "heartbeat dead threshold" "$O2CB_HEARTBEAT_THRESHOLD" "$MIN_HEARTBEAT_THRESHOLD" "$DEF_HEARTBEAT_THRESHOLD"
    O2CB_HEARTBEAT_THRESHOLD="$RET_VAL"
    read_timeout "network idle timeout in ms" "$O2CB_IDLE_TIMEOUT_MS" "$MIN_IDLE_TIMEOUT_MS" "$DEF_IDLE_TIMEOUT_MS"
    O2CB_IDLE_TIMEOUT_MS="$RET_VAL"
    read_timeout "network keepalive delay in ms" "$O2CB_KEEPALIVE_DELAY_MS" "$MIN_KEEPALIVE_DELAY_MS" "$DEF_KEEPALIVE_DELAY_MS"
    O2CB_KEEPALIVE_DELAY_MS="$RET_VAL"
    read_timeout "network reconnect delay in ms" "$O2CB_RECONNECT_DELAY_MS" "$MIN_RECONNECT_DELAY_MS" "$DEF_RECONNECT_DELAY_MS"
    O2CB_RECONNECT_DELAY_MS="$RET_VAL"
    # XXX ask about mount point base
}
make_dir()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "make_dir(): Requires an argument" >&2
        return 1
    fi
    DIR="$1"
    if [ -e "$DIR" ]
    then
        if [ -d "$DIR" ]
        then
            return 2
        fi
        echo "make_dir(): File $DIR is not a directory" >&2
        return 1
    fi
    echo -n "Creating directory '$DIR': "
    mkdir -p "$DIR" 2>/dev/null
    if [ $? != 0 ]
    then
        echo "Unable to create directory '$DIR'" >&2
        return 1
    fi
    return 0
}
driver_filesystem()
{
    if [ -z "$1" ]
    then
        echo "driver_filesystem(): Missing an argument" >&2
        exit 1
    fi
    FSNAME="$1"
    PSEUDO="$2"
    FSOUT="$(awk '(NF == 1 && $1 ~ /^'$FSNAME'$/) || $2 ~ /^'$FSNAME'$/{
                      print $1;exit
                  }' /proc/filesystems 2>/dev/null)"
    test -n "$FSOUT"
    return $?
}
load_filesystem()
{
    if [ "$#" != "1" -o -z "$1" ]
    then
        echo "load_filesystem(): Missing an argument" >&2
        return 1
    fi
    FSNAME="$1"
    driver_filesystem "$FSNAME" && return 2
    echo -n "Loading filesystem \"$FSNAME\": "
    modprobe -s "$FSNAME"
    if [ "$?" != 0 ]
    then
        echo "Unable to load filesystem \"$FSNAME\"" >&2
        return 1
    fi
    return 0
}
unload_filesystem()
{
    if [ "$#" != "1" -o -z "$1" ]
    then
        echo "unload_filesystem(): Missing an argument" >&2
        return 1
    fi
    FSNAME="$1"
    driver_filesystem "$FSNAME" || return 2
    MODOUT="`awk '$1 ~ /^'$FSNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
    if [ -z "$MODOUT" ]
    then
        # The driver is built in, we can't unload it.
        return 2
    fi
    case "$MODOUT" in
    $FSNAME\ 0)
        ;;
    $FSNAME\ *)
        # The driver is busy, leave it alone
        return 2
        ;;
    *)
        echo -n "Invalid module parsing! "
        return 1
        ;;
    esac
    echo -n "Unloading module \"$FSNAME\": "
    modprobe -rs "$FSNAME"
    if [ "$?" != 0 ]
    then
        echo "Unable to unload module \"$FSNAME\"" >&2
        return 1
    fi
    return 0
}
check_filesystem()
{
    if [ "$#" != "2" -o -z "$1" -o -z "$2" ]
    then
        echo "check_filesystem(): Missing arguments" >&2
        exit 1
    fi
    FSNAME="$1"
    MOUNTPOINT="$2"
    FULL_MOUNTSEARCH="`echo "$MOUNTPOINT" | sed -e 's/\//\\\\\//g'`"
    MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/ && $3 ~ /^'$FSNAME'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
    test -n "$MOUNTOUT"
    return $?
}
mount_filesystem()
{
    if [ "$#" != "2" -o -z "$1" -o -z "$2" ]
    then
        echo "mount_filesystem(): Missing arguments" >&2
        return 1
    fi
    FSNAME="$1"
    MOUNTPOINT="$2"
    check_filesystem "$FSNAME" "$MOUNTPOINT" && return 2
    load_filesystem "$FSNAME"
    if_fail $?
    # XXX some policy?
    if [ ! -e "$MOUNTPOINT" ]; then
        make_dir $MOUNTPOINT
        if_fail "$?"
    fi
    echo -n "Mounting ${FSNAME} filesystem at ${MOUNTPOINT}: "
    mount -t ${FSNAME} ${FSNAME} ${MOUNTPOINT}
    if [ $? != 0 ]
    then
        echo "Unable to mount ${FSNAME} filesystem" >&2
        return 1
    fi
    return 0
}
o2cbmounts()
{
    if [ "$#" != "1" -o -z "$1" ]
    then
        echo "o2cbmounts(): Missing arguments" >&2
        exit 1
    fi
    FSNAME="$1"
    LC_ALL=C awk -v FSNAME=$FSNAME 'BEGIN {fsname = FSNAME;} $3 == fsname  { print $2 }' /proc/mounts
}
unmount_filesystem()
{
    if [ "$#" != "2" -o -z "$1" -o -z "$2" ]
    then
        echo "unmount_filesystem(): Missing arguments" >&2
        return 1
    fi
    FSNAME="$1"
    MOUNTPOINT="$2"
    if check_filesystem "$FSNAME" "$MOUNTPOINT"
    then
        echo -n "Unmounting ${FSNAME} filesystem: "
        remaining=$(o2cbmounts $FSNAME)
        sig=
        retry=3
        while [ -n "$remaining" -a "$retry" -gt 0 ]
        do
            if [ "$retry" -lt 3 ]; then
                echo -n "Retry unmounting $FSNAME} filesystem: "
            fi
            umount $MOUNTPOINT
            RC=$?
            if_fail $RC
            remaining=$(o2cbmounts $FSNAME)
            [ -z "$remaining" ] && break
            fuser -km $sig $remaining >/dev/null 2>&1
            sleep 5
            retry=$(($retry - 1))
            sig=-9
        done
	
        remaining=$(o2cbmounts $FSNAME)
        if [ -n "$remaining" ]
        then
            echo "Unable to unmount ${FSNAME} filesystem" >&2
            return 1
        fi
    fi
    unload_filesystem "$FSNAME"
    return $?
}
status_filesystem()
{
    if [ "$#" != "2" -o -z "$1" -o -z "$2" ]
    then
        echo "status_filesystem(): Missing arguments" >&2
        return 1
    fi
    FSNAME="$1"
    MOUNTPOINT="$2"
    echo -n "Driver for \"$FSNAME\": "
    if driver_filesystem "$FSNAME"
    then
        echo "Loaded"
    else
        echo "Not loaded"
        return 0
    fi
    echo -n "Filesystem \"$FSNAME\": "
    if check_filesystem "$FSNAME" "$MOUNTPOINT"
    then
        echo "Mounted"
        return 2
    fi
    echo "Not mounted"
    return 0
}
status_daemon()
{
    DAEMON="/sbin/ocfs2_controld.${O2CB_STACK}"
    echo -n "Checking for control daemon: "
    if [ -n "$(pidofproc "$DAEMON")" ]
    then
        echo "$DAEMON"
        return 0
    else
        echo "not running"
        return 1
    fi
}
bringup_daemon()
{
    DAEMON="/sbin/ocfs2_controld.${O2CB_STACK}"
    echo -n "Starting $(basename "$DAEMON"): "
    start_daemon "$DAEMON"
    [ $? != 0 ] && return 1
    COUNT=0
    while [ -z "$(pidofproc "$DAEMON")" ]
    do
        COUNT="$(expr "$COUNT" + 1)"
        if [ "$COUNT" -gt "$BRINGUP_TIMEOUT" ]
        then
            return 1
        fi
        sleep 1
    done
    return 0
}
kill_daemon()
{
    SIGNAL="$1"
    DAEMON="/sbin/ocfs2_controld.${O2CB_STACK}"
    status_daemon >/dev/null 2>&1 || return 2
    PID="$(pidofproc "$DAEMON")"
    echo -n "Stopping $(basename "$DAEMON"): "
    killproc "$DAEMON" $SIGNAL
    TRIED=
    while :
    do
        NEWPID="$(pidofproc "$DAEMON")"
        if [ -z "$NEWPID" -o "$NEWPID" != "$PID" ]
        then
            echo "Stopped"
            return
        fi
        [ -n "$TRIED" ] && break
        TRIED=t
        # Give it one chance to exit
        sleep 1
    done
    echo "Failed"
    return 1
}
list_nodes_o2cb()
{
    check_filesystem "debugfs" "$DEBUGFS_DIR"
    if [ "$?" -ne "0" ]
    then
        return
    fi
    nodestr=$(cat $DEBUGFS_DIR/o2hb/livenodes)
    echo "Nodes in O2CB cluster: $nodestr"
}
list_heartbeat_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "list_heartbeat_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    RC=0
    if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
    then
        ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
        do
            if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
            then
                dev=$(cat "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}/dev")
                echo "  ${regionstr}${HBUUID} /dev/${dev}"
            fi
        done
    fi
}
check_heartbeat_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "check_heartbeat_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    RC=0
    if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
    then
        ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
        do
            if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
            then
                return 2;
            fi
        done
        if [ $? = 2 ]
        then
            RC=2
        fi
    fi
    return $RC
}
clean_heartbeat_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "clean_heartbeat_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    if [ ! -f "$(configfs_path)/cluster/${CLUSTER}/heartbeat/*" ]
    then
        return
    fi
    echo -n "Cleaning heartbeat on cluster \"${CLUSTER}\": "
    ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
    do
        if [ ! -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
        then
            continue
        fi
        OUTPUT="`ocfs2_hb_ctl -I -u ${HBUUID} 2>&1`"
        if [ $? != 0 ]
        then
            echo "Failed"
            echo "${OUTPUT}" >&2
            exit 1
        fi
        REF="`echo ${OUTPUT} | awk '/refs/ {print $2; exit;}' 2>&1`"
        if [ $REF != 0 ]
        then
           echo "Failed"
           echo "At least one heartbeat region still active" >&2
           exit 1
        else
           OUTPUT="`ocfs2_hb_ctl -K -u ${HBUUID} 2>&1`"
        fi
    done
    if [ $? = 1 ]
    then
        exit 1
    fi
    echo "OK"
}
clean_cluster_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "clean_cluster_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    if [ -d "$(configfs_path)/cluster/${CLUSTER}/node/" ]
    then
        ls -1 "$(configfs_path)/cluster/${CLUSTER}/node/" | while read NODE
        do
            rmdir "$(configfs_path)/cluster/${CLUSTER}/node/${NODE}" >/dev/null 2>&1
        done
    fi
    if [ -d "$(configfs_path)/cluster/${CLUSTER}" ]
    then
        rmdir "$(configfs_path)/cluster/${CLUSTER}" >/dev/null 2>&1
    fi
    if [ -d "$(configfs_path)/cluster/${CLUSTER}" ]
    then
        return 2
    fi
    return 0
}
select_stack_plugin()
{
    case "$O2CB_STACK" in
    o2cb)
        echo o2cb
        ;;
    ????)
        echo user
        ;;
    *)
        echo -n "Checking if cluster stack \"$O2CB_STACK\" is supported: "
        if_fail 1 "Invalid cluster stack name \"$O2CB_STACK\""
        ;;
    esac
 }
load_stack_o2cb()
{
    PLUGIN="o2cb"
    PLUGIN_MODULE="ocfs2_stack_${PLUGIN}"
    #
    # Older drivers don't have stack plugins.  They only support the
    # classic stack.  It is loaded in ocfs2_nodemanager, which is pulled
    # in during the load of ocfs2_dlmfs.  Thus, if we are using the classic
    # stack and cannot load the stack plugin, we silently let the later
    # code try for older drivers.
    #
    # For a newer driver, if ocfs2_stackglue is loaded, we'll see
    # CLUSTER_STACK_FILE.  Thus, we can determine what mode we're in.
    #
    [ ! -e "$CLUSTER_STACK_FILE" ] && \
        modprobe -s ocfs2_stackglue
    # If we're a newer driver, CLUSTER_STACK_FILE will now appear
    if [ -e "$CLUSTER_STACK_FILE" ]
    then
        SP_OUT="$(awk '/^'$PLUGIN'$/{print; exit}' "$LOADED_PLUGINS_FILE" 2>/dev/null)"
        if [ -z "$SP_OUT" ]
        then
            echo -n "Loading stack plugin \"$PLUGIN\": "
            modprobe -s "$PLUGIN_MODULE"
            [ "$?" != 0 ] && if_fail 1 "Unable to load module \"$PLUGIN_MODULE\""
            if_fail 0
        fi
    fi
    mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
    if_fail $?
    return 0
}
userdlm_domains()
{
    magic=$(stat -f --printf="%t" ${DLMFS_DIR})
    if [ "x$magic" = "x$DLMFS_MAGIC" ]
    then
        ls ${DLMFS_DIR}
    fi
}
userdlm_status()
{
    [ -n "$(userdlm_domains)" ] && {
        echo "Active userdlm domains: " $(userdlm_domains)
    }
}
clean_userdlm_domains()
{
    # Cleanup only if mounted
    magic=$(stat -f --printf="%t" ${DLMFS_DIR})
    if [ "x$magic" = "x$DLMFS_MAGIC" ]
    then
        echo -n "Clean userdlm domains: "
        # Kill all processes accessing dlmfs
        fuser -km -9 ${DLMFS_DIR} >/dev/null 2>&1
        # Remove all domains and locks
        for domain in $(userdlm_domains)
        do
            domain_path="${DLMFS_DIR}/${domain}"
            magic=$(stat -f --printf="%t" ${domain_path})
            if [ "x$magic" = "x$DLMFS_MAGIC" ]
            then
                rm -rf ${domain_path}
            fi
        done
        echo "OK"
    fi
}
dlmfs_user_capable()
{
    if [ -e "$DLMFS_CAPABILITIES_FILE" ]
    then
        CAP_LINE="$(awk '/\ystackglue\y/{print}' "$DLMFS_CAPABILITIES_FILE" 2>/dev/null)"
    else
        CAP_LINE="$(modinfo ocfs2_dlmfs 2>/dev/null |
                        awk '/parm:[ \t]*capabilities:.*\ystackglue\y/{
                                print
                            }')"
    fi
    test x"$CAP_LINE" != x
}
load_stack_user()
{
    PLUGIN="user"
    PLUGIN_MODULE="ocfs2_stack_${PLUGIN}"
    #
    # Older drivers don't have stack plugins.  They only support the
    # classic stack.  It is loaded in ocfs2_nodemanager, which is pulled
    # in during the load of ocfs2_dlmfs.  Thus, if we are using the classic
    # stack and cannot load the stack plugin, we silently let the later
    # code try for older drivers.
    #
    # For a newer driver, if ocfs2_stackglue is loaded, we'll see
    # CLUSTER_STACK_FILE.  Thus, we can determine what mode we're in.
    #
    [ ! -e "$CLUSTER_STACK_FILE" ] && \
        modprobe -s ocfs2_stackglue
    if [ ! -e "$CLUSTER_STACK_FILE" ]
    then
        echo -n "Checking if stack \"$O2CB_STACK\" is supported: "
        if_fail 1 "User stack plugin is not supported"
    fi
    SP_OUT="$(awk '/^'$PLUGIN'$/{print; exit}' "$LOADED_PLUGINS_FILE" 2>/dev/null)"
    if [ -z "$SP_OUT" ]
    then
        echo -n "Loading stack plugin \"$PLUGIN\": "
        modprobe -s "$PLUGIN_MODULE"
        [ "$?" != 0 ] && if_fail 1 "Unable to load module \"$PLUGIN_MODULE\""
        if_fail 0
    fi
    if dlmfs_user_capable
    then
        mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
        if_fail $?
    fi
    return 0
}
unload_stack_plugins()
{
    # Whether not loaded or old drivers, if we can't find the stack glue,
    # we have nothing to do.
    [ ! -e "$LOADED_PLUGINS_FILE" ] && return 2
    while read plugin
    do
        unload_module "ocfs2_stack_${plugin}"
        if_fail $? "Unable to unload ocfs2_stack_${plugin}"
    done <"$LOADED_PLUGINS_FILE"
    unload_module "ocfs2_stackglue"
    if_fail $? "Unable to unload ocfs2_stackglue"
}
unload_stack_o2cb()
{
    PLUGIN="o2cb"
    PLUGIN_MODULE="ocfs2_stack_${PLUGIN}"
    if [ -d "$(configfs_path)/cluster/" ]
    then
        ls -1 $(configfs_path)/cluster/ | while read CLUSTER
        do
            if [ ! -L "$(configfs_path)/cluster/${CLUSTER}" -a \
                 -d "$(configfs_path)/cluster/${CLUSTER}" ]
            then
                echo "Unable to unload modules as O2CB cluster ${CLUSTER} is still online" >&2
                exit 1
            fi
        done
        if [ $? = 1 ]
        then
            exit 1
        fi
    fi
    unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
    if_fail $?
    unload_stack_plugins
}
unload_stack_user()
{
    PLUGIN="$(select_stack_plugin)"
    PLUGIN_MODULE="ocfs2_stack_${PLUGIN}"
    if status_daemon >/dev/null 2>&1
    then
        echo "Unable to unload modules as the cluster is still online" >&2
        exit 1
    fi
    unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR
    if_fail $?
    unload_stack_plugins
}
status_stack_plugin()
{
    PLUGIN="$(select_stack_plugin)"
    if [ ! -e "$LOADED_PLUGINS_FILE" ]
    then
        # The old stack may be fine here.
        [ "$PLUGIN" = "o2cb" ] && return
        echo "Stack glue driver: Not loaded"
        return
    fi
    echo "Stack glue driver: Loaded"
    echo -n "Stack plugin \"$PLUGIN\": "
    if grep "$PLUGIN" "$LOADED_PLUGINS_FILE" >/dev/null 2>&1
    then
        echo "Loaded"
    else
        echo "Not loaded"
    fi
}
status_stack_o2cb()
{
    status_stack_plugin
    status_filesystem "ocfs2_dlmfs" $DLMFS_DIR
}
status_stack_user()
{
    status_stack_plugin
    echo -n "Driver for \"ocfs2\": "
    if driver_filesystem "ocfs2"
    then
        echo "Loaded"
    else
        echo "Not loaded"
    fi
 }
unload_module()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "unload_module(): Requires an argument" >&2
        return 1
    fi
    MODNAME="$1"
    MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
    if [ -z "$MODOUT" ]
    then
        return 2
    fi
    case "$MODOUT" in
    $MODNAME\ 0)
        ;;
    $MODNAME\ *)
        return 2
        ;;
    *)
        echo -n "Invalid module parsing! "
        return 1
        ;;
    esac
    echo -n "Unloading module \"$MODNAME\": "
    modprobe -rs "$MODNAME"
    if [ "$?" != 0 ]
    then
        echo "Unable to unload module \"$MODNAME\"" >&2
        return 1
    fi
    return 0
}
check_load_module()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "check_load_module(): Requires an argument" >&2
        return 1
    fi
    MODNAME="$1"
    echo -n "Module \"$MODNAME\": "
    MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
    if [ -z "$MODOUT" ]
    then
        echo "Not loaded"
        return 0
    fi
    echo "Loaded"
    return 2
}
load()
{
    PLUGIN="$(select_stack_plugin)"
    touch_lockfile
    # XXX: SPECIAL CASE!  We must load configfs for configfs_path() to work
    load_filesystem "configfs"
    if_fail $?
    mount_filesystem "configfs" "$(configfs_path)"
    if_fail $?
    load_stack_$PLUGIN
    return 0
}
load_status()
{
    PLUGIN="$(select_stack_plugin)"
    status_filesystem "configfs" "$(configfs_path)"
    status_stack_$PLUGIN
    return 0
}
register_cluster_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "register_cluster_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    if ! [ -f ${CLUSTERCONF} ]
    then
        echo -n "Checking O2CB cluster configuration : "
        if_fail 1
    fi
    echo -n "Registering O2CB cluster \"${CLUSTER}\": "
    OUTPUT=$(o2cb register-cluster "${CLUSTER}" 2>&1)
    if [ $? = 0 ]
    then
        echo "OK"
        return 0
    else
        echo "Failed"
        echo "$OUTPUT"
    fi
    return 1
}
unregister_cluster_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "unregister_cluster_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    echo -n "Unregistering O2CB cluster \"${CLUSTER}\": "
    OUTPUT=$(o2cb unregister-cluster "${CLUSTER}" 2>&1)
    if [ $? = 0 ]
    then
        echo "OK"
        return 0
    else
        echo "Failed"
        echo "$OUTPUT"
    fi
    return 1
}
check_register_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "check_register_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    RC=0
    if [ -d "$(configfs_path)/cluster/${CLUSTER}/node/" ]
    then
        ls -1 "$(configfs_path)/cluster/${CLUSTER}/node/" | while read NODE
        do
            LOCAL="`cat \"$(configfs_path)/cluster/${CLUSTER}/node/${NODE}/local\"`"
            if [ $LOCAL = 1 ]
            then
                return 2
            fi
        done
        if [ $? = 2 ]
        then
            RC=2
        fi
    fi
    return $RC
}
start_global_heartbeat_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "start_global_heartbeat_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    if ! [ -f ${CLUSTERCONF} ]
    then
        echo -n "Checking O2CB cluster configuration : "
        if_fail 1
    fi
    global_heartbeat_enabled_o2cb
    if [ $? -ne 1 ]
    then
        return 0;
    fi
    echo -n "Starting global heartbeat for cluster \"${CLUSTER}\": "
    OUTPUT=$(o2cb start-heartbeat "${CLUSTER}" 2>&1)
    if [ $? = 0 ]
    then
        echo "OK"
        return 0
    else
        echo "Failed"
        echo "$OUTPUT"
    fi
    return 1
}
stop_global_heartbeat_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "stop_global_heartbeat_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    global_heartbeat_enabled_o2cb
    if [ $? -ne 1 ]
    then
        return 0;
    fi
    echo -n "Stopping global heartbeat on cluster \"${CLUSTER}\": "
    OUTPUT=$(o2cb stop-heartbeat "${CLUSTER}" 2>&1)
    if [ $? = 0 ]
    then
        echo "OK"
        return 0
    else
        echo "Failed"
        echo "$OUTPUT"
    fi
    return 1
}
online_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "online_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    # allow re-online if global heartbeat enabled
    check_online $CLUSTER
    if [ $? = 2 ]
    then
        global_heartbeat_enabled_o2cb
        if [ $? -ne 1 ]
        then
            echo "Cluster ${CLUSTER} already online"
            return 1
        fi
    fi
    register_cluster_o2cb "${CLUSTER}"
    if [ $? -eq 1 ]
    then
        unregister_cluster_o2cb "${CLUSTER}"
        return 1
    fi
    echo -n "Setting O2CB cluster timeouts : "
    set_timeouts_o2cb
    echo "OK"
    start_global_heartbeat_o2cb "${CLUSTER}"
    if [ $? -eq 1 ]
    then
        stop_global_heartbeat_o2cb "${CLUSTER}"
        return 1
    fi
    o2hbmonitor 2>/dev/null
    return 0
}
online_user()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "online_user(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    check_online $CLUSTER
    if [ $? = 2 ]
    then
        echo "Cluster ${CLUSTER} already online"
        return 1
    fi
    load_filesystem "ocfs2"
    if_fail $? "Unable to load ocfs2 driver"
    bringup_daemon
    if_fail $? "Unable to start control daemon"
}
online()
{
    CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
    if [ -z "$CLUSTER" ]
    then
        echo "Cluster not known"
        return
    fi
    PLUGIN="$(select_stack_plugin)"
    if [ -f "$CLUSTER_STACK_FILE" ]
    then
        echo -n "Setting cluster stack \"$O2CB_STACK\": "
        echo "$O2CB_STACK" >"$CLUSTER_STACK_FILE" 2>/dev/null
        if_fail $? "Unable to store cluster stack \"$O2CB_STACK\""
    elif [ "$O2CB_STACK" != "o2cb" ]
    then
        echo -n "Setting cluster stack \"$O2CB_STACK\": "
        if_fail 1 "Stack \"$O2CB_STACK\" is not supported"
    fi
    online_$PLUGIN "$CLUSTER"
}
check_online_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "check_online_o2cb(): Requires an argument" >&2
        return 1
    fi
    CLUSTER="$1"
    check_register_o2cb "$CLUSTER"
    if [ $? -ne 2 ]
    then
         return $RC
    fi
    global_heartbeat_enabled_o2cb "$CLUSTER"
    if [ $? -eq 0 ]
    then
        return 2
    fi
    check_heartbeat_o2cb "$CLUSTER"
    return $?
}
check_online_user()
{
    if status_daemon >/dev/null 2>&1
    then
        return 2
    else
        return 1
    fi
}
check_online()
{
    PLUGIN="$(select_stack_plugin)"
    check_online_$PLUGIN $1
}
offline_o2cb()
{
    if [ "$#" -lt "2" -o -z "$1" -o -z "$2" ]
    then
        echo "offline_o2cb(): Missing arguments" >&2
        return 1
    fi
    CLUSTER="$1"
    FORCE="$2"
    if [ ! -e "$(configfs_path)/cluster/${CLUSTER}" ]
    then
        return
    fi
    stop_global_heartbeat_o2cb "$CLUSTER"
    clean_heartbeat_o2cb $CLUSTER
    echo -n "Stopping O2CB cluster ${CLUSTER}: "
    check_heartbeat_o2cb $CLUSTER
    if [ $? != 0 ]
    then
        echo "Failed"
        echo "Unable to stop cluster as heartbeat region still active" >&2
        exit 1
    fi
    killall -e o2hbmonitor 2>/dev/null
    # ignoring force-offline as this should be enough
    unregister_cluster_o2cb "${CLUSTER}"
    return $?
}
offline_user()
{
    if [ "$#" -lt "2" -o -z "$1" -o -z "$2" ]
    then
        echo "offline_user(): Missing arguments" >&2
        return 1
    fi
    CLUSTER="$1"
    FORCE="$2"
    kill_daemon
    [ $? = 1 -a "$FORCE" -eq 1 ] && kill_daemon -9
}
offline()
{
    CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
    if [ -z "$CLUSTER" ]
    then
        return
    fi
    PLUGIN="$(select_stack_plugin)"
    if [ $# -gt 1 ]
    then
        FORCE=$2
    else
        FORCE=0
    fi
    clean_userdlm_domains
    offline_$PLUGIN "$CLUSTER" "$FORCE"
    unload_filesystem "ocfs2"
    if_fail "$?"
}
start()
{
    if [ "$O2CB_ENABLED" != "true" ]
    then
        exit 0
    fi
    load
    online "$1"
}
unload()
{
    PLUGIN="$(select_stack_plugin)"
    unload_stack_$PLUGIN
    remove_lockfile
    # Only unmount configfs if there are no other users
    if [ -z "$(ls -1 "$(configfs_path)" 2>/dev/null)" ]
    then
        unmount_filesystem "configfs" "$(configfs_path)"
        if_fail $?
    fi
}
stop()
{
    offline "$1"
    unload
}
configure()
{
    configure_ask
    if [ -z "$DPKGRECONF" ]; then
	write_sysconfig
	if_fail "$?" "Unable to write the driver configuration"
    fi
}
online_status_o2cb()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "online_status_o2cb(): Missing arguments" >&2
        return 1
    fi
    CLUSTER="$1"
    echo -n "Checking O2CB cluster \"$CLUSTER\": "
    check_online_o2cb $CLUSTER
    if [ $? = 2 ]
    then
       echo "Online"
    else
       echo "Offline"
       return 0;
    fi
    show_timeouts_o2cb
    HBMODE="Local"
    global_heartbeat_enabled_o2cb "$CLUSTER"
    if [ $? -eq 1 ]
    then
        HBMODE="Global"
    fi
    echo "  Heartbeat mode: ${HBMODE}"
    echo -n "Checking O2CB heartbeat: "
    check_heartbeat_o2cb $CLUSTER
    if [ $? -eq 2 ]
    then
        echo "Active"
    else
        echo "Not active"
        return 0;
    fi
    if [ $HBMODE = "Global" ]
    then
        list_heartbeat_o2cb $CLUSTER
        list_nodes_o2cb
    fi
}
online_status_user()
{
    status_daemon
}
online_status()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        echo "online_status(): Missing arguments" >&2
        return 1
    fi
    CLUSTER="$1"
    PLUGIN="$(select_stack_plugin)"
    online_status_$PLUGIN "$CLUSTER"
}
status()
{
    load_status
    CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
    if [ -z "$CLUSTER" ]
    then
        return 1;
    fi
    online_status "$CLUSTER"
    userdlm_status
}
online-status()
{
    CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
    if [ -z "$CLUSTER" ]
    then
        return 2
    fi
    check_online "$CLUSTER"
    RC=$?
    if [ "$RC" = "2" ]
    then
        echo "online"
        exit 0
    elif [ "$RC" = "0" ]
    then
        echo "offline"
        exit 1
    else
        echo "error"
        exit 2
    fi
}
case "$1" in
    start)
        start "$2"
        ;;
    status)
        status "$2"
        ;;
    stop)
        stop "$2"
        ;;
    restart)
        stop "$2"
        start "$2"
        ;;
    force-reload)
        stop "$2"
        start "$2"
        ;;
    load)
        load
        ;;
    online)
        load
        online "$2"
        ;;
    online-status)
        online-status "$2"
        ;;
    offline)
        offline "$2"
        ;;
    force-offline)
        offline "$2" 1
        ;;
    unload)
        offline "$2"
        unload
        ;;
    configure)
        configure
        if [ "$O2CB_ENABLED" = "true" ]
        then
            start
        else
            stop
        fi
        ;;
    enable)
        O2CB_ENABLED=true
        write_sysconfig
        if_fail "$?" "Unable to write the driver configuration"
        start
        ;;
    disable)
        O2CB_ENABLED=false
        write_sysconfig
        if_fail "$?" "Unable to write the driver configuration"
        stop
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|force-offline|status|online-status}"
        exit 1
        ;;
esac
exit 0


-- debconf information excluded



More information about the Debian-ha-maintainers mailing list