4 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6 # Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
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(2) test with disk read errors
31 # "panic: vm_page_readahead_finish: 0xfffffe000d88d758 is invalid" seen:
32 # https://people.freebsd.org/~pho/stress/log/sendfile25.txt
34 # Test scenario suggestion by chs@
37 [ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
38 kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 &&
47 sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile25.c
48 mycc -o sendfile25 -Wall -Wextra -O0 -g sendfile25.c || exit 1
52 mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
53 [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
55 mdconfig -a -t swap -s 2g -u $mdstart
56 gnop create /dev/md$mdstart
57 newfs $newfs_flags -n -b $((32 * 1024)) /dev/md$mdstart.nop > /dev/null
58 mount /dev/md$mdstart.nop $mntpoint
62 dd if=/dev/zero of=$mntpoint/file bs=416k count=1 status=none
65 sendfile25: sendfile: sendfile25: read(), sendfile25.c:61: Broken pipe
66 Connection reset by peer'
67 while [ $((`date +%s` - start)) -lt 10 ]; do
69 mount /dev/md$mdstart.nop $mntpoint
70 ls -l $mntpoint > /dev/null
71 gnop configure -e 5 -r 1 /dev/md$mdstart.nop
72 /tmp/sendfile25 $mntpoint/file /dev/null 12345
73 gnop configure -e 5 -r 0 /dev/md$mdstart.nop
77 gnop destroy /dev/md$mdstart.nop
78 mdconfig -d -u $mdstart
79 [ $notloaded ] && gnop unload
80 rm -f /tmp/sendfile25 /tmp/sendfile25.c
84 #include <sys/param.h>
85 #include <sys/socket.h>
90 #include <netinet/in.h>
104 int tcpsock, msgsock;
107 struct sockaddr_in inetaddr, inetpeer;
111 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
112 err(1, "socket(), %s:%d", __FILE__, __LINE__);
114 if (setsockopt(tcpsock,
115 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
116 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
118 inetaddr.sin_family = AF_INET;
119 inetaddr.sin_addr.s_addr = INADDR_ANY;
120 inetaddr.sin_port = htons(port);
121 inetaddr.sin_len = sizeof(inetaddr);
124 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)
125 err(1, "bind(), %s:%d", __FILE__, __LINE__);
127 if (listen(tcpsock, 5) < 0)
128 err(1, "listen(), %s:%d", __FILE__, __LINE__);
130 len = sizeof(inetpeer);
131 if ((msgsock = accept(tcpsock,
132 (struct sockaddr *)&inetpeer, &len)) < 0)
133 err(1, "accept(), %s:%d", __FILE__, __LINE__);
136 if ((buf = malloc(bufsize)) == NULL)
137 err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);
139 if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1)
140 err(1, "open(%s)", outputFile);
143 if ((n = read(msgsock, buf, bufsize)) < 0)
144 err(1, "read(), %s:%d", __FILE__, __LINE__);
149 if ((write(fd, buf, n)) != n)
160 struct sockaddr_in inetaddr;
161 struct hostent *hostent;
168 for (i = 1; i < 5; i++) {
169 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
170 err(1, "socket(), %s:%d", __FILE__, __LINE__);
172 if (setsockopt(tcpsock,
173 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
174 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
176 size = getpagesize() -4;
177 if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size,
179 err(1, "setsockopt(SO_SNDBUF), %s:%d",
182 hostent = gethostbyname ("localhost");
183 memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,
184 sizeof (struct in_addr));
186 inetaddr.sin_family = AF_INET;
187 inetaddr.sin_port = htons(port);
188 inetaddr.sin_len = sizeof(inetaddr);
190 r = connect(tcpsock, (struct sockaddr *) &inetaddr,
198 err(1, "connect(), %s:%d", __FILE__, __LINE__);
200 if (stat(inputFile, &statb) != 0)
201 err(1, "stat(%s)", inputFile);
203 if ((fd = open(inputFile, O_RDONLY)) == -1)
204 err(1, "open(%s)", inputFile);
206 off = 12 * 32 * 1024;
207 if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1)
214 main(int argc, char **argv)
219 fprintf(stderr, "Usage: %s <inputFile outputFile portNumber\n",
224 outputFile = argv[2];
225 port = atoi(argv[3]);
227 if ((pid = fork()) == 0) {
230 } else if (pid > 0) {
234 err(1, "fork(), %s:%d", __FILE__, __LINE__);