Merge branch 'test_suite' into ronnie_target
[nivanova/samba-autobuild/.git] / ctdb / config / events.d / 50.samba
1 #!/bin/sh
2 # ctdb event script for Samba
3
4 . $CTDB_BASE/functions
5
6 detect_init_style
7
8 case $CTDB_INIT_STYLE in
9         suse)
10                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
11                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-nmb}
12                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
13                 ;;
14         debian)
15                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-samba}
16                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
17                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
18                 ;;
19         *)
20                 # should not happen, but for now use redhat style as default:
21                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
22                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
23                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
24                 ;;
25 esac
26
27 service_name="samba"
28 service_start="start_samba"
29 service_stop="stop_samba"
30
31 loadconfig
32
33 start_samba() {
34         # create the state directory for samba
35         mkdir -p $CTDB_VARDIR/state/samba
36
37         # make sure samba is not already started
38         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
39                 service "$CTDB_SERVICE_SMB" stop > /dev/null 2>&1
40                 service "$CTDB_SERVICE_NMB" stop > /dev/null 2>&1
41                 killall -0 -q smbd && {
42                     sleep 1
43                     # make absolutely sure samba is dead
44                     killall -q -9 smbd
45                 }
46
47                 killall -0 -q nmbd && {
48                     sleep 1
49                     # make absolutely sure samba is dead
50                     killall -q -9 nmbd
51                 }
52         }
53
54         # make sure winbind is not already started
55         check_ctdb_manages_winbind
56         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
57                 service "$CTDB_SERVICE_WINBIND" stop > /dev/null 2>&1
58                 killall -0 -q winbindd && {
59                     sleep 1
60                     # make absolutely sure winbindd is dead
61                     killall -q -9 winbindd
62                 }
63
64         }
65
66         # start the winbind service
67         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
68                 service "$CTDB_SERVICE_WINBIND" start || {
69                         echo failed to start winbind
70                         exit 1
71                 }
72
73         }
74
75         # start Samba service. Start it reniced, as under very heavy load 
76         # the number of smbd processes will mean that it leaves few cycles for
77         # anything else
78         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
79                 net serverid wipe
80
81                 nice_service "$CTDB_SERVICE_NMB" start || {
82                         echo failed to start nmbd
83                         exit 1
84                 }
85
86                 nice_service "$CTDB_SERVICE_SMB" start || {
87                         echo failed to start samba
88                         exit 1
89                 }
90         }
91         return 0
92 }
93
94 stop_samba() {
95         # shutdown Samba when ctdb goes down
96         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
97                 service "$CTDB_SERVICE_SMB" stop
98                 service "$CTDB_SERVICE_NMB" stop
99         }
100
101         # stop the winbind service
102         check_ctdb_manages_winbind
103         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
104                 service "$CTDB_SERVICE_WINBIND" stop
105         }
106
107         return 0
108 }
109
110 # set default samba cleanup period - in minutes
111 [ -z "$SAMBA_CLEANUP_PERIOD" ] && {
112     SAMBA_CLEANUP_PERIOD=10
113 }
114
115 # we keep a cached copy of smb.conf here
116 smbconf_cache="$CTDB_VARDIR/state/samba/smb.conf.cache"
117
118
119 #############################################
120 # update the smb.conf cache in the foreground
121 testparm_foreground_update() {
122     mkdir -p "$CTDB_VARDIR/state/samba" || exit 1
123     testparm -s 2> /dev/null | egrep -v 'registry.shares.=|include.=' > "$smbconf_cache"
124 }
125
126 #############################################
127 # update the smb.conf cache in the background
128 testparm_background_update() {
129     # if the cache doesn't exist, then update in the foreground
130     [ -f $smbconf_cache ] || {
131         testparm_foreground_update
132     }
133     # otherwise do a background update
134     (
135         tmpfile="${smbconf_cache}.$$"
136         testparm -s > $tmpfile 2> /dev/null &
137         # remember the pid of the teamparm process
138         pid="$!"
139         # give it 10 seconds to run
140         timeleft=10
141         while [ $timeleft -gt 0 ]; do
142             timeleft=$(($timeleft - 1))
143             # see if the process still exists
144             kill -0 $pid > /dev/null 2>&1 || {
145                 # it doesn't exist, grab its exit status
146                 wait $pid
147                 [ $? = 0 ] || {
148                     echo "50.samba: smb.conf background update exited with status $?"
149                     rm -f "${tmpfile}"
150                     exit 1
151                 }               
152                 # put the new smb.conf contents in the cache (atomic rename)
153                 # make sure we remove references to the registry while doing 
154                 # this to ensure that running testparm on the cache does
155                 # not use the registry
156                 egrep -v 'registry.shares.=|include.=' < "$tmpfile" > "${tmpfile}.2"
157                 rm -f "$tmpfile"
158                 mv -f "${tmpfile}.2" "$smbconf_cache" || {
159                     echo "50.samba: failed to update background cache"
160                     rm -f "${tmpfile}.2"
161                     exit 1
162                 }
163                 exit 0
164             }
165             # keep waiting for testparm to finish
166             sleep 1
167         done
168         # it took more than 10 seconds - kill it off
169         rm -f "${tmpfile}"
170         kill -9 "$pid" > /dev/null 2>&1
171         echo "50.samba: timed out updating smbconf cache in background"
172         exit 1
173     ) &
174 }
175
176 ##################################################
177 # show the testparm output using a cached smb.conf 
178 # to avoid registry access
179 testparm_cat() {
180     [ -f $smbconf_cache ] || {
181         testparm_foreground_update
182     }
183     testparm -s "$smbconf_cache" "$@" 2>/dev/null
184 }
185
186 # function to see if ctdb manages winbind
187 check_ctdb_manages_winbind() {
188   [ -z "$CTDB_MANAGES_WINBIND" ] && {
189     secmode=`testparm_cat --parameter-name=security`
190     case $secmode in
191         ADS|DOMAIN)
192             CTDB_MANAGES_WINBIND="yes";
193             ;;
194         *)
195             CTDB_MANAGES_WINBIND="no";
196             ;;
197     esac
198   }
199 }
200
201 list_samba_shares ()
202 {
203     testparm_cat |
204     sed -n -e 's@^[[:space:]]*path[[:space:]]*=[[:space:]]@@p' |
205     sed -e 's/"//g'
206 }
207
208
209 ###########################
210 # periodic cleanup function
211 periodic_cleanup() {
212     # running smbstatus scrubs any dead entries from the connections
213     # and sessionid database
214     # echo "Running periodic cleanup of samba databases"
215     smbstatus -np > /dev/null 2>&1 &
216 }
217
218 ###########################
219
220 [ "$1" = "monitor" ] && {
221 ctdb_start_stop_service
222 ctdb_start_stop_service "winbind"
223 }
224
225 is_ctdb_managed_service || is_ctdb_managed_service "winbind" || exit 0
226
227 ###########################
228
229 case "$1" in 
230      startup)
231         ctdb_service_start
232         ;;
233         
234      shutdown)
235         ctdb_service_stop
236         ;;
237
238      monitor)
239         # Create a dummy file to track when we need to do periodic cleanup
240         # of samba databases
241         [ -f $CTDB_VARDIR/state/samba/periodic_cleanup ] || {
242                 touch $CTDB_VARDIR/state/samba/periodic_cleanup
243         }
244         [ `find $CTDB_VARDIR/state/samba/periodic_cleanup -mmin +$SAMBA_CLEANUP_PERIOD | wc -l` -eq 1 ] && {
245                 # Cleanup the databases
246                 periodic_cleanup
247                 touch $CTDB_VARDIR/state/samba/periodic_cleanup
248         }
249
250         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
251                 [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" = "yes" ] || {
252                         testparm_background_update
253
254                         testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
255                             testparm_foreground_update
256                             testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
257                                 echo "ERROR: testparm shows smb.conf is not clean"
258                                 exit 1
259                             }
260                         }
261                         
262                         list_samba_shares |
263                         ctdb_check_directories_probe || {
264                             testparm_foreground_update
265                             list_samba_shares |
266                             ctdb_check_directories
267                         } || exit $?
268                 }
269
270                 smb_ports="$CTDB_SAMBA_CHECK_PORTS"
271                 [ -z "$smb_ports" ] && {
272                         smb_ports=`testparm_cat --parameter-name="smb ports"`
273                 }
274                 ctdb_check_tcp_ports $smb_ports || exit $?
275         }
276
277         # check winbind is OK
278         check_ctdb_manages_winbind
279         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
280                 ctdb_check_command "winbind" "wbinfo -p"
281         }
282         ;;
283
284      takeip|releaseip)
285         iface=$2
286         ip=$3
287         maskbits=$4
288
289         smbcontrol winbindd ip-dropped $ip >/dev/null 2>/dev/null
290         ;;
291     *)
292         ctdb_standard_event_handler "$@"
293         ;;
294 esac
295
296 exit 0