Index: user/pho/stress2/misc/sendfile.sh =================================================================== --- user/pho/stress2/misc/sendfile.sh (revision 332057) +++ user/pho/stress2/misc/sendfile.sh (revision 332058) @@ -1,217 +1,216 @@ #!/bin/sh # # Copyright (c) 2009 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario for sendfile livelock seen on 7.2-STABLE for non SMP # Scenario by kib@ . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > sendfile.c mycc -o sendfile -Wall sendfile.c -pthread rm -f sendfile.c [ -d "$RUNDIR" ] || mkdir -p $RUNDIR cd $RUNDIR in=inputFile out=outputFile for i in 1 2 3 4 8 16 1k 2k 3k 4k 5k 1m 2m 3m 4m 5m ; do rm -f $in $out - dd if=/dev/random of=$in bs=$i count=1 2>&1 | \ - egrep -v "records|transferred" + dd if=/dev/random of=$in bs=$i count=1 status=none /tmp/sendfile $in $out 12345 cmp $in $out || { echo FAIL; ls -l $in $out; } rm -f $in $out done rm -f /tmp/sendfile exit EOF #include #include #include #include #include #include #include #include #include #include #include #include int port; char *inputFile; char *outputFile; int bufsize = 4096; static void reader(void) { int tcpsock, msgsock; int on; socklen_t len; struct sockaddr_in inetaddr, inetpeer; int n, t, *buf, fd; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(bufsize)) == NULL) err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) err(1, "open(%s)", outputFile); for (;;) { if ((n = read(msgsock, buf, bufsize)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { int tcpsock, on; struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; int i, r, fd; off_t off = 0; #if 1 size_t size; #endif on = 1; for (i = 1; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); #if 1 /* livelock trigger */ size = getpagesize() -4; if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, __LINE__); #endif hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(inputFile, &statb) != 0) err(1, "stat(%s)", inputFile); if ((fd = open(inputFile, O_RDONLY)) == -1) err(1, "open(%s)", inputFile); if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) err(1, "sendfile"); return; } int main(int argc, char **argv) { pid_t pid; if (argc != 4) { fprintf(stderr, "Usage: %s 0) { reader(); kill(pid, SIGINT); } else err(1, "fork(), %s:%d", __FILE__, __LINE__); return (0); } Index: user/pho/stress2/misc/sendfile11.sh =================================================================== --- user/pho/stress2/misc/sendfile11.sh (revision 332057) +++ user/pho/stress2/misc/sendfile11.sh (revision 332058) @@ -1,237 +1,236 @@ #!/bin/sh # # Copyright (c) 2017 Dell EMC Isilon # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 # sendfile(2) && block size > page size: # panic: vnode_pager_generic_getpages: sector size 8192 too large . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > sendfile11.c mycc -o sendfile11 -Wall sendfile11.c -pthread || exit 1 rm -f sendfile11.c set -e mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart mdconfig -a -t swap -s 2g -u $mdstart -dd if=/dev/random of=/tmp/geli.key bs=64 count=1 > /dev/null 2>&1 +dd if=/dev/random of=/tmp/geli.key bs=64 count=1 status=none echo test | geli init -s 8192 -J - -K /tmp/geli.key /dev/md$mdstart > /dev/null echo test | geli attach -j - -k /tmp/geli.key /dev/md$mdstart newfs $newfs_flags /dev/md$mdstart.eli > /dev/null mount /dev/md${mdstart}.eli $mntpoint chmod 777 $mntpoint set +e cd $mntpoint -dd if=/dev/zero of=file bs=1m count=512 +dd if=/dev/zero of=file bs=1m count=512 status=none (cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100) & sleep 5 /tmp/sendfile11 file output 12345; s=$? cd $odir while pkill swap; do sleep 1 done wait while mount | grep $mntpoint | grep -q /dev/md; do umount $mntpoint || sleep 1 done checkfs /dev/md${mdstart}.eli || s=$? geli kill /dev/md$mdstart.eli mdconfig -d -u $mdstart rm -f /tmp/geli.key /tmp/sendfile11 exit $s EOF #include #include #include #include #include #include #include #include #include #include #include #include #define BUFSIZE 8192 static int port; static char *inputFile; static char *outputFile; static void reader(void) { struct sockaddr_in inetaddr, inetpeer; socklen_t len; int tcpsock, msgsock; int *buf, fd, n, on, t; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(BUFSIZE)) == NULL) err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) err(1, "open(%s)", outputFile); for (;;) { if ((n = read(msgsock, buf, BUFSIZE)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; off_t off = 0; size_t size; int i, fd, on, r, tcpsock; on = 1; for (i = 1; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); size = getpagesize() -4; if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, __LINE__); hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(inputFile, &statb) != 0) err(1, "stat(%s)", inputFile); if ((fd = open(inputFile, O_RDONLY)) == -1) err(1, "open(%s)", inputFile); if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) err(1, "sendfile"); return; } int main(int argc, char **argv) { pid_t pid; int e, s; if (argc != 4) { fprintf(stderr, "Usage: %s 0) { reader(); kill(pid, SIGINT); waitpid(pid, &s, 0); if (s != 0) e = 1; } else err(1, "fork(), %s:%d", __FILE__, __LINE__); return (e); } Index: user/pho/stress2/misc/sendfile12.sh =================================================================== --- user/pho/stress2/misc/sendfile12.sh (revision 332057) +++ user/pho/stress2/misc/sendfile12.sh (revision 332058) @@ -1,245 +1,244 @@ #!/bin/sh # # Copyright (c) 2017 Dell EMC Isilon # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 # Test scenario suggestion by alc@ # sendfile(2) using SF_NOCACHE and a mmap'ed file with touched pages. # "panic: vm_page_free_toq: freeing mapped page 0xc49e53bc" seen: # https://people.freebsd.org/~pho/stress/log/sendfile12.txt . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > sendfile12.c mycc -o sendfile12 -Wall sendfile12.c -pthread || exit 1 rm -f sendfile12.c set -e mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart mdconfig -a -t swap -s 2g -u $mdstart newfs $newfs_flags /dev/md$mdstart > /dev/null mount /dev/md${mdstart} $mntpoint chmod 777 $mntpoint set +e cd $mntpoint -dd if=/dev/zero of=file bs=1m count=512 2>&1 | egrep -v "records|transferred" +dd if=/dev/zero of=file bs=1m count=512 status=none (cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100) > /dev/null & sleep 5 /tmp/sendfile12 file output 12345; s=$? cd $odir while pkill swap; do sleep 1 done wait while mount | grep $mntpoint | grep -q /dev/md; do umount $mntpoint || sleep 1 done checkfs /dev/md${mdstart} || s=$? mdconfig -d -u $mdstart rm -f /tmp/sendfile12 exit $s EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUFSIZE 8192 static int port; static char *inputFile; static char *outputFile; static void reader(void) { struct sockaddr_in inetaddr, inetpeer; socklen_t len; int tcpsock, msgsock; int *buf, fd, n, on, t; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(BUFSIZE)) == NULL) err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) err(1, "open(%s)", outputFile); for (;;) { if ((n = read(msgsock, buf, BUFSIZE)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; off_t off = 0; size_t size; int i, fd, on, r, tcpsock; char *cp; on = 1; for (i = 1; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); size = getpagesize() -4; if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, __LINE__); hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(inputFile, &statb) != 0) err(1, "stat(%s)", inputFile); if ((fd = open(inputFile, O_RDWR)) == -1) err(1, "open(%s)", inputFile); if ((cp = mmap(NULL, statb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) err(1, "mmap"); cp[0] = 1; if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, SF_NOCACHE) == -1) err(1, "sendfile"); return; } int main(int argc, char **argv) { pid_t pid; int e, s; if (argc != 4) { fprintf(stderr, "Usage: %s 0) { reader(); kill(pid, SIGINT); waitpid(pid, &s, 0); if (s != 0) e = 1; } else err(1, "fork(), %s:%d", __FILE__, __LINE__); return (e); } Index: user/pho/stress2/misc/sendfile2.sh =================================================================== --- user/pho/stress2/misc/sendfile2.sh (revision 332057) +++ user/pho/stress2/misc/sendfile2.sh (revision 332058) @@ -1,145 +1,144 @@ #!/bin/sh # # Copyright (c) 2010 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario for sendfile corruption of read only input file # Scenario by Ming Fu . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > sendfile2.c mycc -o sendfile2 -Wall sendfile2.c rm -f sendfile2.c [ -d "$RUNDIR" ] || mkdir -p $RUNDIR cd $RUNDIR -dd if=/dev/random of=large bs=1m count=3 2>&1 | - egrep -v "records|transferred" +dd if=/dev/random of=large bs=1m count=3 status=none md1=`md5 large` nc -l 7000 > lf & sleep 0.1 /tmp/sendfile2 kill $! 2>/dev/null wait md2=`md5 large` [ "$md1" != "$md2" ] && printf "%s\n%s\n" "$md1" "$md2" rm -f /tmp/sendfile2 large lf exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main () { int s, f; struct sockaddr_in addr; struct hostent *hostent; int flags; char str[32]="\r\n800\r\n"; char *p = str; struct stat sb; int n; fd_set wset; int64_t size; off_t sbytes; off_t sent = 0; int chunk; alarm(120); s = socket(AF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(7000); hostent = gethostbyname ("localhost"); memcpy (&addr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); n = connect(s, (struct sockaddr *)&addr, sizeof (addr)); if (n < 0) warn ("fail to connect"); flags = fcntl(s, F_GETFL); flags |= O_NONBLOCK; fcntl(s, F_SETFL); f = open("large", O_RDONLY); if (f < 0) warn("fail to open file"); n = fstat(f, &sb); if (n < 0) warn("fstat failed"); size = sb.st_size; chunk = 0; while (size > 0) { FD_ZERO(&wset); FD_SET(s, &wset); n = select(f+1, NULL, &wset, NULL, NULL); if (n < 0) continue; if (chunk > 0) { sbytes = 0; n = sendfile(f, s, sent, chunk, NULL, &sbytes, 0); if (n < 0) continue; chunk -= sbytes; size -= sbytes; sent += sbytes; continue; } if (size > 2048) chunk = 2048; else chunk = size; n = sprintf(str, "\r\n%x\r\n", 2048); p = str; write(s, p, n); } return (0); } Index: user/pho/stress2/misc/sendfile3.sh =================================================================== --- user/pho/stress2/misc/sendfile3.sh (revision 332057) +++ user/pho/stress2/misc/sendfile3.sh (revision 332058) @@ -1,215 +1,213 @@ #!/bin/sh # # Copyright (c) 2011 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario for sendfile deadlock (processes stuck in sfbufa) # Variation of sendfile.sh # kern.ipc.nsfbufs should be low for this test . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > sendfile3.c mycc -o sendfile3 -Wall -Wextra sendfile3.c rm -f sendfile3.c [ -d "$RUNDIR" ] || mkdir -p $RUNDIR cd $RUNDIR in=inputFile out=outputFile parallel=20 for i in 50m 100m; do rm -f $in - dd if=/dev/random of=$in bs=$i count=1 2>&1 | \ - egrep -v "records|transferred" + dd if=/dev/random of=$in bs=$i count=1 status=none for j in `jot $parallel`; do rm -f ${out}$j /tmp/sendfile3 $in ${out}$j 1234$j & done wait for j in `jot $parallel`; do rm -f ${out}$j done done rm -f $in /tmp/sendfile3 exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #include int port; char *inputFile; char *outputFile; int bufsize = 4096; static void reader(void) { int tcpsock, msgsock; int on; socklen_t len; struct sockaddr_in inetaddr, inetpeer; int n, t, *buf, fd; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(bufsize)) == NULL) - err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); + err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) - err(1, "open(%s)", outputFile); + err(1, "open(%s)", outputFile); for (;;) { if ((n = read(msgsock, buf, bufsize)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { int tcpsock, on; struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; int i, r, fd; off_t off = 0; on = 1; for (i = 0; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); bzero((char *) &inetaddr, sizeof(inetaddr)); hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(inputFile, &statb) != 0) err(1, "stat(%s)", inputFile); if ((fd = open(inputFile, O_RDONLY)) == -1) err(1, "open(%s)", inputFile); if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) err(1, "sendfile"); } int main(int argc, char **argv) { pid_t pid; if (argc != 4) { fprintf(stderr, "Usage: %s 0) { reader(); kill(pid, SIGINT); waitpid(pid, NULL, 0); } else err(1, "fork(), %s:%d", __FILE__, __LINE__); return (0); } Index: user/pho/stress2/misc/sendfile4.sh =================================================================== --- user/pho/stress2/misc/sendfile4.sh (revision 332057) +++ user/pho/stress2/misc/sendfile4.sh (revision 332058) @@ -1,145 +1,143 @@ #!/bin/sh # # Copyright (c) 2011 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # sendfile(2) test by kib@ # Both processes will sit in the sbwait state forever: . ../default.cfg here=`pwd` cd /tmp sed '1,/^EOF/d' < $here/$0 > sendfile4.c mycc -o sendfile4 -Wall -Wextra -O2 sendfile4.c || exit rm -f sendfile4.c cd $here -dd if=/dev/zero of=$diskimage bs=1m count=6 2>&1 | \ - egrep -v "records|transferred" - +dd if=/dev/zero of=$diskimage bs=1m count=6 status=none /tmp/sendfile4 $diskimage || echo FAIL rm -f /tmp/sendfile4 $diskimage exit EOF #include #include #include #include #include #include #include #include #include #include #include static void handler(int i __unused) { _exit(1); } int main(int argc, char *argv[]) { const char *from_name; char *buf; int sv[2]; struct stat st; off_t written, pos; int child, error, from, status; if (argc != 2) errx(1, "Usage: %s from", argv[0]); from_name = argv[1]; from = open(from_name, O_RDONLY); if (from == -1) err(1, "open read %s", from_name); error = fstat(from, &st); if (error == -1) err(1, "stat %s", from_name); error = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); if (error == -1) err(1, "socketpair"); signal(SIGALRM, handler); alarm(120); child = fork(); if (child == -1) err(1, "fork"); else if (child != 0) { close(sv[1]); pos = 0; for (;;) { error = sendfile(from, sv[0], pos, st.st_size - pos, NULL, &written, 0); if (error == -1) { if (errno != EAGAIN) err(1, "sendfile"); } pos += written; if (pos == st.st_size) break; } close(sv[0]); waitpid(child, &status, 0); } else { close(sv[0]); buf = malloc(st.st_size); if (buf == NULL) err(1, "malloc %jd", st.st_size); pos = 0; for (;;) { written = 413; if (written > st.st_size - pos) written = st.st_size - pos; #if 0 written = st.st_size - pos; if (written > 1000) written = 1000; written = arc4random_uniform(written) + 1; #endif error = read(sv[1], buf + pos, written); if (error == -1) err(1, "read"); else if (error == 0) errx(1, "short read"); pos += error; if (pos == st.st_size) break; } close(sv[1]); _exit(0); } return (0); } Index: user/pho/stress2/misc/sendfile5.sh =================================================================== --- user/pho/stress2/misc/sendfile5.sh (revision 332057) +++ user/pho/stress2/misc/sendfile5.sh (revision 332058) @@ -1,166 +1,165 @@ #!/bin/sh # # Copyright (c) 2011 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # sendfile(2) test by kib@ # Deadlock seen. [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg here=`pwd` file=`basename $diskimage` dir=`dirname $diskimage` cd /tmp sed '1,/^EOF/d' < $here/$0 > sendfile5.c mycc -o sendfile5 -Wall -Wextra -O2 sendfile5.c rm -f sendfile5.c need=1024 [ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)'}` \ -lt $need ] && printf "Need %d MB on %s.\n" $need `dirname $diskimage` && exit 0 -dd if=/dev/zero of=$diskimage bs=1m count=$need 2>&1 | - egrep -v "records|transferred" +dd if=/dev/zero of=$diskimage bs=1m count=$need status=none cd $here mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mount -t tmpfs tmpfs $mntpoint echo "Testing tmpfs(5)" cp $diskimage $mntpoint /tmp/sendfile5 $mntpoint/$file umount $mntpoint mdconfig -a -t swap -s 2g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint echo "Testing FFS" cp $diskimage $mntpoint /tmp/sendfile5 $mntpoint/$file umount $mntpoint mdconfig -d -u $mdstart mount -t nullfs $dir $mntpoint echo "Testing nullfs(5)" /tmp/sendfile5 $mntpoint/$file umount $mntpoint rm -f /tmp/sendfile5 $diskimage exit EOF #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { const char *from_name; char *buf; int sv[2]; struct stat st; off_t written, pos; int child, error, from, status; if (argc != 2) errx(1, "Usage: %s from", argv[0]); from_name = argv[1]; from = open(from_name, O_RDONLY); if (from == -1) err(1, "open read %s", from_name); error = fstat(from, &st); if (error == -1) err(1, "stat %s", from_name); error = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); if (error == -1) err(1, "socketpair"); child = fork(); if (child == -1) err(1, "fork"); else if (child != 0) { close(sv[1]); pos = 0; for (;;) { error = sendfile(from, sv[0], pos, st.st_size - pos, NULL, &written, 0); if (error == -1) { if (errno != EAGAIN) err(1, "sendfile"); } pos += written; if (pos == st.st_size) break; } close(sv[0]); waitpid(child, &status, 0); } else { close(sv[0]); buf = malloc(st.st_size); if (buf == NULL) err(1, "malloc %jd", st.st_size); pos = 0; for (;;) { written = 413; if (written > st.st_size - pos) written = st.st_size - pos; #if 0 written = st.st_size - pos; if (written > 1000) written = 1000; written = arc4random_uniform(written) + 1; #endif error = read(sv[1], buf + pos, written); if (error == -1) err(1, "read"); else if (error == 0) errx(1, "short read"); pos += error; if (pos == st.st_size) break; } close(sv[1]); _exit(0); } return (0); } Index: user/pho/stress2/misc/sendfile6.sh =================================================================== --- user/pho/stress2/misc/sendfile6.sh (revision 332057) +++ user/pho/stress2/misc/sendfile6.sh (revision 332058) @@ -1,257 +1,257 @@ #!/bin/sh # # Copyright (c) 2013 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario by Nate Eldredge neldredge math ucsdnedu # kern/127213: [tmpfs] sendfile on tmpfs data corruption # Variation of tmpfs7.sh where UFS is used instead of tmpfs. [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg set -e odir=`pwd` cd /tmp cat > sendfile6_server.c < #include #include #include #include "util.h" int main(int argc, char *argv[]) { int f, listener, connection; if (argc < 3) { fprintf(stderr, "Usage: %s filename socketname\n", argv[0]); exit(1); } if ((f = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } if ((listener = listen_unix_socket(argv[2])) < 0) { exit(1); } if ((connection = accept_unix_socket(listener)) >= 0) { real_sendfile(f, connection); } return 0; } EOF cat > sendfile6_client.c < #include #include #include #include "util.h" int main(int argc, char *argv[]) { int s; if (argc < 2) { fprintf(stderr, "Usage: %s socketname\n", argv[0]); exit(1); } if ((s = connect_unix_socket(argv[1])) < 0) { exit(1); } fake_sendfile(s, 1); return 0; } EOF cat > util.c < #include #include #include #include #include #include #include #include #include int create_unix_socket(void) { int fd; if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } return fd; } int make_unix_sockaddr(const char *pathname, struct sockaddr_un *sa) { memset(sa, 0, sizeof(*sa)); sa->sun_family = PF_LOCAL; if (strlen(pathname) + 1 > sizeof(sa->sun_path)) { // fprintf(stderr, "%s: pathname too long (max %lu)\n", // pathname, sizeof(sa->sun_path)); errno = ENAMETOOLONG; return -1; } strcpy(sa->sun_path, pathname); return 0; } static char *sockname; void delete_socket(void) { unlink(sockname); } int listen_unix_socket(const char *path) { int fd; struct sockaddr_un sa; if (make_unix_sockaddr(path, &sa) < 0) return -1; if ((fd = create_unix_socket()) < 0) return -1; if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); close(fd); return -1; } sockname = strdup(path); atexit(delete_socket); if (listen(fd, 5) < 0) { perror("listen"); close(fd); return -1; } return fd; } int accept_unix_socket(int fd) { int s; if ((s = accept(fd, NULL, 0)) < 0) { perror("accept"); return -1; } return s; } int connect_unix_socket(const char *path) { int fd; struct sockaddr_un sa; if (make_unix_sockaddr(path, &sa) < 0) return -1; if ((fd = create_unix_socket()) < 0) return -1; if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return -1; } return fd; } #define BUFSIZE 65536 int fake_sendfile(int from, int to) { char buf[BUFSIZE]; int v; int sent = 0; while ((v = read(from, buf, BUFSIZE)) > 0) { int d = 0; while (d < v) { int w = write(to, buf, v - d); if (w <= 0) { perror("write"); return -1; } d += w; sent += w; } } if (v != 0) { perror("read"); return -1; } return sent; } int real_sendfile(int from, int to) { int v; v = sendfile(from, to, 0, 0, NULL, NULL, 0); if (v < 0) { perror("sendfile"); } return v; } EOF cat > util.h < #include #include #include #include #include #include int create_unix_socket(void); int make_unix_sockaddr(const char *pathname, struct sockaddr_un *sa); int listen_unix_socket(const char *path); int accept_unix_socket(int fd); int connect_unix_socket(const char *path); int fake_sendfile(int from, int to); int real_sendfile(int from, int to); EOF mycc -c -Wall -Wextra -O2 util.c mycc -o sendfile6_server -Wall -Wextra -O2 sendfile6_server.c util.o mycc -o sendfile6_client -Wall -Wextra -O2 sendfile6_client.c util.o rm -f sendfile6_server.c sendfile6_client.c util.c util.o util.h mysocket mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mdconfig -a -t swap -s 1g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint -dd if=/dev/random of=$mntpoint/data bs=123456 count=1 > /dev/null 2>&1 +dd if=/dev/random of=$mntpoint/data bs=123456 count=1 status=none ./sendfile6_server $mntpoint/data mysocket & sleep 0.2 ./sendfile6_client mysocket > data.$$ wait cmp $mntpoint/data data.$$ || { echo "FAIL Data mismatch"; ls -l $mntpoint/data data.$$; } rm -f data.$$ sendfile6_server sendfile6_client mysocket while mount | grep "on $mntpoint " | grep -q /dev/md; do umount $mntpoint || sleep 1 done mdconfig -d -u $mdstart Index: user/pho/stress2/misc/sendfile8.sh =================================================================== --- user/pho/stress2/misc/sendfile8.sh (revision 332057) +++ user/pho/stress2/misc/sendfile8.sh (revision 332058) @@ -1,271 +1,271 @@ #!/bin/sh # # Copyright (c) 2017 Dell EMC Isilon # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # sendfile(2) + parallel file size change. Bug 217789. # "panic: Assertion size > 0 failed at ../../../kern/subr_vmem.c:1082" seen: # Fixed in r315910 . ../default.cfg [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 dir=/tmp odir=`pwd` cd $dir sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile8.c mycc -o sendfile8 -Wall -Wextra -O0 -g sendfile8.c || exit 1 rm -f sendfile8.c cd $odir mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart mdconfig -a -t swap -s 1g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint cd $mntpoint -dd if=/dev/random of=in bs=1m count=50 2>&1 | egrep -v "records|transferred" +dd if=/dev/random of=in bs=1m count=50 status=none /tmp/sendfile8 in out 76543 s=$? cd $odir for i in `jot 6`; do mount | grep -q "on $mntpoint " || break umount $mntpoint && break || sleep 10 done [ $i -eq 6 ] && exit 1 mdconfig -d -u $mdstart rm -rf /tmp/sendfile8 exit $s EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int port; static char *input, *output; #define BUFSIZE 4096 #define PARALLEL 1 #define RUNTIME (1 * 60) static void mess(void) { off_t length; int fd; if ((fd = open(input, O_RDWR)) == -1) err(1, "open(%s)", input); length = arc4random() % 100 * 1024 * 1024; if (ftruncate(fd, length) == -1) err(1, "truncate(%jd)", length); close(fd); } static void reader(void) { struct sockaddr_in inetaddr, inetpeer; socklen_t len; int tcpsock, msgsock; int on; int n, t, *buf, fd; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(BUFSIZE)) == NULL) err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); if ((fd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) err(1, "open(%s)", output); for (;;) { if ((n = read(msgsock, buf, BUFSIZE)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; off_t off = 0; size_t size; int i, r, fd; int tcpsock, on; on = 1; for (i = 1; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); size = getpagesize() -4; if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, __LINE__); hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(input, &statb) != 0) err(1, "stat(%s)", input); if ((fd = open(input, O_RDONLY)) == -1) err(1, "open(%s)", input); if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) err(1, "sendfile"); return; } static void test(void) { pid_t pid; if ((pid = fork()) == 0) { writer(); _exit(0); } reader(); kill(pid, SIGINT); if (waitpid(pid, NULL, 0) != pid) err(1, "waitpid(%d)", pid); _exit(0); } int main(int argc, char *argv[]) { time_t start; int e, i, j, pids[PARALLEL], status; if (argc != 4) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } input = argv[1]; output = argv[2]; port = atoi(argv[3]); e = 0; start = time(NULL); while ((time(NULL) - start) < RUNTIME && e == 0) { for (i = 0; i < PARALLEL; i++) { if ((pids[i] = fork()) == 0) test(); } for (j = 0; j < 100; j++) { mess(); usleep(arc4random() % 10000); } for (i = 0; i < PARALLEL; i++) { if (waitpid(pids[i], &status, 0) == -1) err(1, "waitpid(%d)", pids[i]); e += status == 0 ? 0 : 1; } } return (e); } Index: user/pho/stress2/misc/sendfile9.sh =================================================================== --- user/pho/stress2/misc/sendfile9.sh (revision 332057) +++ user/pho/stress2/misc/sendfile9.sh (revision 332058) @@ -1,270 +1,270 @@ #!/bin/sh # # Copyright (c) 2017 Dell EMC Isilon # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # "kmem are D+ 0 0:00,10 /tmp/sendfile9 in out 76543" seen. # Fixed in r315910 . ../default.cfg [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 dir=/tmp odir=`pwd` cd $dir sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile9.c mycc -o sendfile9 -Wall -Wextra -O0 -g sendfile9.c || exit 1 rm -f sendfile9.c cd $odir mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart mdconfig -a -t swap -s 1g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags -n md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint cd $mntpoint -dd if=/dev/random of=in bs=1m count=50 2>&1 | egrep -v "records|transferred" +dd if=/dev/random of=in bs=1m count=50 status=none /tmp/sendfile9 in out 76543 s=$? cd $odir for i in `jot 6`; do mount | grep -q "on $mntpoint " || break umount $mntpoint && break || sleep 10 done [ $i -eq 6 ] && exit 1 mdconfig -d -u $mdstart rm -rf /tmp/sendfile9 exit $s EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int port; static char *input, *output; #define BUFSIZE 4096 #define PARALLEL 1 #define RUNTIME (1 * 60) static void mess(void) { off_t length; int fd; if ((fd = open(input, O_RDWR)) == -1) err(1, "open(%s)", input); length = arc4random() % 100 * 1024 * 1024; if (ftruncate(fd, length) == -1) err(1, "truncate(%jd)", length); close(fd); } static void reader(void) { struct sockaddr_in inetaddr, inetpeer; socklen_t len; int tcpsock, msgsock; int on; int n, t, *buf, fd; on = 1; if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) err(1, "bind(), %s:%d", __FILE__, __LINE__); if (listen(tcpsock, 5) < 0) err(1, "listen(), %s:%d", __FILE__, __LINE__); len = sizeof(inetpeer); if ((msgsock = accept(tcpsock, (struct sockaddr *)&inetpeer, &len)) < 0) err(1, "accept(), %s:%d", __FILE__, __LINE__); t = 0; if ((buf = malloc(BUFSIZE)) == NULL) err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); if ((fd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) err(1, "open(%s)", output); for (;;) { if ((n = read(msgsock, buf, BUFSIZE)) < 0) err(1, "read(), %s:%d", __FILE__, __LINE__); t += n; if (n == 0) break; if ((write(fd, buf, n)) != n) err(1, "write"); } close(msgsock); close(fd); return; } static void writer(void) { struct sockaddr_in inetaddr; struct hostent *hostent; struct stat statb; off_t off = 0; size_t size; int i, r, fd; int tcpsock, on; on = 1; for (i = 1; i < 5; i++) { if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket(), %s:%d", __FILE__, __LINE__); if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); size = getpagesize() -4; if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0) err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__, __LINE__); hostent = gethostbyname ("localhost"); memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr)); inetaddr.sin_family = AF_INET; inetaddr.sin_addr.s_addr = INADDR_ANY; inetaddr.sin_port = htons(port); inetaddr.sin_len = sizeof(inetaddr); r = connect(tcpsock, (struct sockaddr *) &inetaddr, sizeof(inetaddr)); if (r == 0) break; sleep(1); close(tcpsock); } if (r < 0) err(1, "connect(), %s:%d", __FILE__, __LINE__); if (stat(input, &statb) != 0) err(1, "stat(%s)", input); if ((fd = open(input, O_RDONLY)) == -1) err(1, "open(%s)", input); if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) err(1, "sendfile"); return; } static void test(void) { pid_t pid; if ((pid = fork()) == 0) { writer(); _exit(0); } reader(); kill(pid, SIGINT); if (waitpid(pid, NULL, 0) != pid) err(1, "waitpid(%d)", pid); _exit(0); } int main(int argc, char *argv[]) { time_t start; int e, i, j, pids[PARALLEL], status; if (argc != 4) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } input = argv[1]; output = argv[2]; port = atoi(argv[3]); e = 0; start = time(NULL); while ((time(NULL) - start) < RUNTIME && e == 0) { for (i = 0; i < PARALLEL; i++) { if ((pids[i] = fork()) == 0) test(); } for (j = 0; j < 100; j++) { mess(); usleep(arc4random() % 10000); } for (i = 0; i < PARALLEL; i++) { if (waitpid(pids[i], &status, 0) == -1) err(1, "waitpid(%d)", pids[i]); e += status == 0 ? 0 : 1; } } return (e); } Index: user/pho/stress2/misc/tmpfs7.sh =================================================================== --- user/pho/stress2/misc/tmpfs7.sh (revision 332057) +++ user/pho/stress2/misc/tmpfs7.sh (revision 332058) @@ -1,251 +1,251 @@ #!/bin/sh # # Copyright (c) 2013 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test scenario by Nate Eldredge neldredge math ucsdnedu # kern/127213: [tmpfs] sendfile on tmpfs data corruption [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg set -e odir=`pwd` cd /tmp cat > server.c < #include #include #include #include "util.h" int main(int argc, char *argv[]) { int f, listener, connection; if (argc < 3) { fprintf(stderr, "Usage: %s filename socketname\n", argv[0]); exit(1); } if ((f = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } if ((listener = listen_unix_socket(argv[2])) < 0) { exit(1); } if ((connection = accept_unix_socket(listener)) >= 0) { real_sendfile(f, connection); } return 0; } EOF cat > client.c < #include #include #include #include "util.h" int main(int argc, char *argv[]) { int s; if (argc < 2) { fprintf(stderr, "Usage: %s socketname\n", argv[0]); exit(1); } if ((s = connect_unix_socket(argv[1])) < 0) { exit(1); } fake_sendfile(s, 1); return 0; } EOF cat > util.c < #include #include #include #include #include #include #include #include #include int create_unix_socket(void) { int fd; if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } return fd; } int make_unix_sockaddr(const char *pathname, struct sockaddr_un *sa) { memset(sa, 0, sizeof(*sa)); sa->sun_family = PF_LOCAL; if (strlen(pathname) + 1 > sizeof(sa->sun_path)) { // fprintf(stderr, "%s: pathname too long (max %lu)\n", // pathname, sizeof(sa->sun_path)); errno = ENAMETOOLONG; return -1; } strcpy(sa->sun_path, pathname); return 0; } static char *sockname; void delete_socket(void) { unlink(sockname); } int listen_unix_socket(const char *path) { int fd; struct sockaddr_un sa; if (make_unix_sockaddr(path, &sa) < 0) return -1; if ((fd = create_unix_socket()) < 0) return -1; if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); close(fd); return -1; } sockname = strdup(path); atexit(delete_socket); if (listen(fd, 5) < 0) { perror("listen"); close(fd); return -1; } return fd; } int accept_unix_socket(int fd) { int s; if ((s = accept(fd, NULL, 0)) < 0) { perror("accept"); return -1; } return s; } int connect_unix_socket(const char *path) { int fd; struct sockaddr_un sa; if (make_unix_sockaddr(path, &sa) < 0) return -1; if ((fd = create_unix_socket()) < 0) return -1; if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return -1; } return fd; } #define BUFSIZE 65536 int fake_sendfile(int from, int to) { char buf[BUFSIZE]; int v; int sent = 0; while ((v = read(from, buf, BUFSIZE)) > 0) { int d = 0; while (d < v) { int w = write(to, buf, v - d); if (w <= 0) { perror("write"); return -1; } d += w; sent += w; } } if (v != 0) { perror("read"); return -1; } return sent; } int real_sendfile(int from, int to) { int v; v = sendfile(from, to, 0, 0, NULL, NULL, 0); if (v < 0) { perror("sendfile"); } return v; } EOF cat > util.h < #include #include #include #include #include #include int create_unix_socket(void); int make_unix_sockaddr(const char *pathname, struct sockaddr_un *sa); int listen_unix_socket(const char *path); int accept_unix_socket(int fd); int connect_unix_socket(const char *path); int fake_sendfile(int from, int to); int real_sendfile(int from, int to); EOF mycc -c -Wall -Wextra -O2 util.c mycc -o server -Wall -Wextra -O2 server.c util.o mycc -o client -Wall -Wextra -O2 client.c util.o rm -f server.c client.c util.c util.o util.h mysocket mount | grep "$mntpoint" | grep -q tmpfs && umount $mntpoint mount -t tmpfs tmpfs $mntpoint -dd if=/dev/random of=$mntpoint/data bs=123456 count=1 > /dev/null 2>&1 +dd if=/dev/random of=$mntpoint/data bs=123456 count=1 status=none ./server $mntpoint/data mysocket & sleep 0.2 ./client mysocket > data.$$ cmp $mntpoint/data data.$$ || { echo "FAIL Data mismatch"; ls -l $mntpoint/data data.$$; } rm -f data.$$ server client mysocket wait while mount | grep "$mntpoint" | grep -q tmpfs; do umount $mntpoint || sleep 1 done