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