xref: /freebsd/tools/test/stress2/misc/kevent17.sh (revision d7ff2ded474871d69f19b0d03deed5f66d78435e)
1*d7ff2dedSPeter Holm#!/bin/sh
2*d7ff2dedSPeter Holm
3*d7ff2dedSPeter Holm#
4*d7ff2dedSPeter Holm# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
5*d7ff2dedSPeter Holm#
6*d7ff2dedSPeter Holm# SPDX-License-Identifier: BSD-2-Clause
7*d7ff2dedSPeter Holm#
8*d7ff2dedSPeter Holm
9*d7ff2dedSPeter Holm# A kqueuex(KQUEUE_CPONFORK) test scenario
10*d7ff2dedSPeter Holm# Test scenario suggestion by: kib
11*d7ff2dedSPeter Holm
12*d7ff2dedSPeter Holm. ../default.cfg
13*d7ff2dedSPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
14*d7ff2dedSPeter Holm
15*d7ff2dedSPeter Holmdir=/tmp
16*d7ff2dedSPeter Holmodir=`pwd`
17*d7ff2dedSPeter Holmprog=$(basename "$0" .sh)
18*d7ff2dedSPeter Holmcd $dir
19*d7ff2dedSPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
20*d7ff2dedSPeter Holmmycc -o $prog -Wall -Wextra -O0 -g $prog.c || exit 1
21*d7ff2dedSPeter Holmrm -f $prog.c
22*d7ff2dedSPeter Holmcd $odir
23*d7ff2dedSPeter Holm
24*d7ff2dedSPeter Holmset -e
25*d7ff2dedSPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
26*d7ff2dedSPeter Holm[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
27*d7ff2dedSPeter Holmmdconfig -a -t swap -s 2g -u $mdstart
28*d7ff2dedSPeter Holmnewfs $newfs_flags md$mdstart > /dev/null
29*d7ff2dedSPeter Holmmount /dev/md$mdstart $mntpoint
30*d7ff2dedSPeter Holmset +e
31*d7ff2dedSPeter Holm
32*d7ff2dedSPeter Holm(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100 > /dev/null) &
33*d7ff2dedSPeter Holmcd $mntpoint
34*d7ff2dedSPeter Holm$dir/$prog
35*d7ff2dedSPeter Holms=$?
36*d7ff2dedSPeter Holm[ -f $prog.core -a $s -eq 0 ] &&
37*d7ff2dedSPeter Holm    { ls -l $prog.core; mv $prog.core /tmp; s=1; }
38*d7ff2dedSPeter Holmcd $odir
39*d7ff2dedSPeter Holmwhile pkill -9 swap; do :; done
40*d7ff2dedSPeter Holmwait
41*d7ff2dedSPeter Holm
42*d7ff2dedSPeter Holmfor i in `jot 6`; do
43*d7ff2dedSPeter Holm	mount | grep -q "on $mntpoint " || break
44*d7ff2dedSPeter Holm	umount $mntpoint && break || sleep 10
45*d7ff2dedSPeter Holmdone
46*d7ff2dedSPeter Holm[ $i -eq 6 ] && exit 1
47*d7ff2dedSPeter Holmmdconfig -d -u $mdstart
48*d7ff2dedSPeter Holmrm -rf $dir/$prog
49*d7ff2dedSPeter Holmexit $s
50*d7ff2dedSPeter Holm
51*d7ff2dedSPeter HolmEOF
52*d7ff2dedSPeter Holm#include <sys/param.h>
53*d7ff2dedSPeter Holm#include <sys/event.h>
54*d7ff2dedSPeter Holm#include <sys/mman.h>
55*d7ff2dedSPeter Holm#include <sys/stat.h>
56*d7ff2dedSPeter Holm#include <sys/wait.h>
57*d7ff2dedSPeter Holm
58*d7ff2dedSPeter Holm#include <machine/atomic.h>
59*d7ff2dedSPeter Holm
60*d7ff2dedSPeter Holm#include <err.h>
61*d7ff2dedSPeter Holm#include <errno.h>
62*d7ff2dedSPeter Holm#include <fcntl.h>
63*d7ff2dedSPeter Holm#include <stdio.h>
64*d7ff2dedSPeter Holm#include <stdlib.h>
65*d7ff2dedSPeter Holm#include <string.h>
66*d7ff2dedSPeter Holm#include <time.h>
67*d7ff2dedSPeter Holm#include <unistd.h>
68*d7ff2dedSPeter Holm
69*d7ff2dedSPeter Holmstatic volatile u_int *share;
70*d7ff2dedSPeter Holmstatic int  loops;
71*d7ff2dedSPeter Holmstatic char *file = "file";
72*d7ff2dedSPeter Holm
73*d7ff2dedSPeter Holm#define MAXLOOPS 100
74*d7ff2dedSPeter Holm#define PARALLEL 1
75*d7ff2dedSPeter Holm#define RUNTIME (2 * 60)
76*d7ff2dedSPeter Holm#define SYNC 0
77*d7ff2dedSPeter Holm
78*d7ff2dedSPeter Holmstatic void
79*d7ff2dedSPeter Holmtest(void)
80*d7ff2dedSPeter Holm{
81*d7ff2dedSPeter Holm	pid_t pid;
82*d7ff2dedSPeter Holm        struct kevent ev[2];
83*d7ff2dedSPeter Holm        struct timespec ts;
84*d7ff2dedSPeter Holm        int kq, fd, n;
85*d7ff2dedSPeter Holm
86*d7ff2dedSPeter Holm	if ((fd = open(file, O_RDONLY, 0)) == -1)
87*d7ff2dedSPeter Holm		err(1, "open(%s). %s:%d", file, __func__, __LINE__);
88*d7ff2dedSPeter Holm
89*d7ff2dedSPeter Holm	atomic_add_int(&share[SYNC], 1);
90*d7ff2dedSPeter Holm	while (share[SYNC] != PARALLEL)
91*d7ff2dedSPeter Holm		usleep(10000);
92*d7ff2dedSPeter Holm
93*d7ff2dedSPeter Holm	if ((kq = kqueuex(KQUEUE_CPONFORK)) < 0)
94*d7ff2dedSPeter Holm		err(1, "kqueuex");
95*d7ff2dedSPeter Holm
96*d7ff2dedSPeter Holm	ts.tv_sec  = 5;
97*d7ff2dedSPeter Holm	ts.tv_nsec = 0;
98*d7ff2dedSPeter Holm	n = 0;
99*d7ff2dedSPeter Holm	EV_SET(&ev[n], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
100*d7ff2dedSPeter Holm		NOTE_DELETE, 0, 0);
101*d7ff2dedSPeter Holm	n++;
102*d7ff2dedSPeter Holm
103*d7ff2dedSPeter Holm	if (kevent(kq, ev, n, NULL, 0, NULL) < 0)
104*d7ff2dedSPeter Holm		err(1, "kevent()");
105*d7ff2dedSPeter Holm	if (loops >= MAXLOOPS) {	/* start using fork(2) */
106*d7ff2dedSPeter Holm		if ((pid = fork()) == 0) {
107*d7ff2dedSPeter Holm			n = kevent(kq, NULL, 0, ev, 1, &ts);
108*d7ff2dedSPeter Holm			if (n == -1)
109*d7ff2dedSPeter Holm				err(1, "kevent() in fork\n");
110*d7ff2dedSPeter Holm			close(fd);
111*d7ff2dedSPeter Holm			close(kq);
112*d7ff2dedSPeter Holm			_exit(0);
113*d7ff2dedSPeter Holm		}
114*d7ff2dedSPeter Holm		if (waitpid(pid, NULL, 0) != pid)
115*d7ff2dedSPeter Holm			err(1, "waitpid(%d)\n", pid);
116*d7ff2dedSPeter Holm	}
117*d7ff2dedSPeter Holm
118*d7ff2dedSPeter Holm	n = kevent(kq, NULL, 0, ev, 1, &ts);
119*d7ff2dedSPeter Holm	if (n == -1)
120*d7ff2dedSPeter Holm		err(1, "kevent()");
121*d7ff2dedSPeter Holm	close(fd);
122*d7ff2dedSPeter Holm	close(kq);
123*d7ff2dedSPeter Holm
124*d7ff2dedSPeter Holm	_exit(0);
125*d7ff2dedSPeter Holm}
126*d7ff2dedSPeter Holm
127*d7ff2dedSPeter Holmint
128*d7ff2dedSPeter Holmmain(void)
129*d7ff2dedSPeter Holm{
130*d7ff2dedSPeter Holm	pid_t pids[PARALLEL];
131*d7ff2dedSPeter Holm	size_t len;
132*d7ff2dedSPeter Holm	time_t start;
133*d7ff2dedSPeter Holm	int e, fd, i, status;
134*d7ff2dedSPeter Holm
135*d7ff2dedSPeter Holm	e = 0;
136*d7ff2dedSPeter Holm	len = PAGE_SIZE;
137*d7ff2dedSPeter Holm	loops = 0;
138*d7ff2dedSPeter Holm	if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
139*d7ff2dedSPeter Holm	    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
140*d7ff2dedSPeter Holm		err(1, "mmap");
141*d7ff2dedSPeter Holm
142*d7ff2dedSPeter Holm	start = time(NULL);
143*d7ff2dedSPeter Holm	while ((time(NULL) - start) < RUNTIME && e == 0) {
144*d7ff2dedSPeter Holm		loops++;
145*d7ff2dedSPeter Holm		if ((fd = open(file, O_CREAT | O_TRUNC | O_RDWR, 0660)) ==
146*d7ff2dedSPeter Holm		    -1)
147*d7ff2dedSPeter Holm			err(1, "open(%s)", file);
148*d7ff2dedSPeter Holm		close(fd);
149*d7ff2dedSPeter Holm		share[SYNC] = 0;
150*d7ff2dedSPeter Holm		for (i = 0; i < PARALLEL; i++) {
151*d7ff2dedSPeter Holm
152*d7ff2dedSPeter Holm			if ((pids[i] = fork()) == 0)
153*d7ff2dedSPeter Holm				test();
154*d7ff2dedSPeter Holm			if (pids[i] == -1)
155*d7ff2dedSPeter Holm				err(1, "fork()");
156*d7ff2dedSPeter Holm		}
157*d7ff2dedSPeter Holm		while (share[SYNC] != PARALLEL)
158*d7ff2dedSPeter Holm			usleep(10000);
159*d7ff2dedSPeter Holm		if (unlink(file) == -1)
160*d7ff2dedSPeter Holm			err(1, "unlink(%s). %s:%d\n", file,
161*d7ff2dedSPeter Holm				    __FILE__, __LINE__);
162*d7ff2dedSPeter Holm		for (i = 0; i < PARALLEL; i++) {
163*d7ff2dedSPeter Holm			if (waitpid(pids[i], &status, 0) == -1)
164*d7ff2dedSPeter Holm				err(1, "waitpid(%d)", pids[i]);
165*d7ff2dedSPeter Holm			if (status != 0) {
166*d7ff2dedSPeter Holm				if (WIFSIGNALED(status))
167*d7ff2dedSPeter Holm					fprintf(stderr,
168*d7ff2dedSPeter Holm					    "pid %d exit signal %d\n",
169*d7ff2dedSPeter Holm					    pids[i], WTERMSIG(status));
170*d7ff2dedSPeter Holm			}
171*d7ff2dedSPeter Holm			e += status == 0 ? 0 : 1;
172*d7ff2dedSPeter Holm		}
173*d7ff2dedSPeter Holm	}
174*d7ff2dedSPeter Holm
175*d7ff2dedSPeter Holm	return (e);
176*d7ff2dedSPeter Holm}
177