Bring in FreeBSD's stress2 stress testing suite.
[dragonfly.git] / test / stress / stress2 / misc / nfsrename.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 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
32
33
34 . ../default.cfg
35
36 # Test scenario by jhb@
37
38 odir=`pwd`
39 cd /tmp
40 sed '1,/^EOF/d' < $odir/$0 > nfsrename.c
41 cc -o nfsrename -Wall nfsrename.c
42 rm -f nfsrename.c
43 cd $odir
44
45 mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint
46 mount -t nfs -o tcp -o retrycnt=3 -o intr -o soft -o rw 127.0.0.1:/tmp $mntpoint
47
48
49 #export RUNDIR=$mntpoint/stressX
50 #export runRUNTIME=2m
51 #(cd /home/pho/stress2; ./run.sh disk.cfg) &
52
53 for i in `jot 10`; do
54         /tmp/nfsrename  $mntpoint/nfsrename.$i &
55 done
56 for i in `jot 10`; do
57         wait
58 done
59 killall nfsrename
60 rm -f $mntpoint/nfsrename.*
61
62 umount $mntpoint > /dev/null 2>&1
63 while mount | grep "$mntpoint" | grep -q nfs; do
64         umount -f $mntpoint > /dev/null 2>&1
65 done
66
67 rm -f /tmp/nfsrename
68 exit
69
70 EOF
71 /*
72  * Try to expose races with doing renames over NFS that require silly
73  * renames.  This results in 2 different RENAME RPCs leaving a race
74  * window where the file may not exist.  It also appears that FreeBSD
75  * with shared lookups in NFS can get confused and possibly reference
76  * the sillyrenamed file in lookup but the file is deleted by the time
77  * open gets to it.
78  */
79
80 #include <err.h>
81 #include <libgen.h>
82 #include <limits.h>
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <unistd.h>
86
87 const char *filename;
88 const char *dir;
89
90 static void
91 usage(void)
92 {
93
94         fprintf(stderr, "nfsrename: [-n children] file\n");
95         exit(1);
96 }
97
98 static void
99 read_file(void)
100 {
101         FILE *fp;
102         char buffer[4096];
103
104         fp = fopen(filename, "r");
105         if (fp == NULL) {
106                 warn("fopen");
107                 return;
108         }
109         while (!feof(fp)) {
110                 if (fread(buffer, sizeof(buffer), 1, fp) < sizeof(buffer))
111                         break;
112         }
113         if (ferror(fp))
114                 warnx("fread encountered an error");
115         fclose(fp);
116 }
117
118 static void
119 write_file(void)
120 {
121         FILE *fp;
122         char path[1024];
123         int fd;
124
125         snprintf(path, sizeof(path), "%s/nfsrename.XXXXXX", dir);
126         fd = mkstemp(path);
127         if (fd < 0) {
128                 warn("mkstemp");
129                 return;
130         }
131
132         fp = fdopen(fd, "w");
133         if (fp == NULL) {
134                 warn("fopen:writer");
135                 close(fd);
136                 unlink(path);
137         }
138
139         fprintf(fp, "blah blah blah garbage %ld\n", random());
140         fclose(fp);
141         if (rename(path, filename) < 0) {
142                 warn("rename");
143                 unlink(path);
144         }
145 }
146
147 static void
148 random_sleep(int base, int slop)
149 {
150         long val;
151
152         val = random() % slop;
153         usleep(base + val);
154 }
155
156 static void
157 child(void)
158 {
159
160         for (;;) {
161                 random_sleep(500, 50);
162                 read_file();
163         }
164         exit(0);
165 }
166
167 int
168 main(int ac, char **av)
169 {
170         long i, nchild;
171         char *cp;
172         int ch;
173
174         nchild = 1;
175         while ((ch = getopt(ac, av, "n:")) != -1) {
176                 switch (ch) {
177                 case 'n':
178                         nchild = strtol(optarg, &cp, 0);
179                         if (*cp != '\0')
180                                 errx(1, "Invalid count %s", optarg);
181                         break;
182                 case '?':
183                 default:
184                         usage();
185                 }
186         }
187         ac -= optind;
188         av += optind;
189
190         if (ac == 0)
191                 errx(1, "Missing filename");
192         else if (ac > 1)
193                 errx(1, "Extra arguments");
194
195         filename = av[0];
196         dir = dirname(filename);
197         srandomdev();
198         write_file();
199
200         for (i = 0; i < nchild; i++) {
201                 switch (fork()) {
202                 case 0:
203                         child();
204                 case -1:
205                         err(1, "fork");
206                 }
207         }
208
209         for (i = 0; i < 10000; i++) {
210                 random_sleep(1500, 1000);
211                 write_file();
212         }
213
214         return (0);
215 }