Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src Pull up following revision(s) (requested by thorpej in ti...



details:   https://anonhg.NetBSD.org/src/rev/2be32c811df5
branches:  netbsd-9
changeset: 988218:2be32c811df5
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Oct 04 14:32:38 2021 +0000

description:
Pull up following revision(s) (requested by thorpej in ticket #1351):

        sys/miscfs/fifofs/fifo_vnops.c: revision 1.88
        sys/kern/uipc_syscalls.c: revision 1.201
        tests/lib/libc/sys/t_poll.c: revision 1.6
        tests/lib/libc/sys/t_poll.c: revision 1.7
        tests/lib/libc/sys/t_poll.c: revision 1.8

- Strenghen the poll(2) fifo_inout test to ensure that once the reader
has read enough that exactly PIPE_BUF space is available that the FIFO
becomes writable again.
- When creating a FIFO, ensure that the receive low water mark is 1
(a FIFO must be readable when at least 1 byte is available); this
was already the case implicitly, but this makes it explicit.
- Similarly, set the send low water mark to PIPE_BUF to ensure that
the pipe is writable when at least PIPE_BUF bytes of space are available
in the send buffer.  Without this change, the strengthened test case
above does not pass (the default send low water mark is larger than
PIPE_BUF; see soreserve()).
- Make the same low water mark changes to the PIPE_SOCKETPAIR case.

In the fifo_hup1 test, also ensure that POLLHUP is de-asserted when a
new writer appears.

Add a fifo_inout test case that validates the expected POLLIN / POLLOUT
behavior for FIFOs:
- A FIFO is readable so long as at least 1 byte is available.
- A FIFO is writable so long as at least PIPE_BUF (obtained with _PC_PIPE_BUF)
  space is avaiable.
This will be cloned for a forthcoming kevent test case.

diffstat:

 sys/kern/uipc_syscalls.c       |   19 +++++-
 sys/miscfs/fifofs/fifo_vnops.c |   21 ++++++-
 tests/lib/libc/sys/t_poll.c    |  123 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 158 insertions(+), 5 deletions(-)

diffs (240 lines):

diff -r bc823478c613 -r 2be32c811df5 sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c  Sat Oct 02 11:08:51 2021 +0000
+++ b/sys/kern/uipc_syscalls.c  Mon Oct 04 14:32:38 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_syscalls.c,v 1.199 2018/11/12 09:21:13 hannken Exp $      */
+/*     $NetBSD: uipc_syscalls.c,v 1.199.4.1 2021/10/04 14:32:38 martin Exp $   */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.199 2018/11/12 09:21:13 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.199.4.1 2021/10/04 14:32:38 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pipe.h"
@@ -1319,6 +1319,21 @@
        wf->f_socket = wso;
        fildes[1] = fd;
        solock(wso);
+       /*
+        * Pipes must be readable when there is at least 1
+        * byte of data available in the receive buffer.
+        *
+        * Pipes must be writable when there is space for
+        * at least PIPE_BUF bytes in the send buffer.
+        * If we're increasing the low water mark for the
+        * send buffer, then mimick how soreserve() would
+        * have set the high water mark.
+        */
+       rso->so_rcv.sb_lowat = 1;
+       if (wso->so_snd.sb_lowat < PIPE_BUF) {
+               wso->so_snd.sb_hiwat = PIPE_BUF * 2;
+       }
+       wso->so_snd.sb_lowat = PIPE_BUF;
        error = unp_connect2(wso, rso);
        sounlock(wso);
        if (error != 0)
diff -r bc823478c613 -r 2be32c811df5 sys/miscfs/fifofs/fifo_vnops.c
--- a/sys/miscfs/fifofs/fifo_vnops.c    Sat Oct 02 11:08:51 2021 +0000
+++ b/sys/miscfs/fifofs/fifo_vnops.c    Mon Oct 04 14:32:38 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fifo_vnops.c,v 1.79.8.1 2021/10/02 11:07:55 martin Exp $       */
+/*     $NetBSD: fifo_vnops.c,v 1.79.8.2 2021/10/04 14:32:38 martin Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.79.8.1 2021/10/02 11:07:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.79.8.2 2021/10/04 14:32:38 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -156,6 +156,23 @@
                        kmem_free(fip, sizeof(*fip));
                        return (error);
                }
+
+               /*
+                * FIFOs must be readable when there is at least 1
+                * byte of data available in the receive buffer.
+                *
+                * FIFOs must be writable when there is space for
+                * at least PIPE_BUF bytes in the send buffer.
+                * If we're increasing the low water mark for the
+                * send buffer, then mimick how soreserve() would
+                * have set the high water mark.
+                */
+               rso->so_rcv.sb_lowat = 1;
+               if (wso->so_snd.sb_lowat < PIPE_BUF) {
+                       wso->so_snd.sb_hiwat = PIPE_BUF * 2;
+               }
+               wso->so_snd.sb_lowat = PIPE_BUF;
+
                fip->fi_readers = 0;
                fip->fi_writers = 0;
                wso->so_state |= SS_CANTRCVMORE;
diff -r bc823478c613 -r 2be32c811df5 tests/lib/libc/sys/t_poll.c
--- a/tests/lib/libc/sys/t_poll.c       Sat Oct 02 11:08:51 2021 +0000
+++ b/tests/lib/libc/sys/t_poll.c       Mon Oct 04 14:32:38 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: t_poll.c,v 1.3.34.1 2021/10/02 11:07:55 martin Exp $   */
+/*     $NetBSD: t_poll.c,v 1.3.34.2 2021/10/04 14:32:38 martin Exp $   */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -39,6 +39,7 @@
 #include <paths.h>
 #include <poll.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
 
@@ -397,6 +398,113 @@
        }
 }
 
