1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# This file and its contents are supplied under the terms of the
6# Common Development and Distribution License ("CDDL"), version 1.0.
7# You may only use this file in accordance with the terms of version
8# 1.0 of the CDDL.
9#
10# A full copy of the text of the CDDL should have accompanied this
11# source.  A copy of the CDDL is also available via the Internet at
12# http://www.illumos.org/license/CDDL.
13#
14# CDDL HEADER END
15#
16
17#
18# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
19#
20
21# DESCRIPTION:
22#	Ensure that the MMP thread is notified when MULTIHOST_INTERVAL is
23#	reduced, and that changes to MULTIHOST_INTERVAL and
24#	MULTIHOST_FAIL_INTERVALS do not trigger pool suspensions.
25#
26# STRATEGY:
27#	1. Set MULTIHOST_INTERVAL to much longer than the test duration
28#	2. Create a zpool and enable multihost
29#	3. Verify no MMP writes occurred
30#	4. Set MULTIHOST_INTERVAL to 1 second
31#	5. Sleep briefly
32#	6. Verify MMP writes began
33#	7. Verify mmp_fail and mmp_write in uberblock reflect tunables
34#	8. Repeatedly change tunables relating to pool suspension
35#
36
37. $STF_SUITE/include/libtest.shlib
38. $STF_SUITE/tests/functional/mmp/mmp.cfg
39. $STF_SUITE/tests/functional/mmp/mmp.kshlib
40
41verify_runnable "both"
42
43function cleanup
44{
45	default_cleanup_noexit
46	log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_DEFAULT
47	log_must set_tunable64 MULTIHOST_FAIL_INTERVALS \
48	    $MMP_FAIL_INTERVALS_DEFAULT
49	log_must mmp_clear_hostid
50}
51
52log_assert "mmp threads notified when MULTIHOST_INTERVAL reduced"
53log_onexit cleanup
54
55log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_HOUR
56log_must mmp_set_hostid $HOSTID1
57
58default_setup_noexit $DISK
59log_must zpool set multihost=on $TESTPOOL
60
61clear_mmp_history
62log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_DEFAULT
63uber_count=$(count_mmp_writes $TESTPOOL 1)
64
65if [ $uber_count -eq 0 ]; then
66	log_fail "ERROR: mmp writes did not start when MULTIHOST_INTERVAL reduced"
67fi
68
69# 7. Verify mmp_write and mmp_fail are written
70for fails in $(seq $MMP_FAIL_INTERVALS_MIN $((MMP_FAIL_INTERVALS_MIN*2))); do
71	for interval in $(seq $MMP_INTERVAL_MIN 200 $MMP_INTERVAL_DEFAULT); do
72		log_must set_tunable64 MULTIHOST_FAIL_INTERVALS $fails
73		log_must set_tunable64 MULTIHOST_INTERVAL $interval
74		sync_pool $TESTPOOL
75		typeset mmp_fail=$(zdb $TESTPOOL 2>/dev/null |
76		    awk '/mmp_fail/ {print $NF}')
77		if [ $fails -ne $mmp_fail ]; then
78			log_fail "ERROR: mmp_fail $mmp_fail != $fails"
79		fi
80		typeset mmp_write=$(zdb $TESTPOOL 2>/dev/null |
81		    awk '/mmp_write/ {print $NF}')
82		if [ $interval -ne $mmp_write ]; then
83			log_fail "ERROR: mmp_write $mmp_write != $interval"
84		fi
85	done
86done
87
88
89# 8. Repeatedly change MULTIHOST_INTERVAL and fail_intervals
90for x in $(seq 10); do
91	typeset new_interval=$(( (RANDOM % 20 + 1) * $MMP_INTERVAL_MIN ))
92	log_must set_tunable64 MULTIHOST_INTERVAL $new_interval
93	typeset action=$((RANDOM %10))
94	if [ $action -eq 0 ]; then
95		log_must zpool export -a
96		log_must mmp_clear_hostid
97		log_must mmp_set_hostid $HOSTID1
98		log_must zpool import $TESTPOOL
99	elif [ $action -eq 1 ]; then
100		log_must zpool export -F $TESTPOOL
101		log_must zpool import $TESTPOOL
102	elif [ $action -eq 2 ]; then
103		log_must zpool export -F $TESTPOOL
104		log_must mmp_clear_hostid
105		log_must mmp_set_hostid $HOSTID2
106		log_must zpool import -f $TESTPOOL
107	elif [ $action -eq 3 ]; then
108		log_must zpool export -F $TESTPOOL
109		log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_MIN
110		log_must zpool import $TESTPOOL
111	elif [ $action -eq 4 ]; then
112		log_must set_tunable64 MULTIHOST_FAIL_INTERVALS \
113		    $((RANDOM % MMP_FAIL_INTERVALS_DEFAULT))
114	fi
115	sleep 5
116done
117
118
119log_pass "mmp threads notified when MULTIHOST_INTERVAL reduced"
120