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 59newfs $opt md${md1} > /dev/null 60mount /dev/md${md1} $mp1 61chmod 777 $mp1 62 63mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2 64[ -c /dev/md$md2 ] && mdconfig -d -u $md2 65mdconfig -a -t swap -s ${size}m -u $md2 66newfs $opt md${md2} > /dev/null 67mount /dev/md${md2} $mp2 68chmod 777 $mp2 69 70su $testuser -c "cd $mp1; /tmp/pfl" & 71pids=$! 72su $testuser -c "cd $mp2; /tmp/pfl" & 73pids="$pids $!" 74sleep .5 75s=0 76start=`date '+%s'` 77while pgrep -q pfl; do 78 if [ $((`date '+%s'`- start)) -gt 900 ]; then 79 s=1 80 echo "$0 timed out." 81 pkill -9 pfl 82 fi 83 sleep 10 84done 85for p in $pids; do 86 wait $p 87 [ $? -ne 0 ] && s=2 88done 89 90while mount | grep "$mp2 " | grep -q /dev/md; do 91 umount $mp2 || sleep 1 92done 93mdconfig -d -u $md2 94while mount | grep "$mp1 " | grep -q /dev/md; do 95 umount $mp1 || sleep 1 96done 97rm -f /tmp/pfl 98mdconfig -d -u $md1 99exit $s 100 101EOF 102#include <sys/mount.h> 103#include <sys/param.h> 104#include <sys/stat.h> 105#include <sys/wait.h> 106 107#include <err.h> 108#include <errno.h> 109#include <fcntl.h> 110#include <sched.h> 111#include <stdio.h> 112#include <stdlib.h> 113#include <unistd.h> 114 115#define PARALLEL 10 116 117static void 118test(void) 119{ 120 pid_t pid; 121 int fd, i, j; 122 char file[128]; 123 124 pid = getpid(); 125 sprintf(file,"d%05d", pid); 126 if (mkdir(file, 0740) == -1) 127 err(1, "mkdir(%s)", file); 128 chdir(file); 129 for (j = 0; j < 10000; j++) { 130 sprintf(file,"p%05d.%05d", pid, j); 131 if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == 132 -1) { 133 if (errno != EINTR) { 134 warn("mkdir(%s). %s:%d", file, __FILE__, 135 __LINE__); 136 unlink("continue"); 137 break; 138 } 139 } 140 if (arc4random() % 100 < 10) 141 if (write(fd, "1", 1) != 1) 142 err(1, "write()"); 143 close(fd); 144 145 } 146 sleep(3); 147 148 for (i = --j; i >= 0; i--) { 149 sprintf(file,"p%05d.%05d", pid, i); 150 if (unlink(file) == -1) 151 err(3, "unlink(%s)", file); 152 153 } 154 chdir(".."); 155 sprintf(file,"d%05d", pid); 156 if (rmdir(file) == -1) 157 err(3, "unlink(%s)", file); 158} 159 160int 161main(void) 162{ 163 pid_t pids[PARALLEL]; 164 int e, fd, j, k, s; 165 166 umask(0); 167 if ((fd = open("continue", O_CREAT, 0644)) == -1) 168 err(1, "open()"); 169 close(fd); 170 e = 0; 171 for (j = 0; j < PARALLEL; j++) { 172 if ((pids[j] = fork()) == 0) { 173 for (k = 0; k < 40; k++) 174 test(); 175 _exit(0); 176 } 177 } 178 179 for (j = 0; j < PARALLEL; j++) { 180 if (waitpid(pids[j], &s, 0) == -1) 181 err(1, "waitpid(%d)", pids[j]); 182 e += s == 0 ? 0 : 1; 183 } 184 185 return (e); 186} 187