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
This commit is contained in:
Kyle Evans 2024-03-04 22:14:07 -06:00
parent 02c57f7b48
commit 47ad4f2d45
4 changed files with 9 additions and 5 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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 */