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