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