From 5608ef175917eaf5aa7542d9f872baca87d94a1c Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 2 Mar 2015 17:55:51 -0800 Subject: [PATCH 1/1] kernel - Refactor the kernel message buffer code * Add a separate tracking index for /dev/klog (syslog) so it does not eat the base index for the in-memory buffer. * Change the way the FIFO indexes work. The indexes are no longer stored as modulo size values. Instead they are simply adjusted without a modulo, making calculations easier. * When the FIFO is full we now add around ~1KB of slop to reduce instances where SMP collisions implode the buffer. This also required adjusting the kern.msgbuf sysctl to avoid dumping the 'slop' area (it used to just dump the entire buffer). * Adjust dmesg to operate more consistently, and to modulo the indices when making calculations. * The dmesg -a option now dumps the prefix for syslog / console output messages. Before it tried to strip them out, which created problems in distinguishing kprintf()d output from syslog output. * Adjust the console tty support thread (which copies the dmesg buffer to the console) as well as /dev/klog to use the new index methodology. * It is now possible for the indexes to wrap the buffer multiple times (between e.g. bufl and bufx), and it obviously makes no sense to try to dump the overwritten data over and over again, so if indexes get totally out of whack we reset bufr and bufl as needed to the size of the buffer. --- sbin/dmesg/dmesg.c | 58 +++++--- sys/kern/subr_log.c | 106 ++++++++++----- sys/kern/subr_prf.c | 166 ++++++++++++++++------- sys/platform/vkernel/i386/cpu_regs.c | 46 ------- sys/platform/vkernel64/x86_64/cpu_regs.c | 46 ------- sys/sys/msgbuf.h | 15 +- 6 files changed, 240 insertions(+), 197 deletions(-) diff --git a/sbin/dmesg/dmesg.c b/sbin/dmesg/dmesg.c index 1b12d9cbf0..e3312b3855 100644 --- a/sbin/dmesg/dmesg.c +++ b/sbin/dmesg/dmesg.c @@ -74,7 +74,6 @@ main(int argc, char **argv) int pri = 0; int tailmode = 0; int kno; - unsigned int rindex; size_t buflen, bufpos; setlocale(LC_CTYPE, ""); @@ -115,9 +114,9 @@ main(int argc, char **argv) if (memf == NULL && nlistf == NULL && tailmode == 0) { /* Running kernel. Use sysctl. */ + buflen = 0; if (sysctlbyname("kern.msgbuf", NULL, &buflen, NULL, 0) == -1) err(1, "sysctl kern.msgbuf"); - buflen += 4096; /* add some slop */ if ((bp = malloc(buflen)) == NULL) errx(1, "malloc failed"); if (sysctlbyname("kern.msgbuf", bp, &buflen, NULL, 0) == -1) @@ -126,6 +125,12 @@ main(int argc, char **argv) bufpos = 0; dumpbuf(bp, bufpos, buflen, &newl, &skip, &pri); } else { + u_int rindex; + u_int xindex; + u_int ri; + u_int xi; + u_int n; + /* Read in kernel message buffer, do sanity checks. */ kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg"); if (kd == NULL) @@ -142,38 +147,51 @@ main(int argc, char **argv) errx(1, "kvm_read: %s", kvm_geterr(kd)); if (KREAD((long)bufp, cur)) errx(1, "kvm_read: %s", kvm_geterr(kd)); - if (cur.msg_magic != MSG_MAGIC) + if (cur.msg_magic != MSG_MAGIC && cur.msg_magic != MSG_OMAGIC) errx(1, "kernel message buffer has different magic " "number"); /* - * Start point. Use rindex == bufx as our end-of-buffer - * indication but for the initial rindex from the kernel - * this means the buffer has cycled and is 100% full. + * NOTE: current algorithm is compatible with both old and + * new msgbuf structures. The new structure doesn't + * modulo the indexes (so we do), and adds a separate + * log index which we don't access here. */ + rindex = cur.msg_bufr; - if (rindex == cur.msg_bufx) { - if (++rindex >= cur.msg_size) - rindex = 0; - } for (;;) { - if (cur.msg_bufx >= rindex) - buflen = cur.msg_bufx - rindex; + /* + * Calculate index for dump and do sanity clipping. + */ + xindex = cur.msg_bufx; + n = xindex - rindex; + if (n > cur.msg_size - 1024) { + rindex = xindex - cur.msg_size + 2048; + n = xindex - rindex; + } + ri = rindex % cur.msg_size; + xi = xindex % cur.msg_size; + + if (ri < xi) + buflen = xi - ri; else - buflen = cur.msg_size - rindex; + buflen = cur.msg_size - ri; + if (buflen > n) + buflen = n; if (buflen > INCRBUFSIZE) buflen = INCRBUFSIZE; - if (kvm_read(kd, (long)cur.msg_ptr + rindex, + + if (kvm_read(kd, (long)cur.msg_ptr + ri, bp, buflen) != (ssize_t)buflen) { errx(1, "kvm_read: %s", kvm_geterr(kd)); } if (buflen) dumpbuf(bp, 0, buflen, &newl, &skip, &pri); + ri = (ri + buflen) % cur.msg_size; + n = n - buflen; rindex += buflen; - if (rindex >= cur.msg_size) - rindex = 0; - if (rindex == cur.msg_bufx) { + if ((int)n <= 0) { if (tailmode == 0) break; fflush(stdout); @@ -224,7 +242,7 @@ dumpbuf(char *bp, size_t bufpos, size_t buflen, *skip = 0; *newl = 1; } if (ch == '>') { - if (LOG_FAC(*pri) == LOG_KERN || all_opt) + if (LOG_FAC(*pri) == LOG_KERN) *newl = *skip = 0; } else if (ch >= '0' && ch <= '9') { *pri *= 10; @@ -232,14 +250,14 @@ dumpbuf(char *bp, size_t bufpos, size_t buflen, } continue; } - if (*newl && ch == '<') { + if (*newl && ch == '<' && all_opt == 0) { *pri = 0; *skip = 1; continue; } if (ch == '\0') continue; - *newl = ch == '\n'; + *newl = (ch == '\n'); vis(buf, ch, 0, 0); if (buf[1] == 0) putchar(buf[0]); diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index 92ce846899..95f4945070 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -109,7 +109,7 @@ static int logclose(struct dev_close_args *ap) { log_open = 0; - callout_stop(&logsoftc.sc_callout); + callout_stop_sync(&logsoftc.sc_callout); logsoftc.sc_state = 0; funsetown(&logsoftc.sc_sigio); return (0); @@ -121,38 +121,67 @@ logread(struct dev_read_args *ap) { struct uio *uio = ap->a_uio; struct msgbuf *mbp = msgbufp; - long l; int error = 0; - - crit_enter(); - while (mbp->msg_bufr == mbp->msg_bufx) { + u_int lindex; + u_int xindex; + u_int lindex_modulo; + u_int n; + + /* + * Handle blocking + */ + while (mbp->msg_bufl == mbp->msg_bufx) { + crit_enter(); if (ap->a_ioflag & IO_NDELAY) { crit_exit(); return (EWOULDBLOCK); } - logsoftc.sc_state |= LOG_RDWAIT; + atomic_set_int(&logsoftc.sc_state, LOG_RDWAIT); if ((error = tsleep((caddr_t)mbp, PCATCH, "klog", 0))) { crit_exit(); return (error); } + /* don't bother clearing LOG_RDWAIT */ + crit_exit(); } - crit_exit(); - logsoftc.sc_state &= ~LOG_RDWAIT; - - while (uio->uio_resid > 0) { - l = (long)mbp->msg_bufx - (long)mbp->msg_bufr; - if (l < 0) - l = mbp->msg_size - mbp->msg_bufr; - l = (long)szmin(l, uio->uio_resid); - if (l == 0) - break; - error = uiomove((caddr_t)msgbufp->msg_ptr + mbp->msg_bufr, - (size_t)l, uio); + + /* + * Loop reading data + */ + while (uio->uio_resid > 0 && mbp->msg_bufl != mbp->msg_bufx) { + lindex = mbp->msg_bufl; + xindex = mbp->msg_bufx; + cpu_ccfence(); + + /* + * Clean up if too much time has passed causing us to wrap + * the buffer. This will lose some data. If more than ~4GB + * then this will lose even more data. + */ + n = xindex - lindex; + if (n > mbp->msg_size - 1024) { + lindex = xindex - mbp->msg_size + 2048; + n = xindex - lindex; + } + + /* + * Calculates contiguous bytes we can read in one loop. + */ + lindex_modulo = lindex % mbp->msg_size; + n = mbp->msg_size - lindex_modulo; + if (n > xindex - lindex) + n = xindex - lindex; + if ((size_t)n > uio->uio_resid) + n = (u_int)uio->uio_resid; + + /* + * Copy (n) bytes of data. + */ + error = uiomove((caddr_t)msgbufp->msg_ptr + lindex_modulo, + (size_t)n, uio); if (error) break; - mbp->msg_bufr += l; - if (mbp->msg_bufr >= mbp->msg_size) - mbp->msg_bufr = 0; + mbp->msg_bufl = lindex + n; } return (error); } @@ -195,7 +224,7 @@ logfiltread(struct knote *kn, long hint) int ret = 0; crit_enter(); - if (msgbufp->msg_bufr != msgbufp->msg_bufx) + if (msgbufp->msg_bufl != msgbufp->msg_bufx) ret = 1; crit_exit(); @@ -217,8 +246,8 @@ logtimeout(void *arg) if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL) pgsigio(logsoftc.sc_sigio, SIGIO, 0); if (logsoftc.sc_state & LOG_RDWAIT) { + atomic_clear_int(&logsoftc.sc_state, LOG_RDWAIT); wakeup((caddr_t)msgbufp); - logsoftc.sc_state &= ~LOG_RDWAIT; } callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second, logtimeout, NULL); @@ -228,24 +257,35 @@ logtimeout(void *arg) static int logioctl(struct dev_ioctl_args *ap) { - long l; + struct msgbuf *mbp = msgbufp; + u_int lindex; + u_int xindex; + u_int n; switch (ap->a_cmd) { case FIONREAD: - /* return number of characters immediately available */ - crit_enter(); - l = msgbufp->msg_bufx - msgbufp->msg_bufr; - crit_exit(); - if (l < 0) - l += msgbufp->msg_size; - *(int *)ap->a_data = l; + lindex = mbp->msg_bufl; + xindex = mbp->msg_bufx; + cpu_ccfence(); + + /* + * Clean up if too much time has passed causing us to wrap + * the buffer. This will lose some data. If more than ~4GB + * then this will lose even more data. + */ + n = xindex - lindex; + if (n > mbp->msg_size - 1024) { + lindex = xindex - mbp->msg_size + 2048; + n = xindex - lindex; + } + *(int *)ap->a_data = n; break; case FIOASYNC: if (*(int *)ap->a_data) - logsoftc.sc_state |= LOG_ASYNC; + atomic_set_int(&logsoftc.sc_state, LOG_ASYNC); else - logsoftc.sc_state &= ~LOG_ASYNC; + atomic_clear_int(&logsoftc.sc_state, LOG_ASYNC); break; case FIOSETOWN: diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index c59c26e604..c3c882e8ae 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -905,8 +905,9 @@ kvcreinitspin(void) static void constty_daemon(void) { - int rindex = -1; - int windex = -1; + u_int rindex; + u_int xindex; + u_int n; struct msgbuf *mbp; struct tty *tp; @@ -914,54 +915,64 @@ constty_daemon(void) constty_td, SHUTDOWN_PRI_FIRST); constty_td->td_flags |= TDF_SYSTHREAD; + mbp = msgbufp; + rindex = mbp->msg_bufr; /* persistent loop variable */ + xindex = mbp->msg_bufx - 1; /* anything different than bufx */ + cpu_ccfence(); + for (;;) { kproc_suspend_loop(); crit_enter(); - mbp = msgbufp; - if (mbp == NULL || msgbufmapped == 0 || - windex == mbp->msg_bufx) { + if (mbp != msgbufp) + mbp = msgbufp; + if (xindex == mbp->msg_bufx || + mbp == NULL || + msgbufmapped == 0) { tsleep(constty_td, 0, "waiting", hz*60); crit_exit(); continue; } - windex = mbp->msg_bufx; crit_exit(); /* * Get message buf FIFO indices. rindex is tracking. */ + xindex = mbp->msg_bufx; + cpu_ccfence(); if ((tp = constty) == NULL) { - rindex = mbp->msg_bufx; + rindex = xindex; continue; } /* - * Don't blow up if the message buffer is broken + * Check if the calculated bytes has rolled the whole + * message buffer. */ - if (windex < 0 || windex >= mbp->msg_size) - continue; - if (rindex < 0 || rindex >= mbp->msg_size) - rindex = windex; + n = xindex - rindex; + if (n > mbp->msg_size - 1024) { + rindex = xindex - mbp->msg_size + 2048; + n = xindex - rindex; + } /* * And dump it. If constty gets stuck will give up. */ - while (rindex != windex) { - if (tputchar((uint8_t)mbp->msg_ptr[rindex], tp) < 0) { + while (rindex != xindex) { + u_int ri = rindex % mbp->msg_size; + if (tputchar((uint8_t)mbp->msg_ptr[ri], tp) < 0) { constty = NULL; - rindex = mbp->msg_bufx; + rindex = xindex; break; } - if (++rindex >= mbp->msg_size) - rindex = 0; if (tp->t_outq.c_cc >= tp->t_ohiwat) { tsleep(constty_daemon, 0, "blocked", hz / 10); if (tp->t_outq.c_cc >= tp->t_ohiwat) { - rindex = windex; + rindex = xindex; break; } } + ++rindex; } } } @@ -1021,36 +1032,51 @@ static void msgaddchar(int c, void *dummy) { struct msgbuf *mbp; - int rindex; - int windex; + u_int lindex; + u_int rindex; + u_int xindex; + u_int n; if (!msgbufmapped) return; mbp = msgbufp; - windex = mbp->msg_bufx; - mbp->msg_ptr[windex] = c; - if (++windex >= mbp->msg_size) - windex = 0; + lindex = mbp->msg_bufl; rindex = mbp->msg_bufr; - if (windex == rindex) { - rindex += 32; - if (rindex >= mbp->msg_size) - rindex -= mbp->msg_size; + xindex = mbp->msg_bufx++; /* Allow SMP race */ + cpu_ccfence(); + + mbp->msg_ptr[xindex % mbp->msg_size] = c; + n = xindex - lindex; + if (n > mbp->msg_size - 1024) { + lindex = xindex - mbp->msg_size + 2048; + cpu_ccfence(); + mbp->msg_bufl = lindex; + } + n = xindex - rindex; + if (n > mbp->msg_size - 1024) { + rindex = xindex - mbp->msg_size + 2048; + cpu_ccfence(); mbp->msg_bufr = rindex; } - mbp->msg_bufx = windex; } static void msgbufcopy(struct msgbuf *oldp) { - int pos; - - pos = oldp->msg_bufr; - while (pos != oldp->msg_bufx) { - msglogchar(oldp->msg_ptr[pos], -1); - if (++pos >= oldp->msg_size) - pos = 0; + u_int rindex; + u_int xindex; + u_int n; + + rindex = oldp->msg_bufr; + xindex = oldp->msg_bufx; + cpu_ccfence(); + + n = xindex - rindex; + if (n > oldp->msg_size - 1024) + rindex = xindex - oldp->msg_size + 2048; + while (rindex != xindex) { + msglogchar(oldp->msg_ptr[rindex % oldp->msg_size], -1); + ++rindex; } } @@ -1063,8 +1089,7 @@ msgbufinit(void *ptr, size_t size) size -= sizeof(*msgbufp); cp = (char *)ptr; msgbufp = (struct msgbuf *) (cp + size); - if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_size != size || - msgbufp->msg_bufx >= size || msgbufp->msg_bufr >= size) { + if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_size != size) { bzero(cp, size); bzero(msgbufp, sizeof(*msgbufp)); msgbufp->msg_magic = MSG_MAGIC; @@ -1073,6 +1098,7 @@ msgbufinit(void *ptr, size_t size) msgbufp->msg_ptr = cp; if (msgbufmapped && oldp != msgbufp) msgbufcopy(oldp); + cpu_mfence(); msgbufmapped = 1; oldp = msgbufp; } @@ -1082,8 +1108,14 @@ msgbufinit(void *ptr, size_t size) static int sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) { + struct msgbuf *mbp; struct ucred *cred; int error; + u_int rindex_modulo; + u_int xindex_modulo; + u_int rindex; + u_int xindex; + u_int n; /* * Only wheel or root can access the message log. @@ -1102,15 +1134,44 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) /* * Unwind the buffer, so that it's linear (possibly starting with * some initial nulls). + * + * We don't push the entire buffer like we did before because + * bufr (and bufl) now advance in chunks when the fifo is full, + * rather than one character. */ - error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr + msgbufp->msg_bufx, - msgbufp->msg_size - msgbufp->msg_bufx, req); + mbp = msgbufp; + rindex = mbp->msg_bufr; + xindex = mbp->msg_bufx; + n = xindex - rindex; + if (n > mbp->msg_size - 1024) { + rindex = xindex - mbp->msg_size + 2048; + n = xindex - rindex; + } + rindex_modulo = rindex % mbp->msg_size; + xindex_modulo = xindex % mbp->msg_size; + + if (rindex_modulo < xindex_modulo) { + error = sysctl_handle_opaque(oidp, + mbp->msg_ptr + rindex_modulo, + xindex_modulo - rindex_modulo, + req); + } else if (n <= mbp->msg_size - rindex_modulo) { + error = sysctl_handle_opaque(oidp, + mbp->msg_ptr + rindex_modulo, + n - rindex_modulo, + req); + } else { + error = sysctl_handle_opaque(oidp, + mbp->msg_ptr + rindex_modulo, + mbp->msg_size - rindex_modulo, + req); + n -= mbp->msg_size - rindex_modulo; + if (error == 0) + error = sysctl_handle_opaque(oidp, mbp->msg_ptr, + n, req); + } if (error) return (error); - if (msgbufp->msg_bufx > 0) { - error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr, - msgbufp->msg_bufx, req); - } return (error); } @@ -1126,8 +1187,9 @@ sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); if (!error && req->newptr) { /* Clear the buffer and reset write pointer */ + msgbufp->msg_bufr = msgbufp->msg_bufx; + msgbufp->msg_bufl = msgbufp->msg_bufx; bzero(msgbufp->msg_ptr, msgbufp->msg_size); - msgbufp->msg_bufr = msgbufp->msg_bufx = 0; msgbuf_clear = 0; } return (error); @@ -1141,7 +1203,9 @@ SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear, DB_SHOW_COMMAND(msgbuf, db_show_msgbuf) { - int i, j; + u_int rindex; + u_int i; + u_int j; if (!msgbufmapped) { db_printf("msgbuf not mapped yet\n"); @@ -1149,10 +1213,14 @@ DB_SHOW_COMMAND(msgbuf, db_show_msgbuf) } db_printf("msgbufp = %p\n", msgbufp); db_printf("magic = %x, size = %d, r= %d, w = %d, ptr = %p\n", - msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_bufr, - msgbufp->msg_bufx, msgbufp->msg_ptr); + msgbufp->msg_magic, msgbufp->msg_size, + msgbufp->msg_bufr % msgbufp->msg_size, + msgbufp->msg_bufx % msgbufp->msg_size, + msgbufp->msg_ptr); + + rindex = msgbufp->msg_bufr; for (i = 0; i < msgbufp->msg_size; i++) { - j = (i + msgbufp->msg_bufr) % msgbufp->msg_size; + j = (i + rindex) % msgbufp->msg_size; db_printf("%c", msgbufp->msg_ptr[j]); } db_printf("\n"); diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 60377270f6..b21e5d39c9 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -150,52 +150,6 @@ SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD, SYSCTL_ULONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &Maxmem, 0, ""); -#if 0 - -static int -sysctl_machdep_msgbuf(SYSCTL_HANDLER_ARGS) -{ - int error; - - /* Unwind the buffer, so that it's linear (possibly starting with - * some initial nulls). - */ - error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr+msgbufp->msg_bufr, - msgbufp->msg_size-msgbufp->msg_bufr,req); - if(error) return(error); - if(msgbufp->msg_bufr>0) { - error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr, - msgbufp->msg_bufr,req); - } - return(error); -} - -SYSCTL_PROC(_machdep, OID_AUTO, msgbuf, CTLTYPE_STRING|CTLFLAG_RD, - 0, 0, sysctl_machdep_msgbuf, "A","Contents of kernel message buffer"); - -static int msgbuf_clear; - -static int -sysctl_machdep_msgbuf_clear(SYSCTL_HANDLER_ARGS) -{ - int error; - error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, - req); - if (!error && req->newptr) { - /* Clear the buffer and reset write pointer */ - bzero(msgbufp->msg_ptr,msgbufp->msg_size); - msgbufp->msg_bufr=msgbufp->msg_bufx=0; - msgbuf_clear=0; - } - return (error); -} - -SYSCTL_PROC(_machdep, OID_AUTO, msgbuf_clear, CTLTYPE_INT|CTLFLAG_RW, - &msgbuf_clear, 0, sysctl_machdep_msgbuf_clear, "I", - "Clear kernel message buffer"); - -#endif - /* * Send an interrupt to process. * diff --git a/sys/platform/vkernel64/x86_64/cpu_regs.c b/sys/platform/vkernel64/x86_64/cpu_regs.c index 92cdf5bcb0..3ef29bdfb5 100644 --- a/sys/platform/vkernel64/x86_64/cpu_regs.c +++ b/sys/platform/vkernel64/x86_64/cpu_regs.c @@ -147,52 +147,6 @@ SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD, SYSCTL_ULONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &Maxmem, 0, ""); -#if 0 - -static int -sysctl_machdep_msgbuf(SYSCTL_HANDLER_ARGS) -{ - int error; - - /* Unwind the buffer, so that it's linear (possibly starting with - * some initial nulls). - */ - error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr+msgbufp->msg_bufr, - msgbufp->msg_size-msgbufp->msg_bufr,req); - if(error) return(error); - if(msgbufp->msg_bufr>0) { - error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr, - msgbufp->msg_bufr,req); - } - return(error); -} - -SYSCTL_PROC(_machdep, OID_AUTO, msgbuf, CTLTYPE_STRING|CTLFLAG_RD, - 0, 0, sysctl_machdep_msgbuf, "A","Contents of kernel message buffer"); - -static int msgbuf_clear; - -static int -sysctl_machdep_msgbuf_clear(SYSCTL_HANDLER_ARGS) -{ - int error; - error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, - req); - if (!error && req->newptr) { - /* Clear the buffer and reset write pointer */ - bzero(msgbufp->msg_ptr,msgbufp->msg_size); - msgbufp->msg_bufr=msgbufp->msg_bufx=0; - msgbuf_clear=0; - } - return (error); -} - -SYSCTL_PROC(_machdep, OID_AUTO, msgbuf_clear, CTLTYPE_INT|CTLFLAG_RW, - &msgbuf_clear, 0, sysctl_machdep_msgbuf_clear, "I", - "Clear kernel message buffer"); - -#endif - /* * Send an interrupt to process. * diff --git a/sys/sys/msgbuf.h b/sys/sys/msgbuf.h index 7e89bed21e..c69649b38a 100644 --- a/sys/sys/msgbuf.h +++ b/sys/sys/msgbuf.h @@ -42,13 +42,22 @@ #include #endif +/* + * NOTE! The indices are not masked against msg_size. All accessors + * must mask the indices against msg_size to get actual buffer + * indexes. For relative block sizes, simple subtraction can be + * used using unsigned integers. + */ struct msgbuf { -#define MSG_MAGIC 0x063062 +#define MSG_MAGIC 0x063064 +#define MSG_OMAGIC 0x063062 unsigned int msg_magic; unsigned int msg_size; /* size of buffer area */ - unsigned int msg_bufx; /* write pointer */ - unsigned int msg_bufr; /* read pointer */ + unsigned int msg_bufx; /* write index - kernel */ + unsigned int msg_bufr; /* base index - kernel */ char * msg_ptr; /* pointer to buffer */ + unsigned int msg_bufl; /* read index - log device */ + unsigned int msg_unused01; }; #ifdef _KERNEL -- 2.41.0