[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