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