Implement sbuf_prf(), which takes an sbuf and outputs it
to stdout in the non-kernel case and to the console+log in the kernel case. For the kernel case it hooks the putbuf() machinery underneath printf(9) so that the buffer is written completely atomically and without a copy into another temporary buffer. This is useful for fixing compound console/log messages that become broken and interleaved when multiple threads are competing for the console. Reviewed by: ken, imp Sponsored by: Netflix
This commit is contained in:
parent
6d91604093
commit
388f3ce6c3
@ -57,7 +57,8 @@
|
||||
.Nm sbuf_delete ,
|
||||
.Nm sbuf_start_section ,
|
||||
.Nm sbuf_end_section ,
|
||||
.Nm sbuf_hexdump
|
||||
.Nm sbuf_hexdump ,
|
||||
.Nm sbuf_putbuf
|
||||
.Nd safe string composition
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
@ -124,6 +125,8 @@
|
||||
.Fa "const char *hdr"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn sbuf_putbuf "struct sbuf *s"
|
||||
.In sys/sysctl.h
|
||||
.Ft struct sbuf *
|
||||
.Fn sbuf_new_for_sysctl "struct sbuf *s" "char *buf" "int length" "struct sysctl_req *req"
|
||||
@ -472,6 +475,12 @@ representation of the bytes if possible.
|
||||
See the
|
||||
.Xr hexdump 3
|
||||
man page for more details on the interface.
|
||||
.Pp
|
||||
The
|
||||
.Fn sbuf_putbuf
|
||||
function printfs the sbuf to stdout if in userland, and to the console
|
||||
and log if in the kernel.
|
||||
It does not drain the buffer or update any pointers.
|
||||
.Sh NOTES
|
||||
If an operation caused an
|
||||
.Fa sbuf
|
||||
|
@ -410,6 +410,23 @@ vprintf(const char *fmt, va_list ap)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static void
|
||||
prf_putbuf(char *bufr, int flags, int pri)
|
||||
{
|
||||
|
||||
if (flags & TOLOG)
|
||||
msglogstr(bufr, pri, /*filter_cr*/1);
|
||||
|
||||
if (flags & TOCONS) {
|
||||
if ((panicstr == NULL) && (constty != NULL))
|
||||
msgbuf_addstr(&consmsgbuf, -1,
|
||||
bufr, /*filter_cr*/ 0);
|
||||
|
||||
if ((constty == NULL) ||(always_console_output))
|
||||
cnputs(bufr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
putbuf(int c, struct putchar_arg *ap)
|
||||
{
|
||||
@ -431,18 +448,7 @@ putbuf(int c, struct putchar_arg *ap)
|
||||
|
||||
/* Check if the buffer needs to be flushed. */
|
||||
if (ap->remain == 2 || c == '\n') {
|
||||
|
||||
if (ap->flags & TOLOG)
|
||||
msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1);
|
||||
|
||||
if (ap->flags & TOCONS) {
|
||||
if ((panicstr == NULL) && (constty != NULL))
|
||||
msgbuf_addstr(&consmsgbuf, -1,
|
||||
ap->p_bufr, /*filter_cr*/ 0);
|
||||
|
||||
if ((constty == NULL) ||(always_console_output))
|
||||
cnputs(ap->p_bufr);
|
||||
}
|
||||
prf_putbuf(ap->p_bufr, ap->flags, ap->pri);
|
||||
|
||||
ap->p_next = ap->p_bufr;
|
||||
ap->remain = ap->n_bufr;
|
||||
@ -1221,3 +1227,19 @@ counted_warning(unsigned *counter, const char *msg)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
void
|
||||
sbuf_putbuf(struct sbuf *sb)
|
||||
{
|
||||
|
||||
prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1);
|
||||
}
|
||||
#else
|
||||
void
|
||||
sbuf_putbuf(struct sbuf *sb)
|
||||
{
|
||||
|
||||
printf("%s", sbuf_data(sb));
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user