Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Feb 2017 18:25:06 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314397 - in head: share/man/man9 sys/kern
Message-ID:  <201702281825.v1SIP6qx075872@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Tue Feb 28 18:25:06 2017
New Revision: 314397
URL: https://svnweb.freebsd.org/changeset/base/314397

Log:
  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

Modified:
  head/share/man/man9/sbuf.9
  head/sys/kern/subr_prf.c

Modified: head/share/man/man9/sbuf.9
==============================================================================
--- head/share/man/man9/sbuf.9	Tue Feb 28 18:10:03 2017	(r314396)
+++ head/share/man/man9/sbuf.9	Tue Feb 28 18:25:06 2017	(r314397)
@@ -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

Modified: head/sys/kern/subr_prf.c
==============================================================================
--- head/sys/kern/subr_prf.c	Tue Feb 28 18:10:03 2017	(r314396)
+++ head/sys/kern/subr_prf.c	Tue Feb 28 18:25:06 2017	(r314397)
@@ -411,6 +411,23 @@ vprintf(const char *fmt, va_list ap)
 }
 
 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)
 {
 	/* Check if no console output buffer was provided. */
@@ -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
 	}
 }
 #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



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