]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/test/stress2/misc/datamove5.sh
contrib/bc: update to version 5.1.1
[FreeBSD/FreeBSD.git] / tools / test / stress2 / misc / datamove5.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2016 EMC Corp.
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 # Variation of the datamove2.sh, using NULLFS
30 # No problems seen.
31
32 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
33
34 . ../default.cfg
35
36 here=`pwd`
37 cd /tmp
38 sed '1,/^EOF/d' < $here/$0 > datamove5.c
39 mycc -o datamove5 -Wall -Wextra -O2 -g datamove5.c
40 rm -f datamove5.c
41
42 mp1=$mntpoint
43 mp2=${mntpoint}2
44 [ -d $mp2 ] || mkdir $mp2
45
46 mount | grep -wq $mp2 && umount $mp2
47 mount | grep -wq $mp1 && umount $mp1
48 mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
49 mdconfig -a -t swap -s 2g -u $mdstart || exit 1
50 bsdlabel -w md$mdstart auto
51 newfs $newfs_flags md${mdstart}$part > /dev/null
52 mount /dev/md${mdstart}$part $mp1
53
54 mount -t nullfs $opt $mp1 $mp2
55 chmod 777 $mp2
56
57 for i in `jot 5`; do
58         su $testuser -c "cd $mp2; /tmp/datamove5"
59 done
60
61 while mount | grep -wq $mp2;  do
62         umount $mp2 || sleep 1
63 done
64 while mount | grep $mp1 | grep -q /dev/md; do
65         umount $mp1 || sleep 1
66 done
67 mdconfig -d -u $mdstart
68
69 rm -rf /tmp/datamove5
70 exit 0
71 EOF
72 /*-
73  * Copyright (c) 2006, Stephan Uphoff <ups@freebsd.org>
74  * All rights reserved.
75  *
76  * Redistribution and use in source and binary forms, with or without
77  * modification, are permitted provided that the following conditions
78  * are met:
79  * 1. Redistributions of source code must retain the above copyright
80  *    notice unmodified, this list of conditions, and the following
81  *    disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  *    notice, this list of conditions and the following disclaimer in the
84  *    documentation and/or other materials provided with the distribution.
85  *
86  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
87  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
88  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
89  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
90  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
91  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
92  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
93  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
95  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96  */
97
98 #include <err.h>
99 #include <fcntl.h>
100 #include <stdio.h>
101 #include <stdlib.h>
102 #include <sys/mman.h>
103 #include <sys/stat.h>
104 #include <sys/types.h>
105 #include <sys/wait.h>
106 #include <unistd.h>
107
108 int     prepareFile(char *filename, int *fdp);
109 int     mapBuffer  (char **bufferp, int fd1, int fd2);
110 int     startIO    (int fd, char *buffer);
111
112 int     pagesize;
113
114 #define FILESIZE (32*1024)
115 char    wbuffer   [FILESIZE];
116
117 /* Create a FILESIZE sized file - then remove file data from the cache */
118 int
119 prepareFile(char *filename, int *fdp)
120 {
121         int     fd;
122         int     len;
123         int     status;
124         void    *addr;
125
126         fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
127         if (fd == -1) {
128                 perror(filename);
129                 return fd;
130         }
131         len = write(fd, wbuffer, FILESIZE);
132         if (len < 0) {
133                 perror("Write failed");
134                 return 1;
135         }
136         status = fsync(fd);
137         if (status != 0) {
138                 perror("fsync failed");
139                 return 1;
140         }
141         addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
142         if (addr == MAP_FAILED) {
143                 perror("Mmap failed");
144                 return 1;
145         }
146         status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC);
147         if (status != 0) {
148                 perror("Msync failed");
149                 return 1;
150         }
151         if (munmap(addr, FILESIZE) == -1) {
152                 perror("munmap failed");
153                 return 1;
154         }
155
156         *fdp = fd;
157         return 0;
158 }
159
160 /* mmap a 2 page buffer - first page is from fd1, second page from fd2 */
161 int
162 mapBuffer(char **bufferp, int fd1, int fd2)
163 {
164         void *addr;
165         char *buffer;
166
167         addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);
168         if (addr == MAP_FAILED) {
169                 perror("Mmap failed");
170                 return 1;
171         }
172         buffer = addr;
173         addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED |
174                     MAP_SHARED, fd2, 0);
175
176         if (addr == MAP_FAILED) {
177                 perror("Mmap2 failed");
178                 return 1;
179         }
180         *bufferp = buffer;
181         return 0;
182 }
183
184 void
185 unmapBuffer(char *bufferp)
186 {
187         if (munmap(bufferp, pagesize * 2) == -1)
188                 err(1, "unmap 1. buffer");
189         /*
190            The following unmaps something random, which could trigger:
191            Program received signal SIGSEGV, Segmentation fault.
192            free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311
193         */
194
195 #if 0
196         if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1)
197                 err(1, "unmap 2. buffer");
198 #endif
199 }
200
201 int
202 startIO(int fd, char *buffer)
203 {
204         ssize_t len;
205
206         len = write(fd, buffer, 2 * pagesize);
207         if (len == -1) {
208                 perror("write failed");
209                 return 1;
210         }
211         return 0;
212 }
213
214 int
215 main()
216 {
217
218         int     fdA, fdB, fdDelayA, fdDelayB;
219         int     status;
220         int     i;
221         char    *bufferA, *bufferB;
222         pid_t   pid;
223
224         pagesize = getpagesize();
225
226         for (i = 0; i < 1000; i++) {
227                 if ((prepareFile("A", &fdA))
228                     || (prepareFile("B", &fdB))
229                     || (prepareFile("DelayA", &fdDelayA))
230                     || (prepareFile("DelayB", &fdDelayB))
231                     || (mapBuffer(&bufferA, fdDelayA, fdB))
232                     || (mapBuffer(&bufferB, fdDelayB, fdA)))
233                         exit(1);
234
235                 pid = fork();
236
237                 if (pid == 0) {
238                         status = startIO(fdA, bufferA);
239                         exit(status);
240                 }
241                 if (pid == -1) {
242                         perror("fork");
243                         exit(1);
244                 }
245                 status = startIO(fdB, bufferB);
246                 if (wait(&status) == -1)
247                         err(1, "wait");
248
249                 close(fdA);
250                 close(fdB);
251                 close(fdDelayA);
252                 close(fdDelayB);
253                 unmapBuffer(bufferA);
254                 unmapBuffer(bufferB);
255                 unlink("A");
256                 unlink("B");
257                 unlink("DelayA");
258                 unlink("DelayB");
259         }
260         exit(status);
261
262 }