Skip to content

Commit

Permalink
dmesg: detect wrapped msgbuf on the kernel side and if so, skip first…
Browse files Browse the repository at this point in the history
… line

Since 59f256e 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.
  • Loading branch information
glebius committed Feb 5, 2022
1 parent 6598559 commit c999e34
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
4 changes: 0 additions & 4 deletions sbin/dmesg/dmesg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
23 changes: 20 additions & 3 deletions sys/kern/subr_prf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);

Expand Down

0 comments on commit c999e34

Please sign in to comment.