xref: /aosp_15_r20/external/ltp/testcases/kernel/connectors/pec/cn_pec.sh (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2008 FUJITSU LIMITED
4# Copyright (c) 2021 Joerg Vehlow <[email protected]>
5# Copyright (c) 2021 Petr Vorel <[email protected]>
6#
7# Author: Li Zefan <[email protected]>
8#
9# Process event connector is a netlink connector that reports process events
10# to userspace. It sends events such as fork, exec, id change and exit.
11
12TST_OPTS="n:"
13TST_SETUP=setup
14TST_TESTFUNC=do_test
15TST_PARSE_ARGS=parse_args
16TST_USAGE=usage
17TST_NEEDS_ROOT=1
18TST_NEEDS_TMPDIR=1
19TST_NEEDS_CHECKPOINTS=1
20TST_TEST_DATA="fork exec exit uid gid"
21
22num_events=10
23
24LISTENER_ID=0
25GENERATOR_ID=1
26
27usage()
28{
29	cat << EOF
30usage: $0 [-n <nevents>]
31
32OPTIONS
33-n      The number of evetns to generate per test (default 10)
34EOF
35}
36
37parse_args()
38{
39	case $1 in
40	n) num_events=$2;;
41	esac
42}
43
44# Find a free file handle
45free_fd()
46{
47	local fd
48
49	for fd in $(seq 200); do
50		# Sapwn a new sh, because redirecting to a non existing file handle
51		# will trigger a syntax error.
52		sh -c ": 2>/dev/null >&$fd || : 2>/dev/null <&$fd" 2>/dev/null
53		if [ $? -ne 0 ]; then
54			echo $fd
55			return
56		fi
57	done
58}
59
60setup()
61{
62	if ! grep -q cn_proc /proc/net/connector; then
63		tst_brk TCONF "Process Event Connector is not supported or kernel < 2.6.26"
64	fi
65
66	tst_res TINFO "Test process events connector"
67}
68
69do_test()
70{
71	local event=$2
72	local gen_pid list_pid gen_rc lis_rc
73	local expected_events fd_act failed act_nevents exp act
74
75	tst_res TINFO "Testing $2 event (nevents=$num_events)"
76
77	event_generator -n $num_events -e $event -c $GENERATOR_ID >gen.log &
78	gen_pid=$!
79
80	pec_listener -p $gen_pid -c $LISTENER_ID >lis.log &
81	lis_pid=$!
82
83	TST_CHECKPOINT_WAIT $LISTENER_ID
84	TST_CHECKPOINT_WAKE $GENERATOR_ID
85
86	wait $gen_pid
87	gen_rc=$?
88	wait $lis_pid
89	lis_rc=$?
90
91	if [ $gen_rc -ne 0 ]; then
92		tst_brk TBROK "failed to execute event_generator"
93	fi
94
95	if [ $lis_rc -ne 0 ]; then
96		tst_brk TBROK "failed to execute pec_listener"
97	fi
98
99	# The listener writes the same messages as the generator, but it can
100	# also see more events (e.g. for testing exit, a fork is generated).
101	# So: The events generated by the generator have to be in the same order
102	# as the events printed by the listener, but my interleaved with other
103	# messages. To correctly compare them, we have to open both logs
104	# and iterate over both of them at the same time, skipping messages
105	# in the listener log, that are not of interest.
106	# Because some messages may be multiple times in the listener log,
107	# we have to open it only once!
108	# This however does not check, if the listener sees more messages,
109	# than expected.
110
111	fd_act=$(free_fd)
112	[ -z "$fd_act" ] && tst_brk TBROK "No free filehandle found"
113	eval "exec ${fd_act}<lis.log"
114
115	failed=0
116	act_nevents=0
117	while read -r exp; do
118		local found=0
119		act_nevents=$((act_nevents + 1))
120		while read -r act; do
121			if [ "$exp" = "$act" ]; then
122				found=1
123				break
124			fi
125		done <&${fd_act}
126		if [ $found -ne 1 ]; then
127			failed=1
128			tst_res TFAIL "Event was not detected by the event listener: $exp"
129			break
130		fi
131	done <gen.log
132
133	eval "exec ${fd_act}<&-"
134
135	if [ $failed -eq 0 ]; then
136		if [ $act_nevents -ne $num_events ]; then
137			tst_res TBROK "Expected $num_events, but $act_nevents generated"
138		else
139			tst_res TPASS "All events detected"
140		fi
141	else
142		# TFAIL message is already printed in the loop above
143		cat lis.log
144	fi
145}
146
147. tst_test.sh
148tst_run
149