Hi,

something that has often bothered me, is that once you hook up a
console to a headless server, you've missed all the output.
This makes it harder to diagnose bugs in rc(8) startup skripts
from remote. Another thing i've missed is that fsck(8) output
will just scroll by and is usually lost.

Why not dump the initial output from /dev/console into
a share of the system message buffer and make it readable
via dmesg -c?

Things like the fixed 16k size and bumping the message buffer
on various platforms need still to be discussed, but how's the
idea in general?

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  7 Dec 2014 12:47:40 -0000
@@ -38,6 +38,7 @@
 .Nd display the system message buffer
 .Sh SYNOPSIS
 .Nm dmesg
+.Op Fl c
 .Op Fl M Ar core
 .Op Fl N Ar system
 .Sh DESCRIPTION
@@ -57,6 +58,11 @@ Extract the name list from the specified
 .Ar system
 instead of the default
 .Pa /bsd .
+.It Fl c
+Display the contents of the console message buffer instead.
+This can be used to review
+.Xr rc 8
+system startup messages.
 .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  7 Dec 2014 12:47:40 -0000
@@ -66,11 +66,15 @@ main(int argc, char *argv[])
        char *p;
        struct msgbuf cur;
        char *memf, *nlistf, *bufdata = NULL;
+       int readconsolemsgs = 0;
        char buf[5];
 
        memf = nlistf = NULL;
-       while ((ch = getopt(argc, argv, "M:N:")) != -1)
+       while ((ch = getopt(argc, argv, "cM:N:")) != -1)
                switch(ch) {
+               case 'c':
+                       readconsolemsgs = 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] = readconsolemsgs ? 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] = readconsolemsgs ? 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 [-c] [-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      7 Dec 2014 12:47:40 -0000
@@ -444,19 +444,27 @@ 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));
+               return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
+       }
        case KERN_MSGBUF:
+       case KERN_CMSGBUF: {
+               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 7 Dec 2014 12:47:40 -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 7 Dec 2014 12:47:40 -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      7 Dec 2014 12:47:40 -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    7 Dec 2014 12:47:40 -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    7 Dec 2014 12:47:40 -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