New diff after some feedback:

Restrict this to root only, since there might be sensitive
information in the output. e.g. fsck output revealing files.
Thanks Theo.

Use -s, since -c is already used in other BSDs.
I did not go with -a, since that does sth. slightly different on
FreeBSD. Thanks Olli.

Index: sbin/dmesg/dmesg.8
===================================================================
RCS file: /cvs/src/sbin/dmesg/dmesg.8,v
retrieving revision 1.14
diff -u -p -p -u -r1.14 dmesg.8
--- sbin/dmesg/dmesg.8  14 Aug 2013 06:32:35 -0000      1.14
+++ sbin/dmesg/dmesg.8  10 Dec 2014 21:36:00 -0000
@@ -38,6 +38,7 @@
 .Nd display the system message buffer
 .Sh SYNOPSIS
 .Nm dmesg
+.Op Fl s
 .Op Fl M Ar core
 .Op Fl N Ar system
 .Sh DESCRIPTION
@@ -57,6 +58,12 @@ Extract the name list from the specified
 .Ar system
 instead of the default
 .Pa /bsd .
+.It Fl s
+Display the contents of the console message buffer instead.
+This can be used to review
+.Xr rc 8
+system startup messages.
+This option is limited to the superuser.
 .El
 .Sh FILES
 .Bl -tag -width /var/run/dmesg.boot -compact
Index: sbin/dmesg/dmesg.c
===================================================================
RCS file: /cvs/src/sbin/dmesg/dmesg.c,v
retrieving revision 1.23
diff -u -p -p -u -r1.23 dmesg.c
--- sbin/dmesg/dmesg.c  22 Apr 2014 20:43:12 -0000      1.23
+++ sbin/dmesg/dmesg.c  10 Dec 2014 21:36:00 -0000
@@ -66,11 +66,15 @@ main(int argc, char *argv[])
        char *p;
        struct msgbuf cur;
        char *memf, *nlistf, *bufdata = NULL;
+       int startupmsgs = 0;
        char buf[5];
 
        memf = nlistf = NULL;
