From 6a5ba658dd480206187776e3c25d9f710fac90fd Mon Sep 17 00:00:00 2001 From: KUROSAWA Takahiro Date: Tue, 7 Jul 2026 21:09:06 +0200 Subject: tests/sendfile: move the helper program to common In order to reuse the sendfile_helper program in pf tests, move it to tests/sys/common directory, indicatint that it is also used from another places than sys/kern. Also make the readlen variable static. Reviewed by: gelbius, kp Differential Revision: https://reviews.freebsd.org/D58040 --- tests/sys/common/Makefile | 4 + tests/sys/common/sendfile_helper.c | 177 +++++++++++++++++++++++++++++++++++++ tests/sys/kern/Makefile | 2 - tests/sys/kern/sendfile_helper.c | 177 ------------------------------------- tests/sys/kern/sendfile_test.sh | 2 +- 5 files changed, 182 insertions(+), 180 deletions(-) create mode 100644 tests/sys/common/sendfile_helper.c delete mode 100644 tests/sys/kern/sendfile_helper.c (limited to 'tests') diff --git a/tests/sys/common/Makefile b/tests/sys/common/Makefile index 269aa9d52f9a..e42e9537f1a8 100644 --- a/tests/sys/common/Makefile +++ b/tests/sys/common/Makefile @@ -9,4 +9,8 @@ ${PACKAGE}FILESMODE_divert.py=0555 ${PACKAGE}FILESMODE_sender.py=0555 ${PACKAGE}FILESMODE_net_receiver.py=0555 +BINDIR= ${TESTSDIR} +PROGS+= sendfile_helper +LIBADD.sendfile_helper+= pthread + .include diff --git a/tests/sys/common/sendfile_helper.c b/tests/sys/common/sendfile_helper.c new file mode 100644 index 000000000000..c92a194bff2d --- /dev/null +++ b/tests/sys/common/sendfile_helper.c @@ -0,0 +1,177 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Netflix, Inc. + * + * 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. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char buf[1024*1024]; +static ssize_t readlen; +static volatile bool read_done = false; + +static int +tcp_socketpair(int *sv) +{ + struct sockaddr_in sin = { + .sin_len = sizeof(struct sockaddr_in), + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + int flags; + int ls; + + ls = socket(PF_INET, SOCK_STREAM, 0); + if (ls < 0) + err(1, "socket ls"); + + if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &(socklen_t){1}, + sizeof(int)) < 0) + err(1, "SO_REUSEADDR"); + + if (bind(ls, (struct sockaddr *)&sin, sizeof(sin)) < 0) + err(1, "bind ls"); + + if (getsockname(ls, (struct sockaddr *)&sin, + &(socklen_t){ sizeof(sin) }) < 0) + err(1, "getsockname"); + + if (listen(ls, 5) < 0) + err(1, "listen ls"); + + sv[0] = socket(PF_INET, SOCK_STREAM, 0); + if (sv[0] < 0) + err(1, "socket cs"); + + flags = fcntl(sv[0], F_GETFL); + flags |= O_NONBLOCK; + if (fcntl(sv[0], F_SETFL, flags) == -1) + err(1, "fcntl +O_NONBLOCK"); + + if (connect(sv[0], (void *)&sin, sizeof(sin)) == -1 && + errno != EINPROGRESS) + err(1, "connect cs"); + + sv[1] = accept(ls, NULL, 0); + if (sv[1] < 0) + err(1, "accept ls"); + + flags &= ~O_NONBLOCK; + if (fcntl(sv[0], F_SETFL, flags) == -1) + err(1, "fcntl -O_NONBLOCK"); + + close(ls); + + return (0); +} + +static void * +receiver(void *arg) +{ + int s = *(int *)arg; + ssize_t rv; + + do { + rv = read(s, buf, sizeof(buf)); + if (rv == -1) + err(2, "read receiver"); + if (rv == 0) + break; + readlen -= rv; + } while (readlen != 0); + + read_done = true; + + return NULL; +} + +static void +usage(void) +{ + errx(1, "usage: %s [-u] ", getprogname()); +} + +int +main(int argc, char **argv) +{ + pthread_t pt; + off_t start; + int ch, fd, ss[2], flags, error; + bool pf_unix = false; + + while ((ch = getopt(argc, argv, "u")) != -1) + switch (ch) { + case 'u': + pf_unix = true; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 4) + usage(); + + start = strtoull(argv[1], NULL, 0); + readlen = strtoull(argv[2], NULL, 0); + flags = strtoul(argv[3], NULL, 0); + + fd = open(argv[0], O_RDONLY); + if (fd < 0) + err(1, "open"); + + if (pf_unix) { + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, ss) != 0) + err(1, "socketpair"); + } else + tcp_socketpair(ss); + + error = pthread_create(&pt, NULL, receiver, &ss[1]); + if (error) + errc(1, error, "pthread_create"); + + if (sendfile(fd, ss[0], start, readlen, NULL, NULL, flags) < 0) + err(3, "sendfile"); + + while (!read_done) + usleep(1000); + + exit(0); +} diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index f7e06968520a..f7f5d1825e01 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -92,7 +92,6 @@ ${PACKAGE}FILESMODE_sonewconn_overflow.py=0555 BINDIR= ${TESTSDIR} PROGS+= coredump_phnum_helper PROGS+= pdeathsig_helper -PROGS+= sendfile_helper CFLAGS.aslr+= -I${SRCTOP}/tests LIBADD.aslr+= util @@ -116,7 +115,6 @@ LIBADD.procdesc+= kvm pthread LIBADD.shutdown_dgram+= pthread LIBADD.socket_msg_waitall+= pthread LIBADD.socket_splice+= pthread -LIBADD.sendfile_helper+= pthread LIBADD.fdgrowtable_test+= util pthread kvm procstat LIBADD.sigwait+= rt LIBADD.ktrace_test+= sysdecode diff --git a/tests/sys/kern/sendfile_helper.c b/tests/sys/kern/sendfile_helper.c deleted file mode 100644 index 6365531e312c..000000000000 --- a/tests/sys/kern/sendfile_helper.c +++ /dev/null @@ -1,177 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2020 Netflix, Inc. - * - * 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. - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char buf[1024*1024]; -ssize_t readlen; -static volatile bool read_done = false; - -static int -tcp_socketpair(int *sv) -{ - struct sockaddr_in sin = { - .sin_len = sizeof(struct sockaddr_in), - .sin_family = AF_INET, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; - int flags; - int ls; - - ls = socket(PF_INET, SOCK_STREAM, 0); - if (ls < 0) - err(1, "socket ls"); - - if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &(socklen_t){1}, - sizeof(int)) < 0) - err(1, "SO_REUSEADDR"); - - if (bind(ls, (struct sockaddr *)&sin, sizeof(sin)) < 0) - err(1, "bind ls"); - - if (getsockname(ls, (struct sockaddr *)&sin, - &(socklen_t){ sizeof(sin) }) < 0) - err(1, "getsockname"); - - if (listen(ls, 5) < 0) - err(1, "listen ls"); - - sv[0] = socket(PF_INET, SOCK_STREAM, 0); - if (sv[0] < 0) - err(1, "socket cs"); - - flags = fcntl(sv[0], F_GETFL); - flags |= O_NONBLOCK; - if (fcntl(sv[0], F_SETFL, flags) == -1) - err(1, "fcntl +O_NONBLOCK"); - - if (connect(sv[0], (void *)&sin, sizeof(sin)) == -1 && - errno != EINPROGRESS) - err(1, "connect cs"); - - sv[1] = accept(ls, NULL, 0); - if (sv[1] < 0) - err(1, "accept ls"); - - flags &= ~O_NONBLOCK; - if (fcntl(sv[0], F_SETFL, flags) == -1) - err(1, "fcntl -O_NONBLOCK"); - - close(ls); - - return (0); -} - -static void * -receiver(void *arg) -{ - int s = *(int *)arg; - ssize_t rv; - - do { - rv = read(s, buf, sizeof(buf)); - if (rv == -1) - err(2, "read receiver"); - if (rv == 0) - break; - readlen -= rv; - } while (readlen != 0); - - read_done = true; - - return NULL; -} - -static void -usage(void) -{ - errx(1, "usage: %s [-u] ", getprogname()); -} - -int -main(int argc, char **argv) -{ - pthread_t pt; - off_t start; - int ch, fd, ss[2], flags, error; - bool pf_unix = false; - - while ((ch = getopt(argc, argv, "u")) != -1) - switch (ch) { - case 'u': - pf_unix = true; - break; - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc != 4) - usage(); - - start = strtoull(argv[1], NULL, 0); - readlen = strtoull(argv[2], NULL, 0); - flags = strtoul(argv[3], NULL, 0); - - fd = open(argv[0], O_RDONLY); - if (fd < 0) - err(1, "open"); - - if (pf_unix) { - if (socketpair(PF_LOCAL, SOCK_STREAM, 0, ss) != 0) - err(1, "socketpair"); - } else - tcp_socketpair(ss); - - error = pthread_create(&pt, NULL, receiver, &ss[1]); - if (error) - errc(1, error, "pthread_create"); - - if (sendfile(fd, ss[0], start, readlen, NULL, NULL, flags) < 0) - err(3, "sendfile"); - - while (!read_done) - usleep(1000); - - exit(0); -} diff --git a/tests/sys/kern/sendfile_test.sh b/tests/sys/kern/sendfile_test.sh index 7e549eec610a..b2e329126d85 100755 --- a/tests/sys/kern/sendfile_test.sh +++ b/tests/sys/kern/sendfile_test.sh @@ -38,7 +38,7 @@ MD_DEVS="md.devs" MNT=mnt FILE=$MNT/file -HELPER="$(atf_get_srcdir)/sendfile_helper" +HELPER="$(atf_get_srcdir)/../common/sendfile_helper" BSIZE=4096 atf_test_case io_success cleanup -- cgit v1.3