diff options
author | phk <phk@FreeBSD.org> | 2000-12-20 21:50:37 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2000-12-20 21:50:37 +0000 |
commit | 04b71d6b6d5b879ea0b817c773f4ce96507247f6 (patch) | |
tree | 18b700d20c419e56eb1134864e3113062e525f28 /sys/kern | |
parent | 05d0cf88f1bd8f0d0cc7cb861444fa750759e7ba (diff) | |
download | FreeBSD-src-04b71d6b6d5b879ea0b817c773f4ce96507247f6.zip FreeBSD-src-04b71d6b6d5b879ea0b817c773f4ce96507247f6.tar.gz |
Replace logwakeup() with "int msgbuftrigger". There is little
point in calling a function just to set a flag.
Keep better track of the syslog FAC/PRI code and try to DTRT if
they mingle.
Log all writes to /dev/console to syslog with <console.info>
priority. The formatting is not preserved, there is no robust,
way of doing it. (Ideas with patches welcome).
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_log.c | 14 | ||||
-rw-r--r-- | sys/kern/subr_prf.c | 162 | ||||
-rw-r--r-- | sys/kern/tty_cons.c | 1 |
3 files changed, 113 insertions, 64 deletions
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index 8580f79..d63dfb6 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -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 @@ logpoll(dev_t dev, int events, struct proc *p) 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); diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 4fb776b..2deea14 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -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 @@ struct snprintf_arg { 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 void snprintf_func __P((int ch, void *arg)); static int consintr = 1; /* Ok to handle console interrupts? */ static int msgbufmapped; /* Set when safe to use msgbuf */ +int msgbuftrigger; /* * 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 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) 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 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) tp = p->p_session->s_ttyp; } } + pca.pri = pri; pca.tty = tp; pca.flags = flags; va_start(ap, fmt); @@ -152,7 +155,7 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) va_end(ap); if (shld) SESSRELE(p->p_session); - logwakeup(); + msgbuftrigger = 1; } /* @@ -175,8 +178,6 @@ ttyprintf(struct tty *tp, const char *fmt, ...) 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 @@ extern int log_open; 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 = 1 } -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 = 1 + FREE(miov, M_TEMP); + FREE(consbuffer, M_TEMP); + return; } int @@ -235,10 +256,11 @@ printf(const char *fmt, ...) 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 = 1 consintr = savintr; /* reenable interrupts */ return retval; } @@ -254,9 +276,10 @@ vprintf(const char *fmt, va_list ap) consintr = 0; pca.tty = NULL; pca.flags = TOCONS | TOLOG; + pca.pri = -1; retval = kvprintf(fmt, putchar, &pca, 10, ap); if (!panicstr) - logwakeup(); + msgbuftrigger = 1 consintr = savintr; /* reenable interrupts */ return retval; } @@ -282,7 +305,7 @@ putchar(int c, void *arg) (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 @@ number: } /* - * 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 @@ msgbufcopy(struct msgbuf *oldp) 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; } diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c index d66a75f..784feca 100644 --- a/sys/kern/tty_cons.c +++ b/sys/kern/tty_cons.c @@ -353,6 +353,7 @@ cnwrite(dev, uio, flag) dev = constty->t_dev; else dev = cn_tab->cn_dev; + log_console(uio); return ((*devsw(dev)->d_write)(dev, uio, flag)); } |