xref: /freebsd/tools/test/stress2/misc/kinfo3.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
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