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