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>