ctdb-scripts: Add registration for CTDB_NFS_CALLOUT operations
[Samba.git] / ctdb / config / events.d / 60.nfs
blobfce6beb911838f02ac30cf83b5f6a06e3b78f3a0
1 #!/bin/sh
2 # script to manage nfs in a clustered environment
4 [ -n "$CTDB_BASE" ] || \
5 export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD")
7 . $CTDB_BASE/functions
9 service_name="nfs"
10 loadconfig
11 ctdb_setup_service_state_dir
13 ######################################################################
15 if [ -z "$CTDB_NFS_CALLOUT" ] ; then
16 CTDB_NFS_CALLOUT="${CTDB_BASE}/nfs-linux-kernel-callout"
18 # Always export, for statd callout
19 export CTDB_NFS_CALLOUT
21 nfs_callout_cache="${service_state_dir}/nfs_callout_cache"
22 nfs_callout_cache_callout="${nfs_callout_cache}/CTDB_NFS_CALLOUT"
23 nfs_callout_cache_ops="${nfs_callout_cache}/ops"
25 nfs_callout_register ()
27 mkdir -p "$nfs_callout_cache_ops"
28 rm -f "$nfs_callout_cache_ops"/*
30 echo "$CTDB_NFS_CALLOUT" >"$nfs_callout_cache_callout"
32 _t=$(eval "$CTDB_NFS_CALLOUT" "register")
33 if [ -n "$_t" ] ; then
34 echo "$_t" |
35 while IFS="" read _op ; do
36 touch "${nfs_callout_cache_ops}/${_op}"
37 done
38 else
39 touch "${nfs_callout_cache_ops}/ALL"
43 nfs_callout ()
45 # Re-run registration if $CTDB_NFS_CALLOUT has changed
46 _prev=""
47 if [ -r "$nfs_callout_cache_callout" ] ; then
48 read _prev <"$nfs_callout_cache_callout"
50 if [ "$CTDB_NFS_CALLOUT" != "$_prev" ] ; then
51 nfs_callout_register
54 # Run the operation if it is registered...
55 if [ -e "${nfs_callout_cache_ops}/${1}" ] || \
56 [ -e "${nfs_callout_cache_ops}/ALL" ]; then
57 eval "$CTDB_NFS_CALLOUT" "$@"
61 service_reconfigure ()
63 # Restart lock manager, notify clients
64 if [ -x "${CTDB_BASE}/statd-callout" ] ; then
65 "${CTDB_BASE}/statd-callout" notify &
66 fi >/dev/null 2>&1
69 ######################################################################
71 ######################################################
72 # Check the health of NFS services
74 # Use .check files in given directory.
75 # Default is "${CTDB_BASE}/nfs-checks.d/"
76 ######################################################
77 nfs_check_services ()
79 _dir="${1:-${CTDB_NFS_CHECKS_DIR:-${CTDB_BASE}/nfs-checks.d}}"
81 # Files must end with .check - avoids editor backups, RPM fu, ...
82 for _f in "$_dir"/[0-9][0-9].*.check ; do
83 _t="${_f%.check}"
84 _progname="${_t##*/[0-9][0-9].}"
86 nfs_check_service "$_progname" <"$_f"
87 done
90 ######################################################
91 # Check the health of an NFS service
93 # $1 - progname, passed to rpcinfo (looked up in /etc/rpc)
95 # Reads variables from stdin
97 # Variables are:
99 # * family - "tcp" or "udp" or space separated list
100 # default: tcp, not used with "service_check_cmd"
101 # * version - optional, RPC service version number
102 # default is to omit to check for any version,
103 # not used with "service_check_cmd"
104 # * unhealthy_after - number of check fails before unhealthy
105 # default: 1
106 # * restart_every - number of check fails before restart
107 # default: 0, meaning no restart
108 # * service_stop_cmd - command to stop service
109 # default: no default, must be provided if
110 # restart_every > 0
111 # * service_start_cmd - command to start service
112 # default: no default, must be provided if
113 # restart_every > 0
114 # * service_check_cmd - command to check health of service
115 # default is to check RPC service using rpcinfo
116 # * service_debug_cmd - command to debug a service after trying to stop it;
117 # for example, it can be useful to print stack
118 # traces of threads that have not exited, since
119 # they may be stuck doing I/O;
120 # no default, see also function program_stack_traces()
122 # Quoting in values is not preserved
124 ######################################################
125 nfs_check_service ()
127 _progname="$1"
130 # Subshell to restrict scope variables...
132 # Defaults
133 family="tcp"
134 version=""
135 unhealthy_after=1
136 restart_every=0
137 service_stop_cmd=""
138 service_start_cmd=""
139 service_check_cmd=""
140 service_debug_cmd=""
142 # Eval line-by-line. Expands variable references in values.
143 # Also allows variable name checking, which seems useful.
144 while read _line ; do
145 case "$_line" in
146 \#*|"") : ;; # Ignore comments, blank lines
148 family=*|version=*|\
149 unhealthy_after=*|restart_every=*|\
150 service_stop_cmd=*|service_start_cmd=*|\
151 service_check_cmd=*|service_debug_cmd=*)
153 eval "$_line"
156 echo "ERROR: Unknown variable for ${_progname}: ${_line}"
157 exit 1
158 esac
159 done
161 _service_name="nfs_${_progname}"
163 _ok=false
164 if [ -n "$service_check_cmd" ] ; then
165 # Using eval means variables can contain semicolon separated commands
166 if eval "$service_check_cmd" ; then
167 _ok=true
169 else
170 if nfs_check_rpcinfo \
171 "$_progname" "$version" "$family" >/dev/null ; then
172 _ok=true
176 if $_ok ; then
177 if [ $unhealthy_after -ne 1 -o $restart_every -ne 0 ] ; then
178 ctdb_counter_init "$_service_name"
180 exit 0
183 ctdb_counter_incr "$_service_name"
184 _failcount=$(ctdb_counter_get "$_service_name")
186 _unhealthy=false
187 if [ $unhealthy_after -gt 0 ] ; then
188 if [ $_failcount -ge $unhealthy_after ] ; then
189 _unhealthy=true
190 echo "ERROR: $ctdb_check_rpc_out"
194 if [ $restart_every -gt 0 ] ; then
195 if [ $(($_failcount % $restart_every)) -eq 0 ] ; then
196 if ! $_unhealthy ; then
197 echo "WARNING: $ctdb_check_rpc_out"
199 nfs_restart_service
203 if $_unhealthy ; then
204 exit 1
207 return 0
208 ) || exit 1
211 # Uses: stop_service, start_service, debug_stuck_threads
212 nfs_restart_service ()
214 if [ -z "$service_stop_cmd" -o -z "$service_start_cmd" ] ; then
215 die "ERROR: Can not restart service \"${_progname}\" without corresponding service_start_cmd/service_stop_cmd settings"
218 echo "Trying to restart service \"${_progname}\"..."
219 # Using eval means variables can contain semicolon separated commands
220 eval "$service_stop_cmd"
221 if [ -n "$service_debug_cmd" ] ; then
222 eval "$service_debug_cmd"
224 background_with_logging eval "$service_start_cmd"
227 ######################################################
228 # Check an RPC service with rpcinfo
229 ######################################################
230 ctdb_check_rpc ()
232 _progname="$1" # passed to rpcinfo (looked up in /etc/rpc)
233 _version="$2" # optional, not passed if empty/unset
234 _family="${3:-tcp}" # optional, default is "tcp"
236 _localhost="${CTDB_RPCINFO_LOCALHOST:-127.0.0.1}"
238 if ! ctdb_check_rpc_out=$(rpcinfo -T $_family $_localhost \
239 $_progname $_version 2>&1) ; then
240 ctdb_check_rpc_out="$_progname failed RPC check:
241 $ctdb_check_rpc_out"
242 echo "$ctdb_check_rpc_out"
243 return 1
247 nfs_check_rpcinfo ()
249 _progname="$1" # passed to rpcinfo (looked up in /etc/rpc)
250 _versions="$2" # optional, space separated, not passed if empty/unset
251 _families="${3:-tcp}" # optional, space separated, default is "tcp"
253 for _family in $_families ; do
254 if [ -n "$_versions" ] ; then
255 for _version in $_versions ; do
256 ctdb_check_rpc $_progname $_version $_family || return $?
257 done
258 else
259 ctdb_check_rpc $_progname "" $_family || return $?
261 done
264 ##################################################################
265 # use statd-callout to update NFS lock info
266 ##################################################################
267 nfs_update_lock_info ()
269 if [ -x "$CTDB_BASE/statd-callout" ] ; then
270 "$CTDB_BASE/statd-callout" update
274 ######################################################################
276 ctdb_start_stop_service
278 is_ctdb_managed_service || exit 0
280 ctdb_service_check_reconfigure
282 case "$1" in
283 startup)
284 nfs_callout "$@"
287 shutdown)
288 nfs_callout "$@"
291 takeip)
292 nfs_callout "$@"
293 ctdb_service_set_reconfigure
296 releaseip)
297 nfs_callout "$@"
298 ctdb_service_set_reconfigure
301 monitor)
302 nfs_callout "monitor-pre" || exit $?
304 # Check that directories for shares actually exist
305 if [ "$CTDB_NFS_SKIP_SHARE_CHECK" != "yes" ] ; then
306 nfs_callout "monitor-list-shares" | ctdb_check_directories || \
307 exit $?
310 update_tickles 2049
311 nfs_update_lock_info
313 nfs_check_services
315 nfs_callout "monitor-post" || exit $?
319 ctdb_standard_event_handler "$@"
321 esac
323 exit 0