Subject: kern/1891: statically-sized message buffer wastes space on many ports
To: None <gnats-bugs@gnats.netbsd.org>
From: Chris G. Demetriou <cgd@NetBSD.ORG>
List: netbsd-bugs
Date: 01/04/1996 23:36:31
>Number: 1891
>Category: kern
>Synopsis: kernel msgbuf has fixed size; pages can be partially wasted.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Jan 5 00:05:02 1996
>Last-Modified:
>Originator: Chris G. Demetriou
>Organization:
Kernel Hackers 'r' Us
>Release: NetBSD-current as of January 4, 1996
>Environment:
System: NetBSD sun-lamp.pc.cs.cmu.edu 1.1A NetBSD 1.1A (SUN_LAMP) #19: Thu Jan 4 20:42:03 EST 1996 cgd@sun-lamp.pc.cs.cmu.edu:/usr/src/sys/arch/i386/compile/SUN_LAMP i386
>Description:
The current definition of the kernel message buffer is fixed at
4k in size. This is annoying on machines with a hardware page
sizes > 4k, because:
(1) it's relatively hard to make use of the rest of the
page being used for the message buffer, and
(2) given that you're wasting the space, having a too-small
dmesg buffer is _very_ annoying, if your dmesg output
is the only easy way for you to get crash information.
Similarly, given the current definition of msgbuf, you can't
devote multiple pages to the message buffer, even if you want to.
System developers might want a larger (potentially much larger;
i'd not mind 32k...) message buffer, and it might be nice for ports
to provide it as a compile-time option.
>How-To-Repeat:
on a machine that keeps message buffer output from one boot to the
next (which, as far as i can tell, is _not_ most pc's; they
clear memory):
reboot
reboot again
reboot again
and note that you probably don't have all three boots' dmesg output
available with 'dmesg.' If you're on a machine with an 8k page size,
look at the source to see if a full page is being used for dmesg stuff,
but note that never more than 4k (minus a few bytes, actually) of
message buffer text is available.
>Fix:
I've included diffs to implement a variable-size message buffer, below.
The diffs deal with the machine-specific changes for the i386, but
I didn't do any of the other ports. (Actually, I did the Alpha, too,
but those changes are being committed to my NetBSD/Alpha tree
locally, until they're accepted into the master sources, at which
point i will update the -current NetBSD/Alpha sources.)
With these diffs, old 'dmesg' and 'syslogd' binaries will continue
running, though old 'dmesg' binaries will output a few bytes of
junk at the start of the buffer, and will miss a few bytes at the
end of the buffer.
Once the changes have been applied, new 'syslogd' binaries should
run with old kernels with few side effects, but new 'dmesg'
binaries may or may not work properly with old kernels.
These diffs also rename the 'msgbuf' struct to 'kern_msgbuf', so
that PR 1725 may be fixed more easily.
Index: lib/libc/gen/sysctl.3
===================================================================
RCS file: /a/cvsroot/src/lib/libc/gen/sysctl.3,v
retrieving revision 1.7
diff -c -r1.7 sysctl.3
*** sysctl.3 1995/09/30 07:03:54 1.7
--- sysctl.3 1996/01/05 03:08:57
***************
*** 243,248 ****
--- 243,249 ----
.It KERN\_MAXVNODES integer yes
.It KERN\_MAX\_CANON integer no
.It KERN\_MAX\_INPUT integer no
+ .It KERN\_MSGBUFSIZE integer no
.It KERN\_NAME\_MAX integer no
.It KERN\_NGROUPS integer no
.It KERN\_NO\_TRUNC integer no
***************
*** 312,317 ****
--- 313,320 ----
.It Li KERN_MAX_INPUT
The minimum maximum number of bytes for which space is available in
a terminal input queue.
+ .It Li KERN_MSGBUFSIZE
+ The maximum number of characters that the kernel message buffer can hold.
.It Li KERN_NAME_MAX
The maximum number of bytes in a file name.
.It Li KERN_NGROUPS
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /a/cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.183
diff -c -r1.183 machdep.c
*** machdep.c 1996/01/04 22:22:01 1.183
--- machdep.c 1996/01/05 03:09:15
***************
*** 122,129 ****
int boothowto;
int cpu_class;
! struct msgbuf *msgbufp;
! int msgbufmapped;
vm_map_t buffer_map;
--- 122,128 ----
int boothowto;
int cpu_class;
! caddr_t msgbufaddr;
vm_map_t buffer_map;
***************
*** 154,164 ****
* Initialize error message buffer (at end of core).
*/
/* avail_end was pre-decremented in pmap_bootstrap to compensate */
! for (i = 0; i < btoc(sizeof(struct msgbuf)); i++)
! pmap_enter(pmap_kernel(),
! (vm_offset_t)((caddr_t)msgbufp + i * NBPG),
! avail_end + i * NBPG, VM_PROT_ALL, TRUE);
! msgbufmapped = 1;
printf(version);
identifycpu();
--- 153,161 ----
* Initialize error message buffer (at end of core).
*/
/* avail_end was pre-decremented in pmap_bootstrap to compensate */
! pmap_enter(pmap_kernel(), (vm_offset_t)msgbufaddr, avail_end,
! VM_PROT_ALL, TRUE);
! initmsgbuf(msgbufaddr, NBPG);
printf(version);
identifycpu();
Index: sys/arch/i386/i386/pmap.c
===================================================================
RCS file: /a/cvsroot/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.34
diff -c -r1.34 pmap.c
*** pmap.c 1995/12/09 07:39:02 1.34
--- pmap.c 1996/01/05 03:09:16
***************
*** 180,186 ****
pt_entry_t *pmap_pte __P((pmap_t, vm_offset_t));
#if BSDVM_COMPAT
! #include <sys/msgbuf.h>
/*
* All those kernel PT submaps that BSD is so fond of
--- 180,186 ----
pt_entry_t *pmap_pte __P((pmap_t, vm_offset_t));
#if BSDVM_COMPAT
! extern caddr_t msgbufaddr;
/*
* All those kernel PT submaps that BSD is so fond of
***************
*** 214,220 ****
extern vm_offset_t reserve_dumppages(vm_offset_t);
/* XXX: allow for msgbuf */
! avail_end -= i386_round_page(sizeof(struct msgbuf));
virtual_avail = virtual_start;
virtual_end = VM_MAX_KERNEL_ADDRESS;
--- 214,220 ----
extern vm_offset_t reserve_dumppages(vm_offset_t);
/* XXX: allow for msgbuf */
! avail_end -= NBPG;
virtual_avail = virtual_start;
virtual_end = VM_MAX_KERNEL_ADDRESS;
***************
*** 258,267 ****
va = virtual_avail;
pte = pmap_pte(pmap_kernel(), va);
! SYSMAP(caddr_t ,CMAP1 ,CADDR1 ,1 )
! SYSMAP(caddr_t ,CMAP2 ,CADDR2 ,1 )
! SYSMAP(caddr_t ,XXX_mmap ,vmmap ,1 )
! SYSMAP(struct msgbuf * ,msgbufmap ,msgbufp ,1 )
virtual_avail = va;
#endif
--- 258,267 ----
va = virtual_avail;
pte = pmap_pte(pmap_kernel(), va);
! SYSMAP(caddr_t ,CMAP1 ,CADDR1 ,1 )
! SYSMAP(caddr_t ,CMAP2 ,CADDR2 ,1 )
! SYSMAP(caddr_t ,XXX_mmap ,vmmap ,1 )
! SYSMAP(caddr_t ,msgbufmap ,msgbufaddr ,1 )
virtual_avail = va;
#endif
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /a/cvsroot/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.12
diff -c -r1.12 kern_sysctl.c
*** kern_sysctl.c 1995/10/07 06:28:27 1.12
--- kern_sysctl.c 1996/01/05 03:09:23
***************
*** 56,61 ****
--- 56,62 ----
#include <sys/disklabel.h>
#include <vm/vm.h>
#include <sys/sysctl.h>
+ #include <sys/msgbuf.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
***************
*** 285,290 ****
--- 286,301 ----
return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS));
case KERN_RAWPARTITION:
return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART));
+ case KERN_MSGBUFSIZE:
+ /*
+ * deal with cases where the message buffer has
+ * become corrupted.
+ */
+ if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
+ msgbufenabled = 0;
+ return (ENXIO);
+ }
+ return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs));
default:
return (EOPNOTSUPP);
}
Index: sys/kern/subr_log.c
===================================================================
RCS file: /a/cvsroot/src/sys/kern/subr_log.c,v
retrieving revision 1.8
diff -c -r1.8 subr_log.c
*** subr_log.c 1994/10/30 21:47:47 1.8
--- subr_log.c 1996/01/05 03:09:24
***************
*** 60,65 ****
--- 60,104 ----
int log_open; /* also used in log() */
+ int msgbufmapped; /* is the message buffer mapped */
+ int msgbufenabled; /* is logging to the buffer enabled */
+ struct kern_msgbuf *msgbufp; /* the mapped buffer, itself. */
+
+ void
+ initmsgbuf(buf, bufsize)
+ caddr_t buf;
+ size_t bufsize;
+ {
+ register struct kern_msgbuf *mbp;
+ long new_bufs;
+
+ /* Sanity-check the given size. */
+ if (bufsize < sizeof(struct kern_msgbuf))
+ return;
+
+ mbp = msgbufp = (struct kern_msgbuf *)buf;
+
+ #define offsetof(type, member) ((size_t)(&((type *)0)->member))
+ new_bufs = bufsize - offsetof(struct kern_msgbuf, msg_bufc);
+ #undef offsetof
+ if ((mbp->msg_magic != MSG_MAGIC) || (mbp->msg_bufs != new_bufs) ||
+ (mbp->msg_bufr < 0) || (mbp->msg_bufr >= mbp->msg_bufs) ||
+ (mbp->msg_bufx < 0) || (mbp->msg_bufx >= mbp->msg_bufs)) {
+ /*
+ * If the buffer magic number is wrong, has changed
+ * size (which shouldn't happen often), or is
+ * internally inconsistent, initialize it.
+ */
+
+ bzero(buf, bufsize);
+ mbp->msg_magic = MSG_MAGIC;
+ mbp->msg_bufs = new_bufs;
+ }
+
+ /* mark it as ready for use. */
+ msgbufmapped = msgbufenabled = 1;
+ }
+
/*ARGSUSED*/
int
logopen(dev, flags, mode, p)
***************
*** 67,91 ****
int flags, mode;
struct proc *p;
{
! register struct msgbuf *mbp = msgbufp;
if (log_open)
return (EBUSY);
log_open = 1;
logsoftc.sc_pgid = p->p_pid; /* signal process only */
/*
! * Potential race here with putchar() but since putchar should be
! * called by autoconf, msg_magic should be initialized by the time
! * we get here.
*/
if (mbp->msg_magic != MSG_MAGIC) {
! register int i;
!
! mbp->msg_magic = MSG_MAGIC;
! mbp->msg_bufx = mbp->msg_bufr = 0;
! for (i=0; i < MSG_BSIZE; i++)
! mbp->msg_bufc[i] = 0;
}
return (0);
}
--- 106,129 ----
int flags, mode;
struct proc *p;
{
! register struct kern_msgbuf *mbp = msgbufp;
if (log_open)
return (EBUSY);
log_open = 1;
logsoftc.sc_pgid = p->p_pid; /* signal process only */
+
/*
! * The message buffer is initialized during system configuration.
! * If it's been clobbered, note that and return an error. (This
! * allows a user to potentially read the buffer via /dev/kmem,
! * and try to figure out what clobbered it.
*/
if (mbp->msg_magic != MSG_MAGIC) {
! msgbufenabled = 0;
! return (ENXIO);
}
+
return (0);
}
***************
*** 108,114 ****
struct uio *uio;
int flag;
{
! register struct msgbuf *mbp = msgbufp;
register long l;
register int s;
int error = 0;
--- 146,152 ----
struct uio *uio;
int flag;
{
! register struct kern_msgbuf *mbp = msgbufp;
register long l;
register int s;
int error = 0;
***************
*** 132,138 ****
while (uio->uio_resid > 0) {
l = mbp->msg_bufx - mbp->msg_bufr;
if (l < 0)
! l = MSG_BSIZE - mbp->msg_bufr;
l = min(l, uio->uio_resid);
if (l == 0)
break;
--- 170,176 ----
while (uio->uio_resid > 0) {
l = mbp->msg_bufx - mbp->msg_bufr;
if (l < 0)
! l = mbp->msg_bufs - mbp->msg_bufr;
l = min(l, uio->uio_resid);
if (l == 0)
break;
***************
*** 141,147 ****
if (error)
break;
mbp->msg_bufr += l;
! if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE)
mbp->msg_bufr = 0;
}
return (error);
--- 179,185 ----
if (error)
break;
mbp->msg_bufr += l;
! if (mbp->msg_bufr < 0 || mbp->msg_bufr >= mbp->msg_bufs)
mbp->msg_bufr = 0;
}
return (error);
***************
*** 209,215 ****
l = msgbufp->msg_bufx - msgbufp->msg_bufr;
splx(s);
if (l < 0)
! l += MSG_BSIZE;
*(int *)data = l;
break;
--- 247,253 ----
l = msgbufp->msg_bufx - msgbufp->msg_bufr;
splx(s);
if (l < 0)
! l += msgbufp->msg_bufs;
*(int *)data = l;
break;
Index: sys/kern/subr_prf.c
===================================================================
RCS file: /a/cvsroot/src/sys/kern/subr_prf.c,v
retrieving revision 1.19
diff -c -r1.19 subr_prf.c
*** subr_prf.c 1995/06/16 10:52:17 1.19
--- subr_prf.c 1996/01/05 03:09:24
***************
*** 488,495 ****
int flags;
struct tty *tp;
{
! extern int msgbufmapped;
! register struct msgbuf *mbp;
if (panicstr)
constty = NULL;
--- 488,494 ----
int flags;
struct tty *tp;
{
! register struct kern_msgbuf *mbp;
if (panicstr)
constty = NULL;
***************
*** 501,515 ****
(flags & TOCONS) && tp == constty)
constty = NULL;
if ((flags & TOLOG) &&
! c != '\0' && c != '\r' && c != 0177 && msgbufmapped) {
mbp = msgbufp;
if (mbp->msg_magic != MSG_MAGIC) {
! bzero((caddr_t)mbp, sizeof(*mbp));
! mbp->msg_magic = MSG_MAGIC;
}
- mbp->msg_bufc[mbp->msg_bufx++] = c;
- if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
- mbp->msg_bufx = 0;
}
if ((flags & TOCONS) && constty == NULL && c != '\0')
(*v_putc)(c);
--- 500,523 ----
(flags & TOCONS) && tp == constty)
constty = NULL;
if ((flags & TOLOG) &&
! c != '\0' && c != '\r' && c != 0177 && msgbufenabled) {
mbp = msgbufp;
if (mbp->msg_magic != MSG_MAGIC) {
! /*
! * Arguably should panic or somehow notify the
! * user... but how? Panic may be too drastic,
! * and would obliterate the message being kicked
! * out (maybe a panic itself), and printf
! * would invoke us recursively. Silently punt
! * for now. If syslog is running, it should
! * notice.
! */
! msgbufenabled = 0;
! } else {
! mbp->msg_bufc[mbp->msg_bufx++] = c;
! if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs)
! mbp->msg_bufx = 0;
}
}
if ((flags & TOCONS) && constty == NULL && c != '\0')
(*v_putc)(c);
Index: sys/miscfs/kernfs/kernfs_vnops.c
===================================================================
RCS file: /a/cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v
retrieving revision 1.39
diff -c -r1.39 kernfs_vnops.c
*** kernfs_vnops.c 1995/10/09 14:25:02 1.39
--- kernfs_vnops.c 1996/01/05 03:09:31
***************
*** 140,154 ****
}
case KTT_MSGBUF: {
- extern struct msgbuf *msgbufp;
long n;
! if (off >= MSG_BSIZE)
return (0);
n = msgbufp->msg_bufx + off;
! if (n >= MSG_BSIZE)
! n -= MSG_BSIZE;
! len = min(MSG_BSIZE - n, MSG_BSIZE - off);
*bufp = msgbufp->msg_bufc + n;
return (len);
}
--- 140,171 ----
}
case KTT_MSGBUF: {
long n;
! /*
! * deal with cases where the message buffer has
! * become corrupted.
! */
! if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
! msgbufenabled = 0;
! return (ENXIO);
! }
!
! /*
! * Note that reads of /kern/msgbuf won't necessarily yeild
! * consistent results, if the message buffer is modified
! * while the read is in progress. The worst that can happen
! * is that incorrect data will be read. There's no way
! * that this can crash the system unless the values in the
! * message buffer header are corrupted, but that'll cause
! * the system to die anyway.
! */
! if (off >= msgbufp->msg_bufs)
return (0);
n = msgbufp->msg_bufx + off;
! if (n >= msgbufp->msg_bufs)
! n -= msgbufp->msg_bufs;
! len = min(msgbufp->msg_bufs - n, msgbufp->msg_bufs - off);
*bufp = msgbufp->msg_bufc + n;
return (len);
}
Index: sys/sys/msgbuf.h
===================================================================
RCS file: /a/cvsroot/src/sys/sys/msgbuf.h,v
retrieving revision 1.8
diff -c -r1.8 msgbuf.h
*** msgbuf.h 1995/03/26 20:24:27 1.8
--- msgbuf.h 1996/01/05 03:09:41
***************
*** 35,48 ****
* @(#)msgbuf.h 8.1 (Berkeley) 6/2/93
*/
! #define MSG_BSIZE (4096 - 3 * sizeof(long))
! struct msgbuf {
#define MSG_MAGIC 0x063061
long msg_magic;
long msg_bufx; /* write pointer */
long msg_bufr; /* read pointer */
! char msg_bufc[MSG_BSIZE]; /* buffer */
};
#ifdef _KERNEL
! struct msgbuf *msgbufp;
#endif
--- 35,53 ----
* @(#)msgbuf.h 8.1 (Berkeley) 6/2/93
*/
! struct kern_msgbuf {
#define MSG_MAGIC 0x063061
long msg_magic;
long msg_bufx; /* write pointer */
long msg_bufr; /* read pointer */
! long msg_bufs; /* real msg_bufc size (bytes) */
! char msg_bufc[1]; /* buffer */
};
+
#ifdef _KERNEL
! extern int msgbufmapped; /* is the message buffer mapped */
! extern int msgbufenabled; /* is logging to the buffer enabled */
! extern struct kern_msgbuf *msgbufp; /* the mapped buffer, itself. */
!
! void initmsgbuf __P((caddr_t buf, size_t bufsize));
#endif
Index: sys/sys/sysctl.h
===================================================================
RCS file: /a/cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.9
diff -c -r1.9 sysctl.h
*** sysctl.h 1995/08/04 18:36:08 1.9
--- sysctl.h 1996/01/05 03:09:42
***************
*** 132,138 ****
#define KERN_DOMAINNAME 22 /* string: (YP) domainname */
#define KERN_MAXPARTITIONS 23 /* int: number of partitions/disk */
#define KERN_RAWPARTITION 24 /* int: raw partition number */
! #define KERN_MAXID 25 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
--- 132,139 ----
#define KERN_DOMAINNAME 22 /* string: (YP) domainname */
#define KERN_MAXPARTITIONS 23 /* int: number of partitions/disk */
#define KERN_RAWPARTITION 24 /* int: raw partition number */
! #define KERN_MSGBUFSIZE 25 /* int: max # of chars in msg buffer */
! #define KERN_MAXID 26 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
***************
*** 160,165 ****
--- 161,167 ----
{ "domainname", CTLTYPE_STRING }, \
{ "maxpartitions", CTLTYPE_INT }, \
{ "rawpartition", CTLTYPE_INT }, \
+ { "msgbufsize", CTLTYPE_INT }, \
}
/*
Index: usr.sbin/sysctl/sysctl.8
===================================================================
RCS file: /a/cvsroot/src/usr.sbin/sysctl/sysctl.8,v
retrieving revision 1.4
diff -c -r1.4 sysctl.8
*** sysctl.8 1995/09/30 07:12:49 1.4
--- sysctl.8 1996/01/05 03:09:50
***************
*** 110,115 ****
--- 110,116 ----
.It kern.maxproc integer yes
.It kern.maxfiles integer yes
.It kern.maxpartitions integer no
+ .It kern.msgbufsize integer no
.It kern.rawpartition integer no
.It kern.argmax integer no
.It kern.securelevel integer raise only
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /a/cvsroot/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.5
diff -c -r1.5 syslogd.c
*** syslogd.c 1996/01/02 17:48:41 1.5
--- syslogd.c 1996/01/05 03:09:55
***************
*** 81,86 ****
--- 81,87 ----
#include <sys/un.h>
#include <sys/time.h>
#include <sys/resource.h>
+ #include <sys/sysctl.h>
#include <netinet/in.h>
#include <netdb.h>
***************
*** 194,199 ****
--- 195,201 ----
void die __P((int));
void domark __P((int));
void fprintlog __P((struct filed *, int, char *));
+ int getmsgbufsize __P((void));
void init __P((int));
void logerror __P((char *));
void logmsg __P((int, char *, char *, int));
***************
*** 209,219 ****
int argc;
char *argv[];
{
! int ch, funix, i, inetm, fklog, klogm, len;
struct sockaddr_un sunx, fromunix;
struct sockaddr_in sin, frominet;
FILE *fp;
! char *p, line[MSG_BSIZE + 1];
while ((ch = getopt(argc, argv, "df:m:p:")) != EOF)
switch(ch) {
--- 211,221 ----
int argc;
char *argv[];
{
! int ch, funix, i, inetm, fklog, klogm, len, linesize;
struct sockaddr_un sunx, fromunix;
struct sockaddr_in sin, frominet;
FILE *fp;
! char *p, *line;
while ((ch = getopt(argc, argv, "df:m:p:")) != EOF)
switch(ch) {
***************
*** 249,254 ****
--- 251,265 ----
LocalDomain = p;
} else
LocalDomain = "";
+ linesize = getmsgbufsize();
+ if (linesize < MAXLINE)
+ linesize = MAXLINE;
+ linesize++;
+ line = malloc(linesize);
+ if (line == NULL) {
+ logerror("couldn't allocate line buffer");
+ die(0);
+ }
(void)signal(SIGTERM, die);
(void)signal(SIGINT, Debug ? die : SIG_IGN);
(void)signal(SIGQUIT, Debug ? die : SIG_IGN);
***************
*** 329,335 ****
}
dprintf("got a message (%d, %#x)\n", nfds, readfds);
if (readfds & klogm) {
! i = read(fklog, line, sizeof(line) - 1);
if (i > 0) {
line[i] = '\0';
printsys(line);
--- 340,346 ----
}
dprintf("got a message (%d, %#x)\n", nfds, readfds);
if (readfds & klogm) {
! i = read(fklog, line, linesize - 1);
if (i > 0) {
line[i] = '\0';
printsys(line);
***************
*** 1132,1135 ****
--- 1143,1165 ----
return (c->c_val);
return (-1);
+ }
+
+ /*
+ * Retrieve the size of the kernel message buffer, via sysctl.
+ */
+ int
+ getmsgbufsize()
+ {
+ int msgbufsize, mib[2];
+ size_t size;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_MSGBUFSIZE;
+ size = sizeof msgbufsize;
+ if (sysctl(mib, 2, &msgbufsize, &size, NULL, 0) == -1) {
+ dprintf("couldn't get kern.msgbufsize\n");
+ return (0);
+ }
+ return (msgbufsize);
}
Index: sbin/dmesg/dmesg.c
===================================================================
RCS file: /a/cvsroot/src/sbin/dmesg/dmesg.c,v
retrieving revision 1.8
diff -c -r1.8 dmesg.c
*** dmesg.c 1995/03/18 14:54:49 1.8
--- dmesg.c 1996/01/05 03:21:25
***************
*** 79,86 ****
{
register int ch, newl, skip;
register char *p, *ep;
! struct msgbuf *bufp, cur;
! char *memf, *nlistf;
kvm_t *kd;
char buf[5];
--- 79,86 ----
{
register int ch, newl, skip;
register char *p, *ep;
! struct kern_msgbuf *bufp, cur;
! char *memf, *nlistf, *bufdata;
kvm_t *kd;
char buf[5];
***************
*** 107,113 ****
if (memf != NULL || nlistf != NULL)
setgid(getgid());
! /* Read in kernel message buffer, do sanity checks. */
if ((kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg")) == NULL)
exit (1);
if (kvm_nlist(kd, nl) == -1)
--- 107,113 ----
if (memf != NULL || nlistf != NULL)
setgid(getgid());
! /* Read in message buffer header and data, and do sanity checks. */
if ((kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg")) == NULL)
exit (1);
if (kvm_nlist(kd, nl) == -1)
***************
*** 116,136 ****
errx(1, "%s: msgbufp not found", nlistf ? nlistf : "namelist");
if (KREAD(nl[X_MSGBUF].n_value, bufp) || KREAD((long)bufp, cur))
errx(1, "kvm_read: %s", kvm_geterr(kd));
- kvm_close(kd);
if (cur.msg_magic != MSG_MAGIC)
errx(1, "magic number incorrect");
! if (cur.msg_bufx >= MSG_BSIZE)
cur.msg_bufx = 0;
/*
* The message buffer is circular; start at the read pointer, and
* go to the write pointer - 1.
*/
! p = cur.msg_bufc + cur.msg_bufx;
! ep = cur.msg_bufc + cur.msg_bufx - 1;
for (newl = skip = 0; p != ep; ++p) {
! if (p == cur.msg_bufc + MSG_BSIZE)
! p = cur.msg_bufc;
ch = *p;
/* Skip "\n<.*>" syslog sequences. */
if (skip) {
--- 116,142 ----
errx(1, "%s: msgbufp not found", nlistf ? nlistf : "namelist");
if (KREAD(nl[X_MSGBUF].n_value, bufp) || KREAD((long)bufp, cur))
errx(1, "kvm_read: %s", kvm_geterr(kd));
if (cur.msg_magic != MSG_MAGIC)
errx(1, "magic number incorrect");
! bufdata = malloc(cur.msg_bufs);
! if (bufdata == NULL)
! errx(1, "couldn't allocate space for buffer data");
! if (kvm_read(kd, (long)&bufp->msg_bufc, bufdata,
! cur.msg_bufs) != cur.msg_bufs)
! errx(1, "kvm_read: %s", kvm_geterr(kd));
! kvm_close(kd);
! if (cur.msg_bufx >= cur.msg_bufs)
cur.msg_bufx = 0;
/*
* The message buffer is circular; start at the read pointer, and
* go to the write pointer - 1.
*/
! p = bufdata + cur.msg_bufx;
! ep = bufdata + cur.msg_bufx - 1;
for (newl = skip = 0; p != ep; ++p) {
! if (p == bufdata + cur.msg_bufs)
! p = bufdata;
ch = *p;
/* Skip "\n<.*>" syslog sequences. */
if (skip) {
>Audit-Trail:
>Unformatted: