Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Dec 2000 20:23:43 +0100
From:      Poul-Henning Kamp <phk@freebsd.org>
To:        current@freebsd.org
Subject:   test/review: /dev/console logging patch
Message-ID:  <20743.977081023@critter>

next in thread | raw e-mail | index | archive | help

This patch is for the printf(9), log(9) & /dev/console stuff.
The result is that you can watch the output from /etc/rc in
your /var/log/messages.

Poul-Henning


1. Replace logwakeup() with msgbuftrigger++;  There is little
   point in calling a function to set a flag.

2. Keep better track of the syslog FAC/PRI code and try to DTRT
   if they mingle.

3. Log all writes to /dev/console to syslog with <console.info>
   priority.



Index: kern/subr_log.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_log.c,v
retrieving revision 1.41
diff -u -r1.41 subr_log.c
--- kern/subr_log.c	2000/12/15 21:23:32	1.41
+++ kern/subr_log.c	2000/12/17 10:41:09
@@ -56,7 +56,6 @@
 
 #define LOG_ASYNC	0x04
 #define LOG_RDWAIT	0x08
-#define LOG_NEEDWAKEUP	0x10
 
 static	d_open_t	logopen;
 static	d_close_t	logclose;
@@ -186,22 +185,13 @@
 	return (revents);
 }
 
-void
-logwakeup(void)
-{
-
-	if (!log_open)
-		return;
-	logsoftc.sc_state |= LOG_NEEDWAKEUP;
-}
-
 static void
 logtimeout(void *arg)
 {
 
-	if ((logsoftc.sc_state & LOG_NEEDWAKEUP) == 0)
+	if (msgbuftrigger == 0)
 		return;
-	logsoftc.sc_state &= ~LOG_NEEDWAKEUP;
+	msgbuftrigger = 0;
 	if (!log_open)
 		return;
 	selwakeup(&logsoftc.sc_selp);
Index: kern/subr_prf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_prf.c,v
retrieving revision 1.66
diff -u -r1.66 subr_prf.c
--- kern/subr_prf.c	2000/11/26 20:35:18	1.66
+++ kern/subr_prf.c	2000/12/17 19:11:02
@@ -48,6 +48,7 @@
 #include <sys/tty.h>
 #include <sys/syslog.h>
 #include <sys/cons.h>
+#include <sys/uio.h>
 
 /*
  * Note that stdarg.h and the ANSI style va_start macro is used for both
@@ -64,6 +65,7 @@
 
 struct putchar_arg {
 	int	flags;
+	int	pri;
 	struct	tty *tty;
 };
 
@@ -72,11 +74,13 @@
 	size_t	remain;
 };
 
+extern	int log_open;
+
 struct	tty *constty;			/* pointer to console "window" tty */
 
 static void (*v_putc)(int) = cnputc;	/* routine to putc on virtual console */
-static void  logpri __P((int level));
-static void  msglogchar(int c, void *dummyarg);
+static void  msglogchar(int c, int pri);
+static void  msgaddchar(int c, void *dummy);
 static void  putchar __P((int ch, void *arg));
 static char *ksprintn __P((char *nbuf, u_long num, int base, int *len));
 static char *ksprintqn __P((char *nbuf, u_quad_t num, int base, int *len));
@@ -84,13 +88,13 @@
 
 static int consintr = 1;		/* Ok to handle console interrupts? */
 static int msgbufmapped;		/* Set when safe to use msgbuf */
+int msgbuftrigger = 0;
 
 /*
  * Warn that a system table is full.
  */
 void
-tablefull(tab)
-	const char *tab;
+tablefull(const char *tab)
 {
 
 	log(LOG_ERR, "%s: table is full\n", tab);
@@ -133,10 +137,8 @@
 	struct putchar_arg pca;
 	int retval;
 
-	if (pri != -1) {
-		logpri(pri);
+	if (pri != -1)
 		flags |= TOLOG;
-	}
 	if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
 		SESSHOLD(p->p_session);
 		shld++;
@@ -145,6 +147,7 @@
 			tp = p->p_session->s_ttyp;
 		}
 	}
+	pca.pri = pri;
 	pca.tty = tp;
 	pca.flags = flags;
 	va_start(ap, fmt);
@@ -152,7 +155,7 @@
 	va_end(ap);
 	if (shld)
 		SESSRELE(p->p_session);
