mirror of
https://github.com/samba-team/samba.git
synced 2025-01-07 17:18:11 +03:00
755f060d52
Signed-off-by: Jose A. Rivera <jarrpa@samba.org> Reviewed-by: Martin Schwenke <martin@meltin.net>
305 lines
6.8 KiB
Bash
Executable File
305 lines
6.8 KiB
Bash
Executable File
#!/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
|
|
#
|
|
# * 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
|
|
#
|
|
# * Install 20.nfs-ganesha.check to nfs-checks.d/20.nfs.check
|
|
|
|
# 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
|
|
|
|
# To change the following, edit the default values below. Do not set
|
|
# these - they aren't configuration variables, just hooks for testing.
|
|
nfs_exports_file="${CTDB_NFS_EXPORTS_FILE:-/etc/ganesha/ganesha.conf}"
|
|
nfs_service="${CTDB_NFS_SERVICE:-nfs-ganesha}"
|
|
ganesha_rec_subdir=${CTDB_GANESHA_REC_SUBDIR:-.ganesha}
|
|
procfs=${PROCFS_PATH:-/proc}
|
|
|
|
if [ -z "$CTDB_CLUSTER_FILESYSTEM_TYPE" ] ; then
|
|
CTDB_CLUSTER_FILESYSTEM_TYPE="gpfs"
|
|
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
|
|
|
|
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"
|
|
|
|
# Return 'active' if the shared filesystem is accessible.
|
|
get_cluster_fs_state ()
|
|
{
|
|
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
|
|
gpfs)
|
|
/usr/lpp/mmfs/bin/mmgetstate | awk 'NR == 4 { print $3 }'
|
|
;;
|
|
*)
|
|
echo "File system $CTDB_CLUSTER_FILESYSTEM_TYPE not supported"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
create_ganesha_recdirs ()
|
|
{
|
|
_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}/${ganesha_rec_subdir}"
|
|
mkdir -vp "$_link_dst"
|
|
if [ ! -L "$GANRECDIR" ] ; then
|
|
rm -vrf "$GANRECDIR"
|
|
else
|
|
_t=$(readlink "$GANRECDIR")
|
|
if [ "$_t" != "$_link_dst" ] ; then
|
|
rm -v "$GANRECDIR"
|
|
fi
|
|
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
|
|
return 0
|
|
fi
|
|
|
|
# Check that NFS Ganesha is running, according to PID file
|
|
_pidfile="/var/run/ganesha.pid"
|
|
_ganesha="/usr/bin/ganesha.nfsd"
|
|
if ! { read _pid < "$_pidfile" && \
|
|
grep "$_ganesha" "${procfs}/${_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 ()
|
|
{
|
|
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
|
|
gpfs)
|
|
_nnum=$(get_nodenum)
|
|
_tdate=$(date +"%s")
|
|
_touchtgt="releaseip_${_tdate}_${_nnum}_${2}_${3}_${1}"
|
|
touch "${GANRECDIR2}/${_touchtgt}"
|
|
touch "$GANRECDIR2/my${_touchtgt}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
nfs_takeip ()
|
|
{
|
|
case $CTDB_CLUSTER_FILESYSTEM_TYPE in
|
|
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 ()
|
|
{
|
|
basic_stop "nfs" || true
|
|
|
|
create_ganesha_recdirs
|
|
|
|
basic_start "nfs"
|
|
_f="${procfs}/sys/net/ipv4/tcp_tw_recycle"
|
|
if [ "$_f" ] ; then
|
|
echo 1 >"$_f"
|
|
fi
|
|
}
|
|
|
|
##################################################
|
|
# list share directories
|
|
|
|
nfs_monitor_list_shares ()
|
|
{
|
|
grep Path $nfs_exports_file |
|
|
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 ;;
|
|
register|monitor-pre|monitor-post)
|
|
# Not required/implemented
|
|
:
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|