1#!/bin/sh 2 3# 4# Copyright (c) 2013 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[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 30 31# Test scenario for the change of a global SU lock to a per filesystem lock. 32 33. ../default.cfg 34 35here=`pwd` 36cd /tmp 37sed '1,/^EOF/d' < $here/$0 > pfl.c 38mycc -o pfl -Wall -Wextra pfl.c || exit 1 39rm -f pfl.c 40cd $here 41 42md1=$mdstart 43md2=$((mdstart + 1)) 44mp1=${mntpoint}$md1 45mp2=${mntpoint}$md2 46mkdir -p $mp1 $mp2 47 48usermem=`sysctl -n hw.usermem` 49[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80)) 50size=$((2 * 1024 * 1024 * 1024)) # Ideal disk size is 2G 51[ $((size * 2)) -gt $usermem ] && size=$((usermem / 2)) 52size=$((size / 1024 / 1024)) 53 54opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-j" || echo "-U") 55[ "$newfs_flags" = "-U" ] || opt="" 56mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1 57[ -c /dev/md$md1 ] && mdconfig -d -u $md1 58mdconfig -a -t swap -s ${size}m -u $md1 59bsdlabel -w md$md1 auto 60newfs $opt md${md1}$part > /dev/null 61mount /dev/md${md1}$part $mp1 62chmod 777 $mp1 63 64mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2 65[ -c /dev/md$md2 ] && mdconfig -d -u $md2 66mdconfig -a -t swap -s ${size}m -u $md2 67bsdlabel -w md$md2 auto 68newfs $opt md${md2}$part > /dev/null 69mount /dev/md${md2}$part $mp2 70chmod 777 $mp2 71 72su $testuser -c "cd $mp1; /tmp/pfl" & 73pids=$! 74su $testuser -c "cd $mp2; /tmp/pfl" & 75pids="$pids $!" 76sleep .5 77s=0 78start=`date '+%s'` 79while pgrep -q pfl; do 80 if [ $((`date '+%s'`- start)) -gt 900 ]; then 81 s=1 82 echo "$0 timed out." 83 pkill -9 pfl 84 fi 85 sleep 10 86done 87for p in $pids; do 88 wait $p 89 [ $? -ne 0 ] && s=2 90done 91 92while mount | grep "$mp2 " | grep -q /dev/md; do 93 umount $mp2 || sleep 1 94done 95mdconfig -d -u $md2 96while mount | grep "$mp1 " | grep -q /dev/md; do 97 umount $mp1 || sleep 1 98done 99rm -f /tmp/pfl 100mdconfig -d -u $md1 101exit $s 102 103EOF 104#include <sys/mount.h> 105#include <sys/param.h> 106#include <sys/stat.h> 107#include <sys/wait.h> 108 109#include <err.h> 110#include <errno.h> 111#include <fcntl.h> 112#include <sched.h> 113#include <stdio.h> 114#include <stdlib.h> 115#include <unistd.h> 116 117#define PARALLEL 10 118 119static void 120test(void) 121{ 122 pid_t pid; 123 int fd, i, j; 124 char file[128]; 125 126 pid = getpid(); 127 sprintf(file,"d%05d", pid); 128 if (mkdir(file, 0740) == -1) 129 err(1, "mkdir(%s)", file); 130 chdir(file); 131 for (j = 0; j < 10000; j++) { 132 sprintf(file,"p%05d.%05d", pid, j); 133 if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == 134 -1) { 135 if (errno != EINTR) { 136 warn("mkdir(%s). %s:%d", file, __FILE__, 137 __LINE__); 138 unlink("continue"); 139 break; 140 } 141 } 142 if (arc4random() % 100 < 10) 143 if (write(fd, "1", 1) != 1) 144 err(1, "write()"); 145 close(fd); 146 147 } 148 sleep(3); 149 150 for (i = --j; i >= 0; i--) { 151 sprintf(file,"p%05d.%05d", pid, i); 152 if (unlink(file) == -1) 153 err(3, "unlink(%s)", file); 154 155 } 156 chdir(".."); 157 sprintf(file,"d%05d", pid); 158 if (rmdir(file) == -1) 159 err(3, "unlink(%s)", file); 160} 161 162int 163main(void) 164{ 165 pid_t pids[PARALLEL]; 166 int e, fd, j, k, s; 167 168 umask(0); 169 if ((fd = open("continue", O_CREAT, 0644)) == -1) 170 err(1, "open()"); 171 close(fd); 172 e = 0; 173 for (j = 0; j < PARALLEL; j++) { 174 if ((pids[j] = fork()) == 0) { 175 for (k = 0; k < 40; k++) 176 test(); 177 _exit(0); 178 } 179 } 180 181 for (j = 0; j < PARALLEL; j++) { 182 if (waitpid(pids[j], &s, 0) == -1) 183 err(1, "waitpid(%d)", pids[j]); 184 e += s == 0 ? 0 : 1; 185 } 186 187 return (e); 188} 189