]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/test/stress2/misc/sendfile17.sh
contrib/tzdata: import tzdata 2021c
[FreeBSD/FreeBSD.git] / tools / test / stress2 / misc / sendfile17.sh
1 #!/bin/sh
2
3 #
4 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 #
6 # Copyright (c) 2018 Dell EMC Isilon
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 #    notice, this list of conditions and the following disclaimer in the
15 #    documentation and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # SUCH DAMAGE.
28 #
29
30 # sendfile() over socket pairs test. Variation of sendfile15.sh with
31 # ualarm(2) added.
32
33 # Page fault seen: https://people.freebsd.org/~pho/stress/log/dougm029.txt
34
35 . ../default.cfg
36 [ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
37
38 dir=/tmp
39 odir=`pwd`
40 cd $dir
41 sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile17.c
42 mycc -o sendfile17 -Wall -Wextra -O0 -g sendfile17.c || exit 1
43 rm -f sendfile17.c
44 cd $odir
45
46 set -e
47 mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
48 [ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
49 mdconfig -a -t swap -s 3g -u $mdstart
50 bsdlabel -w md$mdstart auto
51 newfs $newfs_flags md${mdstart}$part > /dev/null
52 mount /dev/md${mdstart}$part $mntpoint
53 set +e
54
55 cd $mntpoint
56 dd if=/dev/random of=input bs=4k count=1 status=none
57 (cd $odir/../testcases/swap; ./swap -t 5m -i 20 > /dev/null) &
58 $dir/sendfile17
59 s=$?
60 while pgrep -q swap; do
61         pkill swap
62 done
63 wait
64 [ -f sendfile17.core -a $s -eq 0 ] &&
65     { ls -l sendfile17.core; mv sendfile17.core $dir; s=1; }
66 cd $odir
67
68 for i in `jot 6`; do
69         mount | grep -q "on $mntpoint " || break
70         umount $mntpoint && break || sleep 10
71         [ $i -eq 6 ] &&
72             { echo FATAL; fstat -mf $mntpoint; exit 1; }
73 done
74 mdconfig -d -u $mdstart
75 rm -rf $dir/sendfile17
76 exit $s
77
78 EOF
79 #include <sys/param.h>
80 #include <sys/fcntl.h>
81 #include <sys/mman.h>
82 #include <sys/socket.h>
83 #include <sys/stat.h>
84 #include <sys/stat.h>
85 #include <sys/uio.h>
86 #include <sys/wait.h>
87
88 #include <machine/atomic.h>
89
90 #include <err.h>
91 #include <errno.h>
92 #include <fcntl.h>
93 #include <stdio.h>
94 #include <stdlib.h>
95 #include <time.h>
96 #include <unistd.h>
97
98 static volatile u_int *share;
99
100 #define PARALLEL 32
101 #define RUNTIME (5 * 60)
102 #define SYNC 0
103
104 static void
105 handler(int i __unused) {
106         _exit(0);
107 }
108
109 static void
110 test(void)
111 {
112         struct stat st;
113         off_t written, pos;
114         int child, error, from, n, status, sv[2];
115         char *buf;
116         const char *from_name;
117
118         atomic_add_int(&share[SYNC], 1);
119         while (share[SYNC] != PARALLEL)
120                 usleep(100);
121
122         from_name = "input";
123
124         if ((from = open(from_name, O_RDONLY)) == -1)
125                 err(1, "open read %s", from_name);
126
127         if ((error = fstat(from, &st)) == -1)
128                 err(1, "stat %s", from_name);
129
130         if ((error = socketpair(AF_UNIX, SOCK_STREAM, 0, sv)) == -1)
131                 err(1, "socketpair");
132
133         signal(SIGALRM, handler);
134         child = fork();
135         if (child == -1)
136                 err(1, "fork");
137         else if (child != 0) {
138                 setproctitle("parent");
139                 close(sv[1]);
140                 pos = 0;
141                 for (;;) {
142                         if (arc4random() % 100 < 20)
143                                 ualarm(arc4random() % 10000, 0);
144                         error = sendfile(from, sv[0], pos, st.st_size - pos,
145                             NULL, &written, 0);
146                         if (error == -1) {
147                                 if (errno != EAGAIN && errno != EPIPE &&
148                                     errno != ENOTCONN)
149                                         err(1, "sendfile");
150                                 _exit(0);;
151                         }
152                         ualarm(0, 0);
153                         pos += written;
154                         if (pos == st.st_size)
155                                 break;
156                 }
157                 close(sv[0]);
158                 if (waitpid(child, &status, 0) != child)
159                         err(1, "waitpid(%d)", child);
160         } else {
161                 setproctitle("child");
162                 close(sv[0]);
163                 buf = malloc(st.st_size);
164                 if (buf == NULL)
165                         err(1, "malloc %jd", st.st_size);
166                 pos = 0;
167                 for (;;) {
168                         written = st.st_size - pos;
169                         if (arc4random() % 100 < 20)
170                                 ualarm(arc4random() % 10000, 0);
171                         n = read(sv[1], buf + pos, written);
172                         ualarm(0, 0);
173                         if (n == -1 && errno != ENOTCONN)
174                                 err(1, "read");
175                         else if (n == 0)
176                                 _exit(0);
177                         pos += n;
178                         if (pos == st.st_size)
179                                 break;
180                 }
181                 close(sv[1]);
182                 _exit(0);
183         }
184
185         _exit(0);
186 }
187
188 int
189 main(void)
190 {
191         pid_t pids[PARALLEL];
192         size_t len;
193         time_t start;
194         int e, i, status;
195
196         e = 0;
197         len = PAGE_SIZE;
198         if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
199             MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
200                 err(1, "mmap");
201
202         start = time(NULL);
203         while ((time(NULL) - start) < RUNTIME && e == 0) {
204                 share[SYNC] = 0;
205                 for (i = 0; i < PARALLEL; i++) {
206                         if ((pids[i] = fork()) == 0)
207                                 test();
208                         if (pids[i] == -1)
209                                 err(1, "fork()");
210                 }
211                 for (i = 0; i < PARALLEL; i++) {
212                         if (waitpid(pids[i], &status, 0) == -1)
213                                 err(1, "waitpid(%d)", pids[i]);
214                         if (status != 0) {
215                                 if (WIFSIGNALED(status))
216                                         fprintf(stderr,
217                                             "pid %d exit signal %d\n",
218                                             pids[i], WTERMSIG(status));
219                         }
220                         e += status == 0 ? 0 : 1;
221                 }
222         }
223
224         return (e);
225 }