]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/test/stress2/misc/rename6.sh
contrib/bc: update to version 5.1.1
[FreeBSD/FreeBSD.git] / tools / test / stress2 / misc / rename6.sh
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 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
30
31 # Demonstrate rename(2) cache problem, where the original name lingers in the VFS cache.
32
33 # Original test scenario by Anton Yuzhaninov <citrin citrin ru>
34
35 . ../default.cfg
36
37 here=`pwd`
38 cd /tmp
39 sed '1,/^EOF/d' < $here/$0 > rename6.c
40 mycc -o rename6 -Wall -Wextra -O2 rename6.c
41 rm -f rename6.c
42 cd $here
43
44 mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
45 mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
46 mdconfig -a -t swap -s 2g -u $mdstart
47 bsdlabel -w md$mdstart auto
48 newfs $newfs_flags md${mdstart}$part > /dev/null
49 mount /dev/md${mdstart}$part $mntpoint
50 chmod 777 $mntpoint
51
52 su $testuser -c "cd $mntpoint; /tmp/rename6"
53
54 while mount | grep -q md${mdstart}$part; do
55         umount $mntpoint || sleep 1
56 done
57 mdconfig -d -u $mdstart
58 rm -f /tmp/rename6
59 exit
60 EOF
61 #include <err.h>
62 #include <errno.h>
63 #include <fcntl.h>
64 #include <sched.h>
65 #include <signal.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <strings.h>
69 #include <sys/param.h>
70 #include <sys/stat.h>
71 #include <sys/time.h>
72 #include <sys/wait.h>
73 #include <time.h>
74 #include <unistd.h>
75
76 pid_t spid;
77 const char *logfile = "test.log";
78
79 void
80 cleanup()
81 {
82         if (kill(spid, SIGINT) == -1 && errno != ESRCH)
83                 err(1, "kill(%d)", spid);
84 }
85
86 static void
87 Stat()
88 {
89         struct stat sb;
90         int i;
91
92         setproctitle("Stat");
93         for (;;) {
94                 for (i = 0; i < 1000; i++) {
95                         stat(logfile, &sb);
96                 }
97                 usleep(1000);
98         }
99 }
100
101 int
102 main(void)
103 {
104         struct stat sb1, sb2;
105         int fd, i;
106         char new[128];
107
108         if ((spid = fork()) == 0)
109                 Stat();
110
111         setproctitle("main");
112         atexit(cleanup);
113         for (i = 0; i < 20000; i++) {
114                 sprintf(new, "test.log.%05d", i);
115                 if ((fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
116                         err(1, "creat(%s)", logfile);
117                 close(fd);
118 #if 1
119                 if (rename(logfile, new) == -1)
120                         warn("rename(%s, %s)", logfile, new);
121 #else
122                 /* No cache problem is seen */
123                 if (link(logfile, new) == -1)
124                         err(1, "link(%s, %s)", logfile, new);
125                 if (unlink(logfile) == -1)
126                         err(1, "unlink(%s)", logfile);
127 #endif
128                 /*
129                  * stat() for logfile and new will be identical sometimes,
130                  * but only when Stat() is running.
131                  */
132                 if (stat(logfile, &sb1) == 0 && stat(new, &sb2) == 0 &&
133                     bcmp(&sb1, &sb2, sizeof(sb1)) == 0) {
134                         fprintf(stderr, "At loop #%d\n", i);
135                         fprintf(stderr, "%-15s: ino = %ju, nlink = %ju,"
136                            " size = %jd\n", logfile, (uintmax_t)sb1.st_ino,
137                            (uintmax_t)sb1.st_nlink, sb1.st_blocks);
138                         fprintf(stderr, "%-15s: ino = %ju, nlink = %ju, "
139                             "size = %jd\n", new    , (uintmax_t)sb2.st_ino,
140                             (uintmax_t)sb2.st_nlink, sb2.st_blocks);
141                 }
142                 unlink(new);
143         }
144
145         kill(spid, SIGINT);
146         wait(NULL);
147
148         return (0);
149 }