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# Looping mksnap_ffs seen. 30 31[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 32 33. ../default.cfg 34 35# Scenario by mckusick@ 36# 37# create a bunch of files/directories 38# create a snapshot 39# remove many (but not all) of those files/directories 40# create some new files/directories in what remains of those 41# original files/directories. 42# create another snapshot 43# repeat { 44# remove many (somewhat different) of those files/directories 45# create some new files/directories in what remains of those 46# remaining files/directories. 47# create a new snapshot 48# remove oldest snapshot 49# } 50 51snap () { 52 for i in `jot 5`; do 53 mksnap_ffs $1 $2 2>&1 | grep -v "Resource temporarily unavailable" 54 [ ! -s $2 ] && rm -f $2 || return 0 55 sleep 1 56 done 57 return 1 58} 59 60here=`pwd` 61cd /tmp 62sed '1,/^EOF/d' < $here/$0 > suj20.c 63mycc -o suj20 -Wall -Wextra -g -O2 suj20.c 64rm -f suj20.c 65 66mount | grep "$mntpoint" | grep -q md$mdstart && umount $mntpoint 67mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 68 69mdconfig -a -t swap -s 1g -u $mdstart 70newfs -j md$mdstart > /dev/null 71mount /dev/md$mdstart $mntpoint 72 73cd $mntpoint 74chmod 777 $mntpoint 75/tmp/suj20 76snap $mntpoint $mntpoint/.snap/snap1 77/tmp/suj20 prune 78snap $mntpoint $mntpoint/.snap/snap2 79/tmp/suj20 80for i in `jot 10`; do 81 /tmp/suj20 prune 82 /tmp/suj20 83 snap $mntpoint $mntpoint/.snap/snap$((i + 2)) 84 sn=`ls -tU $mntpoint/.snap | tail -1` 85 rm -f $mntpoint/.snap/$sn 86done 87cd $here 88 89while mount | grep -q $mntpoint; do 90 umount $mntpoint || sleep 1 91done 92mdconfig -d -u $mdstart 93rm -f /tmp/suj20 94exit 0 95EOF 96#include <sys/types.h> 97#include <err.h> 98#include <errno.h> 99#include <fcntl.h> 100#include <stdio.h> 101#include <stdlib.h> 102#include <sys/stat.h> 103#include <unistd.h> 104 105static char buf[4096]; 106#define ND 100 107#define NF 100 108 109void 110setup(void) 111{ 112 int d, f, fd, i, n; 113 char name[128]; 114 115 for (d = 0; d < ND; d++) { 116 snprintf(name, sizeof(name), "d%03d", d); 117 if (mkdir(name, 00700) == -1 && errno != EEXIST) 118 err(1, "mkdir(%s)", name); 119 if (chdir(name) == -1) 120 err(1, "chdir(%s)", name); 121 for (f = 0; f < NF; f++) { 122 if (arc4random() % 100 < 33) 123 continue; 124 snprintf(name, sizeof(name), "f%03d", f); 125 if ((fd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) 126 err(1, "open(%s)", name); 127 n = arc4random() % 10; 128 for (i = 0; i < n; i++) { 129 if (write(fd, buf, sizeof(buf)) != sizeof(buf)) 130 err(1, "write()"); 131 } 132 close(fd); 133 } 134 if (chdir("..") == -1) 135 err(1, "chdir(%s)", ".."); 136 } 137} 138void 139 140prune(void) 141{ 142 int d, f; 143 char name[128]; 144 145 for (d = 0; d < ND; d++) { 146 snprintf(name, sizeof(name), "d%03d", d); 147 if (chdir(name) == -1) 148 err(1, "chdir(%s)", name); 149 for (f = 0; f < NF; f++) { 150 if (arc4random() % 100 < 33) 151 continue; 152 snprintf(name, sizeof(name), "f%03d", f); 153 if (unlink(name) == -1 && errno != ENOENT) 154 err(1, "unlink(%s)", name); 155 } 156 if (chdir("..") == -1) 157 err(1, "chdir(%s)", ".."); 158 } 159 for (d = 0; d < ND; d++) { 160 if (arc4random() % 100 > 10) 161 continue; 162 snprintf(name, sizeof(name), "rm -rf d%03d", d); 163 system(name); 164 } 165} 166 167int 168main(int argc, char **argv __unused) 169{ 170 if (argc == 1) 171 setup(); 172 if (argc == 2) 173 prune(); 174 175 return (0); 176} 177