18a272653SPeter Holm#!/bin/sh 28a272653SPeter Holm 38a272653SPeter Holm# 4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 58a272653SPeter Holm# 68a272653SPeter Holm# Copyright (c) 2018 Dell EMC Isilon 78a272653SPeter Holm# 88a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 98a272653SPeter Holm# modification, are permitted provided that the following conditions 108a272653SPeter Holm# are met: 118a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 128a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 138a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 148a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 158a272653SPeter Holm# documentation and/or other materials provided with the distribution. 168a272653SPeter Holm# 178a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 188a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 198a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 208a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 218a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 228a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 238a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 248a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 268a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 278a272653SPeter Holm# SUCH DAMAGE. 288a272653SPeter Holm# 298a272653SPeter Holm 308a272653SPeter Holm# Bug 228858 - panic when delivering knote to a process who has opened a 318a272653SPeter Holm# kqueue() is dying 328a272653SPeter Holm# Page fault seen: https://people.freebsd.org/~pho/stress/log/mark052.txt 338a272653SPeter Holm# Fixed by r340897. 348a272653SPeter Holm 358a272653SPeter Holm# Test scenario based on analysis by siddharthtuli gmail com 368a272653SPeter Holm 378a272653SPeter Holm. ../default.cfg 388a272653SPeter Holm 398a272653SPeter Holmodir=`pwd` 408a272653SPeter Holm 418a272653SPeter Holmcd /tmp 428a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > kevent12.c 438a272653SPeter Holmmycc -o kevent12 -Wall -Wextra -O2 -g kevent12.c || exit 1 448a272653SPeter Holmrm -f kevent12.c 458a272653SPeter Holmcd $odir 468a272653SPeter Holm 478a272653SPeter Holm(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -l 100 > /dev/null 2>&1) & 488a272653SPeter Holmpid=$! 498a272653SPeter Holm/tmp/kevent12 508a272653SPeter Holmwhile pgrep -q swap; do 518a272653SPeter Holm pkill -9 swap 528a272653SPeter Holmdone 538a272653SPeter Holmwait $pid 548a272653SPeter Holm 558a272653SPeter Holmrm -f /tmp/kevent12 568a272653SPeter Holmexit 0 578a272653SPeter HolmEOF 588a272653SPeter Holm#include <sys/types.h> 598a272653SPeter Holm#include <sys/event.h> 608a272653SPeter Holm#include <sys/wait.h> 618a272653SPeter Holm 628a272653SPeter Holm#include <err.h> 638a272653SPeter Holm#include <errno.h> 648a272653SPeter Holm#include <signal.h> 658a272653SPeter Holm#include <stdio.h> 668a272653SPeter Holm#include <stdlib.h> 678a272653SPeter Holm#include <string.h> 688a272653SPeter Holm#include <time.h> 698a272653SPeter Holm#include <unistd.h> 708a272653SPeter Holm 718a272653SPeter Holm#define PARALLEL 64 728a272653SPeter Holm#define RUNTIME (5 * 60) 738a272653SPeter Holm 748a272653SPeter Holmstatic pid_t parent; 758a272653SPeter Holmstatic int kq; 768a272653SPeter Holm 778a272653SPeter Holmstatic void 788a272653SPeter Holmhand(int i __unused) { /* handler */ 798a272653SPeter Holm kill(parent, SIGINT); 808a272653SPeter Holm _exit(1); 818a272653SPeter Holm} 828a272653SPeter Holm 838a272653SPeter Holmstatic void 848a272653SPeter Holminit_kq() 858a272653SPeter Holm{ 868a272653SPeter Holm kq = kqueue(); 878a272653SPeter Holm if (kq == -1) 888a272653SPeter Holm err(1, "kqueue"); 898a272653SPeter Holm} 908a272653SPeter Holm 918a272653SPeter Holmstatic void 928a272653SPeter Holmadd_watch(pid_t pid) 938a272653SPeter Holm{ 948a272653SPeter Holm struct kevent kev; 958a272653SPeter Holm char msg[64]; 968a272653SPeter Holm 978a272653SPeter Holm bzero(&kev, sizeof(kev)); 988a272653SPeter Holm kev.ident = pid; 998a272653SPeter Holm kev.flags = EV_ADD | EV_ENABLE; 1008a272653SPeter Holm kev.filter = EVFILT_PROC; 1018a272653SPeter Holm kev.fflags = NOTE_EXIT | NOTE_EXEC | NOTE_TRACK | NOTE_TRACKERR; 1028a272653SPeter Holm 1038a272653SPeter Holm for (;;) { 1048a272653SPeter Holm int res = kevent(kq, &kev, 1, NULL, 0, NULL); 1058a272653SPeter Holm if (res == -1) { 1068a272653SPeter Holm if (errno == EINTR) 1078a272653SPeter Holm continue; 1088a272653SPeter Holm if (errno == ESRCH) 1098a272653SPeter Holm break; 1108a272653SPeter Holm 1118a272653SPeter Holm snprintf(msg, sizeof(msg), 1128a272653SPeter Holm "kevent - add watch for pid %u", pid); 1138a272653SPeter Holm err(1, "%s", msg); 1148a272653SPeter Holm } 1158a272653SPeter Holm else 1168a272653SPeter Holm break; 1178a272653SPeter Holm } 1188a272653SPeter Holm} 1198a272653SPeter Holm 1208a272653SPeter Holmstatic void 1218a272653SPeter Holmpolling() 1228a272653SPeter Holm{ 1238a272653SPeter Holm struct kevent kev[10]; 1248a272653SPeter Holm#if defined(DEBUG) 1258a272653SPeter Holm pid_t pid; 1268a272653SPeter Holm int i; 1278a272653SPeter Holm#endif 1288a272653SPeter Holm 1298a272653SPeter Holm for (;;) { 1308a272653SPeter Holm bzero(&kev, sizeof(kev)); 1318a272653SPeter Holm if (arc4random() % 100 < 10) { 1328a272653SPeter Holm signal(SIGALRM, hand); 1338a272653SPeter Holm ualarm(10000, 0); 1348a272653SPeter Holm } 1358a272653SPeter Holm int res = kevent(kq, NULL, 0, kev, 1368a272653SPeter Holm sizeof(kev) / sizeof(kev[0]), NULL); 1378a272653SPeter Holm if (res == -1) { 1388a272653SPeter Holm if (errno == EINTR) 1398a272653SPeter Holm continue; 1408a272653SPeter Holm 1418a272653SPeter Holm if (errno == ESRCH) 1428a272653SPeter Holm continue; 1438a272653SPeter Holm 1448a272653SPeter Holm err(1, "kevent"); 1458a272653SPeter Holm } 1468a272653SPeter Holm 1478a272653SPeter Holm#if defined(DEBUG) 1488a272653SPeter Holm for (i = 0; i < res; i++) { 1498a272653SPeter Holm pid = kev[i].ident; 1508a272653SPeter Holm if (kev[i].fflags & NOTE_CHILD) { 1518a272653SPeter Holm add_watch(pid); 1528a272653SPeter Holm printf("%u - new process, parent %u\n", pid, 1538a272653SPeter Holm (unsigned int)kev[i].data); 1548a272653SPeter Holm } 1558a272653SPeter Holm if (kev[i].fflags & NOTE_FORK) { 1568a272653SPeter Holm printf("%u forked\n", pid); 1578a272653SPeter Holm } 1588a272653SPeter Holm if (kev[i].fflags & NOTE_EXEC) { 1598a272653SPeter Holm printf("%u called exec\n", pid); 1608a272653SPeter Holm } 1618a272653SPeter Holm if (kev[i].fflags & NOTE_EXIT) { 1628a272653SPeter Holm printf("%u exited\n", pid); 1638a272653SPeter Holm if (parent == pid) 1648a272653SPeter Holm return; 1658a272653SPeter Holm } 1668a272653SPeter Holm if (kev[i].fflags & NOTE_TRACK) { 1678a272653SPeter Holm printf("%u forked - track\n", pid); 1688a272653SPeter Holm } 1698a272653SPeter Holm if (kev[i].fflags & NOTE_TRACKERR) { 1708a272653SPeter Holm fprintf(stderr, "%u - track error\n", pid); 1718a272653SPeter Holm } 1728a272653SPeter Holm } 1738a272653SPeter Holm#endif 1748a272653SPeter Holm } 1758a272653SPeter Holm} 1768a272653SPeter Holm 1778a272653SPeter Holmvoid 1788a272653SPeter Holmchurn(void) 1798a272653SPeter Holm{ 1808a272653SPeter Holm pid_t pid; 1818a272653SPeter Holm time_t start; 1828a272653SPeter Holm char *cmdline[] = { "/usr/bin/true", NULL }; 1838a272653SPeter Holm 1848a272653SPeter Holm start = time(NULL); 1858a272653SPeter Holm while (time(NULL) - start < RUNTIME) { 1868a272653SPeter Holm if ((pid = fork()) == -1) 1878a272653SPeter Holm err(1, "fork"); 1888a272653SPeter Holm if (pid == 0) { 1898a272653SPeter Holm if (execve(cmdline[0], cmdline, NULL) == -1) 1908a272653SPeter Holm err(1, "execve"); 1918a272653SPeter Holm } 1928a272653SPeter Holm if (waitpid(pid, NULL, 0) != pid) 1938a272653SPeter Holm err(1, "waitpid(%d):%d", pid, __LINE__); 1948a272653SPeter Holm } 1958a272653SPeter Holm 1968a272653SPeter Holm _exit(0); 1978a272653SPeter Holm} 1988a272653SPeter Holm 1998a272653SPeter Holmint 2008a272653SPeter Holmtest(void) 2018a272653SPeter Holm{ 2028a272653SPeter Holm if ((parent = fork()) == 0) 2038a272653SPeter Holm churn(); 2048a272653SPeter Holm 2058a272653SPeter Holm init_kq(); 2068a272653SPeter Holm add_watch(parent); 2078a272653SPeter Holm polling(); 2088a272653SPeter Holm if (waitpid(parent, NULL, 0) != parent) 2098a272653SPeter Holm err(1, "waitpid(%d):%d", parent, __LINE__); 2108a272653SPeter Holm 2118a272653SPeter Holm _exit(0); 2128a272653SPeter Holm} 2138a272653SPeter Holm 2148a272653SPeter Holmint 2158a272653SPeter Holmmain(void) 2168a272653SPeter Holm{ 2178a272653SPeter Holm pid_t pids[PARALLEL]; 2188a272653SPeter Holm time_t start; 2198a272653SPeter Holm int i; 2208a272653SPeter Holm 2218a272653SPeter Holm start = time(NULL); 2228a272653SPeter Holm while (time(NULL) - start < RUNTIME) { 2238a272653SPeter Holm for (i = 0; i < PARALLEL; i++) { 2248a272653SPeter Holm if ((pids[i] = fork()) == 0) 2258a272653SPeter Holm test(); 2268a272653SPeter Holm } 2278a272653SPeter Holm for (i = 0; i < PARALLEL; i++) 2288a272653SPeter Holm if (waitpid(pids[i], NULL, 0) != pids[i]) 2298a272653SPeter Holm err(1, "waitpid(%d):%d", pids[i], __LINE__); 2308a272653SPeter Holm } 2318a272653SPeter Holm 2328a272653SPeter Holm return (0); 2338a272653SPeter Holm} 234