xref: /freebsd/tools/test/stress2/misc/msync.sh (revision 8881d206f4e68b564c2c5f50fc717086fc3e827a)
1#!/bin/sh
2
3#
4# Copyright (c) 2013 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# msync(2) / mlockall(2) test scenario.
30# "panic: vm_fault_copy_wired: page missing" seen.
31# http://people.freebsd.org/~pho/stress/log/msync.txt
32# Fixed in r253189.
33
34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35
36. ../default.cfg
37
38dir=/tmp
39odir=`pwd`
40cd $dir
41sed '1,/^EOF/d' < $odir/$0 > $dir/msync.c
42mycc -o msync -Wall -Wextra msync.c -lpthread || exit 1
43rm -f msync.c
44cd $odir
45
46/tmp/msync &
47sleep 180
48while pkill -9 msync; do :; done
49wait
50rm -f /tmp/msync
51exit
52
53EOF
54#include <sys/types.h>
55#include <err.h>
56#include <errno.h>
57#include <fcntl.h>
58#include <pthread.h>
59#include <pwd.h>
60#include <signal.h>
61#include <sys/mman.h>
62#include <stdint.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <sys/param.h>
67#include <sys/stat.h>
68#include <sys/syscall.h>
69#include <sys/wait.h>
70#include <unistd.h>
71
72int syscallno = SYS_msync;
73#define N (128 * 1024 / (int)sizeof(u_int32_t))
74u_int32_t r[N];
75
76static void
77hand(int i __unused) {	/* handler */
78	_exit(1);
79}
80
81unsigned long
82makearg(void)
83{
84	unsigned int i;
85	unsigned long val;
86
87	val = arc4random();
88	i   = arc4random() % 100;
89	if (i < 20)
90		val = val & 0xff;
91	if (i >= 20 && i < 40)
92		val = val & 0xffff;
93	if (i >= 40 && i < 60)
94		val = (unsigned long)(r) | (val & 0xffff);
95#if defined(__LP64__)
96	if (i >= 60) {
97		val = (val << 32) | arc4random();
98		if (i > 80)
99			val = val & 0x00007fffffffffffUL;
100	}
101#endif
102
103	return(val);
104}
105
106void *
107calls(void *arg __unused)
108{
109	int i, num;
110	unsigned long arg1, arg2, arg3;
111
112	usleep(1000);
113	num = syscallno;
114	for (i = 0; i < 500; i++) {
115		arg1 = makearg();
116		arg2 = makearg();
117#if 0
118		arg3 = makearg();
119		arg3 = arg3 & ~MS_INVALIDATE;	/* No problem seen */
120#else
121		arg3 = MS_INVALIDATE;		/* panic */
122#endif
123
124#if 0
125		fprintf(stderr, "%2d : syscall(%3d, 0x%lx, 0x%lx, 0x%lx)\n",
126			i, num, arg1, arg2, arg3);
127		usleep(50000);
128#endif
129		alarm(1);
130		syscall(num, arg1, arg2, arg3);
131		num = 0;
132	}
133
134	return (0);
135}
136void
137wd(void)
138{
139	int i;
140
141	if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
142		err(1, "mlockall failed");
143
144	for (i = 0; i < 800; i++) {
145		if (fork() == 0) {
146			usleep(20000);
147			_exit(0);
148		}
149		wait(NULL);
150		usleep(100000);
151	}
152
153	_exit(0);
154}
155
156int
157main(void)
158{
159	struct passwd *pw;
160	pthread_t cp[50];
161	int e, i, j;
162
163	if (fork() == 0)
164		wd();
165
166	if ((pw = getpwnam("nobody")) == NULL)
167		err(1, "no such user: nobody");
168
169	if (setgroups(1, &pw->pw_gid) ||
170	    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
171	    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
172		err(1, "Can't drop privileges to \"nobody\"");
173	endpwent();
174
175	signal(SIGALRM, hand);
176	signal(SIGILL,  hand);
177	signal(SIGFPE,  hand);
178	signal(SIGSEGV, hand);
179	signal(SIGBUS,  hand);
180	signal(SIGURG,  hand);
181	signal(SIGSYS,  hand);
182	signal(SIGTRAP, hand);
183
184	alarm(180);
185	for (i = 0; i < 8000; i++) {
186		if (fork() == 0) {
187			for (j = 0; j < N; j++)
188				r[j] = arc4random();
189			for (j = 0; j < 50; j++)
190				if ((e = pthread_create(&cp[j], NULL, calls, NULL)) != 0)
191					errc(1, e, "pthread_create");
192
193			for (j = 0; j < 50; j++)
194				pthread_join(cp[j], NULL);
195			_exit(0);
196		}
197		wait(NULL);
198	}
199
200	return (0);
201}
202