More eventscript cleanups. Initial smoke testing seems OK.
[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 [ "$CTDB_MANAGES_SAMBA" = "yes" ] || [ "$CTDB_MANAGES_WINBIND" = "yes" ] || exit 0
34
35 start_samba() {
36         # create the state directory for samba
37         /bin/mkdir -p $CTDB_BASE/state/samba
38
39         # make sure samba is not already started
40         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
41                 service "$CTDB_SERVICE_SMB" stop > /dev/null 2>&1
42                 service "$CTDB_SERVICE_NMB" stop > /dev/null 2>&1
43                 killall -0 -q smbd && {
44                     sleep 1
45                     # make absolutely sure samba is dead
46                     killall -q -9 smbd
47                 }
48
49                 killall -0 -q nmbd && {
50                     sleep 1
51                     # make absolutely sure samba is dead
52                     killall -q -9 nmbd
53                 }
54         }
55
56         # restart the winbind service
57         check_ctdb_manages_winbind
58         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
59                 service "$CTDB_SERVICE_WINBIND" stop > /dev/null 2>&1
60                 killall -0 -q winbindd && {
61                     sleep 1
62                     # make absolutely sure winbindd is dead
63                     killall -q -9 winbindd
64                 }
65                 service "$CTDB_SERVICE_WINBIND" start
66         }
67
68         # start Samba service. Start it reniced, as under very heavy load 
69         # the number of smbd processes will mean that it leaves few cycles for
70         # anything else
71         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
72                 nice_service "$CTDB_SERVICE_NMB" start
73                 nice_service "$CTDB_SERVICE_SMB" start
74         }
75 }
76
77 stop_samba() {
78         # shutdown Samba when ctdb goes down
79         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
80                 service "$CTDB_SERVICE_SMB" stop
81                 service "$CTDB_SERVICE_NMB" stop
82         }
83
84         # stop the winbind service
85         check_ctdb_manages_winbind
86         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
87                 service "$CTDB_SERVICE_WINBIND" stop
88         }
89 }
90
91 # set default samba cleanup period - in minutes
92 [ -z "$SAMBA_CLEANUP_PERIOD" ] && {
93     SAMBA_CLEANUP_PERIOD=10
94 }
95
96 # we keep a cached copy of smb.conf here
97 smbconf_cache="$CTDB_BASE/state/samba/smb.conf.cache"
98
99
100 #############################################
101 # update the smb.conf cache in the foreground
102 testparm_foreground_update() {
103     mkdir -p "$CTDB_BASE/state/samba" || exit 1
104     testparm -s 2> /dev/null | egrep -v 'registry.shares.=|include.=' > "$smbconf_cache"
105 }
106
107 #############################################
108 # update the smb.conf cache in the background
109 testparm_background_update() {
110     # if the cache doesn't exist, then update in the foreground
111     [ -f $smbconf_cache ] || {
112         testparm_foreground_update
113     }
114     # otherwise do a background update
115     (
116         tmpfile="${smbconf_cache}.$$"
117         testparm -s > $tmpfile 2> /dev/null &
118         # remember the pid of the teamparm process
119         pid="$!"
120         # give it 10 seconds to run
121         timeleft=10
122         while [ $timeleft -gt 0 ]; do
123             timeleft=$(($timeleft - 1))
124             # see if the process still exists
125             /bin/kill -0 $pid > /dev/null 2>&1 || {
126                 # it doesn't exist, grab its exit status
127                 wait $pid
128                 [ $? = 0 ] || {
129                     echo "50.samba: smb.conf background update exited with status $?"
130                     rm -f "${tmpfile}"
131                     exit 1
132                 }               
133                 # put the new smb.conf contents in the cache (atomic rename)
134                 # make sure we remove references to the registry while doing 
135                 # this to ensure that running testparm on the cache does
136                 # not use the registry
137                 egrep -v 'registry.shares.=|include.=' < "$tmpfile" > "${tmpfile}.2"
138                 rm -f "$tmpfile"
139                 mv -f "${tmpfile}.2" "$smbconf_cache" || {
140                     echo "50.samba: failed to update background cache"
141                     rm -f "${tmpfile}.2"
142                     exit 1
143                 }
144                 exit 0
145             }
146             # keep waiting for testparm to finish
147             sleep 1
148         done
149         # it took more than 10 seconds - kill it off
150         rm -f "${tmpfile}"
151         /bin/kill -9 "$pid" > /dev/null 2>&1
152         echo "50.samba: timed out updating smbconf cache in background"
153         exit 1
154     ) &
155 }
156
157 ##################################################
158 # show the testparm output using a cached smb.conf 
159 # to avoid registry access
160 testparm_cat() {
161     [ -f $smbconf_cache ] || {
162         testparm_foreground_update
163     }
164     testparm -s "$smbconf_cache" "$@" 2>/dev/null
165 }
166
167 # function to see if ctdb manages winbind
168 check_ctdb_manages_winbind() {
169   [ -z "$CTDB_MANAGES_WINBIND" ] && {
170     secmode=`testparm_cat --parameter-name=security`
171     case $secmode in
172         ADS|DOMAIN)
173             CTDB_MANAGES_WINBIND="yes";
174             ;;
175         *)
176             CTDB_MANAGES_WINBIND="no";
177             ;;
178     esac
179   }
180 }
181
182 list_samba_shares ()
183 {
184     testparm_cat |
185     sed -n -e 's@^[[:space:]]*path[[:space:]]*=[[:space:]]@@p' |
186     sed -e 's/"//g'
187 }
188
189
190 ###########################
191 # periodic cleanup function
192 periodic_cleanup() {
193     # running smbstatus scrubs any dead entries from the connections
194     # and sessionid database
195     # echo "Running periodic cleanup of samba databases"
196     smbstatus -np > /dev/null 2>&1 &
197 }
198
199 case $cmd in 
200      startup)
201         ctdb_service_start
202         ;;
203         
204      shutdown)
205         ctdb_service_stop
206         ;;
207
208      monitor)
209         # Create a dummy file to track when we need to do periodic cleanup
210         # of samba databases
211         [ -f $CTDB_BASE/state/samba/periodic_cleanup ] || {
212                 touch $CTDB_BASE/state/samba/periodic_cleanup
213         }
214         [ `/usr/bin/find $CTDB_BASE/state/samba/periodic_cleanup -mmin +$SAMBA_CLEANUP_PERIOD | wc -l` -eq 1 ] && {
215                 # Cleanup the databases
216                 periodic_cleanup
217                 touch $CTDB_BASE/state/samba/periodic_cleanup
218         }
219
220         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
221                 [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" = "yes" ] || {
222                         testparm_background_update
223
224                         testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
225                             testparm_foreground_update
226                             testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
227                                 echo "ERROR: testparm shows smb.conf is not clean"
228                                 exit 1
229                             }
230                         }
231                         
232                         list_samba_shares |
233                         ctdb_check_directories_probe || {
234                             testparm_foreground_update
235                             list_samba_shares |
236                             ctdb_check_directories
237                         } || exit $?
238                 }
239
240                 smb_ports="$CTDB_SAMBA_CHECK_PORTS"
241                 [ -z "$smb_ports" ] && {
242                         smb_ports=`testparm_cat --parameter-name="smb ports"`
243                 }
244                 ctdb_check_tcp_ports $smb_ports || exit $?
245         }
246
247         # check winbind is OK
248         check_ctdb_manages_winbind
249         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
250                 ctdb_check_command "winbind" "wbinfo -p"
251         }
252         ;;
253
254     status)
255         ctdb_checkstatus || exit $?
256         ;;
257 esac
258
259 # ignore unknown commands
260 exit 0