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