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# No problems seen with SU. Panics with SU+J, just like suj30.sh 30 31# Triggers "known LOR in SU code" when crossmp8.sh is run first: 32# https://people.freebsd.org/~pho/stress/log/rename12.txt. 33 34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 35 36. ../default.cfg 37 38here=`pwd` 39cd /tmp 40sed '1,/^EOF/d' < $here/$0 > rename12.c 41mycc -o rename12 -Wall -Wextra rename12.c || exit 1 42rm -f rename12.c 43 44mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 45mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 46 47mdconfig -a -t swap -s 4g -u $mdstart || exit 1 48bsdlabel -w md$mdstart auto 49newfs $newfs_flags md${mdstart}$part > /dev/null 50mount /dev/md${mdstart}$part $mntpoint 51 52inodes=`df -i $mntpoint | tail -1 | awk '{print $7}'` 53loops=4 54parallel=12 55timeout=1200 56start=`date '+%s'` 57for i in `jot $loops`; do 58 for j in `jot $parallel`; do 59 mkdir -p $mntpoint/d$j/dir1 60 mkdir -p $mntpoint/d$j/dir2 61 (cd $mntpoint/d$j; /tmp/rename12 $((inodes/parallel)) ) & 62 done 63 wait 64 for j in `jot $parallel`; do 65 rmdir $mntpoint/d$j/dir1 66 rmdir $mntpoint/d$j/dir2 67 done 68 [ $((`date '+%s'` - start)) -lt $timeout ] && break 69done 70 71while mount | grep "on $mntpoint " | grep -q /dev/md; do 72 umount $mntpoint || sleep 1 73done 74 75checkfs /dev/md${mdstart}$part; s=$? 76mdconfig -d -u $mdstart 77rm -rf /tmp/rename12 78exit $s 79EOF 80#include <sys/stat.h> 81#include <sys/types.h> 82#include <sys/wait.h> 83 84#include <err.h> 85#include <errno.h> 86#include <fcntl.h> 87#include <libgen.h> 88#include <stdio.h> 89#include <stdlib.h> 90#include <string.h> 91#include <unistd.h> 92 93pid_t crpid; 94long n; 95int mvpipe[2], rmpipe[2]; 96 97void 98cr(void) 99{ 100 pid_t pid; 101 int i; 102 char name[80]; 103 104 setproctitle("cr"); 105 pid = getpid(); 106 usleep(arc4random() & 1000); 107 for (i = 0; i < n; i++) { 108 snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); 109 if (mkdir(name, 0700) == -1) 110 err(1, "mkdir(%s). %s:%d", name, __FILE__, __LINE__); 111 if (write(mvpipe[1], &i, sizeof(i)) != sizeof(i)) 112 err(1, "write mvpipe"); 113 } 114 115 _exit(0); 116} 117 118void 119mv(void) 120{ 121 pid_t pid; 122 int i; 123 char name[80], to[80]; 124 125 setproctitle("mv"); 126 pid = crpid; 127 i = 0; 128 while (i != n - 1 && 129 read(mvpipe[0], &i, sizeof(i)) == sizeof(i)) { 130 snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); 131 snprintf(to , sizeof(to ), "dir2/d.%06d.%06d", pid, i); 132 if (rename(name, to) == -1) 133 warn("rename(%s, %s)", name, to); 134 if (write(rmpipe[1], &i, sizeof(i)) != sizeof(i)) 135 err(1, "write rmpipe"); 136 } 137 _exit(0); 138} 139 140void 141rm(void) 142{ 143 pid_t pid; 144 int i; 145 char to[80]; 146 147 setproctitle("rm"); 148 pid = crpid; 149 i = 0; 150 while (i != n - 1 && 151 read(rmpipe[0], &i, sizeof(i)) == sizeof(i)) { 152 snprintf(to, sizeof(to ), "dir2/d.%06d.%06d", pid, i); 153 if (rmdir(to) == -1) 154 warn("rmdir(%s)", to); 155 } 156 _exit(0); 157} 158 159int 160main(int argc, char **argv) 161{ 162 int r, s; 163 164 if (argc != 2) 165 errx(1, "Usage %s <num inodes>", argv[0]); 166 n = atol(argv[1]); 167 if (n > 32765) { 168 n = 32765 - 1; 169 } 170 171 if (pipe(mvpipe) == -1) 172 err(1, "pipe()"); 173 if (pipe(rmpipe) == -1) 174 err(1, "pipe()"); 175 176 r = 0; 177 if ((crpid = fork()) == 0) 178 cr(); 179 if (fork() == 0) 180 mv(); 181 if (fork() == 0) 182 rm(); 183 184 wait(&s); 185 r += WEXITSTATUS(s); 186 wait(&s); 187 r += WEXITSTATUS(s); 188 wait(&s); 189 r += WEXITSTATUS(s); 190 191 return (r); 192} 193