git: 160788caa3c9 - stable/14 - ktrace: log genio events on failed write

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Mon, 18 Mar 2024 15:53:22 UTC
The branch stable/14 has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=160788caa3c9cac5f21d70962ce330e18a4fe9d5

commit 160788caa3c9cac5f21d70962ce330e18a4fe9d5
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-03-05 04:14:07 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-03-18 15:52:58 +0000

    ktrace: log genio events on failed write
    
    Visibility into the contents of the buffer when a write(2) has failed
    can be immensely useful in debugging IPC issues -- pushing this to
    discuss the idea, or maybe an alternative where we can set a flag like
    KTRFAC_ERRIO to enable it.
    
    When a genio event is potentially raised after an error, currently we'll
    just free the uio and return.  However, such data can be useful when
    debugging communication between processes to, e.g., understand what the
    remote side should have grabbed before closing a pipe.  Tap out the
    entire buffer on failure rather than simply discarding it.
    
    Reviewed by:    kib, markj
    
    (cherry picked from commit 47ad4f2d45e406c6316909bc12bc760b2fdd6afb)
---
 sys/kern/kern_ktrace.c      | 2 +-
 sys/kern/sys_generic.c      | 3 ++-
 sys/kern/uipc_syscalls.c    | 3 ++-
 sys/netinet/sctp_syscalls.c | 6 ++++--
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 75b81457402b..4c1936edc301 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -769,7 +769,7 @@ ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
 	int datalen;
 	char *buf;
 
-	if (error) {
+	if (error != 0 && (rw == UIO_READ || error == EFAULT)) {
 		freeuio(uio);
 		return;
 	}
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index d0d0b1efa354..f3fd39079a82 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -579,7 +579,8 @@ dofilewrite(struct thread *td, int fd, struct file *fp, struct uio *auio,
 	cnt -= auio->uio_resid;
 #ifdef KTRACE
 	if (ktruio != NULL) {
-		ktruio->uio_resid = cnt;
+		if (error == 0)
+			ktruio->uio_resid = cnt;
 		ktrgenio(fd, UIO_WRITE, ktruio, error);
 	}
 #endif
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index c7c2e6544902..85b2214eaeb9 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -791,7 +791,8 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
 		td->td_retval[0] = len - auio.uio_resid;
 #ifdef KTRACE
 	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
+		if (error == 0)
+			ktruio->uio_resid = td->td_retval[0];
 		ktrgenio(s, UIO_WRITE, ktruio, error);
 	}
 #endif
diff --git a/sys/netinet/sctp_syscalls.c b/sys/netinet/sctp_syscalls.c
index a5e4fa8f9603..d67e260b6f99 100644
--- a/sys/netinet/sctp_syscalls.c
+++ b/sys/netinet/sctp_syscalls.c
@@ -290,7 +290,8 @@ sys_sctp_generic_sendmsg(struct thread *td, struct sctp_generic_sendmsg_args *ua
 		td->td_retval[0] = len - auio.uio_resid;
 #ifdef KTRACE
 	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
+		if (error == 0)
+			ktruio->uio_resid = td->td_retval[0];
 		ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
 	}
 #endif /* KTRACE */
@@ -404,7 +405,8 @@ sys_sctp_generic_sendmsg_iov(struct thread *td, struct sctp_generic_sendmsg_iov_
 		td->td_retval[0] = len - auio.uio_resid;
 #ifdef KTRACE
 	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
+		if (error == 0)
+			ktruio->uio_resid = td->td_retval[0];
 		ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
 	}
 #endif /* KTRACE */