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).
This commit is contained in:
parent
05d0cf88f1
commit
04b71d6b6d
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
pca.tty = NULL;
|
||||
pca.pri = level;
|
||||
pca.flags = log_open ? TOLOG : TOCONS;
|
||||
|
||||
s = splhigh();
|
||||
if (level != -1)
|
||||
logpri(level);
|
||||
va_start(ap, fmt);
|
||||
|
||||
retval = kvprintf(fmt, msglogchar, NULL, 10, ap);
|
||||
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)
|
||||
{
|
||||
static int lastpri = -1;
|
||||
static int dangling;
|
||||
char nbuf[MAXNBUF];
|
||||
char *p;
|
||||
|
||||
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 (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;
|
||||
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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ struct msgbuf {
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern int msgbufmapped;
|
||||
extern int msgbuftrigger;
|
||||
extern struct msgbuf *msgbufp;
|
||||
void msgbufinit __P((void *ptr, size_t size));
|
||||
|
||||
|
@ -107,7 +107,7 @@ void tablefull __P((const char *));
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user