ctdb-scripts: Do not de-duplicate the interfaces list
[jsutton/samba-autobuild/.git] / ctdb / config / events / legacy / 50.samba.script
1 #!/bin/sh
2 # ctdb event script for Samba
3
4 [ -n "$CTDB_BASE" ] ||
5         CTDB_BASE=$(d=$(dirname "$0") && cd -P "$d" && 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         ;;
15 debian)
16         CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smbd}
17         ;;
18 *)
19         # Use redhat style as default:
20         CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
21         ;;
22 esac
23
24 service_name="samba"
25
26 load_script_options
27
28 ctdb_setup_state_dir "service" "$service_name"
29
30 generate_smb_interfaces_config()
31 {
32         get_public_ifaces
33         pub_iface_list=$public_ifaces
34         public_ifaces=""
35         for iface in $pub_iface_list;
36         do
37                 public_ifaces="$public_ifaces \"$iface;options=dynamic\""
38         done
39
40         if [ -n "$CTDB_SAMBA_INTERFACES_EXTRA" ]; then
41                 public_ifaces="$public_ifaces $CTDB_SAMBA_INTERFACES_EXTRA"
42         fi
43
44 cat <<EOT > "$CTDB_SAMBA_INTERFACES_FILE"
45     bind interfaces only = yes
46     interfaces = lo $public_ifaces
47 EOT
48 }
49
50 service_start()
51 {
52         # make sure samba is not already started
53         service "$CTDB_SERVICE_SMB" stop >/dev/null 2>&1
54         killall -0 -q smbd && {
55                 sleep 1
56                 # make absolutely sure samba is dead
57                 killall -q -9 smbd
58         }
59         if [ -n "$CTDB_SAMBA_INTERFACES_FILE" ]; then
60                 generate_smb_interfaces_config
61         fi
62         # start Samba service. Start it reniced, as under very heavy load
63         # the number of smbd processes will mean that it leaves few cycles
64         # for anything else
65         nice_service "$CTDB_SERVICE_SMB" start || die "Failed to start samba"
66 }
67
68 service_stop()
69 {
70         service "$CTDB_SERVICE_SMB" stop
71         program_stack_traces "smbd" 5
72 }
73
74 ######################################################################
75 # Show the testparm output using a cached smb.conf to avoid delays due
76 # to registry access.
77
78 # script_state_dir set by ctdb_setup_state_dir()
79 # shellcheck disable=SC2154
80 smbconf_cache="$script_state_dir/smb.conf.cache"
81
82 testparm_foreground_update()
83 {
84         _timeout="$1"
85
86         # No need to remove these temporary files, since there are only 2
87         # of them.
88         _out="${smbconf_cache}.out"
89         _err="${smbconf_cache}.err"
90
91         timeout "$_timeout" testparm -v -s >"$_out" 2>"$_err"
92         case $? in
93         0) : ;;
94         124)
95                 if [ -f "$smbconf_cache" ]; then
96                         echo "WARNING: smb.conf cache update timed out - using old cache file"
97                         return 1
98                 else
99                         echo "ERROR: smb.conf cache create failed - testparm command timed out"
100                         exit 1
101                 fi
102                 ;;
103         *)
104                 if [ -f "$smbconf_cache" ]; then
105                         echo "WARNING: smb.conf cache update failed - using old cache file"
106                         cat "$_err"
107                         return 1
108                 else
109                         echo "ERROR: smb.conf cache create failed - testparm failed with:"
110                         cat "$_err"
111                         exit 1
112                 fi
113                 ;;
114         esac
115
116         # Only using $$ here to avoid a collision.  This is written into
117         # CTDB's own state directory so there is no real need for a secure
118         # temporary file.
119         _tmpfile="${smbconf_cache}.$$"
120         # Patterns to exclude...
121         _pat='^[[:space:]]+(registry[[:space:]]+shares|include|copy|winbind[[:space:]]+separator)[[:space:]]+='
122         grep -Ev "$_pat" <"$_out" >"$_tmpfile"
123         mv "$_tmpfile" "$smbconf_cache" # atomic
124
125         return 0
126 }
127
128 testparm_background_update()
129 {
130         _timeout="$1"
131
132         testparm_foreground_update "$_timeout" >/dev/null 2>&1 </dev/null &
133 }
134
135 testparm_get ()
136 {
137         _param="$1"
138
139         sed -n \
140             -e "s|^[[:space:]]*${_param}[[:space:]]*=[[:space:]]\(..*\)|\1|p" \
141             "$smbconf_cache"
142
143 }
144
145 list_samba_shares()
146 {
147         testparm_get "path" | sed -e 's/"//g'
148 }
149
150 list_samba_ports()
151 {
152         testparm_get "smb ports"
153 }
154
155 ###########################
156
157 case "$1" in
158 startup)
159         service_start
160         ;;
161
162 shutdown)
163         service_stop
164         ;;
165
166 monitor)
167         testparm_foreground_update 10
168         ret=$?
169
170         smb_ports="$CTDB_SAMBA_CHECK_PORTS"
171         if [ -z "$smb_ports" ]; then
172                 smb_ports=$(list_samba_ports)
173                 [ -n "$smb_ports" ] || die "Failed to set smb ports"
174         fi
175         # Intentionally unquoted multi-word value here
176         # shellcheck disable=SC2086
177         ctdb_check_tcp_ports $smb_ports || exit $?
178
179         if [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" != "yes" ]; then
180                 list_samba_shares | ctdb_check_directories || exit $?
181         fi
182
183         if [ $ret -ne 0 ]; then
184                 testparm_background_update 10
185         fi
186         ;;
187 esac
188
189 exit 0