Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / test / stress / stress2 / misc / namecache.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2009 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 # Test case for vfs.lookup_shared=1 that shows possible name cache
32 # inconsistency:
33
34 # $ ls -l /tmp/file.05015?
35 # ls: /tmp/file.050150: No such file or directory
36 # $ fsdb -r /dev/ad4s1e
37 # ** /dev/ad4s1e (NO WRITE)
38 # Examining file system `/dev/ad4s1e'
39 # Last Mounted on /tmp
40 # current inode: directory
41 # I=2 MODE=41777 SIZE=5120
42 #         BTIME=May  7 05:54:47 2006 [0 nsec]
43 #         MTIME=Apr  2 11:27:36 2009 [0 nsec]
44 #         CTIME=Apr  2 11:27:36 2009 [0 nsec]
45 #         ATIME=Apr  2 12:00:30 2009 [0 nsec]
46 # OWNER=root GRP=wheel LINKCNT=35 FLAGS=0 BLKCNT=c GEN=65f71df4
47 # fsdb (inum: 2)> lookup file.050150
48 # component `file.050150': current inode: regular file
49 # I=198 MODE=100600 SIZE=0
50 #         BTIME=Apr  2 11:24:33 2009 [0 nsec]
51 #         MTIME=Apr  2 11:24:33 2009 [0 nsec]
52 #         CTIME=Apr  2 11:24:33 2009 [0 nsec]
53 #         ATIME=Apr  2 11:24:33 2009 [0 nsec]
54 # OWNER=pho GRP=wheel LINKCNT=1 FLAGS=0 BLKCNT=0 GEN=1deaab3a
55 # fsdb (inum: 198)> quit
56 # $
57
58 # Consistency is restored by a umount + mount of the FS
59
60 # Observations:
61 #    No problems seen with vfs.lookup_shared=0.
62 #    Does not fail in a "private" subdirectory
63
64 . ../default.cfg
65
66 odir=`pwd`
67 cd /tmp
68 sed '1,/^EOF/d' < $odir/$0 > namecache.c
69 cc -o namecache -Wall namecache.c
70 rm -f namecache.c
71
72 #dir=/tmp/namecache.dir # No problems seen
73 dir=/tmp
74 [ -d $dir ] || mkdir -p $dir
75 cd $dir
76
77 for i in `jot 30`; do
78         for j in `jot 10`; do
79                 /tmp/namecache &
80         done
81
82         for j in `jot 10`; do
83                 wait
84         done
85 done
86
87 if ls -l ${dir}/file.0* 2>&1 | egrep "file.0[0-9]" | grep -q "No such file"; then
88         echo "ls -l ${dir}/file.0*"
89         ls -l ${dir}/file.0*
90 fi
91
92 rm -f /tmp/namecache # /${dir}/file.0*
93 exit
94 EOF
95 /* Test scenario for possible name cache problem */
96
97 #include <sys/types.h>
98 #include <dirent.h>
99 #include <err.h>
100 #include <fcntl.h>
101 #include <signal.h>
102 #include <stdio.h>
103 #include <stdlib.h>
104 #include <string.h>
105 #include <sys/param.h>
106 #include <sys/stat.h>
107 #include <sys/wait.h>
108 #include <unistd.h>
109
110 static char path[MAXPATHLEN+1];
111 static char buf[64 * 1024];
112
113 void
114 pm(void)
115 {
116         int fd, n;
117         int space = sizeof(buf);
118         struct stat statb;
119         long base;
120         struct dirent *dp;
121         char *bp = buf;
122
123         if ((fd = open(".", O_RDONLY)) == -1)
124                 err(1, "open(%s)", ".");
125
126         do {
127                 if ((n = getdirentries(fd, bp, space, &base)) == -1)
128                         err(1, "getdirentries");
129                 space = space - n;
130                 bp   = bp + n;
131         } while (n != 0);
132         close(fd);
133
134         bp = buf;
135         dp = (struct dirent *)bp;
136         for (;;) {
137                 if (strcmp(path, dp->d_name) == 0) {
138
139                         if (stat(dp->d_name, &statb) == -1) {
140                                 warn("stat(%s)", dp->d_name);
141                                 printf("name: %-10s, inode %7d, type %2d, namelen %d, d_reclen %d\n",
142                                         dp->d_name, dp->d_fileno, dp->d_type, dp->d_namlen,
143                                         dp->d_reclen);
144                                 fflush(stdout);
145                         } else {
146                                 printf("stat(%s) succeeded!\n", path);
147                                 fflush(stdout);
148                         }
149
150                 }
151                 bp = bp + dp->d_reclen;
152                 dp = (struct dirent *)bp;
153                 if (dp->d_reclen <= 0)
154                         break;
155         }
156 }
157
158 static void
159 reader(void) {
160         int fd;
161
162         if ((fd = open(path, O_RDWR, 0600)) < 0) {
163                 warn("open(%s). %s:%d", path, __FILE__, __LINE__);
164                 pm();
165                 exit(1);
166         }
167         close(fd);
168         return;
169 }
170
171 static void
172 writer(void) {
173         int fd;
174
175         if ((fd = open(path, O_RDWR, 0600)) < 0) {
176                 warn("open(%s). %s:%d", path, __FILE__, __LINE__);
177                 pm();
178                 exit(1);
179         }
180         close(fd);
181         return;
182 }
183
184 int
185 main(int argc, char **argv)
186 {
187         pid_t pid;
188         int fd, i, status;
189
190         for (i = 0; i < 10000; i++) {
191                 if (sprintf(path, "file.0%d", getpid()) < 0)
192                         err(1, "sprintf()");
193                 if ((fd = open(path, O_CREAT | O_RDWR, 0600)) == -1)
194                         err(1, "open(%s)", path);
195                 close(fd);
196
197                 if ((pid = fork()) == 0) {
198                         writer();
199                         exit(EXIT_SUCCESS);
200
201                 } else if (pid > 0) {
202                         reader();
203                         if (waitpid(pid, &status, 0) == -1)
204                                 warn("waitpid(%d)", pid);
205                 } else
206                         err(1, "fork(), %s:%d",  __FILE__, __LINE__);
207
208                 if (unlink(path) == -1)
209                         err(1, "unlink(%s). %s:%d", path, __FILE__, __LINE__);
210         }
211         return (0);
212 }