2015-07-01 11:32:35 +03:00
#!/bin/sh
# This is an example CTDB NFS callout script for Ganesha. It is based
# on the last version of 60.ganesha shipped with CTDB. As such, it
# does not try to monitor RPC services that were not monitored by
# 60.ganesha - this might be a useful improvement. It has also not
# been properly tested.
# You should check your version of NFS Ganesha to see if it ships with
# a newer callout.
# To use this:
#
# * Set CTDB_NFS_CALLOUT in your CTDB configuration to point to this
# script
#
2016-04-29 04:58:30 +03:00
# * Rename the following files in nfs-checks.d so that they no longer
# have the ".check" suffix:
# * 10.status.check
# * 20.nfs.check
# * 30.nlockmgr.check
# * 40.mountd.check
# * 50.rquotad.check
2015-07-01 11:32:35 +03:00
#
2015-07-19 14:23:44 +03:00
# * Install 20.nfs-ganesha.check to nfs-checks.d/20.nfs.check
2015-07-01 11:32:35 +03:00
# I (Martin Schwenke) hereby relicense all of my contributions to this
# callout (and, previously, to 60.ganesha) to a license compatible
# with NFS Ganesha (right now this is LGPLv3, but I'm flexible).
# There may be other contributions to be considered for relicensing,
# particularly those in commit 28cbe527d47822f870e8252495ab2a1c8fddd12f.
######################################################################
# Exit on 1st error
set -e
if [ -z "$CTDB_CLUSTER_FILESYSTEM_TYPE" ] ; then
CTDB_CLUSTER_FILESYSTEM_TYPE="gpfs"
fi
# Override for unit testing
if [ -z "$PROCFS_PATH" ] ; then
PROCFS_PATH="/proc"
fi
##################################################
usage ()
{
_c=$(basename $0)
cat <<EOF
usage: $_c { shutdown | startup }
$_c { stop | start | check } nfs
$_c { releaseip | takeip }
$_c { monitor-list-shares }
EOF
exit 1
}
##################################################
# Basic service stop and start
nfs_service="nfs-ganesha-$CTDB_CLUSTER_FILESYSTEM_TYPE"
basic_stop ()
{
case "$1" in
nfs)
service "$nfs_service" stop
;;
*)
usage
esac
}
basic_start ()
{
case "$1" in
nfs)
service "$nfs_service" start
;;
*)
usage
esac
}
##################################################
# "stop" and "start" options for restarting
service_stop ()
{
case "$1" in
nfs)
basic_stop "nfs"
;;
nlockmgr)
# Do nothing - used by statd-callout
:
;;
*)
usage
esac
}
service_start ()
{
case "$1" in
nfs)
basic_start "nfs"
;;
nlockmgr)
# Do nothing - used by statd-callout
:
;;
*)
usage
esac
}
##################################################
# Nitty gritty - monitoring and IP handling
GANRECDIR="/var/lib/nfs/ganesha"
GANRECDIR2="/var/lib/nfs/ganesha/recevents"
GANRECDIR3="/var/lib/nfs/ganesha_local"
2016-04-29 04:58:30 +03:00
# Return 'active' if the shared filesystem is accessible.
2015-07-01 11:32:35 +03:00
get_cluster_fs_state ()
{
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
gpfs)
/usr/lpp/mmfs/bin/mmgetstate | awk 'NR == 4 { print $3 }'
;;
*)
2016-04-29 04:58:30 +03:00
echo "File system $CTDB_CLUSTER_FILESYSTEM_TYPE not supported"
exit 1
2015-07-01 11:32:35 +03:00
;;
esac
}
create_ganesha_recdirs ()
{
[ -n "$CTDB_GANESHA_REC_SUBDIR" ] || CTDB_GANESHA_REC_SUBDIR=".ganesha"
_mounts=$(mount -t $CTDB_CLUSTER_FILESYSTEM_TYPE)
if [ -z "$_mounts" ]; then
echo "startup $CTDB_CLUSTER_FILESYSTEM_TYPE not ready"
exit 0
fi
_mntpt=$(echo "$_mounts" | sort | awk 'NR == 1 {print $3}')
_link_dst="${_mntpt}/${CTDB_GANESHA_REC_SUBDIR}"
mkdir -vp "$_link_dst"
2016-04-28 05:02:47 +03:00
if [ ! -L "$GANRECDIR" ] ; then
rm -vrf "$GANRECDIR"
else
_t=$(readlink "$GANRECDIR")
if [ "$_t" != "$_link_dst" ] ; then
rm -v "$GANRECDIR"
fi
2015-07-01 11:32:35 +03:00
fi
# This is not an "else". It also re-creates the link if it was
# removed above!
if [ ! -e "$GANRECDIR" ]; then
ln -sv "$_link_dst" "$GANRECDIR"
fi
mkdir -p "$GANRECDIR2"
mkdir -p "$GANRECDIR3"
}
service_check ()
{
create_ganesha_recdirs
# Always succeed if cluster filesystem is not active
_cluster_fs_state=$(get_cluster_fs_state)
if [ $_cluster_fs_state != "active" ] ; then
2016-04-29 04:58:30 +03:00
return 0
2015-07-01 11:32:35 +03:00
fi
# Check that NFS Ganesha is running, according to PID file
_pidfile="/var/run/ganesha.pid"
2016-04-29 04:58:30 +03:00
_ganesha="/usr/bin/ganesha.nfsd"
2015-07-01 11:32:35 +03:00
if ! { read _pid < "$_pidfile" && \
grep "$_ganesha" "${PROCFS_PATH}/${_pid}/cmdline" ; } >/dev/null 2>&1 ; then
echo "ERROR: NFS Ganesha not running according to PID file"
return 1
fi
# Check red conditions against limit
_reds_max=2
_reds=$(ls $GANRECDIR3 | grep -c "red")
if [ $_reds -ge $_reds_max ] ; then
echo "Too many red conditions (${_reds}/${_reds_max})"
return 1
fi
# Check for stall
_stall_max=120
_now=$(date +"%s")
_last=$(ls -t $GANRECDIR3 | sed -n -e '1s@_.*@@p')
[ -n $_last ] || _last=$_now # Handle startup
_stall=$(($_now - $_last))
if [ $_stall -ge $_stall_max ] ; then
echo "ERROR: Stalled for ${_stall} second(s)"
return 1
fi
return 0
}
#-------------------------------------------------
get_nodenum ()
{
_nodenum_file="${GANRECDIR}/gpfs_nodenum"
if [ ! -f "$_nodenum_file" ]; then
/usr/lpp/mmfs/bin/mmlsconfig myNodeConfigNumber |
awk '{print $2}' >"$_nodenum_file"
fi
cat "$_nodenum_file"
}
nfs_releaseip ()
{
2016-04-29 04:58:30 +03:00
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
2015-07-01 11:32:35 +03:00
gpfs)
_nnum=$(get_nodenum)
_tdate=$(date +"%s")
_touchtgt="releaseip_${_tdate}_${_nnum}_${2}_${3}_${1}"
touch "${GANRECDIR2}/${_touchtgt}"
touch "$GANRECDIR2/my${_touchtgt}"
;;
esac
}
nfs_takeip ()
{
2016-04-29 04:58:30 +03:00
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
2015-07-01 11:32:35 +03:00
gpfs)
_nnum=$(get_nodenum)
_tdate=$(date +"%s")
_touchtgt="takeip_${_tdate}_${_nnum}_${2}_${3}_${1}"
touch "${GANRECDIR2}/${_touchtgt}"
;;
esac
}
##################################################
# service init startup and final shutdown
nfs_shutdown ()
{
basic_stop "nfs"
}
nfs_startup ()
{
2016-04-29 04:58:30 +03:00
basic_stop "nfs" || true
2015-07-01 11:32:35 +03:00
create_ganesha_recdirs
basic_start "nfs"
_f="${PROCFS_PATH}/sys/net/ipv4/tcp_tw_recycle"
if [ "$_f" ] ; then
echo 1 >"$_f"
fi
}
##################################################
# list share directories
nfs_monitor_list_shares ()
{
grep Path /etc/ganesha/$CTDB_CLUSTER_FILESYSTEM_TYPE.ganesha.exports.conf |
cut -f2 -d\" |
sort -u
}
##################################################
action="$1"
shift
case "$action" in
shutdown) nfs_shutdown ;;
startup) nfs_startup ;;
stop) service_stop "$1" ;;
start) service_start "$1" ;;
check) service_check "$1" ;;
releaseip) nfs_releaseip "$@" ;;
takeip) nfs_takeip "$@" ;;
monitor-list-shares) nfs_monitor_list_shares ;;
2015-07-14 05:11:39 +03:00
register|monitor-pre|monitor-post)
2015-07-01 11:32:35 +03:00
# Not required/implemented
:
;;
*)
usage
esac