ccc68647e3b035e65bf1dfd64c929bfb97d98eeb
[ctdb.git] / config / events.d / 50.samba
1 #!/bin/sh
2 # ctdb event script for Samba
3
4 [ -n "$CTDB_BASE" ] || \
5     export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD")
6
7 . $CTDB_BASE/functions
8
9 detect_init_style
10
11 case $CTDB_INIT_STYLE in
12         suse)
13                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
14                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-nmb}
15                 ;;
16         debian)
17                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-samba}
18                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
19                 ;;
20         *)
21                 # Use redhat style as default:
22                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
23                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
24                 ;;
25 esac
26
27 service_name="samba"
28
29 loadconfig
30
31 ctdb_setup_service_state_dir
32
33 service_start ()
34 {
35     # make sure samba is not already started
36     service "$CTDB_SERVICE_SMB" stop > /dev/null 2>&1
37     if [ -n "$CTDB_SERVICE_NMB" ] ; then
38         service "$CTDB_SERVICE_NMB" stop > /dev/null 2>&1
39     fi
40     killall -0 -q smbd && {
41         sleep 1
42         # make absolutely sure samba is dead
43         killall -q -9 smbd
44     }
45     killall -0 -q nmbd && {
46         sleep 1
47         # make absolutely sure samba is dead
48         killall -q -9 nmbd
49     }
50
51     # start Samba service. Start it reniced, as under very heavy load
52     # the number of smbd processes will mean that it leaves few cycles
53     # for anything else
54     net serverid wipe
55
56     if [ -n "$CTDB_SERVICE_NMB" ] ; then
57         nice_service "$CTDB_SERVICE_NMB" start || die "Failed to start nmbd"
58     fi
59
60     nice_service "$CTDB_SERVICE_SMB" start || die "Failed to start samba"
61 }
62
63 service_stop ()
64 {
65     service "$CTDB_SERVICE_SMB" stop
66     if [ -n "$CTDB_SERVICE_NMB" ] ; then
67         service "$CTDB_SERVICE_NMB" stop
68     fi
69 }
70
71 # we keep a cached copy of smb.conf here
72 smbconf_cache="$service_state_dir/smb.conf.cache"
73
74
75 #############################################
76 # update the smb.conf cache in the foreground
77 testparm_foreground_update() {
78     testparm -s 2> /dev/null | egrep -v 'registry.shares.=|include.=' > "$smbconf_cache"
79 }
80
81 #############################################
82 # update the smb.conf cache in the background
83 testparm_background_update() {
84     # if the cache doesn't exist, then update in the foreground
85     [ -f $smbconf_cache ] || {
86         testparm_foreground_update
87     }
88     # otherwise do a background update
89     (
90         tmpfile="${smbconf_cache}.$$"
91         testparm -s > $tmpfile 2> /dev/null &
92         # remember the pid of the teamparm process
93         pid="$!"
94         # give it 10 seconds to run
95         timeleft=10
96         while [ $timeleft -gt 0 ]; do
97             timeleft=$(($timeleft - 1))
98             # see if the process still exists
99             kill -0 $pid > /dev/null 2>&1 || {
100                 # it doesn't exist, grab its exit status
101                 wait $pid
102                 [ $? = 0 ] || {
103                     echo "50.samba: smb.conf background update exited with status $?"
104                     rm -f "${tmpfile}"
105                     exit 1
106                 }               
107                 # put the new smb.conf contents in the cache (atomic rename)
108                 # make sure we remove references to the registry while doing 
109                 # this to ensure that running testparm on the cache does
110                 # not use the registry
111                 egrep -v 'registry.shares.=|include.=' < "$tmpfile" > "${tmpfile}.2"
112                 rm -f "$tmpfile"
113                 mv -f "${tmpfile}.2" "$smbconf_cache" || {
114                     echo "50.samba: failed to update background cache"
115                     rm -f "${tmpfile}.2"
116                     exit 1
117                 }
118                 exit 0
119             }
120             # keep waiting for testparm to finish
121             sleep 1
122         done
123         # it took more than 10 seconds - kill it off
124         rm -f "${tmpfile}"
125         kill -9 "$pid" > /dev/null 2>&1
126         echo "50.samba: timed out updating smbconf cache in background"
127         exit 1
128     ) &
129 }
130
131 ##################################################
132 # show the testparm output using a cached smb.conf 
133 # to avoid registry access
134 testparm_cat() {
135     [ -f $smbconf_cache ] || {
136         testparm_foreground_update
137     }
138     testparm -v -s "$smbconf_cache" "$@" 2>/dev/null
139 }
140
141 list_samba_shares ()
142 {
143     testparm_cat |
144     sed -n -e 's@^[[:space:]]*path[[:space:]]*=[[:space:]]@@p' |
145     sed -e 's/"//g'
146 }
147
148
149 ###########################
150
151 ctdb_start_stop_service
152
153 is_ctdb_managed_service || exit 0
154
155 ctdb_service_check_reconfigure
156
157 ###########################
158
159 case "$1" in
160      startup)
161         ctdb_service_start
162         ;;
163
164      shutdown)
165         ctdb_service_stop
166         ;;
167
168      monitor)
169         if [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" != "yes" ] ; then
170             testparm_background_update
171
172             testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
173                 testparm_foreground_update
174                 testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && \
175                     die "ERROR: testparm shows smb.conf is not clean"
176             }
177
178             list_samba_shares | ctdb_check_directories_probe || {
179                 testparm_foreground_update
180                 list_samba_shares |
181                 ctdb_check_directories
182             } || exit $?
183         fi
184
185         smb_ports="$CTDB_SAMBA_CHECK_PORTS"
186         if [ -z "$smb_ports" ] ; then
187             smb_ports=`testparm_cat --parameter-name="smb ports"`
188         fi
189         ctdb_check_tcp_ports $smb_ports || exit $?
190         ;;
191
192     *)
193         ctdb_standard_event_handler "$@"
194         ;;
195 esac
196
197 exit 0