Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3153307
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
index 78ed0cb44..aaaf27a2f 100755
--- a/heartbeat/nfsserver
+++ b/heartbeat/nfsserver
@@ -1,481 +1,484 @@
#!/bin/sh
# nfsserver
#
# Description: Manages nfs server as OCF resource
# by hxinwei@gmail.com
# License: GNU General Public License v2 (GPLv2) and later
if [ -n "$OCF_DEBUG_LIBRARY" ]; then
. $OCF_DEBUG_LIBRARY
else
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
fi
DEFAULT_INIT_SCRIPT="/etc/init.d/nfsserver"
DEFAULT_NOTIFY_CMD="/sbin/sm-notify"
DEFAULT_NOTIFY_FOREGROUND="false"
DEFAULT_RPCPIPEFS_DIR="/var/lib/nfs/rpc_pipefs"
EXEC_MODE=0
SELINUX_ENABLED=-1
STATD_PATH="/var/lib/nfs"
STATD_DIR=""
nfsserver_meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="nfsserver">
<version>1.0</version>
<longdesc lang="en">
Nfsserver helps to manage the Linux nfs server as a failover-able resource in Linux-HA.
It depends on Linux specific NFS implementation details, so is considered not portable to other platforms yet.
</longdesc>
<shortdesc lang="en">Manages an NFS server</shortdesc>
<parameters>
<parameter name="nfs_init_script" unique="0" required="0">
<longdesc lang="en">
The default init script shipped with the Linux distro.
The nfsserver resource agent offloads the start/stop/monitor
work to the init script because the procedure to start/stop/monitor
nfsserver varies on different Linux distro. In the event that this
option is not set, this agent will attempt to use an init script at
this location, ${DEFAULT_INIT_SCRIPT}, or detect a systemd unit-file
to use in the event that no init script is detected.
</longdesc>
<shortdesc lang="en">
Init script for nfsserver
</shortdesc>
<content type="string" default="auto detected" />
</parameter>
<parameter name="nfs_notify_cmd" unique="0" required="0">
<longdesc lang="en">
The tool to send out NSM reboot notification, it should be either sm-notify or rpc.statd.
Failover of nfsserver can be considered as rebooting to different machines.
The nfsserver resource agent use this command to notify all clients about the happening of failover.
</longdesc>
<shortdesc lang="en">
The tool to send out notification.
</shortdesc>
<content type="string" default="$DEFAULT_NOTIFY_CMD" />
</parameter>
<parameter name="nfs_notify_foreground" unique="0" required="0">
<longdesc lang="en">
Keeps the notify tool attached to its controlling terminal and running in the foreground.
</longdesc>
<shortdesc lang="en">
Keeps the notify tool running in the foreground.
</shortdesc>
<content type="boolean" default="$DEFAULT_NOTIFY_FOREGROUND" />
</parameter>
<parameter name="nfs_smnotify_retry_time" unique="0" required="0">
<longdesc lang="en">
Specifies the length of sm-notify retry time, in minutes, to continue retrying notifications to unresponsive hosts.
If this option is not specified, sm-notify attempts to send notifications for 15 minutes. Specifying a value of 0
causes sm-notify to continue sending notifications to unresponsive peers until it is manually killed.
</longdesc>
<shortdesc lang="en">
Specifies the length of sm-notify retry time(minutes).
</shortdesc>
<content type="integer" default="" />
</parameter>
<parameter name="nfs_shared_infodir" unique="0" required="1">
<longdesc lang="en">
The nfsserver resource agent will save nfs related information in this specific directory.
And this directory must be able to fail-over before nfsserver itself.
</longdesc>
<shortdesc lang="en">
Directory to store nfs server related information.
</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="nfs_ip" unique="0" required="1">
<longdesc lang="en">
Comma separated list of floating IP addresses used to access the nfs service
</longdesc>
<shortdesc lang="en">
IP addresses.
</shortdesc>
<content type="string"/>
</parameter>
<parameter name="rpcpipefs_dir" unique="0" required="0">
<longdesc lang="en">
The mount point for the sunrpc file system. Default is $DEFAULT_RPCPIPEFS_DIR .
This script will mount(bind) nfs_shared_infodir on /var/lib/nfs/ (can not be changed),
and this script will mount the sunrpc file system on $DEFAULT_RPCPIPEFS_DIR (default, can be changed by this parameter).
If you want to move only rpc_pipefs/ (e.g. to keep rpc_pipefs/ local) from default , please set this value.
</longdesc>
<shortdesc lang="en">
The mount point for the sunrpc file system.
</shortdesc>
<content type="string" default="$DEFAULT_RPCPIPEFS_DIR" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="40" />
<action name="stop" timeout="20s" />
<action name="monitor" depth="0" timeout="20s" interval="10" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="30" />
</actions>
</resource-agent>
END
return $OCF_SUCCESS
}
nfsserver_usage() {
cat <<END
usage: $0 {start|stop|monitor|status|validate-all|meta-data}
END
}
if [ $# -ne 1 ]; then
nfsserver_usage
exit $OCF_ERR_ARGS
fi
case $__OCF_ACTION in
meta-data) nfsserver_meta_data
exit $OCF_SUCCESS
;;
usage|help) nfsserver_usage
exit $OCF_SUCCESS
;;
*)
;;
esac
fp="$OCF_RESKEY_nfs_shared_infodir"
: ${OCF_RESKEY_nfs_notify_cmd="$DEFAULT_NOTIFY_CMD"}
: ${OCF_RESKEY_nfs_notify_foreground="$DEFAULT_NOTIFY_FOREGROUND"}
if [ -z ${OCF_RESKEY_rpcpipefs_dir} ]; then
rpcpipefs_make_dir=$fp/rpc_pipefs
rpcpipefs_umount_dir=${DEFAULT_RPCPIPEFS_DIR}
else
rpcpipefs_make_dir=${OCF_RESKEY_rpcpipefs_dir}
rpcpipefs_umount_dir=${OCF_RESKEY_rpcpipefs_dir}
fi
# Use statd folder if it exists
if [ -d "/var/lib/nfs/statd" ]; then
STATD_DIR="statd"
STATD_PATH="/var/lib/nfs/statd"
fi
# SELinux information. We are taking the permissions from
# the current statd dir and applying it to the HA one that is
# being mounted in its place.
which restorecon > /dev/null 2>&1 && selinuxenabled
SELINUX_ENABLED=$?
if [ $SELINUX_ENABLED -eq 0 ]; then
export SELINUX_LABEL="$(ls -ldZ $STATD_PATH | cut -f4 -d' ')"
fi
##
# EXEC_MODE values
# 1 user init script or default init script
# 2 systemd
#
# On error, this function will terminate the process
# with error code $OCF_ERR_INSTALLED
##
set_exec_mode()
{
##
# If EXEC_MODE is already set, we don't need to run this function again.
##
if [ $EXEC_MODE -ne 0 ]; then
return 0;
fi
##
# If the user defined an init script, It must exist for us to continue
##
if [ -n "$OCF_RESKEY_nfs_init_script" ]; then
# check_binary will exit the process if init script does not exist
check_binary ${OCF_RESKEY_nfs_init_script}
EXEC_MODE=1
return 0
fi
##
# Check to see if the default init script exists, if so we'll use that.
##
if which $DEFAULT_INIT_SCRIPT > /dev/null 2>&1; then
OCF_RESKEY_nfs_init_script=$DEFAULT_INIT_SCRIPT
EXEC_MODE=1
return 0
fi
##
# Last of all, attempt systemd.
##
if which systemctl > /dev/null 2>&1; then
if systemctl list-unit-files | grep nfs-server > /dev/null && systemctl list-unit-files | grep nfs-lock > /dev/null; then
EXEC_MODE=2
return 0
fi
fi
ocf_log err "No init script or systemd unit file detected for nfs server"
exit $OCF_ERR_INSTALLED
}
nfs_systemd_exec()
{
local cmd=$1
local server_res
local lock_res
if [ "$cmd" = "stop" ]; then
systemctl $cmd nfs-server.service
server_res=$?
systemctl $cmd nfs-lock.service
lock_res=$?
else
systemctl $cmd nfs-lock.service
lock_res=$?
systemctl $cmd nfs-server.service
server_res=$?
fi
if [ $lock_res -ne $server_res ]; then
# If one is running and the other isn't, or for whatever other reason
# the return code's aren't the same, this is bad.
ocf_log err "Systemd services nfs-lock and nfs-server are not in the same state after attempting $cmd command"
return $OCF_ERR_GENERIC
fi
return $server_res
}
##
# wrapper for init script and systemd calls.
##
nfs_exec()
{
local cmd=$1
set_exec_mode
case $EXEC_MODE in
1) ${OCF_RESKEY_nfs_init_script} $cmd;;
2) nfs_systemd_exec $cmd;;
esac
}
nfsserver_monitor ()
{
fn=`mktemp`
nfs_exec status > $fn 2>&1
rc=$?
ocf_log debug `cat $fn`
rm -f $fn
#Adapte LSB status code to OCF return code
if [ $rc -eq 0 ]; then
return $OCF_SUCCESS
elif [ $rc -eq 3 ]; then
return $OCF_NOT_RUNNING
else
return $OCF_ERR_GENERIC
fi
}
prepare_directory ()
{
[ -d "$fp" ] || mkdir -p $fp
[ -d "$rpcpipefs_make_dir" ] || mkdir -p $rpcpipefs_make_dir
[ -d "$fp/v4recovery" ] || mkdir -p $fp/v4recovery
[ -d "$fp/$STATD_DIR" ] || mkdir -p "$fp/$STATD_DIR"
[ -d "$fp/$STATD_DIR/sm" ] || mkdir -p "$fp/$STATD_DIR/sm"
[ -d "$fp/$STATD_DIR/sm.ha" ] || mkdir -p "$fp/$STATD_DIR/sm.ha"
[ -d "$fp/$STATD_DIR/sm.bak" ] || mkdir -p "$fp/$STATD_DIR/sm.bak"
[ -n "`id -u rpcuser`" -a "`id -g rpcuser`" ] && chown -R rpcuser.rpcuser "$fp/$STATD_DIR"
[ $SELINUX_ENABLED -eq 0 ] && chcon -R "$SELINUX_LABEL" "$fp"
}
is_bound ()
{
- mount | grep -q "$1 on $2 type none (.*bind)"
- return $?
+ if mount | grep -q "on $1 type"; then
+ return 0
+ fi
+
+ return 1
}
bind_tree ()
{
- if is_bound $fp /var/lib/nfs; then
+ if is_bound /var/lib/nfs; then
ocf_log debug "$fp is already bound to /var/lib/nfs"
return 0
fi
mount --bind $fp /var/lib/nfs
[ $SELINUX_ENABLED -eq 0 ] && restorecon /var/lib/nfs
}
unbind_tree ()
{
if `mount | grep -q " on $rpcpipefs_umount_dir"`; then
umount -t rpc_pipefs $rpcpipefs_umount_dir
fi
- if is_bound $fp /var/lib/nfs; then
+ if is_bound /var/lib/nfs; then
umount /var/lib/nfs
fi
}
nfsserver_start ()
{
if nfsserver_monitor; then
ocf_log debug "NFS server is already started"
return $OCF_SUCCESS
fi
prepare_directory
bind_tree
rm -rf $STATD_PATH/sm.ha/* > /dev/null 2>&1
cp -rf $STATD_PATH/sm $STATD_PATH/sm.bak /var/lib/nfs/state $STATD_PATH/sm.ha > /dev/null 2>&1
ocf_log info "Starting NFS server ..."
fn=`mktemp`
nfs_exec start > $fn 2>&1
rc=$?
ocf_log debug `cat $fn`
rm -f $fn
if [ $rc -ne 0 ]; then
ocf_log err "Failed to start NFS server"
return $rc
fi
#Notify the nfs server has been moved or rebooted
#The init script do that already, but with the hostname, which may be ignored by client
#we have to do it again with the nfs_ip
local opts
case ${OCF_RESKEY_nfs_notify_cmd##*/} in
sm-notify)
# run in foreground, if requested
if ocf_is_true "$OCF_RESKEY_nfs_notify_foreground"; then
opts="-d"
fi
if [ -n "$OCF_RESKEY_nfs_smnotify_retry_time" ]; then
opts="$opts -m $OCF_RESKEY_nfs_smnotify_retry_time"
fi
opts="$opts -f -v"
;;
rpc.statd)
if ocf_is_true "$OCF_RESKEY_nfs_notify_foreground"; then
opts="-F"
fi
opts="$opts -n"
;;
esac
rm -rf $STATD_PATH/sm.ha.save > /dev/null 2>&1
cp -rf $STATD_PATH/sm.ha $STATD_PATH/sm.ha.save > /dev/null 2>&1
for ip in `echo ${OCF_RESKEY_nfs_ip} | sed 's/,/ /g'`; do
${OCF_RESKEY_nfs_notify_cmd} $opts $ip -P $STATD_PATH/sm.ha
rm -rf $STATD_PATH/sm.ha > /dev/null 2>&1
cp -rf $STATD_PATH/sm.ha.save $STATD_PATH/sm.ha > /dev/null 2>&1
done
ocf_log info "NFS server started"
return $OCF_SUCCESS
}
nfsserver_stop ()
{
ocf_log info "Stopping NFS server ..."
fn=`mktemp`
nfs_exec stop > $fn 2>&1
rc=$?
ocf_log debug `cat $fn`
rm -f $fn
if [ $rc -eq 0 ]; then
unbind_tree
ocf_log info "NFS server stopped"
return $OCF_SUCCESS
fi
ocf_log err "Failed to stop NFS server"
return $rc
}
nfsserver_validate ()
{
##
# set_exec_mode will exit if nfs server is not installed
##
set_exec_mode
check_binary ${OCF_RESKEY_nfs_notify_cmd}
if [ x = x"${OCF_RESKEY_nfs_ip}" ]; then
ocf_log err "nfs_ip not set"
exit $OCF_ERR_CONFIGURED
fi
if [ x = "x$OCF_RESKEY_nfs_shared_infodir" ]; then
ocf_log err "nfs_shared_infodir not set"
exit $OCF_ERR_CONFIGURED
fi
if [ -n "$OCF_RESKEY_nfs_smnotify_retry_time" ]; then
if ! ocf_is_decimal "$OCF_RESKEY_nfs_smnotify_retry_time"; then
ocf_log err "Invalid nfs_smnotify_retry_time [$OCF_RESKEY_nfs_smnotify_retry_time]"
exit $OCF_ERR_CONFIGURED
fi
fi
case ${OCF_RESKEY_nfs_notify_cmd##*/} in
sm-notify|rpc.statd) ;;
*)
ocf_log err "Invalid nfs_notify_cmd [$OCF_RESKEY_nfs_notify_cmd]"
exit $OCF_ERR_CONFIGURED
;;
esac
return $OCF_SUCCESS
}
if [ -n "$OCF_RESKEY_CRM_meta_clone" ]; then
ocf_log err "THIS RA DO NOT SUPPORT CLONE MODE!"
exit $OCF_ERR_CONFIGURED
fi
nfsserver_validate
case $__OCF_ACTION in
start) nfsserver_start
;;
stop) nfsserver_stop
;;
monitor) nfsserver_monitor
;;
validate-all) exit $OCF_SUCCESS
;;
*) nfsserver_usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Feb 25, 5:14 PM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1459087
Default Alt Text
(12 KB)
Attached To
Mode
rR Resource Agents
Attached
Detach File
Event Timeline
Log In to Comment