34412aa964d932b6bb2f1cae584ac55ac53e6515
[samba.git] / ctdb / tests / simple / scripts / local_daemons.bash
1 # If we're not running on a real cluster then we need a local copy of
2 # ctdb (and other stuff) in $PATH and we will use local daemons.
3
4 # For ctdbd_wrapper
5 PATH="${CTDB_SCRIPTS_BASE}:${PATH}"
6
7 hdir="$CTDB_SCRIPTS_HELPER_BINDIR"
8 export CTDB_EVENTD="${hdir}/ctdb-eventd"
9 export CTDB_EVENT_HELPER="${hdir}/ctdb-event"
10 export CTDB_LOCK_HELPER="${hdir}/ctdb_lock_helper"
11 export CTDB_RECOVERY_HELPER="${hdir}/ctdb_recovery_helper"
12 export CTDB_TAKEOVER_HELPER="${hdir}/ctdb_takeover_helper"
13 export CTDB_CLUSTER_MUTEX_HELPER="${hdir}/ctdb_mutex_fcntl_helper"
14
15 if [ -n "$TEST_SOCKET_WRAPPER_SO_PATH" ] ; then
16         export LD_PRELOAD="$TEST_SOCKET_WRAPPER_SO_PATH"
17         export SOCKET_WRAPPER_DIR="${SIMPLE_TESTS_VAR_DIR}/sw"
18         mkdir -p "$SOCKET_WRAPPER_DIR"
19 fi
20
21 # onnode will execute this, which fakes ssh against local daemons
22 export ONNODE_SSH="${TEST_SUBDIR}/scripts/ssh_local_daemons.sh"
23
24 #######################################
25
26 # If the given IP is hosted then print 2 items: maskbits and iface
27 have_ip ()
28 {
29         local addr="$1"
30         local bits t
31
32         case "$addr" in
33         *:*) bits=128 ;;
34         *)   bits=32  ;;
35         esac
36
37         t=$(ip addr show to "${addr}/${bits}")
38         [ -n "$t" ]
39 }
40
41 setup_nodes ()
42 {
43         local have_all_ips=true
44         local i
45         for i in $(seq 1 $TEST_LOCAL_DAEMONS) ; do
46                 if [ -n "$CTDB_USE_IPV6" ]; then
47                         local j=$(printf "%02x" $i)
48                         local node_ip="fd00::5357:5f${j}"
49                         if have_ip "$node_ip" ; then
50                                 echo "$node_ip"
51                         else
52                                 cat >&2 <<EOF
53 ERROR: ${node_ip} not on an interface, please add it
54 EOF
55                                 have_all_ips=false
56                         fi
57                 else
58                         local j=$((i + 10))
59                         echo "127.0.0.${j}"
60                 fi
61         done
62
63         # Fail if we don't have all of the IPv6 addresses assigned
64         $have_all_ips
65 }
66
67 setup_public_addresses ()
68 {
69         local pnn_no_ips="$1"
70
71         local i
72         for i in $(seq 1 $TEST_LOCAL_DAEMONS) ; do
73                 if  [ $((i - 1)) -eq $pnn_no_ips ] ; then
74                         continue
75                 fi
76
77                 # 2 public addresses on most nodes, just to make
78                 # things interesting
79                 local j=$((i + TEST_LOCAL_DAEMONS))
80                 if [ -n "$CTDB_USE_IPV6" ]; then
81                         printf "fc00:10::1:%x/64 lo\n" "$i"
82                         printf "fc00:10::1:%x/64 lo\n" "$j"
83                 else
84                         printf "192.168.234.%x/24 lo\n" "$i"
85                         printf "192.168.234.%x/24 lo\n" "$j"
86                 fi
87         done
88 }
89
90 setup_ctdb ()
91 {
92         local no_public_addresses=false
93         local no_event_scripts=false
94         local disable_failover=false
95         case "$1" in
96         --no-public-addresses) no_public_addresses=true ;;
97         --no-event-scripts)    no_event_scripts=true    ;;
98         --disable-failover)    disable_failover=true    ;;
99         esac
100
101         nodes_file="${SIMPLE_TESTS_VAR_DIR}/nodes"
102         setup_nodes >"$nodes_file" || return 1
103
104         # If there are (strictly) greater than 2 nodes then we'll
105         # randomly choose a node to have no public addresses
106         local pnn_no_ips=-1
107         if [ $TEST_LOCAL_DAEMONS -gt 2 ] ; then
108                 pnn_no_ips=$((RANDOM % TEST_LOCAL_DAEMONS))
109         fi
110
111         local public_addresses_all="${SIMPLE_TESTS_VAR_DIR}/public_addresses"
112         setup_public_addresses $pnn_no_ips >"$public_addresses_all"
113
114         local pnn
115         for pnn in $(seq 0 $(($TEST_LOCAL_DAEMONS - 1))) ; do
116                 setup_ctdb_base "$SIMPLE_TESTS_VAR_DIR" "node.${pnn}" \
117                                 functions notify.sh debug-hung-script.sh
118
119                 cp "$nodes_file" "${CTDB_BASE}/nodes"
120
121                 local public_addresses="${CTDB_BASE}/public_addresses"
122
123                 if  $no_public_addresses || [ $pnn_no_ips -eq $pnn ] ; then
124                         echo "Node ${pnn} will have no public IPs."
125                         : >"$public_addresses"
126                 else
127                         cp "$public_addresses_all" "$public_addresses"
128                 fi
129
130                 local node_ip=$(sed -n -e "$(($pnn + 1))p" "$nodes_file")
131
132                 local db_dir="${CTDB_BASE}/db"
133                 local d
134                 for d in "volatile" "persistent" "state" ; do
135                         mkdir -p "${db_dir}/${d}"
136                 done
137
138                 if $no_event_scripts ; then
139                         rm -vf "${CTDB_BASE}/events/legacy/"*
140                 fi
141
142                 cat >"${CTDB_BASE}/ctdb.conf" <<EOF
143 [logging]
144         location = file:${CTDB_BASE}/log.ctdb
145         log level = INFO
146
147 [cluster]
148         recovery lock = ${SIMPLE_TESTS_VAR_DIR}/rec.lock
149         node address = ${node_ip}
150
151 [database]
152         volatile database directory = ${db_dir}/volatile
153         persistent database directory = ${db_dir}/persistent
154         state database directory = ${db_dir}/state
155
156 [failover]
157         disabled = ${disable_failover}
158
159 [event]
160         debug script = debug-hung-script.sh
161 EOF
162         done
163 }
164
165 start_ctdb_1 ()
166 {
167         local pnn="$1"
168
169         CTDBD="${VALGRIND} ctdbd" \
170              onnode "$pnn" ctdbd_wrapper start
171 }
172
173 ctdb_start_all ()
174 {
175     echo "Starting $TEST_LOCAL_DAEMONS ctdb daemons..."
176
177     local pnn
178     for pnn in $(seq 0 $(($TEST_LOCAL_DAEMONS - 1))) ; do
179         start_ctdb_1 "$pnn"
180     done
181 }
182
183 stop_ctdb_1 ()
184 {
185         local pnn="$1"
186
187         onnode "$pnn" ctdbd_wrapper stop
188 }
189
190 ctdb_stop_all ()
191 {
192     echo "Stopping $TEST_LOCAL_DAEMONS ctdb daemons..."
193
194     local pnn
195     for pnn in $(seq 0 $(($TEST_LOCAL_DAEMONS - 1))) ; do
196         stop_ctdb_1 "$pnn"
197     done
198
199     rm -rf "${SIMPLE_TESTS_VAR_DIR}/test.db"
200 }
201
202 restart_ctdb_1 ()
203 {
204         stop_ctdb_1 "$1"
205         start_ctdb_1 "$1"
206 }
207
208 # onnode will use CTDB_BASES to help the ctdb tool connection to each
209 # daemon
210 export CTDB_BASES=""
211 for i in $(seq 0 $(($TEST_LOCAL_DAEMONS - 1))) ; do
212         b="${SIMPLE_TESTS_VAR_DIR}/node.${i}"
213         CTDB_BASES="${CTDB_BASES}${CTDB_BASES:+ }${b}"
214 done
215
216 # Need a default CTDB_BASE for onnode (to find the functions file).
217 # Any node will do, so pick the 1st...
218 export CTDB_BASE="${CTDB_BASES%% *}"