Bring in FreeBSD's stress2 stress testing suite.
[dragonfly.git] / test / stress / stress2 / misc / fragments.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2010 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 # Scenario that causes "panic: brelse: free buffer onto another queue???"
32 # Idea for scenario by kib@. Fixed in r203818
33
34 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35
36 . ../default.cfg
37 here=`pwd`
38
39 cd /tmp
40 sed '1,/^EOF/d' < $here/$0 > fragments.c
41 rm -f /tmp/fragments
42 cc -o fragments -Wall -Wextra -O2 -g fragments.c
43 rm -f fragments.c
44 cd $here
45
46 mount | grep "$mntpoint" | grep -q md$mdstart && umount -f ${mntpoint}
47 mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
48
49 mdconfig -a -t swap -s 1g -u $mdstart
50 bsdlabel -w md$mdstart auto
51 newfs -U -m 0 md${mdstart}${part} > /dev/null 2>&1
52 mount /dev/md${mdstart}${part} /mnt
53 chmod 777 /mnt
54
55 cd /mnt
56 su ${testuser} -c "/tmp/fragments"
57 cd $here
58
59 umount /mnt
60 mount | grep "$mntpoint" | grep -q md$mdstart && umount -f ${mntpoint}
61 mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
62
63 rm -f /tmp/fragments
64 exit
65 EOF
66 #include <err.h>
67 #include <errno.h>
68 #include <fcntl.h>
69 #include <stdio.h>
70 #include <stdlib.h>
71 #include <string.h>
72 #include <sys/mount.h>
73 #include <sys/param.h>
74 #include <sys/stat.h>
75 #include <sys/wait.h>
76 #include <unistd.h>
77
78 #define LOOPS 50000
79 #define PARALLEL 8
80
81 static  pid_t pid;
82 static  char *buf;
83
84 void
85 cleanup(int n)
86 {
87         int i, j, start;
88         int nb = 0;
89         char file[128];
90         struct statfs sbuf;
91         struct stat sb;
92
93         if (n == -1) {
94                 for (i = 0; i < LOOPS; i++) {
95                         sprintf(file,"t%05d", i);
96                         unlink(file);
97                 }
98                 return;
99         }
100
101         start = arc4random() % n;
102         for (i = 0; i < LOOPS; i++) {
103                 j = (start + i) % LOOPS;
104                 sprintf(file,"t%05d", j);
105                 if (stat(file, &sb) != 0)
106                         continue;
107
108                 if (sb.st_size == 0) {
109                         unlink(file);
110                         continue;
111                 }
112                 if (truncate(file, 0) == 0) {
113                         nb++;
114                         continue;
115                 }
116                 if (nb > 10)
117                         break;
118         }
119
120
121         for (i = 0; i < 10; i++) {
122                 if (statfs(".", &sbuf) < 0)
123                         err(1, "statfs(%s)", ".");
124
125                 if (sbuf.f_bfree > 8)
126                         return;
127         }
128
129         for (i = 0; i < LOOPS; i++) {
130                 j = (start + i) % LOOPS;
131                 sprintf(file,"t%05d", j);
132                 if (unlink(file) == 0) {
133                         return;
134                 }
135         }
136 }
137
138 void
139 fragments(void)
140 {
141         int i, len;
142         char file[128];
143         int fd;
144
145         for (i = 0;; i++) {
146                 sprintf(file,"d%d/f%05d.%05d", i/1000, pid, i);
147
148                 if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
149                         if (errno != ENOSPC)
150                                 warn("open(%s)", file);
151                         break;
152                 }
153
154                 len =  2 * 1024;
155                 if (write(fd, buf, len) != len) {
156                 }
157
158                 close(fd);
159         }
160 }
161
162 void
163 blocks(void)
164 {
165         int i, len;
166         char file[128];
167         int fd;
168
169         for (i = 0;; i++) {
170                 sprintf(file,"d%d/b%05d.%05d", i/1000, pid, i);
171
172                 if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
173                         if (errno != ENOSPC)
174                                 warn("open(%s)", file);
175                         break;
176                 }
177
178                 len =  16 * 1024;
179                 if (write(fd, buf, len) != len) {
180                 }
181
182                 close(fd);
183         }
184 }
185
186 void
187 setup(void)
188 {
189         int i;
190         char file[128];
191
192         for (i = 0; i < 300; i++) {
193                 sprintf(file,"d%d", i);
194                 if (mkdir(file, 0700) == -1)
195                         warn("mkdir(%s)", file);
196         }
197
198         blocks();
199         fragments();
200
201         for (i = 0;i < 8; i++) {
202                 sprintf(file,"d%d/b%05d.%05d", i/1000, pid, i);
203                 unlink(file);
204                 unlink(file);
205         }
206         for (i = 0;i < 1; i++) {
207                 sprintf(file,"d%d/f%05d.%05d", i/1000, pid, i);
208                 unlink(file);
209         }
210
211 }
212
213 int
214 test(void)
215 {
216         int i, len, n;
217         char file[128];
218         int fd;
219
220         for (i = 0; i < LOOPS; i++) {
221                 sprintf(file,"t%05d", i);
222
223                 if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
224                         continue;
225                 }
226 //              n = arc4random() % (12 + 1);
227                 n = 0;
228                 len = (arc4random() % (16 * 1024) + 1) + n * 16;
229                 while (len > 0) {
230                         if (write(fd, buf, len) == len)
231                                 break;
232                         len = len / 2;
233                         usleep(1000);
234                 }
235                 close(fd);
236                 if (len == 0) {
237                         cleanup(i);
238                 }
239         }
240
241         exit(0);
242
243         return (0);
244 }
245
246 int
247 main()
248 {
249         int i, j, status;
250
251         pid = getpid();
252         if ((buf = malloc(12 * 16 * 1024)) == NULL)
253                 err(1, "malloc()");
254
255         setup();
256         for (j = 0; j < 50; j++) {
257                 for (i = 0; i < PARALLEL; i++) {
258                         if (fork() == 0)
259                                 test();
260                 }
261                 for (i = 0; i < PARALLEL; i++)
262                         wait(&status);
263                 cleanup(-1);
264         }
265         return (0);
266 }