3 # This is an example CTDB NFS callout script for Ganesha. It is based
4 # on the last version of 60.ganesha shipped with CTDB. As such, it
5 # does not try to monitor RPC services that were not monitored by
6 # 60.ganesha - this might be a useful improvement. It has also not
7 # been properly tested.
9 # You should check your version of NFS Ganesha to see if it ships with
14 # * Set CTDB_NFS_CALLOUT in your CTDB configuration to point to (a
15 # copy of) this script, making sure it is executable.
17 # * Create a new directory alongside the nfs-checks.d directory, for
18 # example nfs-checks-ganesha.d. Install 20.nfs-ganesha.check in
19 # this directory. Symlink to any other check files from
20 # nfs-checks.d that should still be used, such as
21 # 00.portmapper.check. Set CTDB_NFS_CHECKS_DIR to point to this new
22 # directory of check files.
24 # * It is recommended, but not required, to install the grace_period
25 # script (usually shipped in a utils package for NFS-Ganesha) to
26 # /usr/bin/grace_period
28 # I (Martin Schwenke) hereby relicense all of my contributions to this
29 # callout (and, previously, to 60.ganesha) to a license compatible
30 # with NFS Ganesha (right now this is LGPLv3, but I'm flexible).
31 # There may be other contributions to be considered for relicensing,
32 # particularly those in commit 28cbe527d47822f870e8252495ab2a1c8fddd12f.
34 ######################################################################
39 # Filesystem type and mount point for the (typically clustered)
40 # volume that will contain the NFS-Ganesha state.
41 state_fs="${CTDB_NFS_STATE_FS_TYPE:-gpfs}"
42 state_dir="${CTDB_NFS_STATE_MNT}" # No sane default.
44 # To change the following, edit the default values below. Do not set
45 # these - they aren't configuration variables, just hooks for testing.
46 nfs_exports_file="${CTDB_NFS_EXPORTS_FILE:-/etc/ganesha/ganesha.conf}"
47 nfs_service="${CTDB_NFS_SERVICE:-nfs-ganesha}"
48 ganesha_rec_subdir=${CTDB_GANESHA_REC_SUBDIR:-.ganesha}
49 procfs=${PROCFS_PATH:-/proc}
53 GANRECDIR="/var/lib/nfs/ganesha"
56 if [ -z "${state_dir}" ]; then
57 echo "CTDB_NFS_STATE_MNT not defined for GlusterFS"
61 NODESTATEDIR="$state_dir/nfs-ganesha/$host"
62 GANSTATEDIR="$state_dir/nfs-ganesha/.noderefs"
63 NODESTATELN="$GANSTATEDIR/$host"
68 ##################################################
74 usage: $_c { shutdown | startup }
75 $_c { stop | start | check } nfs
76 $_c { releaseip | takeip }
77 $_c { monitor-list-shares }
83 ##################################################
84 # Basic service stop and start
90 service "$nfs_service" stop
101 service "$nfs_service" start
108 ##################################################
109 # "stop" and "start" options for restarting
118 # Do nothing - used by statd-callout
133 # Do nothing - used by statd-callout
141 ##################################################
142 # Nitty gritty - monitoring and IP handling
144 # Check that a symlink exists, create it otherwise.
145 # Usage: check_ln <TARGET> <LINK>
148 if [ ! -L "${2}" ] ; then
151 _t=$(readlink "${2}")
152 if [ "$_t" != "${1}" ] ; then
156 # This is not an "else". It also re-creates the link if it was
158 if [ ! -e "${2}" ]; then
159 ln -sfv "${1}" "${2}"
163 # Return 'active' if the shared filesystem is accessible.
164 get_cluster_fs_state ()
168 /usr/lpp/mmfs/bin/mmgetstate | awk 'NR == 4 { print $3 }'
171 # Since we're past create_ganesha_recdirs(), we're active.
175 echo "File system $state_fs not supported"
181 create_ganesha_recdirs ()
183 if ! _mounts=$(mount | grep "$state_fs"); then
184 echo "Failed to find mounts of type $state_fs"
187 if [ -z "$_mounts" ]; then
188 echo "startup $state_fs not ready"
194 _mntpt=$(echo "$_mounts" | sort | awk 'NR == 1 {print $3}')
195 _link_dst="${_mntpt}/${ganesha_rec_subdir}"
196 mkdir -vp "$_link_dst"
197 check_ln "$_link_dst" "$GANRECDIR"
200 [ -d /var/lib/nfs.backup ] || \
201 mv /var/lib/nfs /var/lib/nfs.backup
202 check_ln "$NODESTATEDIR" /var/lib/nfs
204 mkdir -p "${NODESTATEDIR}/ganesha/v4recov"
205 mkdir -p "${NODESTATEDIR}/ganesha/v4old"
206 mkdir -p "${NODESTATEDIR}/statd/sm"
207 mkdir -p "${NODESTATEDIR}/statd/sm.bak"
208 touch "${NODESTATEDIR}/state"
209 touch "${NODESTATEDIR}/statd/state"
211 mkdir -p "$GANSTATEDIR"
212 check_ln "$NODESTATEDIR" "$NODESTATELN"
213 for _dir in "${GANSTATEDIR}/"* ; do
214 # Handle no directories case
215 if [ ! -d "$_dir" ] ; then
219 _node="${_dir##*/}" # basename
220 if [ "${_node}" != "${host}" ]; then
221 check_ln "${GANSTATEDIR}/${_node}/ganesha" \
222 "${NODESTATEDIR}/ganesha/${_node}"
223 check_ln "${GANSTATEDIR}/${_node}/statd" \
224 "${NODESTATEDIR}/statd/${_node}"
233 create_ganesha_recdirs
235 # Always succeed if cluster filesystem is not active
236 _cluster_fs_state=$(get_cluster_fs_state)
237 if [ "$_cluster_fs_state" != "active" ] ; then
241 # Check that NFS Ganesha is running, according to PID file
242 _pidfile="/var/run/ganesha.pid"
243 _ganesha="/usr/bin/ganesha.nfsd"
244 if ! { read -r _pid < "$_pidfile" && \
245 grep "$_ganesha" "${procfs}/${_pid}/cmdline" ; } >/dev/null 2>&1
248 echo "ERROR: NFS Ganesha not running according to PID file"
255 #-------------------------------------------------
259 if [ -x "/usr/bin/grace_period" ]; then
260 /usr/bin/grace_period "2:${2}"
262 dbus-send --print-reply --system --dest=org.ganesha.nfsd \
263 /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace \
272 check_ln "$NODESTATEDIR" "${GANSTATEDIR}/${2}"
275 if [ -x "/usr/bin/grace_period" ]; then
276 /usr/bin/grace_period "5:${2}"
278 dbus-send --print-reply --system --dest=org.ganesha.nfsd \
279 /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace \
284 ##################################################
285 # service init startup and final shutdown
294 basic_stop "nfs" || true
296 create_ganesha_recdirs
299 _f="${procfs}/sys/net/ipv4/tcp_tw_recycle"
300 if [ -f "$_f" ] ; then
305 ##################################################
306 # list share directories
308 nfs_monitor_list_shares ()
310 grep Path "$nfs_exports_file" |
315 ##################################################
331 ##################################################
337 shutdown) nfs_shutdown ;;
338 startup) nfs_startup ;;
339 stop) service_stop "$1" ;;
340 start) service_start "$1" ;;
341 check) service_check "$1" ;;
342 releaseip) nfs_releaseip "$@" ;;
343 takeip) nfs_takeip "$@" ;;
344 monitor-list-shares) nfs_monitor_list_shares ;;
345 register) nfs_register ;;
346 monitor-pre|monitor-post|releaseip-pre|takeip-pre)
347 # Not required/implemented