casaroli opened a new pull request, #21768: URL: https://github.com/apache/nuttx/pull/21768
depends-on: apache/nuttx/pull/21614 depends-on: apache/nuttx/pull/21767 depends-on: apache/nuttx/pull/21737 ## Summary A datagram of a socket pair now goes into the FIFO as one atomic frame (`local_send_frame()`, `PIPEIOC_ATOMICWRITE`, from 6b50d0c8de4), and a stream send that waits now ends at a signal. This PR builds on #21614 and on #21767 (its first two commits are those of #21767 until it merges). Its own commits: - net/local: Send a datagram of a socket pair as one frame. `local_pair_send()` (#21614) wrote the header and the data with two writes. A reader with `O_NONBLOCK` could get the header before the data, and then lost the boundaries of the next datagrams; a blocking send waited inside the datagram, so a signal could not end it. Now `local_socketpair()` puts the two datagram FIFOs in the atomic mode, and `local_pair_send()` sends with `local_send_frame()`, which gets the address of the sender as an argument (`""` for a pair, so `recvfrom()` gives no address, as before). The FIFO does not see `MSG_DONTWAIT`, so for this flag `local_pair_send()` still checks the space first. - net/local: Let a signal end a blocked send() of a stream socket. `local_fifo_write()` wrote again after `-EINTR` and after a short write, so a signal did not end `send()` or `write()` of a stream socket that waits for space. Now `local_send_packet()` calls `file_write()` once per segment and stops at an error or a short write: `-EINTR` before the first byte, else the bytes sent (POSIX). `local_fifo_write()` is removed. The datagram cases of signals during a send need no new pipe ioctl: the atomic frame waits for space for the whole frame before it copies, and a signal ends that wait with `EINTR`. ## Impact Local sockets only. The same code in flat, protected and kernel builds; no architecture code. What a program sees: - `send()`, `sendto()`, `sendmsg()` and `write()` of a datagram socket pair: a datagram goes whole or not at all, also for a reader with `O_NONBLOCK`; a signal ends a send that waits for space with `EINTR` (before, the send went on). - `send()` and `write()` of a stream socket that waits for space end at a signal: `EINTR` before any data, else the number of bytes sent. Also in a flat build (before, the call went on), and also with `SA_RESTART`, which NuttX does not implement. A signal whose default action ends the process now ends a process that waits in such a send. - Documentation: no page describes Unix domain sockets or the pipe ioctls; no change. ## Testing Tests: 8 new cases in `cmocka_net_local_dgram` (they follow in a nuttx-apps PR, on apache/nuttx-apps#4003): `poll_full`, `poll_fullwait`, `send_intr`, `pair_intr`, `stream_send_intr` (sends that wait for space; a signal during the wait), `pair_iov`, `send_iov` (`sendmsg()` of one datagram in 12 parts, two of them empty, on a pair and to a bound socket), `pair_whole` (a reader with `O_NONBLOCK` reads a full pair with no pause while a send waits in another thread: each datagram must come whole). All 8 pass on Linux (7.0, arm64 container, host libc). Also the programs of #21614: `dgramabs`, `listenclose`, `peercred`, `dgrampair`, `sockintr` (signals, each case in a child) and `dgramconn`. qemu-armv8a (arm64, HVF, 1 CPU), make, apps #4003 with the apps PR, each case alone (`cmocka_net_local_dgram <dir> <case>`), a boot ends at a crash or a hang. knsh: kernel build, programs from `/system/bin`; nsh: flat build, builtins. Options: `NET`, `NET_IPv4`, `NET_LOOPBACK`, `NET_TCP`, `NET_UDP`, `NET_SOCKOPTS`, `NET_LOCAL` with stream, datagram and SCM, `PIPES`, `FS_TMPFS`, `DEBUG_ASSERTIONS`, `SIG_DEFAULT`, `SCHED_WAITPID`. | | #21614 (5eb6d40e7f8, on master 36cdd5ac3af) | this PR (with #21767) | |---|---|---| | `cmocka_net_local_dgram`, knsh and nsh | 87 of 91 PASS; FAIL: `pair_intr`, `stream_send_intr` (the send returns 100 after the reader made space, not -1 `EINTR`), `send_iov` (`EMSGSIZE`), `pair_whole` (the reader gets a header without its data, then only -1 `EAGAIN`) | 91 PASS | | `cmocka_net_local` | knsh 6 PASS, nsh 4 PASS | knsh 6 PASS, nsh 4 PASS | | `sockintr` (19 cases) | knsh: 9 PASS, `stream-sendfull`, `stream-sendpart` FAIL, then `stream-sendterm` hangs (`SIGTERM` does not end the process); nsh: 13 PASS, 6 FAIL (`stream-sendfull`, `stream-sendpart`, `dgram-sendclose`, `dgram-sendfull` and the 2 `SA_RESTART` cases) | knsh and nsh: 17 PASS; the 2 `SA_RESTART` cases FAIL (NuttX has no `SA_RESTART`, also on #21614) | | `dgrampair`, `dgramconn`, `listenclose`, `peercred` (knsh) | 18, 21, 3, 5 PASS | 18, 21, 3, 5 PASS | | `dgramabs` | knsh 11 PASS; nsh 10 PASS, `recvtcplong` FAIL (TCP, also on master) | the same | | ostest, knsh and nsh | status 0 | status 0 | `pair_iov` passes on #21614 too (it wrote the parts one by one); it covers the new copy path of `local_send_frame()`. Builds with `EXTRAFLAGS="-Wno-cpp -Werror"`, with `NET`, `NET_LOCAL`, `NETDEV_LATEINIT`, `NET_SOCKOPTS`, `PIPES`: qemu-armv8a:nsh (flat) with stream, datagram and `NET_LOCAL_SCM`, with datagram only and with stream only; mps2-an500:knsh (protected, armv7-m) and rv-virt:knsh64 (kernel, riscv64), each with stream, datagram and `NET_LOCAL_SCM`: all OK, no warning. Compilers: aarch64-none-elf GCC 14.2, arm-none-eabi GCC 15.3, riscv-none-elf GCC 14.3. Kconfig: qemu-armv8a:nsh with `NET_LOCAL_DGRAM` and `SERIAL` off has no `FS_UIO` on #21614, and `FS_UIO=y` with this PR. `tools/checkpatch.sh -c -u -m -g` passes. Not run: CMake builds, sim, other compilers than GCC. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
