Every existing splice call in this file either passes SPLICE_F_NONBLOCK or runs on a blocking socket, so nothing exercises the socket's own O_NONBLOCK on the splice path. A change that stops consulting sock->file->f_flags puts splice(2) and sendfile(2) back to sleeping in tls_rx_rec_wait() while a peer streams empty records, and the suite still reports pass.
Run the zero-length record variants a second time with O_NONBLOCK set on the socket and SPLICE_F_NONBLOCK left out of the splice flags. Each variant expects the same result with either flag. A kernel that ignores the socket flag sleeps in the EAGAIN variant until the harness timeout rather than returning. Signed-off-by: Chuck Lever <[email protected]> --- tools/testing/selftests/net/tls.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c index aa66d0bbd1b5..cdd53b8f0ed8 100644 --- a/tools/testing/selftests/net/tls.c +++ b/tools/testing/selftests/net/tls.c @@ -2829,7 +2829,11 @@ FIXTURE_TEARDOWN(zero_len_splice) * EAGAIN for a run with no payload behind it, and EINVAL for a control * record behind the run. */ -TEST_F(zero_len_splice, test) +static void +zero_len_do_splice(struct __test_metadata *_metadata, + FIXTURE_DATA(zero_len_splice) *self, + const FIXTURE_VARIANT(zero_len_splice) *variant, + unsigned int splice_flags) { struct pollfd pfd = { .fd = self->cfd, .events = POLLIN }; const struct raw_rec *payload; @@ -2837,16 +2841,13 @@ TEST_F(zero_len_splice, test) ssize_t ret; int p[2]; - if (self->notls) - SKIP(return, "no TLS support"); - ASSERT_GE(pipe(p), 0); payload = zero_len_send_recs(_metadata, self->fd, variant->recs); if (variant->splice_ret < 0) { ret = splice(self->cfd, NULL, p[1], NULL, sizeof(buf), - SPLICE_F_NONBLOCK); + splice_flags); EXPECT_EQ(ret, -1); EXPECT_EQ(errno, -variant->splice_ret); } else { @@ -2854,7 +2855,7 @@ TEST_F(zero_len_splice, test) * below blocks until the harness timeout. */ ASSERT_EQ(splice(self->cfd, NULL, p[1], NULL, sizeof(buf), - SPLICE_F_NONBLOCK), variant->splice_ret); + splice_flags), variant->splice_ret); ret = read(p[0], buf, sizeof(buf)); EXPECT_EQ(ret, variant->splice_ret); if (ret == variant->splice_ret) @@ -2869,6 +2870,31 @@ TEST_F(zero_len_splice, test) close(p[1]); } +TEST_F(zero_len_splice, test) +{ + if (self->notls) + SKIP(return, "no TLS support"); + + zero_len_do_splice(_metadata, self, variant, SPLICE_F_NONBLOCK); +} + +/* The socket's O_NONBLOCK governs the record wait, as on a plain TCP + * socket, so splice behaves the same with or without SPLICE_F_NONBLOCK. + */ +TEST_F(zero_len_splice, nonblock_socket) +{ + int sflags; + + if (self->notls) + SKIP(return, "no TLS support"); + + sflags = fcntl(self->cfd, F_GETFL, 0); + ASSERT_GE(sflags, 0); + ASSERT_EQ(fcntl(self->cfd, F_SETFL, sflags | O_NONBLOCK), 0); + + zero_len_do_splice(_metadata, self, variant, 0); +} + FIXTURE(tls_err) { int fd, cfd; -- 2.55.0
