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