/*) : ;;
*) EVENTSCRIPTS_PATH="${PWD}/${EVENTSCRIPTS_PATH}" ;;
esac
+ export CTDB_HELPER_BINDIR="$EVENTSCRIPTS_PATH"
fi
export EVENTSCRIPTS_PATH
PATH="${EVENTSCRIPTS_PATH}:${PATH}"
+export CTDB="ctdb"
+
export EVENTSCRIPTS_TESTS_VAR_DIR="${TEST_VAR_DIR}/unit_eventscripts"
if [ -d "$EVENTSCRIPTS_TESTS_VAR_DIR" -a \
"$EVENTSCRIPTS_TESTS_VAR_DIR" != "/unit_eventscripts" ] ; then
rm -r "$EVENTSCRIPTS_TESTS_VAR_DIR"
fi
mkdir -p "$EVENTSCRIPTS_TESTS_VAR_DIR"
-export CTDB_VARDIR="$EVENTSCRIPTS_TESTS_VAR_DIR/ctdb"
+export CTDB_SCRIPT_VARDIR="$EVENTSCRIPTS_TESTS_VAR_DIR/script-state"
export CTDB_LOGGING="file:${EVENTSCRIPTS_TESTS_VAR_DIR}/log.ctdb"
touch "${CTDB_LOGGING#file:}" || \
die "Unable to setup logging for \"$CTDB_LOGGING\""
-if [ -d "${TEST_SUBDIR}/etc" ] ; then
+if [ -d "${TEST_SUBDIR}/etc" ] ; then
cp -a "${TEST_SUBDIR}/etc" "$EVENTSCRIPTS_TESTS_VAR_DIR"
- export CTDB_ETCDIR="${EVENTSCRIPTS_TESTS_VAR_DIR}/etc"
+ export CTDB_SYS_ETCDIR="${EVENTSCRIPTS_TESTS_VAR_DIR}/etc"
else
- die "Unable to setup \$CTDB_ETCDIR"
+ die "Unable to setup \$CTDB_SYS_ETCDIR"
fi
if [ -d "${TEST_SUBDIR}/etc-ctdb" ] ; then
export CTDB_DBDIR="${EVENTSCRIPTS_TESTS_VAR_DIR}/db"
- mkdir -p "${CTDB_DBDIR}/persistent"
+ export CTDB_DBDIR_PERSISTENT="${CTDB_DBDIR}/persistent"
+ export CTDB_DBDIR_STATE="${CTDB_DBDIR}/state"
+ mkdir -p "$CTDB_DBDIR_PERSISTENT"
+ mkdir -p "$CTDB_DBDIR_STATE"
export FAKE_TDBTOOL_SUPPORTS_CHECK="yes"
export FAKE_TDB_IS_OK
export FAKE_DATE_OUTPUT
- export FAKE_NETSTAT_TCP_ESTABLISHED FAKE_TCP_LISTEN FAKE_NETSTAT_UNIX_LISTEN
- export FAKE_NETSTAT_TCP_ESTABLISHED_FILE=$(mktemp --tmpdir="$EVENTSCRIPTS_TESTS_VAR_DIR")
+ export FAKE_TCP_LISTEN FAKE_NETSTAT_UNIX_LISTEN
}
tcp_port_down ()
done
}
+_tcp_connections ()
+{
+ _count="$1"
+ _sip="$2"
+ _sport="$3"
+ _cip_base="$4"
+ _cport_base="$5"
+
+ _cip_prefix="${_cip_base%.*}"
+ _cip_suffix="${_cip_base##*.}"
+
+ for _i in $(seq 1 $_count) ; do
+ _cip_last=$((_cip_suffix + _i))
+ _cip="${_cip_prefix}.${_cip_last}"
+ _cport=$((_cport_base + _i))
+ echo "${_sip}:${_sport} ${_cip}:${_cport}"
+ done
+}
+
+setup_tcp_connections ()
+{
+ _t==$(mktemp --tmpdir="$EVENTSCRIPTS_TESTS_VAR_DIR")
+ export FAKE_NETSTAT_TCP_ESTABLISHED_FILE"$_t"
+ _tcp_connections "$@" >"$FAKE_NETSTAT_TCP_ESTABLISHED_FILE"
+}
+
+setup_tcp_connections_unkillable ()
+{
+ # These connections are listed by the "ss" stub but are not
+ # killed by the "ctdb killtcp" stub. So killing these
+ # connections will never succeed... and will look like a time
+ # out.
+ _t=$(_tcp_connections "$@" | sed -e 's/ /|/g')
+ export FAKE_NETSTAT_TCP_ESTABLISHED="$_t"
+}
+
shares_missing ()
{
_fmt="$1" ; shift
export FAKE_CTDB_PNN="$1"
echo "Setting up PNN ${FAKE_CTDB_PNN}"
- export CTDB_VARDIR="$EVENTSCRIPTS_TESTS_VAR_DIR/ctdb/${FAKE_CTDB_PNN}"
- mkdir -p "$CTDB_VARDIR"
+ export CTDB_SCRIPT_VARDIR="$EVENTSCRIPTS_TESTS_VAR_DIR/script-state/${FAKE_CTDB_PNN}"
+ mkdir -p "$CTDB_SCRIPT_VARDIR"
}
setup_ctdb ()
cat >"$FAKE_CTDB_EXTRA_CONFIG"
}
+validate_percentage ()
+{
+ case "$1" in
+ [0-9]|[0-9][0-9]|100) return 0 ;;
+ *) echo "WARNING: ${1} is an invalid percentage${2:+\" in }${2}${2:+\"}"
+ return 1
+ esac
+}
+
setup_memcheck ()
{
+ _mem_usage="${1:-10}" # Default is 10%
+ _swap_usage="${2:-0}" # Default is 0%
+
setup_ctdb
- _swap_total="5857276"
+ _swap_total=5857276
+ _swap_free=$(( (100 - $_swap_usage) * $_swap_total / 100 ))
- if [ "$1" = "bad" ] ; then
- _swap_free=" 4352"
- _mem_cached=" 112"
- _mem_free=" 468"
- else
- _swap_free="$_swap_total"
- _mem_cached="1112"
- _mem_free="1468"
- fi
+ _mem_total=3940712
+ _mem_free=225268
+ _mem_buffers=146120
+ _mem_cached=$(( $_mem_total * (100 - $_mem_usage) / 100 - $_mem_free - $_mem_buffers ))
export FAKE_PROC_MEMINFO="\
-MemTotal: 3940712 kB
-MemFree: 225268 kB
-Buffers: 146120 kB
-Cached: 1139348 kB
+MemTotal: ${_mem_total} kB
+MemFree: ${_mem_free} kB
+Buffers: ${_mem_buffers} kB
+Cached: ${_mem_cached} kB
SwapCached: 56016 kB
Active: 2422104 kB
Inactive: 1019928 kB
SwapFree: ${_swap_free} kB
..."
- export FAKE_FREE_M="\
- total used free shared buffers cached
-Mem: 3848 3634 213 0 142 ${_mem_cached}
--/+ buffers/cache: 2379 ${_mem_free}
-Swap: 5719 246 5473"
+ export CTDB_MONITOR_MEMORY_USAGE
+ export CTDB_MONITOR_SWAP_USAGE
+}
+
+setup_fscheck ()
+{
+ export FAKE_FS_USE="${1:-10}" # Default is 10% usage
+
+ # Causes some variables to be exported
+ setup_ctdb
- export CTDB_MONITOR_FREE_MEMORY
- export CTDB_MONITOR_FREE_MEMORY_WARN
- export CTDB_CHECK_SWAP_IS_NOT_USED
+ export CTDB_MONITOR_FILESYSTEM_USAGE
}
ctdb_get_interfaces ()
fi |
while read _dev _ip _bits ; do
_net=$(ipv4_host_addr_to_net "$_ip" "$_bits")
- _gw="${_net%.*}.1" # a dumb, calculated default
+ _gw="${_net%.*}.254" # a dumb, calculated default
echo "$_ip $_net"
fi | {
while read _dev _ip _bits ; do
_net=$(ipv4_host_addr_to_net "$_ip" "$_bits")
- _gw="${_net%.*}.1" # a dumb, calculated default
+ _gw="${_net%.*}.254" # a dumb, calculated default
_policy_rules="${_policy_rules}
${CTDB_PER_IP_ROUTING_RULE_PREF}: from $_ip lookup ctdb.$_ip "
######################################################################
+setup_ctdb_lvs ()
+{
+ lvs_state_dir="${EVENTSCRIPTS_TESTS_VAR_DIR}/lvs"
+ mkdir -p "$lvs_state_dir"
+
+ export FAKE_LVS_STATE_DIR="${lvs_state_dir}/state"
+ mkdir "$FAKE_LVS_STATE_DIR"
+
+ lvs_header=$(ipvsadm -l -n)
+
+ export CTDB_LVS_PUBLIC_IP="$1"
+ export CTDB_LVS_PUBLIC_IFACE="$2"
+
+ [ -n "$CTDB_LVS_PUBLIC_IP" ] || return 0
+ [ -n "$CTDB_LVS_PUBLIC_IFACE" ] || return 0
+
+ export CTDB_LVS_NODES=$(mktemp --tmpdir="$lvs_state_dir")
+ export FAKE_CTDB_LVS_MASTER=""
+
+ # Read from stdin
+ _pnn=0
+ while read _ip _opts ; do
+ case "$_opts" in
+ master)
+ FAKE_CTDB_LVS_MASTER="$_pnn"
+ echo "$_ip"
+ ;;
+ slave-only)
+ printf "%s\tslave-only\n" "$_ip"
+ ;;
+ *)
+ echo "$_ip"
+ ;;
+ esac
+ _pnn=$(($_pnn + 1))
+ done >"$CTDB_LVS_NODES"
+}
+
+check_ipvsadm ()
+{
+ if [ "$1" = "NULL" ] ; then
+ required_result 0 <<EOF
+$lvs_header
+EOF
+ else
+ required_result 0 <<EOF
+$lvs_header
+$(cat)
+EOF
+ fi
+
+ simple_test_command ipvsadm -l -n
+}
+
+check_lvs_ip ()
+{
+ _scope="$1"
+
+ if [ "$_scope" = "NULL" ] ; then
+ required_result 0 <<EOF
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+EOF
+ else
+ required_result 0 <<EOF
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet ${CTDB_LVS_PUBLIC_IP}/32 scope ${_scope} lo
+ valid_lft forever preferred_lft forever
+EOF
+ fi
+
+ simple_test_command ip addr show dev lo
+}
+
+######################################################################
+
ctdb_catdb_format_pairs ()
{
_count=0
setup_ctdb_natgw ()
{
- debug "Setting up NAT gateway"
-
- natgw_config_dir="${TEST_VAR_DIR}/natgw_config"
- mkdir -p "$natgw_config_dir"
-
- # These will accumulate, 1 per test... but will be cleaned up at
- # the end.
- export CTDB_NATGW_NODES=$(mktemp --tmpdir="$natgw_config_dir")
-
- # Read from stdin
- while read _ip _master _dev ; do
- echo "$_ip"
- if [ "$_master" = "master" ] ; then
- export FAKE_CTDB_NATGW_MASTER="$_ip"
- fi
- done >"$CTDB_NATGW_NODES"
-
- # Assume all of the nodes are on a /24 network and have IPv4
- # addresses:
- read _ip <"$CTDB_NATGW_NODES"
- export CTDB_NATGW_PRIVATE_NETWORK="${_ip%.*}.0/24"
-
- # These are fixed. Probably don't use the same network for the
- # private node IPs. To unset the default gateway just set it to
- # "". :-)
- export CTDB_NATGW_PUBLIC_IP="10.1.1.121/24"
- export CTDB_NATGW_PUBLIC_IFACE="eth1"
- export CTDB_NATGW_DEFAULT_GATEWAY="10.1.1.254"
- export CTDB_NATGW_SLAVE_ONLY=""
+ debug "Setting up NAT gateway"
+
+ natgw_config_dir="${TEST_VAR_DIR}/natgw_config"
+ mkdir -p "$natgw_config_dir"
+
+ # These will accumulate, 1 per test... but will be cleaned up at
+ # the end.
+ export CTDB_NATGW_NODES=$(mktemp --tmpdir="$natgw_config_dir")
+
+ # Read from stdin
+ while read _ip _opts ; do
+ case "$_opts" in
+ master)
+ export FAKE_CTDB_NATGW_MASTER="$_ip"
+ echo "$_ip"
+ ;;
+ slave-only)
+ printf "%s\tslave-only\n" "$_ip"
+ ;;
+ *)
+ echo "$_ip"
+ ;;
+ esac
+ done >"$CTDB_NATGW_NODES"
+
+ # Assume all of the nodes are on a /24 network and have IPv4
+ # addresses:
+ read _ip <"$CTDB_NATGW_NODES"
+ export CTDB_NATGW_PRIVATE_NETWORK="${_ip%.*}.0/24"
+
+ # These are fixed. Probably don't use the same network for the
+ # private node IPs. To unset the default gateway just set it to
+ # "". :-)
+ export CTDB_NATGW_PUBLIC_IP="10.1.1.121/24"
+ export CTDB_NATGW_PUBLIC_IFACE="eth1"
+ export CTDB_NATGW_DEFAULT_GATEWAY="10.1.1.254"
+ export CTDB_NATGW_SLAVE_ONLY=""
}
ok_natgw_master_ip_addr_show ()
if [ "$1" != "down" ] ; then
debug "Marking Samba services as up, listening and managed by CTDB"
- # Get into known state.
- eventscript_call ctdb_service_managed
# All possible service names for all known distros.
- for i in "smb" "nmb" "samba" ; do
+ for i in "smb" "nmb" "samba" "smbd" "nmbd" ; do
service "$i" force-started
done
export FAKE_SLEEP_FORCE=0.1
else
debug "Marking Samba services as down, not listening and not managed by CTDB"
- # Get into known state.
- eventscript_call ctdb_service_unmanaged
# All possible service names for all known distros.
- for i in "smb" "nmb" "samba" ; do
+ for i in "smb" "nmb" "samba" "smbd" "nmbd" ; do
service "$i" force-stopped
done
fi
}
+samba_setup_fake_threads ()
+{
+ export FAKE_SMBD_THREAD_PIDS="$*"
+
+ _nl="
+"
+ _out=""
+ _count=0
+ for _pid ; do
+ [ "$_count" -lt 5 ] || break
+ _t=$(program_stack_trace "smbd" $_pid)
+ _out="${_out:+${_out}${_nl}}${_t}"
+ _count=$((_count + 1))
+ done
+ SAMBA_STACK_TRACES="$_out"
+}
+
setup_winbind ()
{
setup_ctdb
if [ "$1" != "down" ] ; then
debug "Marking Winbind service as up and managed by CTDB"
- # Get into known state.
- eventscript_call ctdb_service_managed
service "winbind" force-started
else
debug "Marking Winbind service as down and not managed by CTDB"
- # Get into known state.
- eventscript_call ctdb_service_unmanaged
service "winbind" force-stopped
export CTDB_NFS_SKIP_SHARE_CHECK="no"
- export CTDB_MONITOR_NFS_THREAD_COUNT RPCNFSDCOUNT FAKE_NFSD_THREAD_PIDS
- export CTDB_NFS_DUMP_STUCK_THREADS FAKE_RPC_THREAD_PIDS
+ export RPCNFSDCOUNT
+
+ # This doesn't even need to exist
+ export CTDB_NFS_EXPORTS_FILE="$EVENTSCRIPTS_TESTS_VAR_DIR/etc-exports"
# Reset the failcounts for nfs services.
eventscript_call eval rm -f '$ctdb_fail_dir/nfs_*'
if [ "$1" != "down" ] ; then
debug "Setting up NFS environment: all RPC services up, NFS managed by CTDB"
- eventscript_call ctdb_service_managed
service "nfs" force-started
service "nfslock" force-started
export CTDB_MANAGED_SERVICES="foo nfs bar"
- rpc_services_up "nfs" "mountd" "rquotad" "nlockmgr" "status"
+ rpc_services_up \
+ "portmapper" "nfs" "mountd" "rquotad" "nlockmgr" "status"
+
+ nfs_setup_fake_threads "nfsd"
+ nfs_setup_fake_threads "rpc.foobar" # Just set the variable to empty
else
debug "Setting up NFS environment: all RPC services down, NFS not managed by CTDB"
- eventscript_call ctdb_service_unmanaged
service "nfs" force-stopped
service "nfslock" force-stopped
- eventscript_call startstop_nfs stop
export CTDB_MANAGED_SERVICES="foo bar"
unset CTDB_MANAGES_NFS
setup_nfs_ganesha ()
{
setup_nfs "$@"
- export CTDB_NFS_SERVER_MODE="ganesha"
+ export CTDB_NFS_CALLOUT="${CTDB_BASE}/nfs-ganesha-callout"
if [ "$1" != "down" ] ; then
export CTDB_MANAGES_NFS="yes"
fi
- # We do not support testing the Ganesha-nfsd-specific part of the
- # eventscript.
- export CTDB_SKIP_GANESHA_NFSD_CHECK="yes"
export CTDB_NFS_SKIP_SHARE_CHECK="yes"
}
for _i ; do
debug "Marking RPC service \"${_i}\" as available"
case "$_i" in
- nfs) _t="2:3" ;;
- mountd) _t="1:3" ;;
- rquotad) _t="1:2" ;;
- nlockmgr) _t="3:4" ;;
- status) _t="1:1" ;;
+ portmapper) _t="2:4" ;;
+ nfs) _t="2:3" ;;
+ mountd) _t="1:3" ;;
+ rquotad) _t="1:2" ;;
+ nlockmgr) _t="3:4" ;;
+ status) _t="1:1" ;;
*) die "Internal error - unsupported RPC service \"${_i}\"" ;;
esac
nfs_load_config ()
{
- _etc="$CTDB_ETCDIR" # shortcut for readability
+ _etc="$CTDB_SYS_ETCDIR" # shortcut for readability
for _c in "$_etc/sysconfig/nfs" "$_etc/default/nfs" "$_etc/ctdb/sysconfig/nfs" ; do
if [ -r "$_c" ] ; then
. "$_c"
done
}
+nfs_setup_fake_threads ()
+{
+ _prog="$1" ; shift
+
+ case "$_prog" in
+ nfsd)
+ export PROCFS_PATH=$(mktemp -d --tmpdir="$EVENTSCRIPTS_TESTS_VAR_DIR")
+ _threads="${PROCFS_PATH}/fs/nfsd/threads"
+ mkdir -p $(dirname "$_threads")
+ echo $# >"$_threads"
+ export FAKE_NFSD_THREAD_PIDS="$*"
+ ;;
+ *)
+ export FAKE_RPC_THREAD_PIDS="$*"
+ ;;
+ esac
+}
+
+program_stack_trace ()
+{
+ _prog="$1"
+ _pid="$2"
+
+ cat <<EOF
+Stack trace for ${_prog}[${_pid}]:
+[<ffffffff87654321>] fake_stack_trace_for_pid_${_pid}/stack+0x0/0xff
+EOF
+}
+
program_stack_traces ()
{
_prog="$1"
for _pid in ${FAKE_NFSD_THREAD_PIDS:-$FAKE_RPC_THREAD_PIDS} ; do
[ $_count -le $_max ] || break
- cat <<EOF
-Stack trace for ${_prog}[${_pid}]:
-[<ffffffff87654321>] fake_stack_trace_for_pid_${_pid}/stack+0x0/0xff
-EOF
+ program_stack_trace "$_prog" "$_pid"
_count=$(($_count + 1))
done
}
guess_output ()
{
case "$1" in
- startstop_nfslock\ start)
+ $CTDB_NFS_CALLOUT\ start\ nlockmgr)
echo "&Starting nfslock: OK"
;;
- startstop_nfs\ start)
+ $CTDB_NFS_CALLOUT\ start\ nfs)
cat <<EOF
&Starting nfslock: OK
&Starting nfs: OK
restart_every=0
service_stop_cmd=""
service_start_cmd=""
+ service_check_cmd=""
service_debug_cmd=""
# Don't bother syntax checking, eventscript does that...
. "$_file"
- # Just use the first version, default to 1. This is dumb but
+ # Just use the first version, or use default. This is dumb but
# handles all the cases that we care about now...
if [ -n "$version" ] ; then
_ver="${version%% *}"
else
- _ver=1
+ case "$_rpc_service" in
+ portmapper) _ver="" ;;
+ *) _ver=1 ;;
+ esac
fi
_rpc_check_out="\
$_rpc_service failed RPC check:
rpcinfo: RPC: Program not registered
-program $_rpc_service version $_ver is not available"
+program $_rpc_service${_ver:+ version }${_ver} is not available"
if [ $unhealthy_after -gt 0 -a $_numfails -ge $unhealthy_after ] ; then
_unhealthy=true
echo 0 >"$_rc_file"
fi
- if [ $restart_every -gt 0 -a $(($_numfails % $restart_every)) -eq 0 ] ; then
+ if [ $restart_every -gt 0 ] && \
+ [ $(($_numfails % $restart_every)) -eq 0 ] ; then
if ! $_unhealthy ; then
echo "WARNING: ${_rpc_check_out}" >>"$_out"
fi
######################################################################
+# Recovery lock fakery
+
+cleanup_reclock ()
+{
+ _pattern="${script_dir}/${script}"
+ while pgrep -f "$_pattern" >/dev/null ; do
+ echo "Waiting for backgrounded ${script} to exit..."
+ (FAKE_SLEEP_REALLY=yes sleep 1)
+ done
+}
+
+setup_reclock ()
+{
+ CTDB_RECOVERY_LOCK=$(mktemp --tmpdir="$EVENTSCRIPTS_TESTS_VAR_DIR")
+ export CTDB_RECOVERY_LOCK
+
+ test_cleanup cleanup_reclock
+}
+
+######################################################################
+
# VSFTPD fakery
setup_vsftpd ()
else
debug "Setting up VSFTPD environment: service down, not managed by CTDB"
- eventscript_call ctdb_service_unmanaged
service vsftpd force-stopped
export CTDB_MANAGED_SERVICES="foo"
debug "Setting up HTTPD environment: service down, not managed by CTDB"
for service_name in "apache2" "httpd" ; do
- eventscript_call ctdb_service_unmanaged
service "$service_name" force-stopped
done
##################################################
CTDB_BASE="$CTDB_BASE"
-CTDB_ETCDIR="$CTDB_ETCDIR"
+CTDB_SYS_ETCDIR="$CTDB_SYS_ETCDIR"
ctdb client is "$(which ctdb)"
ip command is "$(which ip)"
EOF
#
# - 2nd argument is the NFS/RPC service being tested
#
-# rpcinfo is used on each iteration to test the availability of the
-# service
+# rpcinfo (or $service_check_cmd) is used on each iteration to test
+# the availability of the service
#
# If this is not set or null then no RPC service is checked and the
# required output is not reset on each iteration. This is useful in
shift 2
fi
if [ -n "$_rpc_service" ] ; then
- if rpcinfo -T tcp localhost "$_rpc_service" >/dev/null 2>&1 ; then
+ _ok=false
+ if [ -n "$service_check_cmd" ] ; then
+ if eval "$service_check_cmd" ; then
+ _ok=true
+ fi
+ else
+ if rpcinfo -T tcp localhost "$_rpc_service" >/dev/null 2>&1 ; then
+ _ok=true
+ fi
+ fi
+
+ if $_ok ; then
_iterate_failcount=0
else
_iterate_failcount=$(($_iterate_failcount + 1))