1#!/bin/sh 2 3# 4# Copyright (c) 2009 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# Test scenario with a 20G files on two UFS2 FSs with 64k/64k 30# Test program will hang (deadlock) in "nbufkv" 31 32# Test scenario by John-Mark Gurney <jmg at funkthat dot com> 33 34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 35 36. ../default.cfg 37 38dir=`dirname $diskimage` 39d1=$dir/diskimage1 40d2=$dir/diskimage2 41rm -f $d1 $d2 42 43size=20 # G 44avail=$((`sysctl -n hw.physmem` / 1024 / 1024 / 1024)) 45[ $((size * 2)) -gt $avail ] && size=$((avail / 2)) 46[ `df -k $dir | tail -1 | awk '{print $4}'` -lt \ 47 $((size * 2 * 1024 * 1024)) ] && 48 echo "Not enough disk space on $dir." && exit 0 49 50odir=`pwd` 51 52USE_TIMEOUT=1 53cd /tmp 54sed '1,/^EOF/d' < $odir/$0 > nbufkv.c 55mycc -o nbufkv -Wall nbufkv.c 56rm -f nbufkv.c 57cd $odir 58 59u1=$mdstart 60u2=$((u1 + 1)) 61mp1=$mntpoint 62mp2=${mntpoint}2 63[ -d $mp1 ] || mkdir $mp1 64[ -d $mp2 ] || mkdir $mp2 65dd if=/dev/zero of=$d1 bs=1m count=${size}k status=none || exit 1 66cp $d1 $d2 || exit 1 67 68mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part 69mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part 70[ -c /dev/md$u2 ] && mdconfig -d -u $u2 71[ -c /dev/md$u1 ] && mdconfig -d -u $u1 72 73mdconfig -a -t vnode -f $d1 -u $u1 || exit 1 74bsdlabel -w md$u1 auto 75newfs -b 65536 -f 65536 -O2 md${u1}$part > /dev/null 76 77mdconfig -a -t vnode -f $d2 -u $u2 || exit 1 78bsdlabel -w md$u2 auto 79newfs -b 65536 -f 65536 -O2 md${u2}$part > /dev/null 80 81mount /dev/md${u1}$part $mp1 82mount /dev/md${u2}$part $mp2 83 84/tmp/nbufkv $mp1 & 85/tmp/nbufkv $mp2 & 86wait 87 88umount /dev/md${u2}$part 89umount /dev/md${u1}$part 90 91mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part 92mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part 93 94mdconfig -d -u $u2 95mdconfig -d -u $u1 96 97rm -rf $d1 $d2 /tmp/nbufkv 98exit 99EOF 100#include <sys/param.h> 101 102#include <err.h> 103#include <fcntl.h> 104#include <signal.h> 105#include <stdio.h> 106#include <stdlib.h> 107#include <unistd.h> 108 109void 110handler(int i) { 111 fprintf(stderr, "FAIL. Timerout.\n"); 112 _exit(0); 113} 114 115void 116work(int fd, size_t n) 117{ 118 int i; 119 120 for (i = 0; i < 128 * 1024; i++) { 121 n = n - PAGE_SIZE; 122 if (lseek(fd, n , SEEK_SET) == -1) 123 err(1, "lseek()"); 124 if (write(fd, "1", 1) != 1) 125 err(1, "write()"); 126 } 127 128} 129 130int 131main(int argc, char **argv) 132{ 133 134 int fd; 135 off_t len; 136 char path[128]; 137 138 len = 20; 139 len = len * 1024 * 1024 * 1024; 140 141 sprintf(path, "%s/nbufkv.%06d", argv[1], getpid()); 142 if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0640)) == -1) 143 err(1,"open(%s)", path); 144 if (ftruncate(fd, len) == -1) 145 err(1, "ftruncate"); 146 147 signal(SIGALRM, handler); 148 alarm(1200); 149 work(fd, len); 150 151 close(fd); 152 if (unlink(path) == -1) 153 err(1, "unlink(%s)", path); 154 155 return (0); 156} 157