-	logwakeup();
+	msgbuftrigger++;
 }
 
 /*
@@ -175,8 +178,6 @@
 	return retval;
 }
 
-extern	int log_open;
-
 /*
  * Log writes to the log buffer, and guarantees not to sleep (so can be
  * called by interrupt routines).  If there is no process reading the
@@ -185,41 +186,61 @@
 void
 log(int level, const char *fmt, ...)
 {
-	int s;
 	va_list ap;
 	int retval;
+	struct putchar_arg pca;
 
-	s = splhigh();
-	if (level != -1)
-		logpri(level);
-	va_start(ap, fmt);
+	pca.tty = NULL;
+	pca.pri = level;
+	pca.flags = log_open ? TOLOG : TOCONS;
 
-	retval = kvprintf(fmt, msglogchar, NULL, 10, ap);
+	va_start(ap, fmt);
+	retval = kvprintf(fmt, putchar, &pca, 10, ap);
 	va_end(ap);
 
-	splx(s);
-	if (!log_open) {
-		struct putchar_arg pca;
-		va_start(ap, fmt);
-		pca.tty = NULL;
-		pca.flags = TOCONS;
-		retval += kvprintf(fmt, putchar, &pca, 10, ap);
-		va_end(ap);
-	}
-	logwakeup();
+	msgbuftrigger++;
 }
 
-static void
-logpri(level)
-	int level;
-{
-	char nbuf[MAXNBUF];
-	char *p;
+#define CONSCHUNK 128
 
-	msglogchar('<', NULL);
-	for (p = ksprintn(nbuf, (u_long)level, 10, NULL); *p;)
-		msglogchar(*p--, NULL);
-	msglogchar('>', NULL);
+void
+log_console(struct uio *uio)
+{
+	int c, i, error, iovlen, nl;
+	struct uio muio;
+	struct iovec *miov = NULL;
+	char *consbuffer;
+	int pri;
+
+	pri = LOG_INFO | LOG_CONSOLE;
+	muio = *uio;
+	iovlen = uio->uio_iovcnt * sizeof (struct iovec);
+	MALLOC(miov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+	MALLOC(consbuffer, char *, CONSCHUNK, M_TEMP, M_WAITOK);
+	bcopy((caddr_t)muio.uio_iov, (caddr_t)miov, iovlen);
+	muio.uio_iov = miov;
+	uio = &muio;
+
+	nl = 0;
+	while (uio->uio_resid > 0) {
+		c = imin(uio->uio_resid, CONSCHUNK);
+		error = uiomove(consbuffer, c, uio);
+		if (error != 0)
+			return;
+		for (i = 0; i < c; i++) {
+			msglogchar(consbuffer[i], pri);
+			if (consbuffer[i] == '\n')
+				nl = 1;
+			else
+				nl = 0;
+		}
+	}
+	if (!nl)
+		msglogchar('\n', pri);
+	msgbuftrigger++;
+	FREE(miov, M_TEMP);
+	FREE(consbuffer, M_TEMP);
+	return;
 }
 
 int
@@ -235,10 +256,11 @@
 	va_start(ap, fmt);
 	pca.tty = NULL;
 	pca.flags = TOCONS | TOLOG;
+	pca.pri = -1;
 	retval = kvprintf(fmt, putchar, &pca, 10, ap);
 	va_end(ap);
 	if (!panicstr)
-		logwakeup();
+		msgbuftrigger++;
 	consintr = savintr;		/* reenable interrupts */
 	return retval;
 }
@@ -254,9 +276,10 @@
 	consintr = 0;
 	pca.tty = NULL;
 	pca.flags = TOCONS | TOLOG;
+	pca.pri = -1;
 	retval = kvprintf(fmt, putchar, &pca, 10, ap);
 	if (!panicstr)
-		logwakeup();
+		msgbuftrigger++;
 	consintr = savintr;		/* reenable interrupts */
 	return retval;
 }
@@ -282,7 +305,7 @@
 	    (flags & TOCONS) && tp == constty)
 		constty = NULL;
 	if ((flags & TOLOG))
-		msglogchar(c, NULL);
+		msglogchar(c, ap->pri);
 	if ((flags & TOCONS) && constty == NULL && c != '\0')
 		(*v_putc)(c);
 }
@@ -703,23 +726,58 @@
 }
 
 /*
- * Put character in log buffer.
+ * Put character in log buffer with a particular priority.
  */
 static void
