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 48newfs $newfs_flags md$mdstart > /dev/null 49mount /dev/md$mdstart $mntpoint 50 51inodes=`df -i $mntpoint | tail -1 | awk '{print $7}'` 52loops=4 53parallel=12 54timeout=1200 55start=`date '+%s'` 56for i in `jot $loops`; do 57 for j in `jot $parallel`; do 58 mkdir -p $mntpoint/d$j/dir1 59 mkdir -p $mntpoint/d$j/dir2 60 (cd $mntpoint/d$j; /tmp/rename12 $((inodes/parallel)) ) & 61 done 62 wait 63 for j in `jot $parallel`; do 64 rmdir $mntpoint/d$j/dir1 65 rmdir $mntpoint/d$j/dir2 66 done 67 [ $((`date '+%s'` - start)) -lt $timeout ] && break 68done 69 70while mount | grep "on $mntpoint " | grep -q /dev/md; do 71 umount $mntpoint || sleep 1 72done 73 74checkfs /dev/md$mdstart; s=$? 75mdconfig -d -u $mdstart 76rm -rf /tmp/rename12 77exit $s 78EOF 79#include <sys/stat.h> 80#include <sys/types.h> 81#include <sys/wait.h> 82 83#include <err.h> 84#include <errno.h> 85#include <fcntl.h> 86#include <libgen.h> 87#include <stdio.h> 88#include <stdlib.h> 89#include <string.h> 90#include <unistd.h> 91 92pid_t crpid; 93long n; 94int mvpipe[2], rmpipe[2]; 95 96void 97cr(void) 98{ 99 pid_t pid; 100 int i; 101 char name[80]; 102 103 setproctitle("cr"); 104 pid = getpid(); 105 usleep(arc4random() & 1000); 106 for (i = 0; i < n; i++) { 107 snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); 108 if (mkdir(name, 0700) == -1) 109 err(1, "mkdir(%s). %s:%d", name, __FILE__, __LINE__); 110 if (write(mvpipe[1], &i, sizeof(i)) != sizeof(i)) 111 err(1, "write mvpipe"); 112 } 113 114 _exit(0); 115} 116 117void 118mv(void) 119{ 120 pid_t pid; 121 int i; 122 char name[80], to[80]; 123 124 setproctitle("mv"); 125 pid = crpid; 126 i = 0; 127 while (i != n - 1 && 128 read(mvpipe[0], &i, sizeof(i)) == sizeof(i)) { 129 snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); 130 snprintf(to , sizeof(to ), "dir2/d.%06d.%06d", pid, i); 131 if (rename(name, to) == -1) 132 warn("rename(%s, %s)", name, to); 133 if (write(rmpipe[1], &i, sizeof(i)) != sizeof(i)) 134 err(1, "write rmpipe"); 135 } 136 _exit(0); 137} 138 139void 140rm(void) 141{ 142 pid_t pid; 143 int i; 144 char to[80]; 145 146 setproctitle("rm"); 147 pid = crpid; 148 i = 0; 149 while (i != n - 1 && 150 read(rmpipe[0], &i, sizeof(i)) == sizeof(i)) { 151 snprintf(to, sizeof(to ), "dir2/d.%06d.%06d", pid, i); 152 if (rmdir(to) == -1) 153 warn("rmdir(%s)", to); 154 } 155 _exit(0); 156} 157 158int 159main(int argc, char **argv) 160{ 161 int r, s; 162 163 if (argc != 2) 164 errx(1, "Usage %s <num inodes>", argv[0]); 165 n = atol(argv[1]); 166 if (n > 32765) { 167 n = 32765 - 1; 168 } 169 170 if (pipe(mvpipe) == -1) 171 err(1, "pipe()"); 172 if (pipe(rmpipe) == -1) 173 err(1, "pipe()"); 174 175 r = 0; 176 if ((crpid = fork()) == 0) 177 cr(); 178 if (fork() == 0) 179 mv(); 180 if (fork() == 0) 181 rm(); 182 183 wait(&s); 184 r += WEXITSTATUS(s); 185 wait(&s); 186 r += WEXITSTATUS(s); 187 wait(&s); 188 r += WEXITSTATUS(s); 189 190 return (r); 191} 192