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