xref: /freebsd/tools/test/stress2/misc/core3.sh (revision 1d386b48)
1#!/bin/sh
2
3#
4# Copyright (c) 2014 EMC Corp.
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 multiple (parallel) core dumps and mount / umount.
30# mount(8) stuck in "ufs" or "tmpfs".
31# http://people.freebsd.org/~pho/stress/log/kostik724.txt
32# Fixed by r272535.
33# On i386 pgrep(1) loops. Fixed by r272566.
34
35# "Sleeping on "pmapdi" with the following non-sleepable locks held:"
36# https://people.freebsd.org/~pho/stress/log/kostik883.txt
37
38[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
39. ../default.cfg
40
41odir=`pwd`
42
43cd /tmp
44sed '1,/^EOF/d' < $odir/$0 > core3.c
45mycc -o core3 -Wall -Wextra -O2 core3.c || exit 1
46rm -f core3.c
47cd $odir
48
49mount | grep -q "on $mntpoint " && umount $mntpoint
50[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
51mdconfig -a -t swap -s 1g -u $mdstart
52newfs $newfs_flags md$mdstart > /dev/null
53mount /dev/md$mdstart $mntpoint
54mkdir $mntpoint/d
55chmod 777 $mntpoint/d
56
57su $testuser -c "/tmp/core3 $mntpoint/d" &
58pid=$!
59sleep 1
60
61while pgrep -q core3; do
62	[ -d $mntpoint/d ] &&
63	   umount -f $mntpoint
64done > /dev/null 2>&1  &
65while pgrep -q core3; do
66	[ -d $mntpoint/d ] ||
67	   mount /dev/md$mdstart $mntpoint
68done > /dev/null 2>&1
69wait $pid
70status=$?
71mount | grep -q "on $mntpoint " &&
72	    umount -f $mntpoint
73mdconfig -d -u $mdstart
74[ $status -ne 0 ] && exit $status
75
76# tmpfs
77mount -o size=1g -t tmpfs tmpfs $mntpoint
78su $testuser -c "/tmp/core3 $mntpoint/d" &
79pid=$!
80sleep 1
81
82while pgrep -q core3; do
83	[ -d $mntpoint/d ] &&
84	   umount -f $mntpoint
85done > /dev/null &
86while pgrep -q core3; do
87	if [ ! -d $mntpoint/d ]; then
88		mount -t tmpfs tmpfs $mntpoint
89		mkdir $mntpoint/d
90	fi
91done
92wait $pid
93status=$?
94for i in `jot 5` ; do
95	mount | grep -q "on $mntpoint " || break
96	umount -f $mntpoint
97	sleep 1
98done
99rm -f /tmp/core3
100exit $status
101EOF
102#include <sys/mman.h>
103#include <sys/wait.h>
104
105#include <err.h>
106#include <signal.h>
107#include <stdio.h>
108#include <stdlib.h>
109#include <string.h>
110#include <time.h>
111#include <unistd.h>
112
113#define PARALLEL 64
114#define SIZ (4 * 1024 * 1024)
115#define TIMEDOUT 22
116
117void *p;
118
119static void
120hand(int i __unused) {	/* handler */
121	_exit(TIMEDOUT);
122}
123
124void
125test(char *argv[])
126{
127	size_t len;
128
129	len = SIZ;
130	p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
131
132	/*
133	 * This loop caused mount to wait in "ufs".
134	 * Adding a usleep(200) would remove the hang.
135	 */
136	signal(SIGALRM, hand);
137	alarm(600);
138	while (chdir(argv[1]) == -1)
139		;
140
141	raise(SIGSEGV);
142
143	_exit(0);
144}
145
146int
147main(int argc, char *argv[])
148{
149	time_t start;
150	int i, s, status;
151
152	if (argc != 2)
153		errx(1, "Usage: %s <path>", argv[0]);
154
155	status = 0;
156	start = time(NULL);
157	while (time(NULL) - start < 600 && status == 0) {
158		for (i = 0; i < PARALLEL; i++) {
159			if (fork() == 0)
160				test(argv);
161		}
162		for (i = 0; i < PARALLEL; i++) {
163			wait(&s);
164			if (WEXITSTATUS(s) == TIMEDOUT)
165				status = 1;
166		}
167	}
168
169	return (status);
170}
171