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# Copyright 2019 Joyent, Inc.
20#
21
22# DESCRIPTION:
23#	Ensure that the MMP thread is notified when zfs_multihost_interval is
24#	reduced, and that changes to zfs_multihost_interval and
25#	zfs_multihost_fail_intervals do not trigger pool suspensions.
26#
27# STRATEGY:
28#	1. Set zfs_multihost_interval to much longer than the test duration
29#	2. Create a zpool and enable multihost
30#	3. Verify no MMP writes occurred
31#	4. Set zfs_multihost_interval to 1 second
32#	5. Sleep briefly
33#	6. Verify MMP writes began
34#	7. Verify mmp_fail and mmp_write in uberblock reflect tunables
35#	8. Repeatedly change tunables relating to pool suspension
36#
37
38. $STF_SUITE/include/libtest.shlib
39. $STF_SUITE/tests/functional/mmp/mmp.cfg
40. $STF_SUITE/tests/functional/mmp/mmp.kshlib
41
42verify_runnable "both"
43
44function cleanup
45{
46	default_cleanup_noexit
47	log_must set_tunable64 zfs_multihost_interval $MMP_INTERVAL_DEFAULT
48	log_must set_tunable32 zfs_multihost_fail_intervals \
49	    $MMP_FAIL_INTERVALS_DEFAULT
50	log_must mmp_clear_hostid
51}
52
53log_assert "mmp threads notified when zfs_multihost_interval reduced"
54log_onexit cleanup
55
56log_must set_tunable64 zfs_multihost_interval $MMP_INTERVAL_HOUR
57log_must mmp_set_hostid $HOSTID1
58
59default_setup_noexit $DISK
60log_must zpool set multihost=on $TESTPOOL
61
62clear_mmp_history
63log_must set_tunable64 zfs_multihost_interval $MMP_INTERVAL_DEFAULT
64uber_count=$(count_mmp_writes $TESTPOOL 1)
65
66if [ $uber_count -eq 0 ]; then
67	log_fail "ERROR: mmp writes did not start when zfs_multihost_interval reduced"
68fi
69
70# 7. Verify mmp_write and mmp_fail are written
71for fails in $(seq $MMP_FAIL_INTERVALS_MIN $((MMP_FAIL_INTERVALS_MIN*2))); do
72	for interval in $(seq $MMP_INTERVAL_MIN 200 $MMP_INTERVAL_DEFAULT); do
73		log_must set_tunable32 zfs_multihost_fail_intervals $fails
74		log_must set_tunable64 zfs_multihost_interval $interval
75		sync_pool $TESTPOOL true
76		typeset mmp_fail=$(zdb $TESTPOOL 2>/dev/null |
77		    awk '/mmp_fail/ {print $NF}')
78		if [ $fails -ne $mmp_fail ]; then
79			log_fail "ERROR: mmp_fail $mmp_fail != $fails"
80		fi
81		typeset mmp_write=$(zdb $TESTPOOL 2>/dev/null |
82		    awk '/mmp_write/ {print $NF}')
83		if [ $interval -ne $mmp_write ]; then
84			log_fail "ERROR: mmp_write $mmp_write != $interval"
85		fi
86	done
87done
88
89
90# 8. Repeatedly change zfs_multihost_interval and fail_intervals
91for x in $(seq 10); do
92	typeset new_interval=$(( (RANDOM % 20 + 1) * $MMP_INTERVAL_MIN ))
93	log_must set_tunable64 zfs_multihost_interval $new_interval
94	typeset action=$((RANDOM %10))
95	if [ $action -eq 0 ]; then
96		if is_linux; then
97			log_must zpool export -a
98			log_must mmp_clear_hostid
99			log_must mmp_set_hostid $HOSTID1
100			log_must zpool import $TESTPOOL
101		fi
102	elif [ $action -eq 1 ]; then
103		log_must zpool export -F $TESTPOOL
104		log_must zpool import $TESTPOOL
105	elif [ $action -eq 2 ]; then
106		log_must zpool export -F $TESTPOOL
107		log_must mmp_clear_hostid
108		log_must mmp_set_hostid $HOSTID2
109		log_must zpool import -f $TESTPOOL
110	elif [ $action -eq 3 ]; then
111		log_must zpool export -F $TESTPOOL
112		log_must set_tunable64 zfs_multihost_interval $MMP_INTERVAL_MIN
113		log_must zpool import $TESTPOOL
114	elif [ $action -eq 4 ]; then
115		log_must set_tunable32 zfs_multihost_fail_intervals \
116		    $((RANDOM % MMP_FAIL_INTERVALS_DEFAULT))
117	fi
118	sleep 5
119done
120
121
122log_pass "mmp threads notified when zfs_multihost_interval reduced"
123