5 export CTDB_TEST_MODE
="yes"
7 # Following 2 lines may be modified by installation script
8 export CTDB_TESTS_ARE_INSTALLED
=false
9 export CTDB_TEST_DIR
=$
(dirname "$0")
11 export TEST_SCRIPTS_DIR
="${CTDB_TEST_DIR}/scripts"
13 .
"${TEST_SCRIPTS_DIR}/common.sh"
15 # common.sh will set TEST_SUBDIR to a stupid value when installed
16 # because common.sh is usually sourced by a test. TEST_SUBDIR needs
17 # to be correctly set so setup_ctdb_base() finds the etc-ctdb/
18 # subdirectory and the test event script is correctly installed, so
20 TEST_SUBDIR
="$CTDB_TEST_DIR"
22 if ! $CTDB_TESTS_ARE_INSTALLED ; then
23 hdir
="$CTDB_SCRIPTS_HELPER_BINDIR"
24 export CTDB_EVENTD
="${hdir}/ctdb-eventd"
25 export CTDB_EVENT_HELPER
="${hdir}/ctdb-event"
26 export CTDB_LOCK_HELPER
="${hdir}/ctdb_lock_helper"
27 export CTDB_RECOVERY_HELPER
="${hdir}/ctdb_recovery_helper"
28 export CTDB_TAKEOVER_HELPER
="${hdir}/ctdb_takeover_helper"
29 export CTDB_CLUSTER_MUTEX_HELPER
="${hdir}/ctdb_mutex_fcntl_helper"
32 ########################################
34 # If the given IP is hosted then print 2 items: maskbits and iface
44 _t
=$
(ip addr show to
"${_addr}/${_bits}")
54 for _i
in $
(seq 0 $
((_num_nodes
- 1)) ) ; do
56 _j
=$
(printf "%04x" $
((0x5f00 + 1 + _i
)) )
57 _node_ip
="fd00::5357:${_j}"
58 if have_ip
"$_node_ip" ; then
62 ERROR: ${_node_ip} not on an interface, please add it
68 _d
=$
(( 1 + (_i
% 100) ))
69 echo "127.0.${_c}.${_d}"
73 # Fail if we don't have all of the IPv6 addresses assigned
77 setup_public_addresses
()
83 for _i
in $
(seq 0 $
((_num_nodes
- 1)) ) ; do
84 if [ "$_i" -eq "$_node_no_ips" ] ; then
88 # 2 public addresses on most nodes, just to make
91 printf 'fc00:10::1:%x/64 lo\n' $
((1 + _i
))
92 printf 'fc00:10::2:%x/64 lo\n' $
((1 + _i
))
94 _c1
=$
(( 100 + (_i
/ 100) ))
95 _c2
=$
(( 200 + (_i
/ 100) ))
96 _d
=$
(( 1 + (_i
% 100) ))
97 printf '192.168.%d.%d/24 lo\n' "$_c1" "$_d"
98 printf '192.168.%d.%d/24 lo\n' "$_c2" "$_d"
103 setup_socket_wrapper
()
105 _socket_wrapper_so
="$1"
107 _so
="${directory}/libsocket-wrapper.so"
108 if [ ! -f "$_socket_wrapper_so" ] ; then
109 die
"$0 setup: Unable to find ${_socket_wrapper_so}"
112 # Find absoluate path if only relative is given
113 case "$_socket_wrapper_so" in
115 *) _socket_wrapper_so
="${PWD}/${_socket_wrapper_so}" ;;
119 ln -s "$_socket_wrapper_so" "$_so"
125 local_daemons_setup_usage
()
128 $0 <directory> setup [ <options>... ]
131 -F Disable failover (default: failover enabled)
132 -N <file> Nodes file (default: automatically generated)
133 -n <num> Number of nodes (default: 3)
134 -P <file> Public addresses file (default: automatically generated)
135 -S <library> Socket wrapper shared library to preload (default: none)
136 -6 Generate IPv6 IPs for nodes, public addresses (default: IPv4)
142 local_daemons_setup
()
144 _disable_failover
=false
147 _public_addresses_file
=""
153 while getopts "FN:n:P:S:6h?" _opt
; do
155 F
) _disable_failover
=true
;;
156 N
) _nodes_file
="$OPTARG" ;;
157 n
) _num_nodes
="$OPTARG" ;;
158 P
) _public_addresses_file
="$OPTARG" ;;
159 S
) _socket_wrapper
="$OPTARG" ;;
161 \?|h
) local_daemons_setup_usage
;;
164 shift $
((OPTIND
- 1))
166 mkdir
-p "$directory"
168 _nodes_all
="${directory}/nodes"
169 if [ -n "$_nodes_file" ] ; then
170 cp "$_nodes_file" "$_nodes_all"
172 setup_nodes
"$_num_nodes" $_use_ipv6 >"$_nodes_all"
175 # If there are (strictly) greater than 2 nodes then we'll
176 # "randomly" choose a node to have no public addresses
178 if [ "$_num_nodes" -gt 2 ] ; then
179 _node_no_ips
=$
(($$
% _num_nodes
))
182 _public_addresses_all
="${directory}/public_addresses"
183 if [ -n "$_public_addresses_file" ] ; then
184 cp "$_public_addresses_file" "$_public_addresses_all"
186 setup_public_addresses
"$_num_nodes" \
188 $_use_ipv6 >"$_public_addresses_all"
191 if [ -n "$_socket_wrapper" ] ; then
192 setup_socket_wrapper
"$_socket_wrapper"
195 for _n
in $
(seq 0 $
((_num_nodes
- 1))) ; do
196 setup_ctdb_base
"$directory" "node.${_n}" \
197 functions notify.sh debug-hung-script.sh
199 cp "$_nodes_all" "${CTDB_BASE}/nodes"
201 _public_addresses
="${CTDB_BASE}/public_addresses"
203 if [ -z "$_public_addresses_file" ] && \
204 [ $_node_no_ips -eq "$_n" ] ; then
205 echo "Node ${_n} will have no public IPs."
206 : >"$_public_addresses"
208 cp "$_public_addresses_all" "$_public_addresses"
211 _node_ip
=$
(sed -n -e "$((_n + 1))p" "$_nodes_all")
213 _db_dir
="${CTDB_BASE}/db"
214 for _d
in "volatile" "persistent" "state" ; do
215 mkdir
-p "${_db_dir}/${_d}"
218 cat >"${CTDB_BASE}/ctdb.conf" <<EOF
220 location = file:${CTDB_BASE}/log.ctdb
224 recovery lock = ${directory}/rec.lock
225 node address = ${_node_ip}
228 volatile database directory = ${_db_dir}/volatile
229 persistent database directory = ${_db_dir}/persistent
230 state database directory = ${_db_dir}/state
233 disabled = ${_disable_failover}
236 debug script = debug-hung-script.sh
241 local_daemons_ssh_usage
()
244 usage: $0 <directory> ssh [ -n ] <ip> <command>
252 if [ $# -lt 2 ] ; then
253 local_daemons_ssh_usage
256 # Only try to respect ssh -n option, others can't be used so discard them
258 while getopts "nh?" _opt
; do
260 n
) _close_stdin
=true
;;
261 \?|h
) local_daemons_ssh_usage
;;
265 shift $
((OPTIND
- 1))
267 if [ $# -lt 2 ] ; then
268 local_daemons_ssh_usage
271 _nodes
="${directory}/nodes"
273 # IP adress of node. onnode can pass hostnames but not in these tests
278 # Determine the correct CTDB base directory
279 _num
=$
(awk -v ip
="$_ip" '$1 == ip { print NR }' "$_nodes")
281 export CTDB_BASE
="${directory}/node.${_node}"
283 if [ ! -d "$CTDB_BASE" ] ; then
284 die
"$0 ssh: Unable to find base for node ${_ip}"
287 if $_close_stdin ; then
296 # onnode will execute this, which fakes ssh against local daemons
297 export ONNODE_SSH
="${0} ${directory} ssh"
299 # onnode just needs the nodes file, so use the common one
300 export CTDB_BASE
="$directory"
303 local_daemons_generic_usage
()
306 usage: $0 <directory> ${1} <nodes>
308 <nodes> can be "all", a node number or any specification supported by onnode
314 local_daemons_start_socket_wrapper
()
316 _so
="${directory}/libsocket-wrapper.so"
319 if [ -d "$_d" ] && [ -f "$_so" ] ; then
320 export SOCKET_WRAPPER_DIR
="$_d"
321 export LD_PRELOAD
="$_so"
325 local_daemons_start
()
327 if [ $# -ne 1 ] ||
[ "$1" = "-h" ] ; then
328 local_daemons_generic_usage
"start"
331 local_daemons_start_socket_wrapper
337 onnode
"$_nodes" "${VALGRIND:-} ctdbd &"
340 local_daemons_stop
()
342 if [ $# -ne 1 ] ||
[ "$1" = "-h" ] ; then
343 local_daemons_generic_usage
"stop"
350 onnode
-p "$_nodes" "${VALGRIND:-} ${CTDB:-ctdb} shutdown"
353 local_daemons_onnode_usage
()
356 usage: $0 <directory> onnode <nodes> <command>...
358 <nodes> can be "all", a node number or any specification supported by onnode
364 local_daemons_onnode
()
366 if [ $# -lt 2 ] ||
[ "$1" = "-h" ] ; then
367 local_daemons_onnode_usage
375 onnode
"$_nodes" "$@"
378 local_daemons_print_socket
()
380 if [ $# -ne 1 ] ||
[ "$1" = "-h" ] ; then
381 local_daemons_generic_usage
"print-socket"
389 _path
="${CTDB_SCRIPTS_HELPER_BINDIR}/ctdb-path"
390 onnode
-q "$_nodes" "${VALGRIND:-} ${_path} socket ctdbd"
396 usage: $0 <directory> <command> [ <options>... ]
399 setup Set up daemon configuration according to given options
400 start Start specified daemon(s)
401 stop Stop specified daemon(s)
402 onnode Run a command in the environment of specified daemon(s)
403 print-socket Print the Unix domain socket used by specified daemon(s)
405 All commands use <directory> for daemon configuration
407 Run command with -h option to see per-command usage
413 if [ $# -lt 2 ] ; then
422 setup
) local_daemons_setup
"$@" ;;
423 ssh) local_daemons_ssh
"$@" ;; # Internal, not shown by usage()
424 start
) local_daemons_start
"$@" ;;
425 stop
) local_daemons_stop
"$@" ;;
426 onnode
) local_daemons_onnode
"$@" ;;
427 print-socket
) local_daemons_print_socket
"$@" ;;