ctdb-scripts: Add GlusterFS support to nfs-ganesha-callout
[Samba.git] / ctdb / doc / examples / nfs-ganesha-callout
blob34794c19adef3bd358d4858f1e95bc7fd85d33b6
1 #!/bin/sh
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
10 # a newer callout.
12 # To use this:
14 # * Set CTDB_NFS_CALLOUT in your CTDB configuration to point to this
15 # script
17 # * Rename the following files in nfs-checks.d so that they no longer
18 # have the ".check" suffix:
19 # * 10.status.check
20 # * 20.nfs.check
21 # * 30.nlockmgr.check
22 # * 40.mountd.check
23 # * 50.rquotad.check
25 # * Install 20.nfs-ganesha.check to nfs-checks.d/20.nfs.check
27 # * It is recommended, but not required, to install the grace_period
28 # script (usually shipped in a utils package for NFS-Ganesha) to
29 # /usr/bin/grace_period
31 # I (Martin Schwenke) hereby relicense all of my contributions to this
32 # callout (and, previously, to 60.ganesha) to a license compatible
33 # with NFS Ganesha (right now this is LGPLv3, but I'm flexible).
34 # There may be other contributions to be considered for relicensing,
35 # particularly those in commit 28cbe527d47822f870e8252495ab2a1c8fddd12f.
37 ######################################################################
39 # Exit on 1st error
40 set -e
42 # Filesystem type and mount point for the (typically clustered)
43 # volume that will contain the NFS-Ganesha state.
44 state_fs="${CTDB_NFS_STATE_FS_TYPE:-gpfs}"
45 state_dir="${CTDB_NFS_STATE_MNT}" # No sane default.
47 # To change the following, edit the default values below. Do not set
48 # these - they aren't configuration variables, just hooks for testing.
49 nfs_exports_file="${CTDB_NFS_EXPORTS_FILE:-/etc/ganesha/ganesha.conf}"
50 nfs_service="${CTDB_NFS_SERVICE:-nfs-ganesha}"
51 ganesha_rec_subdir=${CTDB_GANESHA_REC_SUBDIR:-.ganesha}
52 procfs=${PROCFS_PATH:-/proc}
54 case $state_fs in
55 gpfs)
56 GANRECDIR="/var/lib/nfs/ganesha"
58 glusterfs)
59 if [ -z "${state_dir}" ]; then
60 echo "CTDB_NFS_STATE_MNT not defined for GlusterFS"
61 exit 1
63 host=`hostname`
64 NODESTATEDIR="$state_dir/nfs-ganesha/$host"
65 GANSTATEDIR="$state_dir/nfs-ganesha/.noderefs"
66 NODESTATELN="$GANSTATEDIR/$host"
68 esac
71 ##################################################
73 usage ()
75 _c=$(basename $0)
76 cat <<EOF
77 usage: $_c { shutdown | startup }
78 $_c { stop | start | check } nfs
79 $_c { releaseip | takeip }
80 $_c { monitor-list-shares }
81 EOF
82 exit 1
86 ##################################################
87 # Basic service stop and start
89 basic_stop ()
91 case "$1" in
92 nfs)
93 service "$nfs_service" stop
96 usage
97 esac
100 basic_start ()
102 case "$1" in
103 nfs)
104 service "$nfs_service" start
107 usage
108 esac
111 ##################################################
112 # "stop" and "start" options for restarting
114 service_stop ()
116 case "$1" in
117 nfs)
118 basic_stop "nfs"
120 nlockmgr)
121 # Do nothing - used by statd-callout
125 usage
126 esac
129 service_start ()
131 case "$1" in
132 nfs)
133 basic_start "nfs"
135 nlockmgr)
136 # Do nothing - used by statd-callout
140 usage
141 esac
144 ##################################################
145 # Nitty gritty - monitoring and IP handling
147 # Check that a symlink exists, create it otherwise.
148 # Usage: check_ln <TARGET> <LINK>
149 check_ln ()
151 if [ ! -L "${2}" ] ; then
152 rm -vrf "${2}"
153 else
154 _t=$(readlink "${2}")
155 if [ "$_t" != "${1}" ] ; then
156 rm -v "${2}"
159 # This is not an "else". It also re-creates the link if it was
160 # removed above!
161 if [ ! -e "${2}" ]; then
162 ln -sfv "${1}" "${2}"
166 # Return 'active' if the shared filesystem is accessible.
167 get_cluster_fs_state ()
169 case $state_fs in
170 gpfs)
171 /usr/lpp/mmfs/bin/mmgetstate | awk 'NR == 4 { print $3 }'
173 glusterfs)
174 # Since we're past create_ganesha_recdirs(), we're active.
175 echo "active"
178 echo "File system $state_fs not supported"
179 exit 1
181 esac
184 create_ganesha_recdirs ()
186 if ! _mounts=$(mount | grep $state_fs); then
187 echo "Failed to find mounts of type $state_fs"
188 exit 1
190 if [ -z "$_mounts" ]; then
191 echo "startup $state_fs not ready"
192 exit 0
195 case $state_fs in
196 gpfs)
197 _mntpt=$(echo "$_mounts" | sort | awk 'NR == 1 {print $3}')
198 _link_dst="${_mntpt}/${ganesha_rec_subdir}"
199 mkdir -vp "$_link_dst"
200 check_ln "$_link_dst" "$GANRECDIR"
202 glusterfs)
203 [ -d /var/lib/nfs.backup ] || mv /var/lib/nfs /var/lib/nfs.backup
204 check_ln ${NODESTATEDIR} /var/lib/nfs
206 mkdir -p ${NODESTATEDIR}/ganesha/v4recov
207 mkdir -p ${NODESTATEDIR}/ganesha/v4old
208 mkdir -p ${NODESTATEDIR}/statd/sm
209 mkdir -p ${NODESTATEDIR}/statd/sm.bak
210 touch ${NODESTATEDIR}/state
211 touch ${NODESTATEDIR}/statd/state
213 mkdir -p ${GANSTATEDIR}
214 check_ln ${NODESTATEDIR} ${NODESTATELN}
215 for node in `ls ${GANSTATEDIR}`; do
216 if [ "${node}" != "${host}" ]; then
217 check_ln ${GANSTATEDIR}/${node}/ganesha ${NODESTATEDIR}/ganesha/${node}
218 check_ln ${GANSTATEDIR}/${node}/statd ${NODESTATEDIR}/statd/${node}
220 done
222 esac
225 service_check ()
227 create_ganesha_recdirs
229 # Always succeed if cluster filesystem is not active
230 _cluster_fs_state=$(get_cluster_fs_state)
231 if [ $_cluster_fs_state != "active" ] ; then
232 return 0
235 # Check that NFS Ganesha is running, according to PID file
236 _pidfile="/var/run/ganesha.pid"
237 _ganesha="/usr/bin/ganesha.nfsd"
238 if ! { read _pid < "$_pidfile" && \
239 grep "$_ganesha" "${procfs}/${_pid}/cmdline" ; } >/dev/null 2>&1 ; then
240 echo "ERROR: NFS Ganesha not running according to PID file"
241 return 1
244 return 0
247 #-------------------------------------------------
249 nfs_releaseip ()
251 if [ -x "/usr/bin/grace_period" ]; then
252 /usr/bin/grace_period "2:${2}"
253 else
254 dbus-send --print-reply --system --dest=org.ganesha.nfsd \
255 /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace \
256 string:"2:${2}"
260 nfs_takeip ()
262 case $state_fs in
263 glusterfs)
264 check_ln ${NODESTATEDIR} ${GANSTATEDIR}/${2}
266 esac
267 if [ -x "/usr/bin/grace_period" ]; then
268 /usr/bin/grace_period "5:${2}"
269 else
270 dbus-send --print-reply --system --dest=org.ganesha.nfsd \
271 /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace \
272 string:"5:${2}"
276 ##################################################
277 # service init startup and final shutdown
279 nfs_shutdown ()
281 basic_stop "nfs"
284 nfs_startup ()
286 basic_stop "nfs" || true
288 create_ganesha_recdirs
290 basic_start "nfs"
291 _f="${procfs}/sys/net/ipv4/tcp_tw_recycle"
292 if [ "$_f" ] ; then
293 echo 1 >"$_f"
297 ##################################################
298 # list share directories
300 nfs_monitor_list_shares ()
302 grep Path $nfs_exports_file |
303 cut -f2 -d\" |
304 sort -u
307 ##################################################
309 nfs_register ()
311 cat <<EOF
312 shutdown
313 startup
314 stop
315 start
316 check
317 releaseip
318 takeip
319 monitor-list-shares
323 ##################################################
325 action="$1"
326 shift
328 case "$action" in
329 shutdown) nfs_shutdown ;;
330 startup) nfs_startup ;;
331 stop) service_stop "$1" ;;
332 start) service_start "$1" ;;
333 check) service_check "$1" ;;
334 releaseip) nfs_releaseip "$@" ;;
335 takeip) nfs_takeip "$@" ;;
336 monitor-list-shares) nfs_monitor_list_shares ;;
337 register) nfs_register ;;
338 monitor-pre|monitor-post)
339 # Not required/implemented
343 usage
344 esac