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