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# $FreeBSD$ 29# 30 31# Test scenario with a 20G files on two UFS2 FSs with 64k/64k 32# Test program will hang (deadlock) in "nbufkv" 33 34# Test scenario by John-Mark Gurney <jmg at funkthat dot com> 35 36[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 37 38. ../default.cfg 39 40odir=`pwd` 41 42cd /tmp 43sed '1,/^EOF/d' < $odir/$0 > nbufkv.c 44cc -o nbufkv -Wall nbufkv.c 45rm -f nbufkv.c 46cd $odir 47 48u1=$mdstart 49u2=$((u1 + 1)) 50d1=/tmp/diskimage1 51d2=/tmp/diskimage2 52[ -d mp1 ] || mkdir mp1 53[ -d mp2 ] || mkdir mp2 54truncate -s 20g $d1 55truncate -s 20g $d2 56 57mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part 58mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part 59mdconfig -l | grep -q md${u2} && mdconfig -d -u $u2 60mdconfig -l | grep -q md${u1} && mdconfig -d -u $u1 61 62mdconfig -a -t vnode -f $d1 -u $u1 63bsdlabel -w md$u1 auto 64newfs -b 65536 -f 65536 -O2 md${u1}${part} > /dev/null 65 66mdconfig -a -t vnode -f $d2 -u $u2 67bsdlabel -w md$u2 auto 68newfs -b 65536 -f 65536 -O2 md${u2}${part} > /dev/null 69 70mount /dev/md${u1}$part mp1 71mount /dev/md${u2}$part mp2 72 73/tmp/nbufkv `pwd`/mp1 & 74/tmp/nbufkv `pwd`/mp2 & 75wait;wait 76 77umount /dev/md${u2}$part 78umount /dev/md${u1}$part 79 80mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part 81mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part 82 83mdconfig -d -u $u2 84mdconfig -d -u $u1 85 86rm -rf mp1 mp2 $d1 $d2 /tmp/nbufkv 87exit 88EOF 89#include <sys/types.h> 90#include <err.h> 91#include <stdio.h> 92#include <stdlib.h> 93#include <unistd.h> 94#include <fcntl.h> 95#include <sys/param.h> 96 97void 98work(int fd, size_t n) 99{ 100 int i; 101 102 for (i = 0; i < 128 * 1024; i++) { 103 n = n - PAGE_SIZE; 104 if (lseek(fd, n , SEEK_SET) == -1) 105 err(1, "lseek()"); 106 if (write(fd, "1", 1) != 1) 107 err(1, "write()"); 108 } 109 110} 111 112int 113main(int argc, char **argv) 114{ 115 116 int fd; 117 off_t len; 118 char path[128]; 119 120 len = 20; 121 len = len * 1024 * 1024 * 1024; 122 123 sprintf(path, "%s/nbufkv.%06d", argv[1], getpid()); 124 if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0640)) == -1) 125 err(1,"open()"); 126 if (ftruncate(fd, len) == -1) 127 err(1, "ftruncate"); 128 129 work(fd, len); 130 131 close(fd); 132 if (unlink(path) == -1) 133 err(1, "unlink(%s)", path); 134 135 return (0); 136} 137