Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / test / stress / stress2 / misc / fuzz.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2008 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 # $FreeBSD$
29 #
30
31 # Stress test UFS2 file systems by introducing single bit errors in the FS
32 # fsck fould fix the FS no matter how damaged, but f.x. this panic has been seen:
33 #
34 # panic(c0912b65,dfe96000,0,c09e4060,ef48c778,...) at panic+0x14b
35 # vm_fault(c1868000,dfe96000,1,0) at vm_fault+0x1e0
36 # trap_pfault(ef48c894,0,dfe96000) at trap_pfault+0x137
37 # trap(dfe90008,ef480028,c0690028,d0560000,dfe96000,...) at trap+0x341
38 # calltrap() at calltrap+0x5
39 # --- trap 0xc, eip = 0xc08785a6, esp = 0xef48c8d4, ebp = 0xef48c958 ---
40 # generic_bcopy(c81cd570,d0508000,c5ead600,c87b81c0,0,...) at generic_bcopy+0x1a
41 # ffs_mount(d0508000,c5ead600,0,c09b0860,c5ecfc3c,...) at ffs_mount+0xa14
42 # vfs_domount(c5ead600,cd8c7280,ccb75080,0,...) at vfs_domount+0x687
43 # vfs_donmount(c5ead600,0,ef48cc04) at vfs_donmount+0x2ef
44 # kernel_mount(c5660960,0,bfbfec86,0,fffffffe,...) at kernel_mount+0x6d
45 # ffs_cmount(c5660960,bfbfde50,0,c5ead600,c09b0860,...) at ffs_cmount+0x5d
46 # mount(c5ead600,ef48cd04) at mount+0x156
47 # syscall(3b,3b,3b,804abcf,bfbfe8e4,...) at syscall+0x22f
48
49
50 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
51
52 . ../default.cfg
53
54 D=$diskimage
55
56 tst() {
57    rm -f $D
58    truncate -s 2M $D
59    mdconfig -a -t vnode -f $D -u $mdstart
60    bsdlabel -w md$mdstart auto
61    newfs -b 8192 -f 1024 -U /dev/md${mdstart}${part} > /dev/null 2>&1
62    mount /dev/md${mdstart}${part} $mntpoint
63    cp /etc/passwd /etc/group /etc/hosts $mntpoint
64    cp -r /usr/include/ufs $mntpoint
65    umount $mntpoint
66
67    for i in `jot 50`; do
68       ./fuzz -n 50 $D
69       if fsck -f -y /dev/md${mdstart}${part} 2>&1 | egrep "^[A-Z]" > /dev/null; then
70          if fsck -f -y /dev/md${mdstart}${part} 2>&1 | egrep "^[A-Z]" > /dev/null; then
71             if fsck -f -y /dev/md${mdstart}${part} 2>&1 | egrep "^[A-Z]" > /dev/null; then
72                echo "fsck is giving up in loop $i!"
73                break
74             fi
75          fi
76       fi
77       sync;sync;sync
78       if mount /dev/md${mdstart}${part} $mntpoint; then
79          ls -l $mntpoint > /dev/null
80          find $mntpoint  -exec dd if={} of=/dev/null bs=1m count=3 \; > /dev/null 2>&1
81          umount $mntpoint
82       else
83          echo "Giving up at loop $i"
84          break
85       fi
86    done
87    mdconfig -d -u ${mdstart}
88    rm -f $D
89 }
90
91 odir=`pwd`
92 dir=/tmp
93
94 cd $dir
95 sed '1,/^EOF/d' < $odir/$0 > $dir/fuzz.c
96 cc -o fuzz -Wall fuzz.c
97 rm -f fuzz.c
98
99 for j in `jot 10`; do
100    date '+%T'
101    tst
102 done
103 rm -f fuzz
104
105 exit
106
107 EOF
108 #include <stdio.h>
109 #include <stdlib.h>
110 #include <unistd.h>
111 #include <fcntl.h>
112 #include <sys/stat.h>
113 #include <err.h>
114
115 void
116 usage(void)
117 {
118         fprintf(stderr, "%s {-n <num|-v} <file>\n", getprogname());
119         exit(1);
120 }
121
122 long
123 random_long(long mi, long ma)
124 {
125         return (arc4random()  % (ma - mi + 1) + mi);
126 }
127
128 int
129 main(int argc, char **argv)
130 {
131         int ch, fd, i, times = 1, verbose = 0;
132         long pos;
133         unsigned char bit, buf, mask, old;
134         struct stat sb;
135
136         while ((ch = getopt(argc, argv, "n:v")) != -1)
137                 switch(ch) {
138                 case 'n':       /* Bits to alter */
139                         if (sscanf(optarg, "%d", &times) != 1)
140                                 usage();
141                         break;
142                 case 'v':       /* verbose flag */
143                         verbose += 1;
144                         break;
145                 default:
146                         usage();
147                 }
148         argc -= optind;
149         argv += optind;
150
151         if (argc == 0)
152                 usage();
153
154
155         if ((fd = open(argv[0], O_RDWR)) == -1)
156                 err(1, "open(%s)", argv[0]);
157         if (fstat(fd, &sb) == -1)
158                 err(1, "stat(%s)", argv[0]);
159
160         for (i = 0; i < times; i++) {
161                 pos = random_long(0, sb.st_size - 1);
162                 if (lseek(fd, pos, SEEK_SET) == -1)
163                         err(1, "fseek(%d, %ld)", fd, pos);
164                 if (read(fd, &buf, 1) != 1)
165                         err(1, "read(%d)", fd);
166                 bit = random_long(0,7);
167                 mask = ~(1 << bit);
168                 old = buf;
169                 buf = (buf & mask) | (~buf & ~mask);
170                 if (verbose > 0)
171                         printf("Change %2x to %2x at %4ld by flipping bit %d\n",
172                                         old, buf, pos, bit);
173                 if (lseek(fd, pos, SEEK_SET) == -1)
174                         err(1, "fseek(%d, %ld)", fd, pos);
175                 if (write(fd, &buf, 1) != 1)
176                         err(1, "write(%d)", fd);
177         }
178         close(fd);
179         return (0);
180 }