-       while ((ch = getopt(argc, argv, "M:N:")) != -1)
+       while ((ch = getopt(argc, argv, "sM:N:")) != -1)
                switch(ch) {
+               case 's':
+                       startupmsgs = 1;
+                       break;
                case 'M':
                        memf = optarg;
                        break;
@@ -89,7 +93,7 @@ main(int argc, char *argv[])
                size_t len;
 
                mib[0] = CTL_KERN;
-               mib[1] = KERN_MSGBUFSIZE;
+               mib[1] = startupmsgs ? KERN_CMSGBUFSIZE : KERN_MSGBUFSIZE;
                len = sizeof(msgbufsize);
                if (sysctl(mib, 2, &msgbufsize, &len, NULL, 0))
                        err(1, "sysctl: KERN_MSGBUFSIZE");
@@ -99,7 +103,7 @@ main(int argc, char *argv[])
                if (bufdata == NULL)
                        errx(1, "couldn't allocate space for buffer data");
 
-               mib[1] = KERN_MSGBUF;
+               mib[1] = startupmsgs ? KERN_CMSGBUF : KERN_MSGBUF;
                len = msgbufsize;
                if (sysctl(mib, 2, bufdata, &len, NULL, 0))
                        err(1, "sysctl: KERN_MSGBUF");
@@ -179,6 +183,6 @@ usage(void)
 {
        extern char *__progname;
 
-       fprintf(stderr, "usage: %s [-M core] [-N system]\n", __progname);
+       fprintf(stderr, "usage: %s [-s] [-M core] [-N system]\n", __progname);
        exit(1);
 }
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.274
diff -u -p -p -u -r1.274 kern_sysctl.c
--- sys/kern/kern_sysctl.c      5 Dec 2014 04:35:08 -0000       1.274
+++ sys/kern/kern_sysctl.c      10 Dec 2014 21:36:01 -0000
@@ -444,19 +444,30 @@ kern_sysctl(int *name, u_int namelen, vo
                return (sysctl_rdint(oldp, oldlenp, newp, 0));
 #endif
        case KERN_MSGBUFSIZE:
+       case KERN_CMSGBUFSIZE: {
+               struct msgbuf *mp;
+               mp = (name[0] == KERN_MSGBUFSIZE) ? msgbufp : cmsgbufp;
                /*
                 * deal with cases where the message buffer has
                 * become corrupted.
                 */
-               if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
+               if (!mp || mp->msg_magic != MSG_MAGIC)
                        return (ENXIO);
-               return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs));
-       case KERN_MSGBUF:
+               return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
+       }
+       case KERN_CMSGBUF:
+               if ((error = suser(p, 0)))
+                       return (error);
+               /* FALLTHROUGH */
+       case KERN_MSGBUF: {
+               struct msgbuf *mp;
+               mp = (name[0] == KERN_MSGBUF) ? msgbufp : cmsgbufp;
                /* see note above */
-               if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
+               if (!mp || mp->msg_magic != MSG_MAGIC)
                        return (ENXIO);
-               return (sysctl_rdstruct(oldp, oldlenp, newp, msgbufp,
-                   msgbufp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
+               return (sysctl_rdstruct(oldp, oldlenp, newp, mp,
+                   mp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
+       }
        case KERN_MALLOCSTATS:
                return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp,
                    newp, newlen, p));
Index: sys/kern/subr_log.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_log.c,v
retrieving revision 1.23
diff -u -p -p -u -r1.23 subr_log.c
--- sys/kern/subr_log.c 3 Nov 2014 03:08:00 -0000       1.23
+++ sys/kern/subr_log.c 10 Dec 2014 21:36:01 -0000
@@ -74,8 +74,9 @@ struct logsoftc {
 
 int    log_open;                       /* also used in log() */
 int    msgbufmapped;                   /* is the message buffer mapped */
-int    msgbufenabled;                  /* is logging to the buffer enabled */
+int    cmsgbufenabled;                 /* console buffer logging enabled */
 struct msgbuf *msgbufp;                /* the mapped buffer, itself. */
+struct msgbuf *cmsgbufp;               /* console messages buffer. */
 struct file *syslogf;
 
 void filt_logrdetach(struct knote *kn);
@@ -88,7 +89,7 @@ void
 initmsgbuf(caddr_t buf, size_t bufsize)
 {
        struct msgbuf *mbp;
-       long new_bufs;
+       long new_bufs, new_cbufs = 0;
 
        /* Sanity-check the given size. */
        if (bufsize < sizeof(struct msgbuf))
@@ -96,7 +97,14 @@ initmsgbuf(caddr_t buf, size_t bufsize)
 
        mbp = msgbufp = (struct msgbuf *)buf;
 
-       new_bufs = bufsize - offsetof(struct msgbuf, msg_bufc);
+       /*
+        * Init console message buffer logging,
+        * if it does not consume more than a quarter of the msgbuf space.
+        */
+       if (bufsize / 4 >= CMSGBUFSIZE) {
+               new_cbufs = CMSGBUFSIZE;
+       }
+       new_bufs = bufsize - offsetof(struct msgbuf, msg_bufc) - new_cbufs;
        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)) {
@@ -113,17 +121,23 @@ initmsgbuf(caddr_t buf, size_t bufsize)
        
        /* Always start new buffer data on a new line. */
        if (mbp->msg_bufx > 0 && mbp->msg_bufc[mbp->msg_bufx - 1] != '\n')
-               msgbuf_putchar('\n');
+               msgbuf_putchar(msgbufp, '\n');
 
+       if (new_cbufs) {
+               mbp = cmsgbufp = (struct msgbuf *)(buf + CMSGBUFSIZE);
+               new_bufs = CMSGBUFSIZE - offsetof(struct msgbuf, msg_bufc);
+               memset(mbp, 0, CMSGBUFSIZE);
+               mbp->msg_magic = MSG_MAGIC;
+               mbp->msg_bufs = new_bufs;
+               cmsgbufenabled = 1;
+       }
        /* mark it as ready for use. */
-       msgbufmapped = msgbufenabled = 1;
+       msgbufmapped = 1;
 }
 
 void
-msgbuf_putchar(const char c) 
+msgbuf_putchar(struct msgbuf *mbp, const char c) 
 {
-       struct msgbuf *mbp = msgbufp;
-
        if (mbp->msg_magic != MSG_MAGIC)
                /* Nothing we can do */
                return;
Index: sys/kern/subr_prf.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_prf.c,v
retrieving revision 1.83
diff -u -p -p -u -r1.83 subr_prf.c
--- sys/kern/subr_prf.c 13 Jul 2014 23:49:40 -0000      1.83
+++ sys/kern/subr_prf.c 10 Dec 2014 21:36:01 -0000
@@ -349,7 +349,7 @@ kputchar(int c, int flags, struct tty *t
                constty = NULL;
        if ((flags & TOLOG) &&
            c != '\0' && c != '\r' && c != 0177 && msgbufmapped)
-               msgbuf_putchar(c);
+               msgbuf_putchar(msgbufp, c);
        if ((flags & TOCONS) && (constty == NULL || ddb_active) && c != '\0')
                (*v_putc)(c);
 #ifdef DDB
Index: sys/kern/tty.c
===================================================================
RCS file: /cvs/src/sys/kern/tty.c,v
retrieving revision 1.116
diff -u -p -p -u -r1.116 tty.c
--- sys/kern/tty.c      1 Dec 2014 07:51:47 -0000       1.116
+++ sys/kern/tty.c      10 Dec 2014 21:36:01 -0000
@@ -51,6 +51,7 @@
 #include <sys/vnode.h>
 #include <sys/syslog.h>
 #include <sys/malloc.h>
+#include <sys/msgbuf.h>
 #include <sys/signalvar.h>
 #include <sys/resourcevar.h>
 #include <sys/sysctl.h>
@@ -60,6 +61,7 @@
 
 #include <sys/namei.h>
 
+#include <dev/cons.h>
 #include <dev/rndvar.h>
 
 #include "pty.h"
@@ -1783,6 +1785,17 @@ loop:
                        }
                        if (cc > obufcc)
                                obufcc = cc;
+
+                       /* duplicate /dev/console output into message buffer */
+                       if (cmsgbufenabled && cn_tab &&
+                           cn_tab->cn_dev == tp->t_dev && tp->t_gen == 0) {
+                               int i;
+                               for (i = 0; i < cc; i++) {
+                                       char c = cp[i];
+                                       if (c != '\0' && c != '\r' && c != 0177)
+                                               msgbuf_putchar(cmsgbufp, c);
+                               }
+                       }
                }
                /*
                 * If nothing fancy need be done, grab those characters we
Index: sys/sys/msgbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/msgbuf.h,v
retrieving revision 1.8
diff -u -p -p -u -r1.8 msgbuf.h
--- sys/sys/msgbuf.h    14 Apr 2005 21:58:50 -0000      1.8
+++ sys/sys/msgbuf.h    10 Dec 2014 21:36:01 -0000
@@ -42,8 +42,11 @@ struct       msgbuf {
        char    msg_bufc[1];            /* buffer */
 };
 #ifdef _KERNEL
+#define CMSGBUFSIZE    (4 * 4 * 1024)  /* console message buffer size */
 extern struct msgbuf *msgbufp;
+extern struct msgbuf *cmsgbufp;
+extern int cmsgbufenabled;
 
 void   initmsgbuf(caddr_t buf, size_t bufsize);
-void   msgbuf_putchar(const char c);
+void   msgbuf_putchar(struct msgbuf *, const char c);
 #endif
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.152
diff -u -p -p -u -r1.152 sysctl.h
--- sys/sys/sysctl.h    5 Dec 2014 04:12:48 -0000       1.152
+++ sys/sys/sysctl.h    10 Dec 2014 21:36:01 -0000
@@ -181,7 +181,9 @@ struct ctlname {
 #define        KERN_PROC_CWD           78      /* node: proc cwd */
 #define        KERN_PROC_NOBROADCASTKILL 79    /* node: proc no broadcast kill 
*/
 #define        KERN_PROC_VMMAP         80      /* node: proc vmmap */
-#define        KERN_MAXID              81      /* number of valid kern ids */
+#define        KERN_CMSGBUFSIZE        81      /* int: console message buffer 
size */
+#define        KERN_CMSGBUF            82      /* console message buffer */
+#define        KERN_MAXID              83      /* number of valid kern ids */
 
 #define        CTL_KERN_NAMES { \
        { 0, 0 }, \

Reply via email to