ctdb-scripts: Add test variable CTDB_NFS_DISTRO_STYLE
[vlendec/samba-autobuild/.git] / ctdb / config / nfs-linux-kernel-callout
1 #!/bin/sh
2
3 # Exit on 1st error
4 set -e
5
6 # NFS exports file.  Some code below keeps a cache of output derived
7 # from exportfs(8).  When this file is updated the cache is invalid
8 # and needs to be regenerated.
9 #
10 # To change the file, edit the default value below.  Do not set
11 # CTDB_NFS_EXPORTS_FILE - it isn't a configuration variable, just a
12 # hook for testing.
13 nfs_exports_file="${CTDB_NFS_EXPORTS_FILE:-/var/lib/nfs/etab}"
14
15 # As above, edit the default value below.  CTDB_NFS_DISTRO_STYLE is a
16 # test variable only.
17 nfs_distro_style="${CTDB_NFS_DISTRO_STYLE:-sysvinit-redhat}"
18
19 case "$nfs_distro_style" in
20 sysvinit-*)
21         # Defaults
22         nfs_service="nfs"
23         nfs_lock_service=""
24         nfs_config="/etc/sysconfig/nfs"
25
26         case "$nfs_distro_style" in
27         *-redhat)
28                 nfs_lock_service="nfslock"
29                 ;;
30         *-suse)
31                 nfs_service="nfsserver"
32                 ;;
33         *-debian)
34                 nfs_service="nfs-kernel-server"
35                 nfs_config="/etc/default/nfs-kernel-server"
36                 ;;
37         *)
38                 echo "Internal error"
39                 exit 1
40         esac
41         ;;
42
43 *)
44         echo "Internal error"
45         exit 1
46 esac
47
48 # Override for unit testing
49 if [ -z "$PROCFS_PATH" ] ; then
50     PROCFS_PATH="/proc"
51 fi
52
53 ##################################################
54
55 usage ()
56 {
57     _c=$(basename "$0")
58     cat <<EOF
59 usage: $_c { shutdown | startup }
60        $_c { stop | start } { nfs | nlockmgr }
61        $_c { monitor-list-shares | monitor-post }
62        $_c { register }
63 EOF
64     exit 1
65 }
66
67
68 ##################################################
69 # Basic service stop and start
70
71 basic_stop ()
72 {
73         case "$1" in
74         nfs)
75                 service "$nfs_service" stop
76                 if [ -n "$nfs_lock_service" ] ; then
77                         service "$nfs_lock_service" stop
78                 fi
79                 ;;
80         nfslock)
81                 if [ -n "$nfs_lock_service" ] ; then
82                         service "$nfs_lock_service" stop
83                 else
84                         service "$nfs_service" stop
85                 fi
86                 ;;
87         *)
88                 usage
89         esac
90 }
91
92 basic_start ()
93 {
94         case "$1" in
95         nfs)
96                 if [ -n "$nfs_lock_service" ] ; then
97                         service "$nfs_lock_service" start
98                 fi
99                 service "$nfs_service" start
100                 ;;
101         nfslock)
102                 if [ -n "$nfs_lock_service" ] ; then
103                         service "$nfs_lock_service" start
104                 else
105                         service "$nfs_service" start
106                 fi
107                 ;;
108         *)
109                 usage
110         esac
111 }
112
113 ##################################################
114 # service "stop" and "start" options for restarting
115
116 service_stop ()
117 {
118         case "$1" in
119         nfs)
120                 echo 0 >"${PROCFS_PATH}/fs/nfsd/threads"
121                 basic_stop "nfs" >/dev/null 2>&1 || true
122                 pkill -9 nfsd
123                 ;;
124         nlockmgr)
125                 basic_stop "nfslock" >/dev/null 2>&1 || true
126                 ;;
127         *)
128                 usage
129         esac
130 }
131
132 service_start ()
133 {
134         case "$1" in
135         nfs)
136                 basic_start "nfs"
137                 ;;
138         nlockmgr)
139                 basic_start "nfslock"
140                 ;;
141         *)
142                 usage
143         esac
144 }
145
146 ##################################################
147 # service init startup and final shutdown
148
149 nfs_shutdown ()
150 {
151     basic_stop "nfs"
152 }
153
154 nfs_startup ()
155 {
156     basic_stop "nfs" || true
157     basic_start "nfs"
158     _f="${PROCFS_PATH}/sys/net/ipv4/tcp_tw_recycle"
159     if [ "$_f" ] ; then
160         echo 1 >"$_f"
161     fi
162 }
163
164 ##################################################
165 # monitor-post support
166
167 nfs_check_thread_count ()
168 {
169     # Load NFS configuration to get desired number of threads.
170     if [ -r "$nfs_config" ] ; then
171         . "$nfs_config"
172     fi
173
174     # If $RPCNFSDCOUNT/$USE_KERNEL_NFSD_NUMBER isn't set then we could
175     # guess the default from the initscript.  However, let's just
176     # assume that those using the default don't care about the number
177     # of threads and that they have switched on this feature in error.
178     _configured_threads="${RPCNFSDCOUNT:-${USE_KERNEL_NFSD_NUMBER}}"
179     [ -n "$_configured_threads" ] || return 0
180
181     _threads_file="${PROCFS_PATH}/fs/nfsd/threads"
182
183     # nfsd should be running the configured number of threads.  If
184     # there are a different number of threads then tell nfsd the
185     # correct number.
186     read _running_threads <"$_threads_file" || {
187             echo "WARNING: Reading \"${_threads_file}\" unexpectedly failed"
188             exit 0
189     }
190
191     # Intentionally not arithmetic comparison - avoids extra errors
192     # when above read fails in an unexpected way...
193     if [ "$_running_threads" != "$_configured_threads" ] ; then
194         echo "Attempting to correct number of nfsd threads from ${_running_threads} to ${_configured_threads}"
195         echo "$_configured_threads" >"$_threads_file"
196     fi
197 }
198
199 ##################################################
200 # list share directories
201
202 nfs_monitor_list_shares ()
203 {
204     _cache_file="${CTDB_NFS_CALLOUT_STATE_DIR}/list_shares_cache"
205     # -nt operator is well supported in Linux: dash, bash, ksh, ...
206     # shellcheck disable=SC2039
207     if  [ ! -r "$nfs_exports_file" ] || [ ! -r "$_cache_file" ] || \
208             [ "$nfs_exports_file" -nt "$_cache_file" ] ; then
209         mkdir -p "$CTDB_NFS_CALLOUT_STATE_DIR"
210         # We could just use the contents of $nfs_exports_file.
211         # However, let's regard that file as internal to NFS and use
212         # exportfs, which is the public API.
213         if ! _exports=$(exportfs -v) ; then
214             echo "WARNING: failed to run exportfs to list NFS shares" >&2
215             return
216         fi
217
218         echo "$_exports" |
219             grep '^/' |
220             sed -e 's@[[:space:]][[:space:]]*[^[:space:]()][^[:space:]()]*([^[:space:]()][^[:space:]()]*)$@@' |
221             sort -u >"$_cache_file"
222     fi
223
224     cat "$_cache_file"
225 }
226
227 ##################################################
228
229 nfs_register ()
230 {
231     cat <<EOF
232 shutdown
233 startup
234 stop
235 start
236 monitor-list-shares
237 monitor-post
238 EOF
239 }
240
241 ##################################################
242
243 case "$1" in
244     shutdown)
245         nfs_shutdown
246         ;;
247     startup)
248         nfs_startup
249         ;;
250     stop)
251         service_stop "$2"
252         ;;
253     start)
254         service_start "$2"
255         ;;
256     monitor-list-shares)
257         nfs_monitor_list_shares
258         ;;
259     monitor-post)
260         nfs_check_thread_count
261         ;;
262     register)
263         nfs_register
264         ;;
265     monitor-pre|releaseip|takeip|releaseip-pre|takeip-pre)
266         # Not required/implemented
267         :
268         ;;
269     *)
270         usage
271 esac