1#!/bin/sh 2 3# 4# Copyright (c) 2011 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[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 30 31# Variation of linger.sh, with emphasis on blocks. 32 33. ../default.cfg 34 35here=`pwd` 36cd /tmp 37sed '1,/^EOF/d' < $here/$0 > linger2.c 38mycc -o linger2 -Wall -O2 linger2.c 39rm -f linger2.c 40cd $here 41 42mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint 43mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 44mdconfig -a -t swap -s 1g -u $mdstart 45[ $# -eq 1 ] && opt="$1" 46[ $# -eq 0 ] && opt=$newfs_flags # No argument == default flag 47newfs $opt -n md$mdstart > /dev/null 48mount /dev/md$mdstart $mntpoint 49chmod 777 $mntpoint 50set `df -i $mntpoint | tail -1 | awk '{print $3, $6}'` 51 52min=24 53[ -r $mntpoint/.sujournal ] && { size=88; min=8232; } 54if ! su $testuser -c "cd $mntpoint; /tmp/linger2 $size 2>/dev/null"; then 55 r=`df -i $mntpoint | head -1` 56 echo " $r" 57 for i in `jot 12`; do 58 r=`df -ik $mntpoint | tail -1` 59 [ "$r" != "$old" ] && echo "`date '+%T'` $r" 60 old=$r 61 [ `echo $r | awk '{print $3}'` -le $min ] && break 62 sleep 10 63 done 64fi 65 66while mount | grep "$mntpoint " | grep -q /dev/md; do 67 umount $mntpoint || sleep 1 68done 69mdconfig -d -u $mdstart 70rm -f /tmp/linger2 71exit 72EOF 73#include <err.h> 74#include <errno.h> 75#include <fcntl.h> 76#include <sched.h> 77#include <stdio.h> 78#include <stdlib.h> 79#include <string.h> 80#include <sys/param.h> 81#include <sys/stat.h> 82#include <sys/wait.h> 83#include <unistd.h> 84 85#define PARALLEL 10 86static int size = 89; 87 88int 89test(void) 90{ 91 int error = 0, fd, i, j; 92 pid_t pid; 93 char file[128]; 94 char *buf; 95 96 for (;;) { 97 if (access("rendezvous", R_OK) == 0) 98 break; 99 sched_yield(); 100 } 101 pid = getpid(); 102 buf = malloc(1024 * 1024); 103 for (j = 0; j < size; j++) { 104 sprintf(file,"p%05d.%05d", pid, j); 105 if ((fd = creat(file, 0660)) == -1) { 106 if (errno != EINTR) { 107 warn("creat(%s). %s:%d", file, __FILE__, __LINE__); 108 unlink("continue"); 109 error = 1; 110 break; 111 } 112 } 113 if (write(fd, buf, 1024 * 1024) != 1024 * 1024) { 114 warn("write()"); 115 unlink("continue"); 116 error = 1; 117 break; 118 } 119 if (fd != -1 && close(fd) == -1) 120 err(2, "close(%d)", j); 121 122 } 123 sleep(3); 124 125 if (error == 0) 126 j--; 127 for (i = j; i >= 0; i--) { 128 sprintf(file,"p%05d.%05d", pid, i); 129 if (unlink(file) == -1) 130 warn("unlink(%s)", file); 131 132 } 133 return (error); 134} 135 136int 137main(int argc, char **argv) 138{ 139 int error = 0, fd, i, j, status; 140 141 if (argc == 2) 142 size = atoi(argv[1]); 143 144 umask(0); 145 if ((fd = open("continue", O_CREAT, 0644)) == -1) 146 err(1, "open()"); 147 close(fd); 148 for (i = 0; i < 200; i++) { 149 for (j = 0; j < PARALLEL; j++) { 150 if (fork() == 0) 151 exit(test()); 152 } 153 154 if ((fd = open("rendezvous", O_CREAT, 0644)) == -1) 155 err(1, "open()"); 156 close(fd); 157 158 for (j = 0; j < PARALLEL; j++) { 159 wait(&status); 160 error += status; 161 } 162 163 unlink("rendezvous"); 164 if (access("continue", R_OK) == -1) { 165 break; 166 } 167 } 168 unlink("continue"); 169 170 return (error != 0); 171} 172