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 }, \