git: 47ad4f2d45e4 - main - ktrace: log genio events on failed write

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Tue, 05 Mar 2024 05:44:17 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=47ad4f2d45e406c6316909bc12bc760b2fdd6afb

commit 47ad4f2d45e406c6316909bc12bc760b2fdd6afb
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-03-05 04:14:07 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-03-05 05:44:09 +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
    Differential Revision:  https://reviews.freebsd.org/D43799
---
 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 877a25ffa4cd..6ace3ea52c64 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -767,7 +767,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 f6190c3fb05f..b926f98892a5 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -577,7 +577,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 dce0ab9b53d4..b2d03d932b99 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -772,7 +772,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 */