1#!/bin/sh 2 3# 4# Copyright (c) 2017 Dell EMC Isilon 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# sendfile(2) && block size > page size: 32# panic: vnode_pager_generic_getpages: sector size 8192 too large 33# https://people.freebsd.org/~pho/stress/log/sendfile11.txt 34 35. ../default.cfg 36 37odir=`pwd` 38cd /tmp 39sed '1,/^EOF/d' < $odir/$0 > sendfile11.c 40mycc -o sendfile11 -Wall -O0 sendfile11.c -pthread || exit 1 41rm -f sendfile11.c 42 43set -e 44mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint 45[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 46mdconfig -a -t swap -s 2g -u $mdstart 47 48dd if=/dev/random of=/tmp/geli.key bs=64 count=1 status=none 49echo test | geli init -s 8192 -J - -K /tmp/geli.key /dev/md$mdstart > /dev/null 50echo test | geli attach -j - -k /tmp/geli.key /dev/md$mdstart 51newfs $newfs_flags /dev/md$mdstart.eli > /dev/null 52 53mount /dev/md${mdstart}.eli $mntpoint 54chmod 777 $mntpoint 55set +e 56 57cd $mntpoint 58dd if=/dev/zero of=file bs=1m count=512 status=none 59(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100) & 60sleep 5 61/tmp/sendfile11 file output 12345; s=$? 62cd $odir 63while pkill swap; do 64 sleep 1 65done 66wait 67 68while mount | grep $mntpoint | grep -q /dev/md; do 69 umount $mntpoint || sleep 1 70done 71checkfs /dev/md${mdstart}.eli || s=$? 72geli kill /dev/md$mdstart.eli 73mdconfig -d -u $mdstart 74rm -f /tmp/geli.key /tmp/sendfile11 75exit $s 76EOF 77#include <sys/param.h> 78#include <sys/socket.h> 79#include <sys/stat.h> 80#include <sys/wait.h> 81 82#include <err.h> 83#include <fcntl.h> 84#include <netdb.h> 85#include <netinet/in.h> 86#include <signal.h> 87#include <stdio.h> 88#include <stdlib.h> 89#include <string.h> 90#include <unistd.h> 91 92#define BUFSIZE 8192 93 94static int port; 95static char *inputFile; 96static char *outputFile; 97 98static void 99reader(void) { 100 struct sockaddr_in inetaddr, inetpeer; 101 socklen_t len; 102 int tcpsock, msgsock; 103 int *buf, fd, n, on, t __unused; 104 105 on = 1; 106 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 107 err(1, "socket(), %s:%d", __FILE__, __LINE__); 108 109 if (setsockopt(tcpsock, 110 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 111 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 112 113 inetaddr.sin_family = AF_INET; 114 inetaddr.sin_addr.s_addr = INADDR_ANY; 115 inetaddr.sin_port = htons(port); 116 inetaddr.sin_len = sizeof(inetaddr); 117 118 if (bind(tcpsock, 119 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) 120 err(1, "bind(), %s:%d", __FILE__, __LINE__); 121 122 if (listen(tcpsock, 5) < 0) 123 err(1, "listen(), %s:%d", __FILE__, __LINE__); 124 125 len = sizeof(inetpeer); 126 if ((msgsock = accept(tcpsock, 127 (struct sockaddr *)&inetpeer, &len)) < 0) 128 err(1, "accept(), %s:%d", __FILE__, __LINE__); 129 130 t = 0; 131 if ((buf = malloc(BUFSIZE)) == NULL) 132 err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); 133 134 if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == 135 -1) 136 err(1, "open(%s)", outputFile); 137 138 for (;;) { 139 if ((n = read(msgsock, buf, BUFSIZE)) < 0) 140 err(1, "read(), %s:%d", __FILE__, __LINE__); 141 t += n; 142 if (n == 0) break; 143 144 if ((write(fd, buf, n)) != n) 145 err(1, "write"); 146 } 147 close(msgsock); 148 close(fd); 149 return; 150} 151 152static void 153writer(void) { 154 struct sockaddr_in inetaddr; 155 struct hostent *hostent; 156 struct stat statb; 157 off_t off = 0; 158 size_t size; 159 int i, fd, on, r, tcpsock; 160 161 on = 1; 162 for (i = 1; i < 5; i++) { 163 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 164 err(1, "socket(), %s:%d", __FILE__, __LINE__); 165 166 if (setsockopt(tcpsock, 167 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 168 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 169 170 size = getpagesize() -4; 171 if (setsockopt(tcpsock, 172 SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) 173 err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, 174 __LINE__); 175 176 hostent = gethostbyname ("localhost"); 177 memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, 178 sizeof (struct in_addr)); 179 180 inetaddr.sin_family = AF_INET; 181 inetaddr.sin_port = htons(port); 182 inetaddr.sin_len = sizeof(inetaddr); 183 184 r = connect(tcpsock, (struct sockaddr *) &inetaddr, 185 sizeof(inetaddr)); 186 if (r == 0) 187 break; 188 sleep(1); 189 close(tcpsock); 190 } 191 if (r < 0) 192 err(1, "connect(), %s:%d", __FILE__, __LINE__); 193 194 if (stat(inputFile, &statb) != 0) 195 err(1, "stat(%s)", inputFile); 196 197 if ((fd = open(inputFile, O_RDONLY)) == -1) 198 err(1, "open(%s)", inputFile); 199 200 if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) 201 err(1, "sendfile"); 202 203 return; 204} 205 206int 207main(int argc, char **argv) 208{ 209 pid_t pid; 210 int e, s; 211 212 if (argc != 4) { 213 fprintf(stderr, 214 "Usage: %s <inputFile outputFile portNumber\n", argv[0]); 215 return (1); 216 } 217 e = 0; 218 inputFile = argv[1]; 219 outputFile = argv[2]; 220 port = atoi(argv[3]); 221 222 if ((pid = fork()) == 0) { 223 writer(); 224 exit(EXIT_SUCCESS); 225 } else if (pid > 0) { 226 reader(); 227 kill(pid, SIGINT); 228 waitpid(pid, &s, 0); 229 if (s != 0) 230 e = 1; 231 } else 232 err(1, "fork(), %s:%d", __FILE__, __LINE__); 233 234 return (e); 235} 236