Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 May 2011 14:00:18 -0700
From:      mdf@FreeBSD.org
To:        "Kenneth D. Merry" <ken@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r222537 - in head/sys: kern sys
Message-ID:  <BANLkTim1AQQj1BfqHtYfPWrvaQBp41qDNw@mail.gmail.com>
In-Reply-To: <201105311729.p4VHTwrZ033296@svn.freebsd.org>
References:  <201105311729.p4VHTwrZ033296@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, May 31, 2011 at 10:29 AM, Kenneth D. Merry <ken@freebsd.org> wrote:
> Author: ken
> Date: Tue May 31 17:29:58 2011
> New Revision: 222537
> URL: http://svn.freebsd.org/changeset/base/222537
>
> Log:
> =A0Fix apparent garbage in the message buffer.
>
> =A0While we have had a fix in place (options PRINTF_BUFR_SIZE=3D128) to f=
ix
> =A0scrambled console output, the message buffer and syslog were still get=
ting
> =A0log messages one character at a time. =A0While all of the characters s=
till
> =A0made it into the log (courtesy of atomic operations), they were often
> =A0interleaved when there were multiple threads writing to the buffer at =
the
> =A0same time.

This seems to panic my box with "lock "msgbuf" 0xfffffe0127ffffe0
already initialized".

Unfortunately, though I booted with a fresh CURRENT this morning
successfully, both /boot/kernel and /boot/kernel.old give this panic.
To add insult to injury, when the kernel drops into the debugger, my
keyboard input no longer works so I can't get a stack, etc.

So:

1) Is there anything else I can do to help debug this?
2) how can I resurrect this box without a reinstall?

I will try to repro on a virtual machine so I have a snapshot to come back =
to.

Thanks,
matthew

> =A0This fixes message buffer accesses to use buffering logic as well, so =
that
> =A0strings that are less than PRINTF_BUFR_SIZE will be put into the messa=
ge
> =A0buffer atomically. =A0So now dmesg output should look the same as cons=
ole
> =A0output.
>
> =A0subr_msgbuf.c: =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Convert most message buf=
fer calls to use a new spin
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lock instead of atomic var=
iables in some places.
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Add a new routine, msgbuf_=
addstr(), that adds a
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0NUL-terminated string to a=
 message buffer. =A0This
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0takes a priority argument,=
 which allows us to
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0eliminate some races (at l=
east in the the string
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0at a time case) that are p=
resent in the
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0implementation of msglogch=
ar(). =A0(dangling and
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lastpri are static variabl=
es, and are subject to
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0races when multiple caller=
s are present.)
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msgbuf_addstr() also allow=
s the caller to request
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0that carriage returns be s=
tripped out of the
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0string. =A0This matches th=
e behavior of msglogchar(),
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0but in testing so far it d=
oesn't appear that any
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0newlines are being strippe=
d out. =A0So the carriage
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return removal functionali=
ty may be a candidate
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for removal later on if fu=
rther analysis shows
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0that it isn't necessary.
>
> =A0subr_prf.c: =A0 =A0 =A0 =A0 =A0 Add a new msglogstr() routine that cal=
ls
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msgbuf_logstr().
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Rename putcons() to putbuf=
(). =A0This now handles
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0buffered output to the mes=
sage log as well as
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0the console. =A0Also, remo=
ve the logic in putcons()
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(now putbuf()) that added =
a carriage return before
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0a newline. =A0The console =
path was the only path that
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0needed it, and cnputc() (c=
alled by cnputs())
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0already adds a carriage re=
turn. =A0So this
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0duplication resulted in ke=
rnel-generated console
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0output lines ending in '\r=
''\r''\n'.
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Refactor putchar() to hand=
le the new buffering
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0scheme.
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Add buffering to log().
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Change log_console() to us=
e msglogstr() instead of
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msglogchar(). =A0Don't add=
 extra newlines by default
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0in log_console(). =A0Hide =
that behavior behind a
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tunable/sysctl (kern.log_c=
onsole_add_linefeed) for
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0those who would like the o=
ld behavior. =A0The old
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0behavior led to the insert=
ion of extra newlines
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for log output for program=
s that print out a
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0string, and then a trailin=
g newline on a separate
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0write. =A0(This is visible=
 with dmesg -a.)
