Page MenuHomeClusterLabs Projects

No OneTemporary

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

Mime Type
text/x-diff
Expires
Tue, Feb 25, 5:14 PM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1459087
Default Alt Text
(12 KB)

Event Timeline