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 11*d7ff2dedSPeter Holm# Sleeping thread seen in WiP code: 12*d7ff2dedSPeter Holm# https://people.freebsd.org/~pho/stress/log/log0615.txt 13*d7ff2dedSPeter Holm 14*d7ff2dedSPeter Holm. ../default.cfg 15*d7ff2dedSPeter Holm 16*d7ff2dedSPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 17*d7ff2dedSPeter Holmulimit -k 5000 || { echo FAIL; exit 1; } 18*d7ff2dedSPeter Holm 19*d7ff2dedSPeter Holmodir=`pwd` 20*d7ff2dedSPeter Holmprog=$(basename "$0" .sh) 21*d7ff2dedSPeter Holm 22*d7ff2dedSPeter Holmcd /tmp 23*d7ff2dedSPeter Holmsed '1,/^EOF/d' < $odir/$0 > $prog.c 24*d7ff2dedSPeter Holmmycc -o $prog -Wall -Wextra -O2 -g $prog.c -lpthread || exit 1 25*d7ff2dedSPeter Holmrm -f $prog.c 26*d7ff2dedSPeter Holmcd $odir 27*d7ff2dedSPeter Holm 28*d7ff2dedSPeter Holmmount | grep "on $mntpoint " | grep -q md$mdstart && umount -f $mntpoint 29*d7ff2dedSPeter Holmmdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart 30*d7ff2dedSPeter Holm 31*d7ff2dedSPeter Holmmdconfig -a -t swap -s 2g -u $mdstart 32*d7ff2dedSPeter Holmnewfs $newfs_flags md$mdstart > /dev/null 33*d7ff2dedSPeter Holmmount /dev/md$mdstart $mntpoint 34*d7ff2dedSPeter Holmchmod 777 $mntpoint 35*d7ff2dedSPeter Holm 36*d7ff2dedSPeter Holmsu $testuser -c "(cd $mntpoint; /tmp/$prog)" & 37*d7ff2dedSPeter Holmfor i in `jot 99`; do 38*d7ff2dedSPeter Holm sleep 1 39*d7ff2dedSPeter Holm kill -0 $! 2>/dev/null || break 40*d7ff2dedSPeter Holmdone 41*d7ff2dedSPeter Holmpkill $prog 42*d7ff2dedSPeter Holmwait 43*d7ff2dedSPeter Holmumount -f $mntpoint 44*d7ff2dedSPeter Holm 45*d7ff2dedSPeter Holmwhile mount | grep -q $mntpoint; do 46*d7ff2dedSPeter Holm umount $mntpoint || sleep 1 47*d7ff2dedSPeter Holmdone 48*d7ff2dedSPeter Holmmdconfig -d -u $mdstart 49*d7ff2dedSPeter Holmrm -f /tmp/$prog 50*d7ff2dedSPeter Holm 51*d7ff2dedSPeter Holmexit 0 52*d7ff2dedSPeter HolmEOF 53*d7ff2dedSPeter Holm#include <sys/types.h> 54*d7ff2dedSPeter Holm#include <sys/event.h> 55*d7ff2dedSPeter Holm#include <sys/mman.h> 56*d7ff2dedSPeter Holm#include <sys/wait.h> 57*d7ff2dedSPeter Holm 58*d7ff2dedSPeter Holm#include <err.h> 59*d7ff2dedSPeter Holm#include <errno.h> 60*d7ff2dedSPeter Holm#include <fcntl.h> 61*d7ff2dedSPeter Holm#include <pthread.h> 62*d7ff2dedSPeter Holm#include <sched.h> 63*d7ff2dedSPeter Holm#include <signal.h> 64*d7ff2dedSPeter Holm#include <stdio.h> 65*d7ff2dedSPeter Holm#include <stdlib.h> 66*d7ff2dedSPeter Holm#include <string.h> 67*d7ff2dedSPeter Holm#include <unistd.h> 68*d7ff2dedSPeter Holm 69*d7ff2dedSPeter Holm#define PARALLEL 64 70*d7ff2dedSPeter Holm 71*d7ff2dedSPeter Holmstatic int fd; 72*d7ff2dedSPeter Holmstatic char path[80]; 73*d7ff2dedSPeter Holm 74*d7ff2dedSPeter Holmstatic void * 75*d7ff2dedSPeter Holmspin(void *arg __unused) 76*d7ff2dedSPeter Holm{ 77*d7ff2dedSPeter Holm int i; 78*d7ff2dedSPeter Holm 79*d7ff2dedSPeter Holm for (i= 0;; i++) { 80*d7ff2dedSPeter Holm snprintf(path, sizeof(path), "file.%06d.%d", getpid(), i); 81*d7ff2dedSPeter Holm fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622); 82*d7ff2dedSPeter Holm if (fd == -1 && errno == ENOTDIR) 83*d7ff2dedSPeter Holm break; 84*d7ff2dedSPeter Holm if (fd == -1) 85*d7ff2dedSPeter Holm err(1, "open(%s)", path); 86*d7ff2dedSPeter Holm close(fd); 87*d7ff2dedSPeter Holm fd = 0; 88*d7ff2dedSPeter Holm unlink(path); 89*d7ff2dedSPeter Holm } 90*d7ff2dedSPeter Holm fprintf(stderr, "spin loops: %d\n", i + 1); 91*d7ff2dedSPeter Holm return (NULL); 92*d7ff2dedSPeter Holm} 93*d7ff2dedSPeter Holm 94*d7ff2dedSPeter Holmstatic void * 95*d7ff2dedSPeter Holmtest(void *arg __unused) 96*d7ff2dedSPeter Holm{ 97*d7ff2dedSPeter Holm struct kevent ev; 98*d7ff2dedSPeter Holm struct timespec ts; 99*d7ff2dedSPeter Holm pid_t pid; 100*d7ff2dedSPeter Holm int i, kq, n; 101*d7ff2dedSPeter Holm 102*d7ff2dedSPeter Holm for (i = 0; i < 500000; i++) { 103*d7ff2dedSPeter Holm if ((kq = kqueuex(KQUEUE_CPONFORK)) < 0) 104*d7ff2dedSPeter Holm err(1, "kqueueex(KQUEUE_CPONFORK)"); 105*d7ff2dedSPeter Holm 106*d7ff2dedSPeter Holm n = 0; 107*d7ff2dedSPeter Holm memset(&ev, 0, sizeof(ev)); 108*d7ff2dedSPeter Holm EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, 109*d7ff2dedSPeter Holm NOTE_DELETE|NOTE_RENAME|NOTE_EXTEND, 0, 0); 110*d7ff2dedSPeter Holm n++; 111*d7ff2dedSPeter Holm 112*d7ff2dedSPeter Holm if ((pid = fork()) == 0) { 113*d7ff2dedSPeter Holm kevent(kq, &ev, n, NULL, 0, NULL); 114*d7ff2dedSPeter Holm _exit(0); 115*d7ff2dedSPeter Holm } 116*d7ff2dedSPeter Holm if (waitpid(pid, NULL, 0) != pid) 117*d7ff2dedSPeter Holm err(1, "waitpid(%d)", pid); 118*d7ff2dedSPeter Holm 119*d7ff2dedSPeter Holm kevent(kq, &ev, n, NULL, 0, NULL); 120*d7ff2dedSPeter Holm memset(&ev, 0, sizeof(ev)); 121*d7ff2dedSPeter Holm ts.tv_sec = 0; 122*d7ff2dedSPeter Holm ts.tv_nsec = 1000000; 123*d7ff2dedSPeter Holm if ((n = kevent(kq, NULL, 0, &ev, 1, &ts)) == -1) 124*d7ff2dedSPeter Holm err(1, "kevent()"); 125*d7ff2dedSPeter Holm 126*d7ff2dedSPeter Holm close(kq); 127*d7ff2dedSPeter Holm } 128*d7ff2dedSPeter Holm return (NULL); 129*d7ff2dedSPeter Holm} 130*d7ff2dedSPeter Holm 131*d7ff2dedSPeter Holmint 132*d7ff2dedSPeter Holmmain(void) 133*d7ff2dedSPeter Holm{ 134*d7ff2dedSPeter Holm pthread_t cp[PARALLEL], sp; 135*d7ff2dedSPeter Holm int e, i; 136*d7ff2dedSPeter Holm 137*d7ff2dedSPeter Holm if ((e = pthread_create(&sp, NULL, spin, NULL)) != 0) 138*d7ff2dedSPeter Holm errc(1, e, "pthread_create"); 139*d7ff2dedSPeter Holm 140*d7ff2dedSPeter Holm for (i = 0; i < PARALLEL; i++) { 141*d7ff2dedSPeter Holm if ((e = pthread_create(&cp[i], NULL, test, NULL)) != 0) 142*d7ff2dedSPeter Holm errc(1, e, "pthread_create"); 143*d7ff2dedSPeter Holm } 144*d7ff2dedSPeter Holm 145*d7ff2dedSPeter Holm for (i = 0; i < PARALLEL; i++) 146*d7ff2dedSPeter Holm pthread_join(cp[i], NULL); 147*d7ff2dedSPeter Holm pthread_join(sp, NULL); 148*d7ff2dedSPeter Holm 149*d7ff2dedSPeter Holm close(fd); 150*d7ff2dedSPeter Holm 151*d7ff2dedSPeter Holm return (0); 152*d7ff2dedSPeter Holm} 153