From owner-freebsd-current Sun Dec 17 11:23:54 2000 From owner-freebsd-current@FreeBSD.ORG Sun Dec 17 11:23:44 2000 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from critter.freebsd.dk (flutter.freebsd.dk [212.242.40.147]) by hub.freebsd.org (Postfix) with ESMTP id F136E37B402 for ; Sun, 17 Dec 2000 11:23:43 -0800 (PST) Received: from critter (localhost [127.0.0.1]) by critter.freebsd.dk (8.11.1/8.11.1) with ESMTP id eBHJNhf20745 for ; Sun, 17 Dec 2000 20:23:43 +0100 (CET) (envelope-from phk@critter.freebsd.dk) To: current@freebsd.org Subject: test/review: /dev/console logging patch From: Poul-Henning Kamp Date: Sun, 17 Dec 2000 20:23:43 +0100 Message-ID: <20743.977081023@critter> Sender: phk@critter.freebsd.dk Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 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 #include #include +#include /* * 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