1*896809e2SPeter Holm#!/bin/sh 2*896809e2SPeter Holm 3*896809e2SPeter Holm# 4*896809e2SPeter Holm# SPDX-License-Identifier: BSD-2-Clause 5*896809e2SPeter Holm# 6*896809e2SPeter Holm# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org> 7*896809e2SPeter Holm# 8*896809e2SPeter Holm# Redistribution and use in source and binary forms, with or without 9*896809e2SPeter Holm# modification, are permitted provided that the following conditions 10*896809e2SPeter Holm# are met: 11*896809e2SPeter Holm# 1. Redistributions of source code must retain the above copyright 12*896809e2SPeter Holm# notice, this list of conditions and the following disclaimer. 13*896809e2SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 14*896809e2SPeter Holm# notice, this list of conditions and the following disclaimer in the 15*896809e2SPeter Holm# documentation and/or other materials provided with the distribution. 16*896809e2SPeter Holm# 17*896809e2SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*896809e2SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*896809e2SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*896809e2SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*896809e2SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*896809e2SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*896809e2SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*896809e2SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*896809e2SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*896809e2SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*896809e2SPeter Holm# SUCH DAMAGE. 28*896809e2SPeter Holm# 29*896809e2SPeter Holm 30*896809e2SPeter Holm# killpg(2) version of reaper.sh. No problems seen. 31*896809e2SPeter Holm 32*896809e2SPeter Holm. ../default.cfg 33*896809e2SPeter Holm 34*896809e2SPeter Holmprog=$(basename "$0" .sh) 35*896809e2SPeter Holmcat > /tmp/$prog.c <<EOF 36*896809e2SPeter Holm#include <sys/param.h> 37*896809e2SPeter Holm#include <sys/mman.h> 38*896809e2SPeter Holm#include <sys/wait.h> 39*896809e2SPeter Holm 40*896809e2SPeter Holm 41*896809e2SPeter Holm#include <err.h> 42*896809e2SPeter Holm#include <errno.h> 43*896809e2SPeter Holm#include <pwd.h> 44*896809e2SPeter Holm#include <signal.h> 45*896809e2SPeter Holm#include <stdatomic.h> 46*896809e2SPeter Holm#include <stdio.h> 47*896809e2SPeter Holm#include <stdlib.h> 48*896809e2SPeter Holm#include <time.h> 49*896809e2SPeter Holm#include <unistd.h> 50*896809e2SPeter Holm 51*896809e2SPeter Holmstatic _Atomic(int) *share; 52*896809e2SPeter Holm 53*896809e2SPeter Holm#define GID 0 54*896809e2SPeter Holm#define PARALLEL 10 55*896809e2SPeter Holm#define RDY 1 56*896809e2SPeter Holm#define MAXP 7000 57*896809e2SPeter Holm 58*896809e2SPeter Holmstatic void 59*896809e2SPeter Holmhand(int i __unused) { 60*896809e2SPeter Holm _exit(0); 61*896809e2SPeter Holm} 62*896809e2SPeter Holm 63*896809e2SPeter Holmstatic void 64*896809e2SPeter Holminnerloop(int parallel) 65*896809e2SPeter Holm{ 66*896809e2SPeter Holm pid_t pids[MAXP]; 67*896809e2SPeter Holm struct sigaction sa; 68*896809e2SPeter Holm int i; 69*896809e2SPeter Holm 70*896809e2SPeter Holm usleep(1000); 71*896809e2SPeter Holm for (i = 0; i < parallel; i++) { 72*896809e2SPeter Holm if ((pids[i] = fork()) == 0) { 73*896809e2SPeter Holm sa.sa_handler = hand; 74*896809e2SPeter Holm sigemptyset(&sa.sa_mask); 75*896809e2SPeter Holm sa.sa_flags = 0; 76*896809e2SPeter Holm if (sigaction(SIGUSR1, &sa, NULL) == -1) 77*896809e2SPeter Holm err(1, "sigaction"); 78*896809e2SPeter Holm atomic_fetch_add(&share[RDY], 1); 79*896809e2SPeter Holm setproctitle("child"); 80*896809e2SPeter Holm for (;;) 81*896809e2SPeter Holm pause(); 82*896809e2SPeter Holm _exit(0); /* never reached */ 83*896809e2SPeter Holm } 84*896809e2SPeter Holm if (pids[i] == -1) 85*896809e2SPeter Holm err(1, "fork()"); 86*896809e2SPeter Holm } 87*896809e2SPeter Holm for (i = 0; i < parallel; i++) { 88*896809e2SPeter Holm if (waitpid(pids[i], NULL, 0) != pids[i]) 89*896809e2SPeter Holm err(1, "waitpid(%d) in looper", pids[i]); 90*896809e2SPeter Holm } 91*896809e2SPeter Holm _exit(0); 92*896809e2SPeter Holm} 93*896809e2SPeter Holm 94*896809e2SPeter Holmstatic void 95*896809e2SPeter Holmlooper(void) 96*896809e2SPeter Holm{ 97*896809e2SPeter Holm struct sigaction sa; 98*896809e2SPeter Holm struct passwd *pw; 99*896809e2SPeter Holm pid_t pids[MAXP]; 100*896809e2SPeter Holm int i, parallel; 101*896809e2SPeter Holm 102*896809e2SPeter Holm setproctitle("looper"); 103*896809e2SPeter Holm sa.sa_handler = SIG_IGN; 104*896809e2SPeter Holm sigemptyset(&sa.sa_mask); 105*896809e2SPeter Holm sa.sa_flags = 0; 106*896809e2SPeter Holm if (sigaction(SIGUSR1, &sa, NULL) == -1) 107*896809e2SPeter Holm err(1, "sigaction"); 108*896809e2SPeter Holm 109*896809e2SPeter Holm if ((pw = getpwnam("TUSER")) == NULL) 110*896809e2SPeter Holm err(1, "no such user: TUSER"); 111*896809e2SPeter Holm 112*896809e2SPeter Holm if (setgroups(1, &pw->pw_gid) || 113*896809e2SPeter Holm setegid(pw->pw_gid) || setgid(pw->pw_gid) || 114*896809e2SPeter Holm seteuid(pw->pw_uid) || setuid(pw->pw_uid)) 115*896809e2SPeter Holm err(1, "Can't drop privileges to \"TUSER\""); 116*896809e2SPeter Holm endpwent(); 117*896809e2SPeter Holm setpgrp(0, 0); 118*896809e2SPeter Holm share[GID] = getpgrp(); 119*896809e2SPeter Holm parallel = arc4random() % MAXP + 1; 120*896809e2SPeter Holm parallel = parallel / PARALLEL * PARALLEL; 121*896809e2SPeter Holm for (i = 0; i < PARALLEL; i++) { 122*896809e2SPeter Holm if ((pids[i] = fork()) == 0) 123*896809e2SPeter Holm innerloop(parallel / PARALLEL); 124*896809e2SPeter Holm } 125*896809e2SPeter Holm while (atomic_load(&share[RDY]) != parallel) 126*896809e2SPeter Holm usleep(10000); 127*896809e2SPeter Holm if (killpg(share[GID], SIGUSR1) == -1) 128*896809e2SPeter Holm err(1, "pgkill(%d)", share[GID]); 129*896809e2SPeter Holm for (i = 0; i < 4; i++) { 130*896809e2SPeter Holm if (waitpid(pids[i], NULL, 0) != pids[i]) 131*896809e2SPeter Holm err(1, "waitpid(%d) in looper", pids[i]); 132*896809e2SPeter Holm } 133*896809e2SPeter Holm _exit(0); 134*896809e2SPeter Holm} 135*896809e2SPeter Holm 136*896809e2SPeter Holmint 137*896809e2SPeter Holmmain(void) 138*896809e2SPeter Holm{ 139*896809e2SPeter Holm size_t len; 140*896809e2SPeter Holm time_t start; 141*896809e2SPeter Holm int lpid, s1; 142*896809e2SPeter Holm 143*896809e2SPeter Holm len = PAGE_SIZE; 144*896809e2SPeter Holm if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 145*896809e2SPeter Holm MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 146*896809e2SPeter Holm err(1, "mmap"); 147*896809e2SPeter Holm 148*896809e2SPeter Holm start = time(NULL); 149*896809e2SPeter Holm while (time(NULL) - start < 120) { 150*896809e2SPeter Holm share[GID] = 0; 151*896809e2SPeter Holm share[RDY] = 0; 152*896809e2SPeter Holm if ((lpid = fork()) == 0) 153*896809e2SPeter Holm looper(); 154*896809e2SPeter Holm if (waitpid(lpid, &s1, 0) != lpid) 155*896809e2SPeter Holm err(1, "waitpid looper"); 156*896809e2SPeter Holm } 157*896809e2SPeter Holm 158*896809e2SPeter Holm return (0); 159*896809e2SPeter Holm} 160*896809e2SPeter HolmEOF 161*896809e2SPeter Holmsed -i '' "s#TUSER#$testuser#" /tmp/$prog.c 162*896809e2SPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1 163*896809e2SPeter Holmrm /tmp/$prog.c 164*896809e2SPeter Holm 165*896809e2SPeter Holmexport MAXSWAPPCT=70 166*896809e2SPeter Holmn=1 167*896809e2SPeter Holmstart=`date +%s` 168*896809e2SPeter Holmwhile true; do 169*896809e2SPeter Holm ../testcases/swap/swap -t 2m -i 20 > /dev/null & 170*896809e2SPeter Holm /tmp/$prog & pid=$! 171*896809e2SPeter Holm st=`date +%s` 172*896809e2SPeter Holm while kill -0 $pid > /dev/null 2>&1; do 173*896809e2SPeter Holm e=$((`date +%s` - st)) 174*896809e2SPeter Holm if [ $e -ge 120 ]; then 175*896809e2SPeter Holm while pgrep -q swap; do pkill swap; done 176*896809e2SPeter Holm fi 177*896809e2SPeter Holm if [ $e -ge 600 ]; then 178*896809e2SPeter Holm echo "Failed in loop #$n after $e seconds." 179*896809e2SPeter Holm ps -jU$testuser | head -20 180*896809e2SPeter Holm kill $pid 181*896809e2SPeter Holm pkill -U$testuser 182*896809e2SPeter Holm wait 183*896809e2SPeter Holm rm -f /tmp/$prog 184*896809e2SPeter Holm exit 1 185*896809e2SPeter Holm fi 186*896809e2SPeter Holm done 187*896809e2SPeter Holm wait 188*896809e2SPeter Holm [ $((`date +%s` - start)) -ge 300 ] && break 189*896809e2SPeter Holm n=$((n + 1)) 190*896809e2SPeter Holmdone 191*896809e2SPeter Holmrm /tmp/$prog 192*896809e2SPeter Holmexit 0 193