xref: /freebsd/tools/test/stress2/misc/core3.sh (revision c1d255d3)
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
52bsdlabel -w md$mdstart auto
53newfs $newfs_flags md${mdstart}$part > /dev/null
54mount /dev/md${mdstart}$part $mntpoint
55mkdir $mntpoint/d
56chmod 777 $mntpoint/d
57
58su $testuser -c "/tmp/core3 $mntpoint/d" &
59pid=$!
60sleep 1
61
62while pgrep -q core3; do
63	[ -d $mntpoint/d ] &&
64	   umount -f $mntpoint
65done > /dev/null 2>&1  &
66while pgrep -q core3; do
67	[ -d $mntpoint/d ] ||
68	   mount /dev/md${mdstart}$part $mntpoint
69done > /dev/null 2>&1
70wait $pid
71status=$?
72mount | grep -q "on $mntpoint " &&
73	    umount -f $mntpoint
74mdconfig -d -u $mdstart
75[ $status -ne 0 ] && exit $status
76
77# tmpfs
78mount -o size=1g -t tmpfs tmpfs $mntpoint
79su $testuser -c "/tmp/core3 $mntpoint/d" &
80pid=$!
81sleep 1
82
83while pgrep -q core3; do
84	[ -d $mntpoint/d ] &&
85	   umount -f $mntpoint
86done > /dev/null &
87while pgrep -q core3; do
88	if [ ! -d $mntpoint/d ]; then
89		mount -t tmpfs tmpfs $mntpoint
90		mkdir $mntpoint/d
91	fi
92done
93wait $pid
94status=$?
95for i in `jot 5` ; do
96	mount | grep -q "on $mntpoint " || break
97	umount -f $mntpoint
98	sleep 1
99done
100rm -f /tmp/core3
101exit $status
102EOF
103#include <sys/mman.h>
104#include <sys/wait.h>
105
106#include <err.h>
107#include <signal.h>
108#include <stdio.h>
109#include <stdlib.h>
110#include <string.h>
111#include <time.h>
112#include <unistd.h>
113
114#define PARALLEL 64
115#define SIZ (4 * 1024 * 1024)
116#define TIMEDOUT 22
117
118void *p;
119
120static void
121hand(int i __unused) {	/* handler */
122	_exit(TIMEDOUT);
123}
124
125void
126test(char *argv[])
127{
128	size_t len;
129
130	len = SIZ;
131	p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
132
133	/*
134	 * This loop caused mount to wait in "ufs".
135	 * Adding a usleep(200) would remove the hang.
136	 */
137	signal(SIGALRM, hand);
138	alarm(600);
139	while (chdir(argv[1]) == -1)
140		;
141
142	raise(SIGSEGV);
143
144	_exit(0);
145}
146
147int
148main(int argc, char *argv[])
149{
150	time_t start;
151	int i, s, status;
152
153	if (argc != 2)
154		errx(1, "Usage: %s <path>", argv[0]);
155
156	status = 0;
157	start = time(NULL);
158	while (time(NULL) - start < 600 && status == 0) {
159		for (i = 0; i < PARALLEL; i++) {
160			if (fork() == 0)
161				test(argv);
162		}
163		for (i = 0; i < PARALLEL; i++) {
164			wait(&s);
165			if (WEXITSTATUS(s) == TIMEDOUT)
166				status = 1;
167		}
168	}
169
170	return (status);
171}
172