+ATF_TC_WITH_CLEANUP(fifo_inout);
+ATF_TC_HEAD(fifo_inout, tc)
+{
+       atf_tc_set_md_var(tc, "descr",
+           "Check POLLIN/POLLOUT behavior with fifos");
+}
+
+ATF_TC_BODY(fifo_inout, tc)
+{
+       struct pollfd pfd[2];
+       char *buf;
+       int rfd, wfd;
+       long pipe_buf;
+
+       fifo_support();
+
+       ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0);
+       ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0);
+       ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY | O_NONBLOCK)) >= 0);
+
+       /* Get the maximum atomic pipe write size. */
+       pipe_buf = fpathconf(wfd, _PC_PIPE_BUF);
+       ATF_REQUIRE(pipe_buf > 1);
+
+       buf = malloc(pipe_buf);
+       ATF_REQUIRE(buf != NULL);
+
+       memset(&pfd, 0, sizeof(pfd));
+       pfd[0].fd = rfd;
+       pfd[0].events = POLLIN | POLLRDNORM;
+       pfd[1].fd = wfd;
+       pfd[1].events = POLLOUT | POLLWRNORM;
+
+       /* We expect the FIFO to be writable but not readable. */
+       ATF_REQUIRE(poll(pfd, 2, 0) == 1);
+       ATF_REQUIRE(pfd[0].revents == 0);
+       ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
+
+       /* Write a single byte of data into the FIFO. */
+       ATF_REQUIRE(write(wfd, buf, 1) == 1);
+
+       /* We expect the FIFO to be readable and writable. */
+       ATF_REQUIRE(poll(pfd, 2, 0) == 2);
+       ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
+       ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
+
+       /* Read that single byte back out. */
+       ATF_REQUIRE(read(rfd, buf, 1) == 1);
+
+       /*
+        * Write data into the FIFO until it is full, which is
+        * defined as insufficient buffer space to hold a the
+        * maximum atomic pipe write size.
+        */
+       while (write(wfd, buf, pipe_buf) != -1) {
+               continue;
+       }
+       ATF_REQUIRE(errno == EAGAIN);
+
+       /* We expect the FIFO to be readble but not writable. */
+       ATF_REQUIRE(poll(pfd, 2, 0) == 1);
+       ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
+       ATF_REQUIRE(pfd[1].revents == 0);
+
+       /* Read a single byte of data from the FIFO. */
+       ATF_REQUIRE(read(rfd, buf, 1) == 1);
+
+       /*
+        * Because we have read only a single byte out, there will
+        * be insufficient space for a pipe_buf-sized message, so
+        * the FIFO should still not be writable.
+        */
+       ATF_REQUIRE(poll(pfd, 2, 0) == 1);
+       ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
+       ATF_REQUIRE(pfd[1].revents == 0);
+
+       /*
+        * Now read enough so that exactly pipe_buf space should
+        * be available.  The FIFO should be writable after that.
+        * N.B. we don't care if it's readable at this point.
+        */
+       ATF_REQUIRE(read(rfd, buf, pipe_buf - 1) == pipe_buf - 1);
+       ATF_REQUIRE(poll(pfd, 2, 0) >= 1);
+       ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
+
+       /*
+        * Now read all of the data out of the FIFO and ensure that
+        * we get back to the initial state.
+        */
+       while (read(rfd, buf, pipe_buf) != -1) {
+               continue;
+       }
+       ATF_REQUIRE(errno == EAGAIN);
+
+       ATF_REQUIRE(poll(pfd, 2, 0) == 1);
+       ATF_REQUIRE(pfd[0].revents == 0);
+       ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
+
+       (void)close(wfd);
+       (void)close(rfd);
+}
+
+ATF_TC_CLEANUP(fifo_inout, tc)
+{
+       (void)unlink(fifo_path);
+}
+
 ATF_TC_WITH_CLEANUP(fifo_hup1);
 ATF_TC_HEAD(fifo_hup1, tc)
 {
@@ -423,6 +531,18 @@
 
        ATF_REQUIRE(poll(&pfd, 1, 0) == 1);
        ATF_REQUIRE((pfd.revents & POLLHUP) != 0);
+
+       /*
+        * Check that POLLHUP is cleared when a writer re-connects.
+        * Since the writer will not put any data into the FIFO, we
+        * expect no events.
+        */
+       memset(&pfd, 0, sizeof(pfd));
+       pfd.fd = rfd;
+       pfd.events = POLLIN;
+
+       ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0);
+       ATF_REQUIRE(poll(&pfd, 1, 0) == 0);
 }
 
 ATF_TC_CLEANUP(fifo_hup1, tc)
@@ -490,6 +610,7 @@
        ATF_TP_ADD_TC(tp, pollts_err);
        ATF_TP_ADD_TC(tp, pollts_sigmask);
 
+       ATF_TP_ADD_TC(tp, fifo_inout);
        ATF_TP_ADD_TC(tp, fifo_hup1);
        ATF_TP_ADD_TC(tp, fifo_hup2);
 



Home | Main Index | Thread Index | Old Index