git: c999e3481d93 - main - dmesg: detect wrapped msgbuf on the kernel side and if so, skip first line
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 05 Feb 2022 21:35:39 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=c999e3481d936980354d09e3d6a138e5dde5fabc commit c999e3481d936980354d09e3d6a138e5dde5fabc Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2022-02-05 21:25:38 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2022-02-05 21:35:31 +0000 dmesg: detect wrapped msgbuf on the kernel side and if so, skip first line Since 59f256ec35d3 dmesg(8) will always skip first line of the message buffer, cause it might be incomplete. The problem is that in most cases it is complete, valid and contains the "---<<BOOT>>---" marker. This skip can be disabled with '-a', but that would also unhide all non-kernel messages. Move this functionality from dmesg(8) to kernel, since kernel actually knows if wrap has happened or not. The main motivation for the change is not actually the value of the "---<<BOOT>>---" marker. The problem breaks unit tests, that clear message buffer, perform a test and then check the message buffer for a result. Example of such test is sys/kern/sonewconn_overflow. --- sbin/dmesg/dmesg.c | 4 ---- sys/kern/subr_prf.c | 23 ++++++++++++++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/sbin/dmesg/dmesg.c b/sbin/dmesg/dmesg.c index 469582204f7b..f266e6b98b39 100644 --- a/sbin/dmesg/dmesg.c +++ b/sbin/dmesg/dmesg.c @@ -184,10 +184,6 @@ main(int argc, char *argv[]) /* Strip leading \0's */ while (*p == '\0') p++; - } else if (!all) { - /* Skip the first line, since it is probably incomplete. */ - p = memchr(p, '\n', ep - p); - p++; } for (; p < ep; p = nextp) { nextp = memchr(p, '\n', ep - p); diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 1106587ebbe7..62a0bd0a3699 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -1058,9 +1058,10 @@ msgbufinit(void *ptr, int size) static int sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) { - char buf[128]; + char buf[128], *bp; u_int seq; int error, len; + bool wrap; error = priv_check(req->td, PRIV_MSGBUF); if (error) @@ -1069,13 +1070,29 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) /* Read the whole buffer, one chunk at a time. */ mtx_lock(&msgbuf_lock); msgbuf_peekbytes(msgbufp, NULL, 0, &seq); + wrap = (seq != 0); for (;;) { len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq); mtx_unlock(&msgbuf_lock); if (len == 0) return (SYSCTL_OUT(req, "", 1)); /* add nulterm */ - - error = sysctl_handle_opaque(oidp, buf, len, req); + if (wrap) { + /* Skip the first line, as it is probably incomplete. */ + bp = memchr(buf, '\n', len); + if (bp == NULL) { + mtx_lock(&msgbuf_lock); + continue; + } + wrap = false; + bp++; + len -= bp - buf; + if (len == 0) { + mtx_lock(&msgbuf_lock); + continue; + } + } else + bp = buf; + error = sysctl_handle_opaque(oidp, bp, len, req); if (error) return (error);