You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1197 lines
33 KiB
1197 lines
33 KiB
7 years ago
|
From 3fc7c73f7caa212ef4de4b00e38b7bde2edb0cea Mon Sep 17 00:00:00 2001
|
||
|
From: David Vossel <dvossel@redhat.com>
|
||
|
Date: Thu, 10 Jul 2014 09:50:48 -0500
|
||
|
Subject: [PATCH] nfs updates
|
||
|
|
||
|
---
|
||
|
doc/man/Makefile.am | 1 +
|
||
|
heartbeat/Makefile.am | 1 +
|
||
|
heartbeat/exportfs | 122 ++++++-------
|
||
|
heartbeat/nfsnotify | 315 ++++++++++++++++++++++++++++++++
|
||
|
heartbeat/nfsserver | 492 ++++++++++++++++++++++++++++++++++++++++----------
|
||
|
5 files changed, 764 insertions(+), 167 deletions(-)
|
||
|
create mode 100644 heartbeat/nfsnotify
|
||
|
|
||
|
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
|
||
|
index 344d00d..e97c7e9 100644
|
||
|
--- a/doc/man/Makefile.am
|
||
|
+++ b/doc/man/Makefile.am
|
||
|
@@ -112,6 +112,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \
|
||
|
ocf_heartbeat_mysql.7 \
|
||
|
ocf_heartbeat_mysql-proxy.7 \
|
||
|
ocf_heartbeat_named.7 \
|
||
|
+ ocf_heartbeat_nfsnotify.7 \
|
||
|
ocf_heartbeat_nfsserver.7 \
|
||
|
ocf_heartbeat_nginx.7 \
|
||
|
ocf_heartbeat_oracle.7 \
|
||
|
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
|
||
|
index b67c98e..aab521f 100644
|
||
|
--- a/heartbeat/Makefile.am
|
||
|
+++ b/heartbeat/Makefile.am
|
||
|
@@ -90,6 +90,7 @@ ocf_SCRIPTS = ClusterMon \
|
||
|
mysql \
|
||
|
mysql-proxy \
|
||
|
named \
|
||
|
+ nfsnotify \
|
||
|
nfsserver \
|
||
|
oracle \
|
||
|
oralsnr \
|
||
|
diff --git a/heartbeat/exportfs b/heartbeat/exportfs
|
||
|
index ff5d4f1..471da24 100755
|
||
|
--- a/heartbeat/exportfs
|
||
|
+++ b/heartbeat/exportfs
|
||
|
@@ -95,6 +95,12 @@ Unique fsid within cluster.
|
||
|
Relinquish NFS locks associated with this filesystem when the resource
|
||
|
stops. Enabling this parameter is highly recommended unless the path exported
|
||
|
by this ${__SCRIPT_NAME} resource is also exported by a different resource.
|
||
|
+
|
||
|
+Note: Unlocking is only possible on Linux systems where
|
||
|
+/proc/fs/nfsd/unlock_filesystem exists and is writable. If your system does
|
||
|
+not fulfill this requirement (on account of having an nonrecent kernel,
|
||
|
+for example), you may set this parameter to 0 to silence the associated
|
||
|
+warning.
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">
|
||
|
Unlock filesystem on stop?
|
||
|
@@ -141,7 +147,7 @@ Location of the rmtab backup, relative to directory.
|
||
|
|
||
|
<actions>
|
||
|
<action name="start" timeout="40" />
|
||
|
-<action name="stop" timeout="10" />
|
||
|
+<action name="stop" timeout="120" />
|
||
|
<action name="monitor" depth="0" timeout="20" interval="10" />
|
||
|
<action name="meta-data" timeout="5" />
|
||
|
<action name="validate-all" timeout="30" />
|
||
|
@@ -152,28 +158,41 @@ END
|
||
|
return $OCF_SUCCESS
|
||
|
}
|
||
|
|
||
|
+exportfs_methods() {
|
||
|
+ cat <<-!
|
||
|
+ start
|
||
|
+ stop
|
||
|
+ status
|
||
|
+ monitor
|
||
|
+ validate-all
|
||
|
+ methods
|
||
|
+ meta-data
|
||
|
+ usage
|
||
|
+ !
|
||
|
+}
|
||
|
+
|
||
|
backup_rmtab() {
|
||
|
- local rmtab_backup
|
||
|
- if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
|
||
|
- rmtab_backup="${OCF_RESKEY_directory}/${OCF_RESKEY_rmtab_backup}"
|
||
|
- grep ":${OCF_RESKEY_directory}:" /var/lib/nfs/rmtab > ${rmtab_backup}
|
||
|
- fi
|
||
|
+ local rmtab_backup
|
||
|
+ if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
|
||
|
+ rmtab_backup="${OCF_RESKEY_directory}/${OCF_RESKEY_rmtab_backup}"
|
||
|
+ grep ":${OCF_RESKEY_directory}:" /var/lib/nfs/rmtab > ${rmtab_backup}
|
||
|
+ fi
|
||
|
}
|
||
|
|
||
|
restore_rmtab() {
|
||
|
- local rmtab_backup
|
||
|
- if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
|
||
|
+ local rmtab_backup
|
||
|
+ if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
|
||
|
rmtab_backup="${OCF_RESKEY_directory}/${OCF_RESKEY_rmtab_backup}"
|
||
|
if [ -r ${rmtab_backup} ]; then
|
||
|
- local tmpf=`mktemp`
|
||
|
- sort -u ${rmtab_backup} /var/lib/nfs/rmtab > $tmpf &&
|
||
|
+ local tmpf=`mktemp`
|
||
|
+ sort -u ${rmtab_backup} /var/lib/nfs/rmtab > $tmpf &&
|
||
|
install -o root -m 644 $tmpf /var/lib/nfs/rmtab
|
||
|
- rm -f $tmpf
|
||
|
- ocf_log debug "Restored `wc -l ${rmtab_backup}` rmtab entries from ${rmtab_backup}."
|
||
|
+ rm -f $tmpf
|
||
|
+ ocf_log debug "Restored `wc -l ${rmtab_backup}` rmtab entries from ${rmtab_backup}."
|
||
|
else
|
||
|
- ocf_log warn "rmtab backup ${rmtab_backup} not found or not readable."
|
||
|
+ ocf_log warn "rmtab backup ${rmtab_backup} not found or not readable."
|
||
|
+ fi
|
||
|
fi
|
||
|
- fi
|
||
|
}
|
||
|
|
||
|
exportfs_usage() {
|
||
|
@@ -186,8 +205,8 @@ is_exported() {
|
||
|
local dir=$1
|
||
|
local spec=$2
|
||
|
exportfs |
|
||
|
- sed -e '$! N; s/\n[[:space:]]\+/ /; t; s/[[:space:]]\+\([^[:space:]]\+\)\(\n\|$\)/ \1\2/g; P;D;' |
|
||
|
- grep -q -x -F "$dir $spec"
|
||
|
+ sed -e '$! N; s/\n[[:space:]]\+/ /; t; s/[[:space:]]\+\([^[:space:]]\+\)\(\n\|$\)/ \1\2/g; P;D;' |
|
||
|
+ grep -q -x -F "$dir $spec"
|
||
|
}
|
||
|
|
||
|
exportfs_monitor ()
|
||
|
@@ -209,8 +228,10 @@ exportfs_monitor ()
|
||
|
#Adapt grep status code to OCF return code
|
||
|
case $rc in
|
||
|
0)
|
||
|
- ocf_log info "Directory ${OCF_RESKEY_directory} is exported to ${OCF_RESKEY_clientspec} (started)."
|
||
|
- # Backup the rmtab to ensure smooth NFS-over-TCP failover
|
||
|
+ if [ "$__OCF_ACTION" = "start" ]; then
|
||
|
+ ocf_log info "Directory ${OCF_RESKEY_directory} is exported to ${OCF_RESKEY_clientspec} (started)."
|
||
|
+ fi
|
||
|
+ # Backup the rmtab to ensure smooth NFS-over-TCP failover
|
||
|
backup_rmtab
|
||
|
return $OCF_SUCCESS
|
||
|
;;
|
||
|
@@ -324,60 +345,23 @@ exportfs_stop ()
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
-exportfs_validate ()
|
||
|
+exportfs_validate_all ()
|
||
|
{
|
||
|
- # Checks for required parameters
|
||
|
- if [ -z "$OCF_RESKEY_directory" ]; then
|
||
|
- ocf_log err "Missing required parameter \"directory\""
|
||
|
- exit $OCF_ERR_CONFIGURED
|
||
|
- fi
|
||
|
- if [ -z "$OCF_RESKEY_fsid" ]; then
|
||
|
- ocf_log err "Missing required parameter \"fsid\""
|
||
|
- exit $OCF_ERR_CONFIGURED
|
||
|
- fi
|
||
|
- if [ -z "$OCF_RESKEY_clientspec" ]; then
|
||
|
- ocf_log err "Missing required parameter \"clientspec\""
|
||
|
- exit $OCF_ERR_CONFIGURED
|
||
|
- fi
|
||
|
-
|
||
|
- # Checks applicable only to non-probes
|
||
|
- if ! ocf_is_probe; then
|
||
|
- if [ ! -d $OCF_RESKEY_directory ]; then
|
||
|
- ocf_log err "$OCF_RESKEY_directory does not exist or is not a directory"
|
||
|
- exit $OCF_ERR_INSTALLED
|
||
|
- fi
|
||
|
+ if [ ! -d $OCF_RESKEY_directory ]; then
|
||
|
+ ocf_log err "$OCF_RESKEY_directory does not exist or is not a directory"
|
||
|
+ return $OCF_ERR_INSTALLED
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
-if [ $# -ne 1 ]; then
|
||
|
- exportfs_usage
|
||
|
- exit $OCF_ERR_ARGS
|
||
|
+# If someone puts a trailing slash at the end of the export directory,
|
||
|
+# this agent is going to fail in some unexpected ways due to how
|
||
|
+# export strings are matched. The simplest solution here is to strip off
|
||
|
+# a trailing '/' in the directory before processing anything.
|
||
|
+newdir=$(echo "$OCF_RESKEY_directory" | sed -n -e 's/^\(.*\)\/$/\1/p')
|
||
|
+if [ -n "$newdir" ]; then
|
||
|
+ OCF_RESKEY_directory=$newdir
|
||
|
fi
|
||
|
|
||
|
-case $__OCF_ACTION in
|
||
|
- meta-data) exportfs_meta_data
|
||
|
- exit $OCF_SUCCESS
|
||
|
- ;;
|
||
|
- usage|help) exportfs_usage
|
||
|
- exit $OCF_SUCCESS
|
||
|
- ;;
|
||
|
- *)
|
||
|
- ;;
|
||
|
-esac
|
||
|
-
|
||
|
-exportfs_validate
|
||
|
-
|
||
|
-case $__OCF_ACTION in
|
||
|
- start) exportfs_start
|
||
|
- ;;
|
||
|
- stop) exportfs_stop
|
||
|
- ;;
|
||
|
- status|monitor) exportfs_monitor
|
||
|
- ;;
|
||
|
- validate-all)
|
||
|
- # nothing to do -- we're already validated
|
||
|
- ;;
|
||
|
- *) exportfs_usage
|
||
|
- exit $OCF_ERR_UNIMPLEMENTED
|
||
|
- ;;
|
||
|
-esac
|
||
|
+OCF_REQUIRED_PARAMS="directory fsid clientspec"
|
||
|
+OCF_REQUIRED_BINARIES="exportfs"
|
||
|
+ocf_rarun $*
|
||
|
diff --git a/heartbeat/nfsnotify b/heartbeat/nfsnotify
|
||
|
new file mode 100644
|
||
|
index 0000000..2e242de
|
||
|
--- /dev/null
|
||
|
+++ b/heartbeat/nfsnotify
|
||
|
@@ -0,0 +1,315 @@
|
||
|
+#!/bin/bash
|
||
|
+#
|
||
|
+# Copyright (c) 2014 David Vossel <dvossel@redhat.com>
|
||
|
+# All Rights Reserved.
|
||
|
+#
|
||
|
+# This program is free software; you can redistribute it and/or modify
|
||
|
+# it under the terms of version 2 of the GNU General Public License as
|
||
|
+# published by the Free Software Foundation.
|
||
|
+#
|
||
|
+# This program is distributed in the hope that it would be useful, but
|
||
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
+#
|
||
|
+# Further, this software is distributed without any warranty that it is
|
||
|
+# free of the rightful claim of any third person regarding infringement
|
||
|
+# or the like. Any license provided herein, whether implied or
|
||
|
+# otherwise, applies only to this software file. Patent licenses, if
|
||
|
+# any, provided herein do not apply to combinations of this program with
|
||
|
+# other software, or any other product whatsoever.
|
||
|
+#
|
||
|
+# You should have received a copy of the GNU General Public License
|
||
|
+# along with this program; if not, write the Free Software Foundation,
|
||
|
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||
|
+#
|
||
|
+
|
||
|
+#######################################################################
|
||
|
+# Initialization:
|
||
|
+
|
||
|
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||
|
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||
|
+. ${OCF_FUNCTIONS_DIR}/ocf-directories
|
||
|
+
|
||
|
+#######################################################################
|
||
|
+
|
||
|
+sbindir=$HA_SBIN_DIR
|
||
|
+if [ -z "$sbindir" ]; then
|
||
|
+ sbindir=/usr/sbin
|
||
|
+fi
|
||
|
+
|
||
|
+SELINUX_ENABLED=-1
|
||
|
+
|
||
|
+NFSNOTIFY_TMP_DIR="${HA_RSCTMP}/nfsnotify_${OCF_RESOURCE_INSTANCE}/"
|
||
|
+HA_STATD_PIDFILE="$NFSNOTIFY_TMP_DIR/rpc.statd_${OCF_RESOURCE_INSTANCE}.pid"
|
||
|
+HA_STATD_PIDFILE_PREV="$NFSNOTIFY_TMP_DIR/rpc.statd_${OCF_RESOURCE_INSTANCE}.pid.prev"
|
||
|
+STATD_PATH="/var/lib/nfs/statd"
|
||
|
+SM_NOTIFY_BINARY="${sbindir}/sm-notify"
|
||
|
+IS_RENOTIFY=0
|
||
|
+
|
||
|
+meta_data() {
|
||
|
+ cat <<END
|
||
|
+<?xml version="1.0"?>
|
||
|
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
||
|
+<resource-agent name="nfsnotify" version="0.9">
|
||
|
+<version>1.0</version>
|
||
|
+
|
||
|
+<longdesc lang="en">
|
||
|
+This agent sends NFSv3 reboot notifications to clients which informs clients to reclaim locks.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">sm-notify reboot notifications</shortdesc>
|
||
|
+
|
||
|
+<parameters>
|
||
|
+
|
||
|
+<parameter name="source_host" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+Comma separated list of floating IP addresses or host names that clients use
|
||
|
+to access the nfs service. This will be used to set the source address and
|
||
|
+mon_name of the SN_NOTIFY reboot notifications.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">source IP addresses</shortdesc>
|
||
|
+<content type="string" default="" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="notify_args" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+Additional arguments to send to the sm-notify command. By default
|
||
|
+this agent will always set sm-notify's '-f' option. When the
|
||
|
+source_host option is set, the '-v' option will be used automatically
|
||
|
+to set the proper source address. Any additional sm-notify arguments
|
||
|
+set with this option will be used in addition to the previous default
|
||
|
+arguments.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">sm-notify arguments</shortdesc>
|
||
|
+<content type="string" default="false" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+</parameters>
|
||
|
+
|
||
|
+<actions>
|
||
|
+<action name="start" timeout="90" />
|
||
|
+<action name="stop" timeout="90" />
|
||
|
+<action name="monitor" timeout="90" interval="30" depth="0" />
|
||
|
+<action name="reload" timeout="90" />
|
||
|
+<action name="meta-data" timeout="10" />
|
||
|
+<action name="validate-all" timeout="20" />
|
||
|
+</actions>
|
||
|
+</resource-agent>
|
||
|
+END
|
||
|
+}
|
||
|
+
|
||
|
+v3notify_usage()
|
||
|
+{
|
||
|
+ cat <<END
|
||
|
+usage: $0 {start|stop|monitor|validate-all|meta-data}
|
||
|
+
|
||
|
+Expects to have a fully populated OCF RA-compliant environment set.
|
||
|
+END
|
||
|
+}
|
||
|
+
|
||
|
+v3notify_validate()
|
||
|
+{
|
||
|
+ # check_binary will exit with OCF_ERR_INSTALLED when binary is missing
|
||
|
+ check_binary "$SM_NOTIFY_BINARY"
|
||
|
+ check_binary "pgrep"
|
||
|
+ check_binary "killall"
|
||
|
+
|
||
|
+ return $OCF_SUCCESS
|
||
|
+}
|
||
|
+
|
||
|
+killall_smnotify()
|
||
|
+{
|
||
|
+ # killall sm-notify
|
||
|
+ killall -TERM $SM_NOTIFY_BINARY > /dev/null 2>&1
|
||
|
+ if [ $? -eq 0 ]; then
|
||
|
+ # it is useful to know if sm-notify processes were actually left around
|
||
|
+ # or not during the stop/start operation. Whether this condition is true
|
||
|
+ # or false does not indicate a failure. It does indicate that
|
||
|
+ # there are probably some unresponsive nfs clients out there that are keeping
|
||
|
+ # the sm-notify processes retrying.
|
||
|
+ ocf_log info "previous sm-notify processes terminated before $__OCF_ACTION action."
|
||
|
+ fi
|
||
|
+}
|
||
|
+
|
||
|
+v3notify_stop()
|
||
|
+{
|
||
|
+ killall_smnotify
|
||
|
+
|
||
|
+ rm -f $HA_STATD_PIDFILE_PREV > /dev/null 2>&1
|
||
|
+ mv $HA_STATD_PIDFILE $HA_STATD_PIDFILE_PREV > /dev/null 2>&1
|
||
|
+
|
||
|
+ return $OCF_SUCCESS
|
||
|
+}
|
||
|
+
|
||
|
+check_statd_pidfile()
|
||
|
+{
|
||
|
+ local binary="rpc.statd"
|
||
|
+ local pidfile="$HA_STATD_PIDFILE"
|
||
|
+
|
||
|
+ ocf_log debug "Checking status for ${binary}."
|
||
|
+ if [ -e "$pidfile" ]; then
|
||
|
+ cat /proc/$(cat $pidfile)/cmdline 2>/dev/null | grep -a "${binary}" > /dev/null 2>&1
|
||
|
+ if [ $? -eq 0 ]; then
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ fi
|
||
|
+
|
||
|
+ ocf_log err "$(cat $pidfile) for $binary is no longer running, sm-notify needs to re-notify clients"
|
||
|
+ return $OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+
|
||
|
+ # if we don't have a pid file for rpc.statd, we have not yet sent the notifications
|
||
|
+ return $OCF_NOT_RUNNING
|
||
|
+}
|
||
|
+
|
||
|
+write_statd_pid()
|
||
|
+{
|
||
|
+ local binary="rpc.statd"
|
||
|
+ local pidfile="$HA_STATD_PIDFILE"
|
||
|
+ local pid
|
||
|
+
|
||
|
+ pid=$(pgrep ${binary})
|
||
|
+ case $? in
|
||
|
+ 0)
|
||
|
+ ocf_log info "PID file (pid:${pid} at $pidfile) created for ${binary}."
|
||
|
+ mkdir -p $(dirname $pidfile)
|
||
|
+ echo "$pid" > $pidfile
|
||
|
+ return $OCF_SUCCESS;;
|
||
|
+ 1)
|
||
|
+ rm -f "$pidfile" > /dev/null 2>&1
|
||
|
+ ocf_log info "$binary is not running"
|
||
|
+ return $OCF_NOT_RUNNING;;
|
||
|
+ *)
|
||
|
+ rm -f "$pidfile" > /dev/null 2>&1
|
||
|
+ ocf_log err "Error encountered detecting pid status of $binary"
|
||
|
+ return $OCF_ERR_GENERIC;;
|
||
|
+ esac
|
||
|
+}
|
||
|
+
|
||
|
+copy_statd()
|
||
|
+{
|
||
|
+ local src=$1
|
||
|
+ local dest=$2
|
||
|
+
|
||
|
+ if ! [ -d "$dest" ]; then
|
||
|
+ mkdir -p "$dest"
|
||
|
+ fi
|
||
|
+
|
||
|
+ cp -rpfn $src/sm $src/sm.bak $src/state $dest > /dev/null 2>&1
|
||
|
+
|
||
|
+ # make sure folder ownership and selinux lables stay consistent
|
||
|
+ [ -n "`id -u rpcuser`" -a "`id -g rpcuser`" ] && chown rpcuser.rpcuser "$dest"
|
||
|
+ [ $SELINUX_ENABLED -eq 0 ] && chcon -R "$SELINUX_LABEL" "$dest"
|
||
|
+}
|
||
|
+
|
||
|
+v3notify_start()
|
||
|
+{
|
||
|
+ local rc=$OCF_SUCCESS
|
||
|
+ local cur_statd
|
||
|
+ local statd_backup
|
||
|
+ local is_renotify=0
|
||
|
+
|
||
|
+ # monitor, see if we need to notify or not
|
||
|
+ v3notify_monitor
|
||
|
+ if [ $? -eq 0 ]; then
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ fi
|
||
|
+
|
||
|
+ # kill off any other sm-notify processes that might already be running.
|
||
|
+ killall_smnotify
|
||
|
+
|
||
|
+ # record the pid of rpc.statd. if this pid ever changes, we have to re-notify
|
||
|
+ write_statd_pid
|
||
|
+ rc=$?
|
||
|
+ if [ $rc -ne 0 ]; then
|
||
|
+ return $rc
|
||
|
+ fi
|
||
|
+
|
||
|
+ # if the last time we ran nfs-notify, it was with the same statd process,
|
||
|
+ # consider this a re-notification. During re-notifications we do not let the
|
||
|
+ # sm-notify binary have access to the real statd directory.
|
||
|
+ if [ "$(cat $HA_STATD_PIDFILE)" = "$(cat $HA_STATD_PIDFILE_PREV 2>/dev/null)" ]; then
|
||
|
+ ocf_log info "Renotifying clients"
|
||
|
+ is_renotify=1
|
||
|
+ fi
|
||
|
+
|
||
|
+ statd_backup="$STATD_PATH/nfsnotify.bu"
|
||
|
+ copy_statd "$STATD_PATH" "$statd_backup"
|
||
|
+
|
||
|
+ if [ -z "$OCF_RESKEY_source_host" ]; then
|
||
|
+ if [ "$is_renotify" -eq 0 ]; then
|
||
|
+ cur_statd="$STATD_PATH"
|
||
|
+ else
|
||
|
+ cur_statd="$statd_backup"
|
||
|
+ fi
|
||
|
+ ocf_log info "sending notifications on default source address."
|
||
|
+ $SM_NOTIFY_BINARY -f $OCF_RESKEY_notify_args -P $cur_statd
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ ocf_log err "sm-notify failed, view syslog for more information."
|
||
|
+ return $OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ fi
|
||
|
+
|
||
|
+ # do sm-notify for each ip
|
||
|
+ for ip in `echo ${OCF_RESKEY_source_host} | sed 's/,/ /g'`; do
|
||
|
+
|
||
|
+ # have the first sm-notify use the actual statd directory so the
|
||
|
+ # notify list can be managed properly.
|
||
|
+ if [ "$is_renotify" -eq 0 ]; then
|
||
|
+ cur_statd="$STATD_PATH"
|
||
|
+ # everything after the first notify we are considering a renotification
|
||
|
+ # which means we don't use the real statd directory.
|
||
|
+ is_renotify=1
|
||
|
+ else
|
||
|
+ # use our copied statd directory for the remaining ip addresses
|
||
|
+ cur_statd="$STATD_PATH/nfsnotify_${OCF_RESOURCE_INSTANCE}_${ip}"
|
||
|
+ copy_statd "$statd_backup" "$cur_statd"
|
||
|
+ fi
|
||
|
+
|
||
|
+ ocf_log info "sending notifications with source address $ip"
|
||
|
+ $SM_NOTIFY_BINARY -f $OCF_RESKEY_notify_args -v $ip -P "$cur_statd"
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ ocf_log err "sm-notify with source host set to, $source_host, failed. view syslog for more information"
|
||
|
+ return $OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+ done
|
||
|
+
|
||
|
+ return $OCF_SUCCESS
|
||
|
+}
|
||
|
+
|
||
|
+v3notify_monitor()
|
||
|
+{
|
||
|
+ # verify rpc.statd is up, and that the rpc.statd pid is the same one we
|
||
|
+ # found during the start. otherwise rpc.statd recovered and we need to notify
|
||
|
+ # again.
|
||
|
+ check_statd_pidfile
|
||
|
+}
|
||
|
+
|
||
|
+case $__OCF_ACTION in
|
||
|
+ meta-data) meta_data
|
||
|
+ exit $OCF_SUCCESS;;
|
||
|
+ usage|help) v3notify_usage
|
||
|
+ exit $OCF_SUCCESS;;
|
||
|
+ *)
|
||
|
+ ;;
|
||
|
+esac
|
||
|
+
|
||
|
+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
|
||
|
+
|
||
|
+case $__OCF_ACTION in
|
||
|
+ start) v3notify_start;;
|
||
|
+ stop) v3notify_stop;;
|
||
|
+ monitor) v3notify_monitor;;
|
||
|
+ validate-all) v3notify_validate;;
|
||
|
+ *) v3notify_usage
|
||
|
+ exit $OCF_ERR_UNIMPLEMENTED;;
|
||
|
+esac
|
||
|
+
|
||
|
+rc=$?
|
||
|
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
|
||
|
+exit $rc
|
||
|
+
|
||
|
diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
|
||
|
index bc326e5..e44da1c 100755
|
||
|
--- a/heartbeat/nfsserver
|
||
|
+++ b/heartbeat/nfsserver
|
||
|
@@ -13,13 +13,22 @@ else
|
||
|
fi
|
||
|
|
||
|
DEFAULT_INIT_SCRIPT="/etc/init.d/nfsserver"
|
||
|
-DEFAULT_NOTIFY_CMD="/sbin/sm-notify"
|
||
|
+if ! [ -f $DEFAULT_INIT_SCRIPT ]; then
|
||
|
+ # On some systems, the script is just called nfs
|
||
|
+ DEFAULT_INIT_SCRIPT="/etc/init.d/nfs"
|
||
|
+fi
|
||
|
+
|
||
|
+DEFAULT_NOTIFY_CMD=`which sm-notify`
|
||
|
+DEFAULT_NOTIFY_CMD=${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=""
|
||
|
+NFS_SYSCONFIG="/etc/sysconfig/nfs"
|
||
|
+NFS_SYSCONFIG_LOCAL_BACKUP="/etc/sysconfig/nfs.ha.bu"
|
||
|
+NFS_SYSCONFIG_AUTOGEN_TAG="AUTOGENERATED by $0 high availability resource-agent"
|
||
|
|
||
|
nfsserver_meta_data() {
|
||
|
cat <<END
|
||
|
@@ -53,21 +62,19 @@ Init script for nfsserver
|
||
|
<content type="string" default="auto detected" />
|
||
|
</parameter>
|
||
|
|
||
|
-<parameter name="nfs_notify_cmd" unique="0" required="0">
|
||
|
+<parameter name="nfs_no_notify" 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 occurrence of failover.
|
||
|
+Do not send reboot notifications to NFSv3 clients during server startup.
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">
|
||
|
-The tool to send out notification.
|
||
|
+Disable NFSv3 server reboot notifications
|
||
|
</shortdesc>
|
||
|
-<content type="string" default="$DEFAULT_NOTIFY_CMD" />
|
||
|
+<content type="boolean" default="false" />
|
||
|
</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.
|
||
|
+Keeps the sm-notify attached to its controlling terminal and running in the foreground.
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">
|
||
|
Keeps the notify tool running in the foreground.
|
||
|
@@ -87,25 +94,102 @@ Specifies the length of sm-notify retry time (minutes).
|
||
|
<content type="integer" default="" />
|
||
|
</parameter>
|
||
|
|
||
|
-<parameter name="nfs_shared_infodir" unique="0" required="1">
|
||
|
+<parameter name="nfs_ip" unique="0" required="0">
|
||
|
<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.
|
||
|
+Comma separated list of floating IP addresses used to access the nfs service
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">
|
||
|
-Directory to store nfs server related information.
|
||
|
+IP addresses.
|
||
|
</shortdesc>
|
||
|
-<content type="string" default="" />
|
||
|
+<content type="string"/>
|
||
|
</parameter>
|
||
|
|
||
|
-<parameter name="nfs_ip" unique="0" required="1">
|
||
|
+<parameter name="nfsd_args" unique="0" required="0">
|
||
|
<longdesc lang="en">
|
||
|
-Comma separated list of floating IP addresses used to access the nfs service
|
||
|
+Specifies what arguments to pass to the nfs daemon on startup. View the rpc.nfsd man page for information on what arguments are available.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">
|
||
|
-IP addresses.
|
||
|
+rpc.nfsd options
|
||
|
</shortdesc>
|
||
|
-<content type="string"/>
|
||
|
+<content type="string" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="lockd_udp_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The udp port lockd should listen on.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+lockd udp port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="lockd_tcp_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The tcp port lockd should listen on.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+lockd tcp port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="statd_outgoing_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The source port number sm-notify uses when sending reboot notifications.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+sm-notify source port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="statd_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The port number used for RPC listener sockets.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+rpc.statd listener port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="mountd_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The port number used for rpc.mountd listener sockets.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+rpc.mountd listener port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="rquotad_port" unique="0" required="0">
|
||
|
+<longdesc lang="en">
|
||
|
+The port number used for rpc.rquotad.
|
||
|
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
|
||
|
+</longdesc>
|
||
|
+<shortdesc lang="en">
|
||
|
+rpc.rquotad port
|
||
|
+</shortdesc>
|
||
|
+<content type="integer" />
|
||
|
+</parameter>
|
||
|
+
|
||
|
+<parameter name="nfs_shared_infodir" unique="0" required="0">
|
||
|
+<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="rpcpipefs_dir" unique="0" required="0">
|
||
|
@@ -228,6 +312,7 @@ set_exec_mode()
|
||
|
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
|
||
|
+ # when using systemd, the nfs-lock service file handles nfsv3 locking daemons for us.
|
||
|
return 0
|
||
|
fi
|
||
|
fi
|
||
|
@@ -236,33 +321,6 @@ set_exec_mode()
|
||
|
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.
|
||
|
##
|
||
|
@@ -273,21 +331,45 @@ nfs_exec()
|
||
|
|
||
|
case $EXEC_MODE in
|
||
|
1) ${OCF_RESKEY_nfs_init_script} $cmd;;
|
||
|
- 2) nfs_systemd_exec $cmd;;
|
||
|
+ 2) systemctl $cmd nfs-server.service ;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
+v3locking_exec()
|
||
|
+{
|
||
|
+ local cmd=$1
|
||
|
+ set_exec_mode
|
||
|
+
|
||
|
+ if [ $EXEC_MODE -eq 2 ]; then
|
||
|
+ systemctl $cmd nfs-lock.service
|
||
|
+ else
|
||
|
+ case $cmd in
|
||
|
+ start) locking_start;;
|
||
|
+ stop) locking_stop;;
|
||
|
+ status) locking_status;;
|
||
|
+ esac
|
||
|
+ fi
|
||
|
+}
|
||
|
+
|
||
|
nfsserver_monitor ()
|
||
|
{
|
||
|
fn=`mktemp`
|
||
|
nfs_exec status > $fn 2>&1
|
||
|
rc=$?
|
||
|
- ocf_log debug `cat $fn`
|
||
|
+ ocf_log debug "$(cat $fn)"
|
||
|
rm -f $fn
|
||
|
|
||
|
-#Adapte LSB status code to OCF return code
|
||
|
+ #Adapte LSB status code to OCF return code
|
||
|
if [ $rc -eq 0 ]; then
|
||
|
- return $OCF_SUCCESS
|
||
|
+ # don't report success if nfs servers are up
|
||
|
+ # without locking daemons.
|
||
|
+ v3locking_exec "status"
|
||
|
+ rc=$?
|
||
|
+ if [ $rc -ne 0 ]; then
|
||
|
+ ocf_log error "NFS server is up, but the locking daemons are down"
|
||
|
+ rc=$OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+ return $rc
|
||
|
elif [ $rc -eq 3 ]; then
|
||
|
return $OCF_NOT_RUNNING
|
||
|
else
|
||
|
@@ -295,8 +377,79 @@ nfsserver_monitor ()
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
+set_arg()
|
||
|
+{
|
||
|
+ local key="$1"
|
||
|
+ local value="$2"
|
||
|
+ local file="$3"
|
||
|
+ local requires_sysconfig="$4"
|
||
|
+
|
||
|
+ if [ -z "$value" ]; then
|
||
|
+ return
|
||
|
+ fi
|
||
|
+
|
||
|
+ # only write to the tmp /etc/sysconfig/nfs if sysconfig exists.
|
||
|
+ # otherwise this distro does not support setting these options.
|
||
|
+ if [ -d "/etc/sysconfig" ]; then
|
||
|
+ echo "${key}=\"${value}\"" >> $file
|
||
|
+ elif [ "$requires_sysconfig" = "true" ]; then
|
||
|
+ ocf_log warn "/etc/sysconfig/nfs not found, unable to set port and nfsd args."
|
||
|
+ fi
|
||
|
+
|
||
|
+ export ${key}="${value}"
|
||
|
+}
|
||
|
+
|
||
|
+set_env_args()
|
||
|
+{
|
||
|
+ local tmpconfig=$(mktemp ${HA_RSCTMP}/nfsserver-tmp-XXXXX)
|
||
|
+ local statd_args
|
||
|
+
|
||
|
+ # nfsd args
|
||
|
+ set_arg "RPCNFSDARGS" "$OCF_RESKEY_nfsd_args" "$tmpconfig" "true"
|
||
|
+
|
||
|
+ # mountd args
|
||
|
+ if [ -n "$OCF_RESKEY_mountd_port" ]; then
|
||
|
+ set_arg "RPCMOUNTDOPTS" "-p $OCF_RESKEY_mountd_port" "$tmpconfig" "true"
|
||
|
+ fi
|
||
|
+
|
||
|
+ # statd args. we always want to perform the notify using sm-notify after
|
||
|
+ # both rpc.statd and the nfsd daemons are initialized
|
||
|
+ statd_args="--no-notify"
|
||
|
+ if [ -n "$OCF_RESKEY_statd_outgoing_port" ]; then
|
||
|
+ statd_args="$statd_args -o $OCF_RESKEY_statd_outgoing_port"
|
||
|
+ fi
|
||
|
+ if [ -n "$OCF_RESKEY_statd_port" ]; then
|
||
|
+ statd_args="$statd_args -p $OCF_RESKEY_statd_port"
|
||
|
+ fi
|
||
|
+ set_arg "STATDARG" "$statd_args" "$tmpconfig" "false"
|
||
|
+
|
||
|
+ # lockd ports
|
||
|
+ set_arg "LOCKD_UDPPORT" "$OCF_RESKEY_lockd_udp_port" "$tmpconfig" "true"
|
||
|
+ set_arg "LOCKD_TCPPORT" "$OCF_RESKEY_lockd_tcp_port" "$tmpconfig" "true"
|
||
|
+
|
||
|
+ # rquotad_port
|
||
|
+ set_arg "RPCRQUOTADOPTS" "-p $OCF_RESKEY_rquotad_port" "$tmpconfig" "true"
|
||
|
+
|
||
|
+ # override local nfs config. preserve previous local config though.
|
||
|
+ if [ -s $tmpconfig ]; then
|
||
|
+ cat $NFS_SYSCONFIG | grep -e "$NFS_SYSCONFIG_AUTOGEN_TAG"
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ # backup local nfs config if it doesn't have our HA autogen tag in it.
|
||
|
+ mv -f $NFS_SYSCONFIG $NFS_SYSCONFIG_LOCAL_BACKUP
|
||
|
+ fi
|
||
|
+ echo "# $NFS_SYSCONFIG_AUTOGEN_TAG" > $NFS_SYSCONFIG
|
||
|
+ echo "# local config backup stored here, '$NFS_SYSCONFIG_LOCAL_BACKUP'" >> $NFS_SYSCONFIG
|
||
|
+ cat $tmpconfig >> $NFS_SYSCONFIG
|
||
|
+ fi
|
||
|
+ rm -f $tmpconfig
|
||
|
+}
|
||
|
+
|
||
|
prepare_directory ()
|
||
|
{
|
||
|
+ if [ -z "$fp" ]; then
|
||
|
+ return
|
||
|
+ fi
|
||
|
+
|
||
|
[ -d "$fp" ] || mkdir -p $fp
|
||
|
[ -d "$rpcpipefs_make_dir" ] || mkdir -p $rpcpipefs_make_dir
|
||
|
[ -d "$fp/v4recovery" ] || mkdir -p $fp/v4recovery
|
||
|
@@ -311,6 +464,8 @@ prepare_directory ()
|
||
|
[ -f "$fp/xtab" ] || touch "$fp/xtab"
|
||
|
[ -f "$fp/rmtab" ] || touch "$fp/rmtab"
|
||
|
|
||
|
+ dd if=/dev/urandom of=$fp/$STATD_DIR/state bs=1 count=4 &> /dev/null
|
||
|
+ [ -n "`id -u rpcuser`" -a "`id -g rpcuser`" ] && chown rpcuser.rpcuser "$fp/$STATD_DIR/state"
|
||
|
[ $SELINUX_ENABLED -eq 0 ] && chcon -R "$SELINUX_LABEL" "$fp"
|
||
|
}
|
||
|
|
||
|
@@ -325,6 +480,10 @@ is_bound ()
|
||
|
|
||
|
bind_tree ()
|
||
|
{
|
||
|
+ if [ -z "$fp" ]; then
|
||
|
+ return
|
||
|
+ fi
|
||
|
+
|
||
|
if is_bound /var/lib/nfs; then
|
||
|
ocf_log debug "$fp is already bound to /var/lib/nfs"
|
||
|
return 0
|
||
|
@@ -343,25 +502,195 @@ unbind_tree ()
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
+binary_status()
|
||
|
+{
|
||
|
+ local binary=$1
|
||
|
+ local pid
|
||
|
+
|
||
|
+ pid=$(pgrep ${binary})
|
||
|
+ case $? in
|
||
|
+ 0)
|
||
|
+ echo "$pid"
|
||
|
+ return $OCF_SUCCESS;;
|
||
|
+ 1)
|
||
|
+ return $OCF_NOT_RUNNING;;
|
||
|
+ *)
|
||
|
+ return $OCF_ERR_GENERIC;;
|
||
|
+ esac
|
||
|
+}
|
||
|
+
|
||
|
+locking_status()
|
||
|
+{
|
||
|
+ binary_status "rpc.statd" > /dev/null 2>&1
|
||
|
+}
|
||
|
+
|
||
|
+locking_start()
|
||
|
+{
|
||
|
+ local ret=$OCF_SUCCESS
|
||
|
+
|
||
|
+ ocf_log info "Starting rpc.statd."
|
||
|
+
|
||
|
+ rpc.statd $STATDARG
|
||
|
+
|
||
|
+ ret=$?
|
||
|
+ if [ $ret -ne 0 ]; then
|
||
|
+ ocf_log err "Failed to start rpc.statd"
|
||
|
+ return $ret
|
||
|
+ fi
|
||
|
+ touch /var/lock/subsys/nfslock
|
||
|
+
|
||
|
+ return $ret
|
||
|
+}
|
||
|
+
|
||
|
+terminate()
|
||
|
+{
|
||
|
+ declare pids
|
||
|
+ declare i=0
|
||
|
+
|
||
|
+ while : ; do
|
||
|
+ pids=$(binary_status $1)
|
||
|
+ [ -z "$pids" ] && return 0
|
||
|
+ kill $pids
|
||
|
+ sleep 1
|
||
|
+ ((i++))
|
||
|
+ [ $i -gt 3 ] && return 1
|
||
|
+ done
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+killkill()
|
||
|
+{
|
||
|
+ declare pids
|
||
|
+ declare i=0
|
||
|
+
|
||
|
+ while : ; do
|
||
|
+ pids=$(binary_status $1)
|
||
|
+ [ -z "$pids" ] && return 0
|
||
|
+ kill -9 $pids
|
||
|
+ sleep 1
|
||
|
+ ((i++))
|
||
|
+ [ $i -gt 3 ] && return 1
|
||
|
+ done
|
||
|
+}
|
||
|
+
|
||
|
+stop_process()
|
||
|
+{
|
||
|
+ declare process=$1
|
||
|
+
|
||
|
+ ocf_log info "Stopping $process"
|
||
|
+ if terminate $process; then
|
||
|
+ ocf_log debug "$process is stopped"
|
||
|
+ else
|
||
|
+ if killkill $process; then
|
||
|
+ ocf_log debug "$process is stopped"
|
||
|
+ else
|
||
|
+ ocf_log debug "Failed to stop $process"
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+ fi
|
||
|
+ return 0
|
||
|
+}
|
||
|
+
|
||
|
+locking_stop()
|
||
|
+{
|
||
|
+ ret=0
|
||
|
+
|
||
|
+ # sm-notify can prevent umount of /var/lib/nfs/statd if
|
||
|
+ # it is still trying to notify unresponsive clients.
|
||
|
+ stop_process sm-notify
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ ret=$OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+
|
||
|
+ stop_process rpc.statd
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ ret=$OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+
|
||
|
+ return $ret
|
||
|
+}
|
||
|
+
|
||
|
+notify_locks()
|
||
|
+{
|
||
|
+ if ocf_is_true "$OCF_RESKEY_nfs_no_notify"; then
|
||
|
+ # we've been asked not to notify clients
|
||
|
+ return;
|
||
|
+ fi
|
||
|
+
|
||
|
+ # 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
|
||
|
+
|
||
|
+ if [ -n "$OCF_RESKEY_statd_outgoing_port" ]; then
|
||
|
+ opts="$opts -p $OCF_RESKEY_statd_outgoing_port"
|
||
|
+ fi
|
||
|
+
|
||
|
+ # forces re-notificaiton regardless if notifies have already gone out
|
||
|
+ opts="$opts -f"
|
||
|
+
|
||
|
+ ocf_log info "executing sm-notify"
|
||
|
+ if [ -n "$OCF_RESKEY_nfs_ip" ]; then
|
||
|
+ for ip in `echo ${OCF_RESKEY_nfs_ip} | sed 's/,/ /g'`; do
|
||
|
+ cp -rpfn $STATD_PATH/sm.ha/* $STATD_PATH/ > /dev/null 2>&1
|
||
|
+ sm-notify $opts -v $ip
|
||
|
+ done
|
||
|
+ else
|
||
|
+ sm-notify $opts
|
||
|
+ fi
|
||
|
+}
|
||
|
+
|
||
|
nfsserver_start ()
|
||
|
{
|
||
|
+ local rc;
|
||
|
+
|
||
|
if nfsserver_monitor; then
|
||
|
ocf_log debug "NFS server is already started"
|
||
|
return $OCF_SUCCESS
|
||
|
fi
|
||
|
|
||
|
+ set_env_args
|
||
|
prepare_directory
|
||
|
bind_tree
|
||
|
|
||
|
+ # remove the sm-notify pid so sm-notify will be allowed to run again without requiring a reboot.
|
||
|
+ rm -f /var/run/sm-notify.pid
|
||
|
+ #
|
||
|
+ # Synchronize these before starting statd
|
||
|
+ #
|
||
|
+ cp -rpfn $STATD_PATH/sm.ha/* $STATD_PATH/ > /dev/null 2>&1
|
||
|
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
|
||
|
+ cp -rpf $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 ..."
|
||
|
|
||
|
+ # mounts /proc/fs/nfsd for us
|
||
|
+ lsmod | grep -q nfsd
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ modprobe nfsd
|
||
|
+ fi
|
||
|
+
|
||
|
+ # check to see if we need to start rpc.statd
|
||
|
+ v3locking_exec "status"
|
||
|
+ if [ $? -ne $OCF_SUCCESS ]; then
|
||
|
+ v3locking_exec "start"
|
||
|
+ rc=$?
|
||
|
+ if [ $rc -ne 0 ]; then
|
||
|
+ ocf_log error "Failed to start NFS server locking daemons"
|
||
|
+ return $rc
|
||
|
+ fi
|
||
|
+ else
|
||
|
+ ocf_log info "rpc.statd already up"
|
||
|
+ fi
|
||
|
+
|
||
|
fn=`mktemp`
|
||
|
nfs_exec start > $fn 2>&1
|
||
|
rc=$?
|
||
|
- ocf_log debug `cat $fn`
|
||
|
+ ocf_log debug "$(cat $fn)"
|
||
|
rm -f $fn
|
||
|
|
||
|
if [ $rc -ne 0 ]; then
|
||
|
@@ -369,42 +698,7 @@ nfsserver_start ()
|
||
|
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
|
||
|
-
|
||
|
+ notify_locks
|
||
|
|
||
|
ocf_log info "NFS server started"
|
||
|
return $OCF_SUCCESS
|
||
|
@@ -414,12 +708,23 @@ nfsserver_stop ()
|
||
|
{
|
||
|
ocf_log info "Stopping NFS server ..."
|
||
|
|
||
|
+ # backup the current sm state information to the ha folder before stopping.
|
||
|
+ # the ha folder will be synced after startup, restoring the statd client state
|
||
|
+ rm -rf $STATD_PATH/sm.ha/* > /dev/null 2>&1
|
||
|
+ cp -rpf $STATD_PATH/sm $STATD_PATH/sm.bak /var/lib/nfs/state $STATD_PATH/sm.ha > /dev/null 2>&1
|
||
|
+
|
||
|
fn=`mktemp`
|
||
|
nfs_exec stop > $fn 2>&1
|
||
|
rc=$?
|
||
|
- ocf_log debug `cat $fn`
|
||
|
+ ocf_log debug "$(cat $fn)"
|
||
|
rm -f $fn
|
||
|
|
||
|
+ v3locking_exec "stop"
|
||
|
+ if [ $? -ne 0 ]; then
|
||
|
+ ocf_log err "Failed to stop NFS locking daemons"
|
||
|
+ rc=$OCF_ERR_GENERIC
|
||
|
+ fi
|
||
|
+
|
||
|
if [ $rc -eq 0 ]; then
|
||
|
unbind_tree
|
||
|
ocf_log info "NFS server stopped"
|
||
|
@@ -437,13 +742,9 @@ nfsserver_validate ()
|
||
|
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"
|
||
|
+ if [ -n "$OCF_RESKEY_CRM_meta_clone" ] && [ -n "$OCF_RESKEY_nfs_shared_infodir" ]; then
|
||
|
+ ocf_log err "This RA does not support clone mode when a shared info directory is in use."
|
||
|
exit $OCF_ERR_CONFIGURED
|
||
|
fi
|
||
|
|
||
|
@@ -465,11 +766,6 @@ nfsserver_validate ()
|
||
|
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
|
||
|
--
|
||
|
1.8.4.2
|
||
|
|