>
> =A0msgbuf.h: =A0 =A0 =A0 =A0 =A0 =A0 Add a prototype for msgbuf_addstr().
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Add three new fields to st=
ruct msgbuf, msg_needsnl,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msg_lastpri and msg_lock. =
=A0The first two are needed
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for log message functional=
ity previously handled
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0by msglogchar(). =A0(Which=
 is still active if
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0buffering isn't enabled.)
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Include sys/lock.h and sys=
/mutex.h for the new
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mutex.
>
> =A0Reviewed by: =A0gibbs
>
> Modified:
> =A0head/sys/kern/subr_msgbuf.c
> =A0head/sys/kern/subr_prf.c
> =A0head/sys/sys/msgbuf.h
>
> Modified: head/sys/kern/subr_msgbuf.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/kern/subr_msgbuf.c Tue May 31 17:24:18 2011 =A0 =A0 =A0 =A0(=
r222536)
> +++ head/sys/kern/subr_msgbuf.c Tue May 31 17:29:58 2011 =A0 =A0 =A0 =A0(=
r222537)
> @@ -31,8 +31,16 @@
>
> =A0#include <sys/param.h>
> =A0#include <sys/systm.h>
> +#include <sys/lock.h>
> +#include <sys/mutex.h>
> =A0#include <sys/msgbuf.h>
>
> +/*
> + * Maximum number conversion buffer length: uintmax_t in base 2, plus <>
> + * around the priority, and a terminating NUL.
> + */
> +#define =A0 =A0 =A0 =A0MAXPRIBUF =A0 =A0 =A0 (sizeof(intmax_t) * NBBY + =
3)
> +
> =A0/* Read/write sequence numbers are modulo a multiple of the buffer siz=
e. */
> =A0#define SEQMOD(size) ((size) * 16)
>
> @@ -51,6 +59,9 @@ msgbuf_init(struct msgbuf *mbp, void *pt
> =A0 =A0 =A0 =A0mbp->msg_seqmod =3D SEQMOD(size);
> =A0 =A0 =A0 =A0msgbuf_clear(mbp);
> =A0 =A0 =A0 =A0mbp->msg_magic =3D MSG_MAGIC;
> + =A0 =A0 =A0 mbp->msg_lastpri =3D -1;
> + =A0 =A0 =A0 mbp->msg_needsnl =3D 0;
> + =A0 =A0 =A0 mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN);
> =A0}
>
> =A0/*
> @@ -80,6 +91,11 @@ msgbuf_reinit(struct msgbuf *mbp, void *
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msgbuf_clear(mbp);
> =A0 =A0 =A0 =A0}
> +
> + =A0 =A0 =A0 mbp->msg_lastpri =3D -1;
> + =A0 =A0 =A0 /* Assume that the old message buffer didn't end in a newli=
ne. */
> + =A0 =A0 =A0 mbp->msg_needsnl =3D 1;
> + =A0 =A0 =A0 mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN);
> =A0}
>
> =A0/*
> @@ -110,25 +126,140 @@ msgbuf_getcount(struct msgbuf *mbp)
> =A0}
>
> =A0/*
> - * Append a character to a message buffer. =A0This function can be
> - * considered fully reentrant so long as the number of concurrent
> - * callers is less than the number of characters in the buffer.
> - * However, the message buffer is only guaranteed to be consistent
> - * for reading when there are no callers in this function.
> + * Add a character into the message buffer, and update the checksum and
> + * sequence number.
> + *
> + * The caller should hold the message buffer spinlock.
> + */
> +static inline void
> +msgbuf_do_addchar(struct msgbuf *mbp, u_int *seq, int c)
> +{
> + =A0 =A0 =A0 u_int pos;
> +
> + =A0 =A0 =A0 /* Make sure we properly wrap the sequence number. */
> + =A0 =A0 =A0 pos =3D MSGBUF_SEQ_TO_POS(mbp, *seq);
> +
> + =A0 =A0 =A0 mbp->msg_cksum +=3D (u_int)c -
> + =A0 =A0 =A0 =A0 =A0 (u_int)(u_char)mbp->msg_ptr[pos];
> +
> + =A0 =A0 =A0 mbp->msg_ptr[pos] =3D c;
> +
> + =A0 =A0 =A0 *seq =3D MSGBUF_SEQNORM(mbp, *seq + 1);
> +}
> +
> +/*
> + * Append a character to a message buffer.
> =A0*/
> =A0void
> =A0msgbuf_addchar(struct msgbuf *mbp, int c)
> =A0{
> - =A0 =A0 =A0 u_int new_seq, pos, seq;
> + =A0 =A0 =A0 mtx_lock_spin(&mbp->msg_lock);
> +
> + =A0 =A0 =A0 msgbuf_do_addchar(mbp, &mbp->msg_wseq, c);
> +
> + =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> +}
> +
> +/*
> + * Append a NUL-terminated string with a priority to a message buffer.
> + * Filter carriage returns if the caller requests it.
> + *
> + * XXX The carriage return filtering behavior is present in the
> + * msglogchar() API, however testing has shown that we don't seem to sen=
d
> + * carriage returns down this path. =A0So do we still need it?
> + */
> +void
> +msgbuf_addstr(struct msgbuf *mbp, int pri, char *str, int filter_cr)
> +{
> + =A0 =A0 =A0 u_int seq;
> + =A0 =A0 =A0 size_t len, prefix_len;
> + =A0 =A0 =A0 char prefix[MAXPRIBUF];
> + =A0 =A0 =A0 int nl, i;
> +
> + =A0 =A0 =A0 len =3D strlen(str);
> + =A0 =A0 =A0 prefix_len =3D 0;
> + =A0 =A0 =A0 nl =3D 0;
> +
> + =A0 =A0 =A0 /* If we have a zero-length string, no need to do anything.=
 */
> + =A0 =A0 =A0 if (len =3D=3D 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> +
> + =A0 =A0 =A0 mtx_lock_spin(&mbp->msg_lock);
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* If this is true, we may need to insert a new priority =
sequence,
> + =A0 =A0 =A0 =A0* so prepare the prefix.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (pri !=3D -1)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 prefix_len =3D sprintf(prefix, "<%d>", pri)=
;
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Starting write sequence number.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 seq =3D mbp->msg_wseq;
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Whenever there is a change in priority, we have to ins=
ert a
> + =A0 =A0 =A0 =A0* newline, and a priority prefix if the priority is not =
-1. =A0Here
> + =A0 =A0 =A0 =A0* we detect whether there was a priority change, and whe=
ther we
> + =A0 =A0 =A0 =A0* did not end with a newline. =A0If that is the case, we=
 need to
> + =A0 =A0 =A0 =A0* insert a newline before this string.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (mbp->msg_lastpri !=3D pri && mbp->msg_needsnl !=3D 0) {
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msgbuf_do_addchar(mbp, &seq, '\n');
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mbp->msg_needsnl =3D 0;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 for (i =3D 0; i < len; i++) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* If we just had a newline, and the prio=
rity is not -1
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* (and therefore prefix_len !=3D 0), the=
n we need a priority
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* prefix for this line.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (mbp->msg_needsnl =3D=3D 0 && prefix_len=
 !=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int j;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (j =3D 0; j < prefix_le=
n; j++)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msgbuf_do_a=
ddchar(mbp, &seq, prefix[j]);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* Don't copy carriage returns if the cal=
ler requested
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* filtering.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* XXX This matches the behavior of msglo=
gchar(), but is it
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* necessary? =A0Testing has shown that w=
e don't seem to get
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* carriage returns here.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((filter_cr !=3D 0) && (str[i] =3D=3D '\=
r'))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* Clear this flag if we see a newline. =
=A0This affects whether
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* we need to insert a new prefix or inse=
rt a newline later.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (str[i] =3D=3D '\n')
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mbp->msg_needsnl =3D 0;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mbp->msg_needsnl =3D 1;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msgbuf_do_addchar(mbp, &seq, str[i]);
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Update the write sequence number for the actual number=
 of
> + =A0 =A0 =A0 =A0* characters we put in the message buffer. =A0(Depends o=
n whether
> + =A0 =A0 =A0 =A0* carriage returns are filtered.)
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 mbp->msg_wseq =3D seq;
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Set the last priority.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 mbp->msg_lastpri =3D pri;
> +
> + =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
>
> - =A0 =A0 =A0 do {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 seq =3D mbp->msg_wseq;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_seq =3D MSGBUF_SEQNORM(mbp, seq + 1);
> - =A0 =A0 =A0 } while (atomic_cmpset_rel_int(&mbp->msg_wseq, seq, new_seq=
) =3D=3D 0);
> - =A0 =A0 =A0 pos =3D MSGBUF_SEQ_TO_POS(mbp, seq);
> - =A0 =A0 =A0 atomic_add_int(&mbp->msg_cksum, (u_int)(u_char)c -
> - =A0 =A0 =A0 =A0 =A0 (u_int)(u_char)mbp->msg_ptr[pos]);
> - =A0 =A0 =A0 mbp->msg_ptr[pos] =3D c;
> =A0}
>
> =A0/*
> @@ -141,14 +272,21 @@ msgbuf_getchar(struct msgbuf *mbp)
> =A0 =A0 =A0 =A0u_int len, wseq;
> =A0 =A0 =A0 =A0int c;
>
> + =A0 =A0 =A0 mtx_lock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0wseq =3D mbp->msg_wseq;
> =A0 =A0 =A0 =A0len =3D MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq);
> - =A0 =A0 =A0 if (len =3D=3D 0)
> + =A0 =A0 =A0 if (len =3D=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (-1);
> + =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0if (len > mbp->msg_size)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mbp->msg_rseq =3D MSGBUF_SEQNORM(mbp, wseq=
 - mbp->msg_size);
> =A0 =A0 =A0 =A0c =3D (u_char)mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, mbp->msg=
_rseq)];
> =A0 =A0 =A0 =A0mbp->msg_rseq =3D MSGBUF_SEQNORM(mbp, mbp->msg_rseq + 1);
> +
> + =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0return (c);
> =A0}
>
> @@ -161,10 +299,14 @@ msgbuf_getbytes(struct msgbuf *mbp, char
> =A0{
> =A0 =A0 =A0 =A0u_int len, pos, wseq;
>
> + =A0 =A0 =A0 mtx_lock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0wseq =3D mbp->msg_wseq;
> =A0 =A0 =A0 =A0len =3D MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq);
> - =A0 =A0 =A0 if (len =3D=3D 0)
> + =A0 =A0 =A0 if (len =3D=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (0);
> + =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0if (len > mbp->msg_size) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mbp->msg_rseq =3D MSGBUF_SEQNORM(mbp, wseq=
 - mbp->msg_size);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0len =3D mbp->msg_size;
> @@ -175,6 +317,9 @@ msgbuf_getbytes(struct msgbuf *mbp, char
>
> =A0 =A0 =A0 =A0bcopy(&mbp->msg_ptr[pos], buf, len);
> =A0 =A0 =A0 =A0mbp->msg_rseq =3D MSGBUF_SEQNORM(mbp, mbp->msg_rseq + len)=
;
> +
> + =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0return (len);
> =A0}
>
> @@ -193,16 +338,21 @@ msgbuf_peekbytes(struct msgbuf *mbp, cha
> =A0{
> =A0 =A0 =A0 =A0u_int len, pos, wseq;
>
> + =A0 =A0 =A0 mtx_lock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0if (buf =3D=3D NULL) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Just initialise *seqp. */
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*seqp =3D MSGBUF_SEQNORM(mbp, mbp->msg_wse=
q - mbp->msg_size);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (0);
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0wseq =3D mbp->msg_wseq;
> =A0 =A0 =A0 =A0len =3D MSGBUF_SEQSUB(mbp, wseq, *seqp);
> - =A0 =A0 =A0 if (len =3D=3D 0)
> + =A0 =A0 =A0 if (len =3D=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (0);
> + =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0if (len > mbp->msg_size) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*seqp =3D MSGBUF_SEQNORM(mbp, wseq - mbp->=
msg_size);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0len =3D mbp->msg_size;
> @@ -212,6 +362,9 @@ msgbuf_peekbytes(struct msgbuf *mbp, cha
> =A0 =A0 =A0 =A0len =3D min(len, (u_int)buflen);
> =A0 =A0 =A0 =A0bcopy(&mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, *seqp)], buf, l=
en);
> =A0 =A0 =A0 =A0*seqp =3D MSGBUF_SEQNORM(mbp, *seqp + len);
> +
> + =A0 =A0 =A0 mtx_unlock_spin(&mbp->msg_lock);
> +
> =A0 =A0 =A0 =A0return (len);
> =A0}
>
>
> Modified: head/sys/kern/subr_prf.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/kern/subr_prf.c =A0 =A0Tue May 31 17:24:18 2011 =A0 =A0 =A0 =
=A0(r222536)
> +++ head/sys/kern/subr_prf.c =A0 =A0Tue May 31 17:29:58 2011 =A0 =A0 =A0 =
=A0(r222537)
> @@ -94,6 +94,7 @@ struct snprintf_arg {
> =A0extern int log_open;
>
> =A0static void =A0msglogchar(int c, int pri);
> +static void =A0msglogstr(char *str, int pri, int filter_cr);
> =A0static void =A0putchar(int ch, void *arg);
> =A0static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, i=
nt upper);
> =A0static void =A0snprintf_func(int ch, void *arg);
> @@ -106,6 +107,14 @@ TUNABLE_INT("kern.log_console_output", &
> =A0SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,
> =A0 =A0 &log_console_output, 0, "Duplicate console output to the syslog."=
);
>
> +/*
> + * See the comment in log_console() below for more explanation of this.
> + */
> +static int log_console_add_linefeed =3D 0;
> +TUNABLE_INT("kern.log_console_add_linefeed", &log_console_add_linefeed);
> +SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RW,
> + =A0 =A0&log_console_add_linefeed, 0, "log_console() adds extra newlines=
.");
> +
> =A0static int =A0 =A0 always_console_output =3D 0;
> =A0TUNABLE_INT("kern.always_console_output", &always_console_output);
> =A0SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW,
> @@ -240,16 +249,37 @@ log(int level, const char *fmt, ...)
> =A0{
> =A0 =A0 =A0 =A0va_list ap;
> =A0 =A0 =A0 =A0struct putchar_arg pca;
> +#ifdef PRINTF_BUFR_SIZE
> + =A0 =A0 =A0 char bufr[PRINTF_BUFR_SIZE];
> +#endif
>
> =A0 =A0 =A0 =A0pca.tty =3D NULL;
> =A0 =A0 =A0 =A0pca.pri =3D level;
> =A0 =A0 =A0 =A0pca.flags =3D log_open ? TOLOG : TOCONS;
> +#ifdef PRINTF_BUFR_SIZE
> + =A0 =A0 =A0 pca.p_bufr =3D bufr;
> + =A0 =A0 =A0 pca.p_next =3D pca.p_bufr;
> + =A0 =A0 =A0 pca.n_bufr =3D sizeof(bufr);
> + =A0 =A0 =A0 pca.remain =3D sizeof(bufr);
> + =A0 =A0 =A0 *pca.p_next =3D '\0';
> +#else
> =A0 =A0 =A0 =A0pca.p_bufr =3D NULL;
> +#endif
>
> =A0 =A0 =A0 =A0va_start(ap, fmt);
> =A0 =A0 =A0 =A0kvprintf(fmt, putchar, &pca, 10, ap);
> =A0 =A0 =A0 =A0va_end(ap);
>
> +#ifdef PRINTF_BUFR_SIZE
> + =A0 =A0 =A0 /* Write any buffered console/log output: */
> + =A0 =A0 =A0 if (*pca.p_bufr !=3D '\0') {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (pca.flags & TOLOG)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogstr(pca.p_bufr, level=
, /*filter_cr*/1);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (pca.flags & TOCONS)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cnputs(pca.p_bufr);
> + =A0 =A0 =A0 }
> +#endif
> =A0 =A0 =A0 =A0msgbuftrigger =3D 1;
> =A0}
>
> @@ -258,7 +288,7 @@ log(int level, const char *fmt, ...)
> =A0void
> =A0log_console(struct uio *uio)
> =A0{
> - =A0 =A0 =A0 int c, i, error, nl;
> + =A0 =A0 =A0 int c, error, nl;
> =A0 =A0 =A0 =A0char *consbuffer;
> =A0 =A0 =A0 =A0int pri;
>
> @@ -271,20 +301,48 @@ log_console(struct uio *uio)
>
> =A0 =A0 =A0 =A0nl =3D 0;
> =A0 =A0 =A0 =A0while (uio->uio_resid > 0) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 c =3D imin(uio->uio_resid, CONSCHUNK);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 c =3D imin(uio->uio_resid, CONSCHUNK - 1);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0error =3D uiomove(consbuffer, c, uio);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (error !=3D 0)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D 0; i < c; i++) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogchar(consbuffer[i], p=
ri);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (consbuffer[i] =3D=3D '\=
n')
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nl =3D 1;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nl =3D 0;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Make sure we're NUL-terminated */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 consbuffer[c] =3D '\0';
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (consbuffer[c - 1] =3D=3D '\n')
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nl =3D 1;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nl =3D 0;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogstr(consbuffer, pri, /*filter_cr*/ 1)=
;
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* The previous behavior in log_console() is preserved wh=
en
> + =A0 =A0 =A0 =A0* log_console_add_linefeed is non-zero. =A0For that beha=
vior, if an
> + =A0 =A0 =A0 =A0* individual console write came in that was not terminat=
ed with a
> + =A0 =A0 =A0 =A0* line feed, it would add a line feed.
> + =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0* This results in different data in the message buffer t=
han
> + =A0 =A0 =A0 =A0* appears on the system console (which doesn't add extra=
 line feed
> + =A0 =A0 =A0 =A0* characters).
> + =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0* A number of programs and rc scripts write a line feed,=
 or a period
> + =A0 =A0 =A0 =A0* and a line feed when they have completed their operati=
on. =A0On
> + =A0 =A0 =A0 =A0* the console, this looks seamless, but when displayed w=
ith
> + =A0 =A0 =A0 =A0* 'dmesg -a', you wind up with output that looks like th=
is:
> + =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0* Updating motd:
> + =A0 =A0 =A0 =A0* .
> + =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0* On the console, it looks like this:
> + =A0 =A0 =A0 =A0* Updating motd:.
> + =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0* We could add logic to detect that situation, or just n=
ot insert
> + =A0 =A0 =A0 =A0* the extra newlines. =A0Set the kern.log_console_add_li=
nefeed
> + =A0 =A0 =A0 =A0* sysctl/tunable variable to get the old behavior.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (!nl && log_console_add_linefeed) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 consbuffer[0] =3D '\n';
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 consbuffer[1] =3D '\0';
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogstr(consbuffer, pri, /*filter_cr*/ 1)=
;
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 if (!nl)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogchar('\n', pri);
> =A0 =A0 =A0 =A0msgbuftrigger =3D 1;
> =A0 =A0 =A0 =A0free(uio, M_IOV);
> =A0 =A0 =A0 =A0free(consbuffer, M_TEMP);
> @@ -330,9 +388,11 @@ vprintf(const char *fmt, va_list ap)
> =A0 =A0 =A0 =A0retval =3D kvprintf(fmt, putchar, &pca, 10, ap);
>
> =A0#ifdef PRINTF_BUFR_SIZE
> - =A0 =A0 =A0 /* Write any buffered console output: */
> - =A0 =A0 =A0 if (*pca.p_bufr !=3D '\0')
> + =A0 =A0 =A0 /* Write any buffered console/log output: */
> + =A0 =A0 =A0 if (*pca.p_bufr !=3D '\0') {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cnputs(pca.p_bufr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogstr(pca.p_bufr, pca.pri, /*filter_cr*=
/ 1);
> + =A0 =A0 =A0 }
> =A0#endif
>
> =A0 =A0 =A0 =A0if (!panicstr)
> @@ -342,18 +402,18 @@ vprintf(const char *fmt, va_list ap)
> =A0}
>
> =A0static void
> -putcons(int c, struct putchar_arg *ap)
> +putbuf(int c, struct putchar_arg *ap)
> =A0{
> =A0 =A0 =A0 =A0/* Check if no console output buffer was provided. */
> - =A0 =A0 =A0 if (ap->p_bufr =3D=3D NULL)
> + =A0 =A0 =A0 if (ap->p_bufr =3D=3D NULL) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Output direct to the console. */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 cnputc(c);
> - =A0 =A0 =A0 else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->flags & TOCONS)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cnputc(c);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->flags & TOLOG)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogchar(c, ap->pri);
> + =A0 =A0 =A0 } else {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Buffer the character: */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (c =3D=3D '\n') {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ap->p_next++ =3D '\r';
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ap->remain--;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*ap->p_next++ =3D c;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ap->remain--;
>
> @@ -361,12 +421,35 @@ putcons(int c, struct putchar_arg *ap)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*ap->p_next =3D '\0';
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Check if the buffer needs to be flushed=
. */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->remain < 3 || c =3D=3D '\n') {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cnputs(ap->p_bufr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->remain =3D=3D 2 || c =3D=3D '\n') {
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->flags & TOLOG)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogstr(a=
p->p_bufr, ap->pri, /*filter_cr*/1);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ap->flags & TOCONS) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((panics=
tr =3D=3D NULL) && (constty !=3D NULL))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 msgbuf_addstr(&consmsgbuf, -1,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 ap->p_bufr, /*filter_cr*/ 0);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((constt=
y =3D=3D NULL) ||(always_console_output))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 cnputs(ap->p_bufr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ap->p_next =3D ap->p_bufr;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ap->remain =3D ap->n_bufr;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*ap->p_next =3D '\0';
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* Since we fill the buffer up one charac=
ter at a time,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* this should not happen. =A0We should a=
lways catch it when
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* ap->remain =3D=3D 2 (if not sooner due=
 to a newline), flush
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* the buffer and move on. =A0One way thi=
s could happen is
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* if someone sets PRINTF_BUFR_SIZE to 1 =
or something
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* similarly silly.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 KASSERT(ap->remain > 2, ("Bad buffer logic,=
 remain =3D %zd",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ap->remain));
> =A0 =A0 =A0 =A0}
> =A0}
>
> @@ -381,26 +464,25 @@ putchar(int c, void *arg)
> =A0 =A0 =A0 =A0struct putchar_arg *ap =3D (struct putchar_arg*) arg;
> =A0 =A0 =A0 =A0struct tty *tp =3D ap->tty;
> =A0 =A0 =A0 =A0int flags =3D ap->flags;
> + =A0 =A0 =A0 int putbuf_done =3D 0;
>
> =A0 =A0 =A0 =A0/* Don't use the tty code after a panic or while in ddb. *=
/
> =A0 =A0 =A0 =A0if (kdb_active) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (c !=3D '\0')
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cnputc(c);
> - =A0 =A0 =A0 } else if (panicstr || ((flags & TOCONS) && constty =3D=3D =
NULL)) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (c !=3D '\0')
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 putcons(c, ap);
> =A0 =A0 =A0 =A0} else {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((flags & TOTTY) && tp !=3D NULL)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((panicstr =3D=3D NULL) && (flags & TOTT=
Y) && (tp !=3D NULL))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tty_putchar(tp, c);
> +
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (flags & TOCONS) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (constty !=3D NULL)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msgbuf_addc=
har(&consmsgbuf, c);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (always_console_output &=
& c !=3D '\0')
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 putcons(c, =
ap);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 putbuf(c, ap);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 putbuf_done =3D 1;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 if ((flags & TOLOG))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 msglogchar(c, ap->pri);
> + =A0 =A0 =A0 if ((flags & TOLOG) && (putbuf_done =3D=3D 0)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (c !=3D '\0')
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 putbuf(c, ap);
> + =A0 =A0 =A0 }
> =A0}
>
> =A0/*
> @@ -890,6 +972,15 @@ msglogchar(int c, int pri)
> =A0 =A0 =A0 =A0}
> =A0}
>
> +static void
> +msglogstr(char *str, int pri, int filter_cr)
> +{
> + =A0 =A0 =A0 if (!msgbufmapped)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> +
> + =A0 =A0 =A0 msgbuf_addstr(msgbufp, pri, str, filter_cr);
> +}
> +
> =A0void
> =A0msgbufinit(void *ptr, int size)
> =A0{
>
> Modified: head/sys/sys/msgbuf.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/sys/msgbuf.h =A0 =A0 =A0 Tue May 31 17:24:18 2011 =A0 =A0 =
=A0 =A0(r222536)
> +++ head/sys/sys/msgbuf.h =A0 =A0 =A0 Tue May 31 17:29:58 2011 =A0 =A0 =
=A0 =A0(r222537)
> @@ -33,15 +33,21 @@
> =A0#ifndef _SYS_MSGBUF_H_
> =A0#define =A0 =A0 =A0 =A0_SYS_MSGBUF_H_
>
> +#include <sys/lock.h>
> +#include <sys/mutex.h>
> +
> =A0struct msgbuf {
> - =A0 =A0 =A0 char =A0 =A0*msg_ptr; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* pointe=
r to buffer */
> + =A0 =A0 =A0 char =A0 =A0 =A0 *msg_ptr; =A0 =A0 =A0 =A0 =A0 =A0/* pointe=
r to buffer */
> =A0#define =A0 =A0 =A0 =A0MSG_MAGIC =A0 =A0 =A0 0x063062
> - =A0 =A0 =A0 u_int =A0 msg_magic;
> - =A0 =A0 =A0 u_int =A0 msg_size; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* size of =
buffer area */
> - =A0 =A0 =A0 u_int =A0 msg_wseq; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* write se=
quence number */
> - =A0 =A0 =A0 u_int =A0 msg_rseq; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* read seq=
uence number */
> - =A0 =A0 =A0 u_int =A0 msg_cksum; =A0 =A0 =A0 =A0 =A0 =A0 =A0/* checksum=
 of contents */
> - =A0 =A0 =A0 u_int =A0 msg_seqmod; =A0 =A0 =A0 =A0 =A0 =A0 /* range for =
sequence numbers */
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_magic;
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_size; =A0 =A0 =A0 =A0 =A0 =A0/* size o=
f buffer area */
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_wseq; =A0 =A0 =A0 =A0 =A0 =A0/* write =
sequence number */
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_rseq; =A0 =A0 =A0 =A0 =A0 =A0/* read s=
equence number */
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_cksum; =A0 =A0 =A0 =A0 =A0 /* checksum=
 of contents */
> + =A0 =A0 =A0 u_int =A0 =A0 =A0msg_seqmod; =A0 =A0 =A0 =A0 =A0/* range fo=
r sequence numbers */
> + =A0 =A0 =A0 int =A0 =A0 =A0 =A0msg_lastpri; =A0 =A0 =A0 =A0 /* saved pr=
iority value */
> + =A0 =A0 =A0 int =A0 =A0 =A0 =A0msg_needsnl; =A0 =A0 =A0 =A0 /* set when=
 newline needed */
> + =A0 =A0 =A0 struct mtx msg_lock; =A0 =A0 =A0 =A0 =A0 =A0/* mutex to pro=
tect the buffer */
> =A0};
>
> =A0/* Normalise a sequence number or a difference between sequence number=
s. */
> @@ -59,6 +65,7 @@ extern struct mtx msgbuf_lock;
>
> =A0void =A0 msgbufinit(void *ptr, int size);
> =A0void =A0 msgbuf_addchar(struct msgbuf *mbp, int c);
> +void =A0 msgbuf_addstr(struct msgbuf *mbp, int pri, char *str, int filte=
r_cr);
> =A0void =A0 msgbuf_clear(struct msgbuf *mbp);
> =A0void =A0 msgbuf_copy(struct msgbuf *src, struct msgbuf *dst);
> =A0int =A0 =A0msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen);
> _______________________________________________
> svn-src-head@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org"
>



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