-msglogchar(int c, void *dummyarg)
+msglogchar(int c, int pri)
 {
-	struct msgbuf *mbp;
+	static int lastpri = -1;
+	static int dangling;
+	char nbuf[MAXNBUF];
+	char *p;
 
-	if (c != '\0' && c != '\r' && c != 0177 && msgbufmapped) {
-		mbp = msgbufp;
-		mbp->msg_ptr[mbp->msg_bufx++] = c;
-		if (mbp->msg_bufx >= mbp->msg_size)
-			mbp->msg_bufx = 0;
-		/* If the buffer is full, keep the most recent data. */
-		if (mbp->msg_bufr == mbp->msg_bufx) {
-			if (++mbp->msg_bufr >= mbp->msg_size)
-				mbp->msg_bufr = 0;
+	if (!msgbufmapped)
+		return;
+	if (c == '\0' || c == '\r')
+		return;
+	if (pri != -1 && pri != lastpri) {
+		if (dangling) {
+			msgaddchar('\n', NULL);
+			dangling = 0;
 		}
+		msgaddchar('<', NULL);
+		for (p = ksprintn(nbuf, (u_long)pri, 10, NULL); *p;)
+			msgaddchar(*p--, NULL);
+		msgaddchar('>', NULL);
+		lastpri = pri;
+	}
+	msgaddchar(c, NULL);
+	if (c == '\n') {
+		dangling = 0;
+		lastpri = -1;
+	} else {
+		dangling = 1;
+	}
+}
+
+/*
+ * Put char in log buffer
+ */
+static void
+msgaddchar(int c, void *dummy)
+{
+	struct msgbuf *mbp;
+
+	if (!msgbufmapped)
+		return;
+	mbp = msgbufp;
+	mbp->msg_ptr[mbp->msg_bufx++] = c;
+	if (mbp->msg_bufx >= mbp->msg_size)
+		mbp->msg_bufx = 0;
+	/* If the buffer is full, keep the most recent data. */
+	if (mbp->msg_bufr == mbp->msg_bufx) {
+		if (++mbp->msg_bufr >= mbp->msg_size)
+			mbp->msg_bufr = 0;
 	}
 }
 
@@ -730,7 +788,7 @@
 
 	pos = oldp->msg_bufr;
 	while (pos != oldp->msg_bufx) {
-		msglogchar(oldp->msg_ptr[pos], NULL);
+		msglogchar(oldp->msg_ptr[pos], -1);
 		if (++pos >= oldp->msg_size)
 			pos = 0;
 	}
Index: kern/tty_cons.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_cons.c,v
retrieving revision 1.87
diff -u -r1.87 tty_cons.c
--- kern/tty_cons.c	2000/12/12 21:20:48	1.87
+++ kern/tty_cons.c	2000/12/13 11:28:56
@@ -353,6 +353,7 @@
 		dev = constty->t_dev;
 	else
 		dev = cn_tab->cn_dev;
+	log_console(uio);
 	return ((*devsw(dev)->d_write)(dev, uio, flag));
 }
 
Index: sys/msgbuf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/msgbuf.h,v
retrieving revision 1.14
diff -u -r1.14 msgbuf.h
--- sys/msgbuf.h	2000/01/29 15:29:11	1.14
+++ sys/msgbuf.h	2000/12/17 10:38:45
@@ -47,7 +47,7 @@
 };
 
 #ifdef _KERNEL
-extern int	msgbufmapped;
+extern int	msgbuftrigger;
 extern struct	msgbuf *msgbufp;
 void	msgbufinit	__P((void *ptr, size_t size));
 
Index: sys/systm.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/systm.h,v
retrieving revision 1.130
diff -u -r1.130 systm.h
--- sys/systm.h	2000/12/06 07:09:08	1.130
+++ sys/systm.h	2000/12/17 10:37:24
@@ -107,7 +107,7 @@
 int	kvprintf __P((char const *, void (*)(int, void*), void *, int,
 		      _BSD_VA_LIST_)) __printflike(1, 0);
 void	log __P((int, const char *, ...)) __printflike(2, 3);
-void	logwakeup __P((void));
+void	log_console __P((struct uio *));
 int	printf __P((const char *, ...)) __printflike(1, 2);
 int	snprintf __P((char *, size_t, const char *, ...)) __printflike(3, 4);
 int	sprintf __P((char *buf, const char *, ...)) __printflike(2, 3);
--
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20743.977081023>