xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/events_common.kshlib (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1# SPDX-License-Identifier: CDDL-1.0
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or https://opensource.org/licenses/CDDL-1.0.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
25# Use is subject to license terms.
26#
27# Copyright (c) 2020 by Delphix. All rights reserved.
28#
29
30. $STF_SUITE/include/libtest.shlib
31. $STF_SUITE/tests/functional/events/events.cfg
32
33#
34# wait for 'event' to show up in the log 'file'
35function file_wait_event # file event timeout
36{
37	file=$1
38	event=$2
39	timeout=${3:-120}
40
41	SECONDS=0
42
43	until grep -q "^ZEVENT_CLASS=$event" $ZED_DEBUG_LOG ; do
44		if [[ $SECONDS -gt $timeout ]]; then
45			echo file_wait_event exceeded $SECONDS seconds
46			return 1
47		fi
48
49		sleep 1
50	done
51
52	return 0;
53}
54
55#
56# Wait for up to 'timeout' seconds for the 'file' to settle, i.e.
57# not be updated for a period of 'delay' seconds.
58#
59function file_wait # file delay timeout
60{
61	file=$1
62	delay=${2:-3}
63	timeout=${3:-120}
64
65	SECONDS=0
66
67	while [ $(( $(date +%s) - $(stat -c %Y $file) )) -lt $delay ]; do
68		if [[ $SECONDS -gt $timeout ]]; then
69			echo file_wait exceeded $SECONDS seconds
70			return 1
71		fi
72
73		sleep 1
74	done
75
76	return 0;
77}
78
79function run_and_verify
80{
81	typeset event pool
82	set -A events
83
84	while getopts "e:p:" opt; do
85		case $opt in
86		e)
87			events+=("$OPTARG")
88			;;
89		p)
90			pool=$OPTARG
91			;;
92		esac
93	done
94	shift $(($OPTIND - 1))
95
96	pool=${pool:-$TESTPOOL}
97	fullcmd="$1"
98	read -r cmd _ <<<"$fullcmd"
99
100	# If we aren't running zpool or zfs, something is wrong
101	[[ $cmd == "zpool" || $cmd == "zfs" ]] || \
102	    log_fail "run_and_verify called with \"$cmd ($fullcmd)\""
103
104	log_note "Checking events for command: '$fullcmd'"
105
106	# Remove any previous events from the logs.
107	log_must zpool events -c
108	log_must truncate -s 0 $ZED_DEBUG_LOG
109
110	# Run the command as provided.
111	log_must eval "$fullcmd"
112
113	# Collect the new events and verify there are some.
114	sync_all_pools true
115	log_must eval "zpool events >$TMP_EVENTS 2>/dev/null"
116	log_must eval "zpool events -v > $TMP_EVENTS_FULL 2>/dev/null"
117
118	log_must test -s $TMP_EVENTS
119	log_must test -s $TMP_EVENTS_FULL
120
121	# If the only event is history then we don't observe zed debug log
122	if [[ "${events[0]}" != "sysevent.fs.zfs.history_event" ]]; then
123		# wait for all the non-history events to show up in the
124		# debug log, all-debug.sh filters history events.
125		for event in ${events[*]}; do
126			if [[ "$event" == \
127			    "sysevent.fs.zfs.history_event" ]]; then
128				continue
129			fi
130
131			log_must file_wait_event $ZED_DEBUG_LOG "$event"
132		done
133
134		log_must cp $ZED_DEBUG_LOG $TMP_EVENTS_ZED
135		log_must test -s $TMP_EVENTS_ZED
136
137		log_note "Events logged:"
138		grep "^ZEVENT_CLASS" $TMP_EVENTS_ZED
139	fi
140
141	log_note "Events generated:"
142	cat $TMP_EVENTS
143
144	# Verify all the expected events appear in the log.
145	for event in ${events[*]}; do
146
147		# Verify the event is in in the short output.
148		log_must grep -q "$event" $TMP_EVENTS
149
150		# Verify the event is in the verbose output with pool name.
151		log_mustnot awk -v event="$event" -v crit="pool = \"$pool\"" \
152		    'BEGIN{FS="\n"; RS=""} $0 ~ event && $0 ~ crit { exit 1 }' \
153		    $TMP_EVENTS_FULL
154
155		# all-debug.sh filters history events (seen in ZED_DEBUG_LOG)
156		if [ "$event" = "sysevent.fs.zfs.history_event" ]; then
157			continue
158		fi
159
160		# Verify the event was received by the ZED and logged.
161		log_mustnot awk -v event="$event" -v crit="\\nZEVENT_POOL=$pool" \
162		    'BEGIN{FS="\n"; RS=""} $0 ~ event && $0 ~ crit { exit 1 }' \
163		    $TMP_EVENTS_ZED
164	done
165
166	rm -f $TMP_EVENTS $TMP_EVENTS_FULL $TMP_EVENTS_ZED
167}
168