4 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6 # Copyright (c) 2018 Dell EMC Isilon
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
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.
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
30 # sendfile() over socket pairs test. Variation of sendfile15.sh with
33 # Page fault seen: https://people.freebsd.org/~pho/stress/log/dougm029.txt
36 [ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
41 sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile17.c
42 mycc -o sendfile17 -Wall -Wextra -O0 -g sendfile17.c || exit 1
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
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) &
60 while pgrep -q swap; do
64 [ -f sendfile17.core -a $s -eq 0 ] &&
65 { ls -l sendfile17.core; mv sendfile17.core $dir; s=1; }
69 mount | grep -q "on $mntpoint " || break
70 umount $mntpoint && break || sleep 10
72 { echo FATAL; fstat -mf $mntpoint; exit 1; }
74 mdconfig -d -u $mdstart
75 rm -rf $dir/sendfile17
79 #include <sys/param.h>
80 #include <sys/fcntl.h>
82 #include <sys/socket.h>
88 #include <machine/atomic.h>
98 static volatile u_int *share;
101 #define RUNTIME (5 * 60)
105 handler(int i __unused) {
114 int child, error, from, n, status, sv[2];
116 const char *from_name;
118 atomic_add_int(&share[SYNC], 1);
119 while (share[SYNC] != PARALLEL)
124 if ((from = open(from_name, O_RDONLY)) == -1)
125 err(1, "open read %s", from_name);
127 if ((error = fstat(from, &st)) == -1)
128 err(1, "stat %s", from_name);
130 if ((error = socketpair(AF_UNIX, SOCK_STREAM, 0, sv)) == -1)
131 err(1, "socketpair");
133 signal(SIGALRM, handler);
137 else if (child != 0) {
138 setproctitle("parent");
142 if (arc4random() % 100 < 20)
143 ualarm(arc4random() % 10000, 0);
144 error = sendfile(from, sv[0], pos, st.st_size - pos,
147 if (errno != EAGAIN && errno != EPIPE &&
154 if (pos == st.st_size)
158 if (waitpid(child, &status, 0) != child)
159 err(1, "waitpid(%d)", child);
161 setproctitle("child");
163 buf = malloc(st.st_size);
165 err(1, "malloc %jd", st.st_size);
168 written = st.st_size - pos;
169 if (arc4random() % 100 < 20)
170 ualarm(arc4random() % 10000, 0);
171 n = read(sv[1], buf + pos, written);
173 if (n == -1 && errno != ENOTCONN)
178 if (pos == st.st_size)
191 pid_t pids[PARALLEL];
198 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
199 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
203 while ((time(NULL) - start) < RUNTIME && e == 0) {
205 for (i = 0; i < PARALLEL; i++) {
206 if ((pids[i] = fork()) == 0)
211 for (i = 0; i < PARALLEL; i++) {
212 if (waitpid(pids[i], &status, 0) == -1)
213 err(1, "waitpid(%d)", pids[i]);
215 if (WIFSIGNALED(status))
217 "pid %d exit signal %d\n",
218 pids[i], WTERMSIG(status));
220 e += status == 0 ? 0 : 1;