1#!/bin/sh 2 3# 4# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org> 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Test scenario idea by kib@ 30 31# "panic: double fault" seen due to recursion 32 33[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 34 35. ../default.cfg 36 37mount | grep -q procfs || mount -t procfs procfs /proc 38here=`pwd` 39cd /tmp 40sed '1,/^EOF/d' < $here/$0 > procfs4.c 41mycc -o procfs4 -Wall -Wextra -O2 procfs4.c || exit 1 42rm -f procfs4.c 43cd $here 44 45su $testuser -c /tmp/procfs4 46e=$? 47 48rm -f /tmp/procfs4 49exit $e 50EOF 51#include <sys/param.h> 52#include <sys/ioctl.h> 53#include <sys/param.h> 54#include <sys/types.h> 55#include <sys/wait.h> 56 57#include <err.h> 58#include <errno.h> 59#include <fcntl.h> 60#include <signal.h> 61#include <stdio.h> 62#include <stdlib.h> 63#include <string.h> 64#include <time.h> 65#include <unistd.h> 66 67#define LOOPS 1000 68#define MAXRUN 1200 69#define PARALLEL 10 70 71static int debug; /* Set to 1 for debug output */ 72char *files[] = { 73 "cmdline", 74 "ctl", 75 "dbregs", 76 "etype", 77 "file", 78 "fpregs", 79 "map", 80 "mem", 81 "note", 82 "notepg", 83 "osrel", 84 "regs", 85 "rlimit", 86 "status" 87}; 88 89void 90test(void) 91{ 92 pid_t p; 93 int fd, i, j, n, opens; 94 char path[128]; 95 96 for (i = 0; i < 64; i++) { 97 if ((p = fork()) == 0) { 98 setproctitle("Sleeper"); 99 usleep(20000); 100 usleep(arc4random() % 200); 101 for (j = 0; j < 10000; j++) 102 getpid(); 103 _exit(0); 104 } 105 opens = 0; 106 setproctitle("load"); 107 for (j = 0; j < 14; j++) { 108 snprintf(path, sizeof(path), "/proc/%d/%s", p, files[j]); 109 if ((fd = open(path, O_RDWR)) == -1) 110 if ((fd = open(path, O_RDONLY)) == -1) 111 continue; 112 113 ioctl(fd, FIONREAD, &n); 114 if (ioctl(fd, FIONBIO, &n) != -1) 115 opens++; 116 117 close(fd); 118 } 119 kill(p, SIGHUP); 120 if (debug != 0 && opens == 0) 121 fprintf(stderr, "No ioctl() calls succeeded.\n"); 122 } 123 124 for (i = 0; i < 64; i++) 125 wait(NULL); 126 127 _exit(0); 128} 129 130int 131main(void) 132{ 133 time_t start; 134 int e, i, j; 135 136 e = 0; 137 start = time(NULL); 138 for (i = 0; i < LOOPS; i++) { 139 for (j = 0; j < PARALLEL; j++) { 140 if (fork() == 0) 141 test(); 142 } 143 144 for (j = 0; j < PARALLEL; j++) 145 wait(NULL); 146 usleep(10000); 147 if (time(NULL) - start > MAXRUN) { 148 fprintf(stderr, "FAIL Timeout\n"); 149 e = 1; 150 break; 151 } 152 } 153 154 return (e); 155} 156