1#!/bin/sh 2 3# 4# Copyright (c) 2008 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 by marcus@freebsd.org and kib@freebsd.org 30 31[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 32 33. ../default.cfg 34 35odir=`pwd` 36cd /tmp 37sed '1,/^EOF/d' < $odir/$0 > kinfo3.c 38mycc -o kinfo3 -Wall -Wextra -O0 kinfo3.c -lutil -pthread || exit 1 39rm -f kinfo3.c 40 41s=0 42mount | grep -q procfs || mount -t procfs procfs /proc 43start=`date '+%s'` 44while [ $((`date '+%s'` - start)) -lt 1200 ]; do 45 pids="" 46 for i in `jot 5`; do 47 timeout 5m /tmp/kinfo3 & 48 pids="$pids $!" 49 done 50 for pid in $pids; do 51 wait $pid 52 r=$? 53 [ $r -ne 0 ] && { s=1; echo "Exit code $r"; break; } 54 done 55done 56 57rm -f /tmp/kinfo3 58exit $s 59EOF 60 61#include <sys/types.h> 62#include <sys/signal.h> 63#include <sys/sysctl.h> 64#include <sys/user.h> 65#include <sys/wait.h> 66 67#include <err.h> 68#include <fcntl.h> 69#include <libutil.h> 70#include <pthread.h> 71#include <stdio.h> 72#include <stdlib.h> 73#include <string.h> 74#include <strings.h> 75#include <unistd.h> 76 77static char buf[8096]; 78static volatile sig_atomic_t more; 79 80static void 81handler(int i __unused) { 82 83 more = 0; 84} 85 86static void * 87thr(void *arg __unused) 88{ 89 int fd; 90 91 if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) 92 err(1, "open(/proc/curproc/mem)"); 93 close(fd); 94 return (0); 95} 96 97/* Stir /dev/proc */ 98static int 99churning(void) { 100 pid_t r; 101 pthread_t threads[5]; 102 int i, status;; 103 104 while(more) { 105 r = fork(); 106 if (r == 0) { 107 for (i = 0; i < 5; i++) { 108 if ((r = pthread_create(&threads[i], NULL, thr, 0)) != 0) 109 errc(1, r, "pthread_create()"); 110 } 111 for (i = 0; i < 5; i++) { 112 if ((r = pthread_join(threads[i], NULL)) != 0) 113 errc(1, r, "pthread_join(%d)", i); 114 } 115 116 bzero(buf, sizeof(buf)); 117 _exit(0); 118 } 119 if (r < 0) { 120 perror("fork"); 121 exit(2); 122 } 123 wait(&status); 124 } 125 _exit(0); 126} 127 128/* Get files for each proc */ 129static void 130list(void) 131{ 132 struct kinfo_proc *kipp; 133 struct kinfo_vmentry *freep_vm; 134 struct kinfo_file *freep, *kif __unused; 135 size_t len; 136 long i, j; 137 int cnt, name[4]; 138 139 name[0] = CTL_KERN; 140 name[1] = KERN_PROC; 141 name[2] = KERN_PROC_PROC; 142 143 len = 0; 144 if (sysctl(name, 3, NULL, &len, NULL, 0) < 0) 145 err(-1, "sysctl: kern.proc.all"); 146 147 kipp = malloc(len); 148 if (kipp == NULL) 149 err(1, "malloc"); 150 151 if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) { 152 free(kipp); 153// warn("sysctl: kern.proc.all"); 154 return; 155 } 156 157 for (i = 0; i < (long)(len / sizeof(*kipp)); i++) { 158 159 /* The test starts here */ 160 freep = kinfo_getfile(kipp[i].ki_pid, &cnt); 161 for (j = 0; j < cnt && freep; j++) { 162 kif = &freep[j]; 163// printf("%d : %s\n", kif->kf_fd, kif->kf_path); 164 } 165 free(freep); 166 167 freep_vm = kinfo_getvmmap(kipp[i].ki_pid, &cnt); 168 free(freep_vm); 169 /* End test */ 170 } 171 free(kipp); 172} 173 174int 175main(void) 176{ 177 pid_t r; 178 179 signal(SIGALRM, handler); 180 alarm(30); 181 182 more = 1; 183 if ((r = fork()) == 0) { 184 alarm(30); 185 while(more) 186 churning(); 187 } 188 if (r < 0) { 189 perror("fork"); 190 exit(2); 191 } 192 193 while(more) 194 list(); 195 196 return (0); 197} 198