From owner-freebsd-arch@FreeBSD.ORG Tue Sep 7 18:12:57 2010 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0E14B10656BE for ; Tue, 7 Sep 2010 18:12:57 +0000 (UTC) (envelope-from mdf356@gmail.com) Received: from mail-gx0-f182.google.com (mail-gx0-f182.google.com [209.85.161.182]) by mx1.freebsd.org (Postfix) with ESMTP id C05CC8FC14 for ; Tue, 7 Sep 2010 18:12:56 +0000 (UTC) Received: by gxk24 with SMTP id 24so2403257gxk.13 for ; Tue, 07 Sep 2010 11:12:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type; bh=lFW6ZDXwSh9s6egTfrHHohaZZWo0D+k3gMnXrXegLpA=; b=hFaU0Rrpg7jEBpRGFDIG3Ob9XwwuMiQoVijoYiRWxd8BlIwsZxjuWgX6OF5f0w9ewb aJvp2yrzPuwAZZjFdKc0MG3AasjzC0xyU+eUh2Xsf225CUorhYLvZi1P2n2IbnMDm4c3 Bya8eZTuKsO254dU8q+eM+w9XJrHzNYyyyXbg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; b=IA3UV2FgI7pe9tl/Ie5203HxkR0xLbfaL0ateZKhcaOq4MBvi+ZX+tlvX8GmXXFM7u JStHX/qz7oCJbf0+gF6yrLj7GEz9F9v07M7rJAwJ5tEwhfG7e6LRHL/TPV9QqR+xRtbM O24qxlJpnJArVI+TzkzeLkGy/jK0Leveav/NY= MIME-Version: 1.0 Received: by 10.100.57.1 with SMTP id f1mr149812ana.205.1283883175793; Tue, 07 Sep 2010 11:12:55 -0700 (PDT) Sender: mdf356@gmail.com Received: by 10.100.126.20 with HTTP; Tue, 7 Sep 2010 11:12:55 -0700 (PDT) Date: Tue, 7 Sep 2010 11:12:55 -0700 X-Google-Sender-Auth: EGoRbS9GjK4jwFwDqxOr0gw90Is Message-ID: From: mdf@FreeBSD.org To: FreeBSD Arch Content-Type: text/plain; charset=ISO-8859-1 Subject: Extending sbufs with a drain X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Sep 2010 18:12:57 -0000 Isilon developed a formatted print system basically in parallel with FreeBSD's sbuf code. One of the things isi_format has that sbuf is lacking is the comcept of a drain. Basically a drain is a way to limit the size of the sbuf and, instead of reallocating the buffer when it is full, the contents are flushed under the control of a callback to "elsewhere". The common drains used at Isilon are to flush to log(9), printf(9), and SYSCTL_OUT(9). One of the advantages to using drains is that formatted print functions don't need to know where the data is going; they just always print to an sbuf and let the caller of the formatted print function know what he intended with the data. The first two patches simplify the sbuf(9) code a little. http://people.freebsd.org/~mdf/0001-Replace-the-SBUF_OVERFLOWED-flag-with-an-s_error-cod.patch http://people.freebsd.org/~mdf/0002-Compare-SBUF_FREESPACE-against-0-instead-of-using-th.patch This is the main patch, which uses the drain functionality to extend sbufs (unless the drain is overridden), and also creates an initializer for draining to a sysctl_req. The man page changes are included in this patch. http://people.freebsd.org/~mdf/0003-Add-drain-functionality-to-sbufs.-The-drain-is-a-fun.patch I would like to commit this work later this week. One possibility to allow MFC is to package the drain variables (function pointer, argument, error code storage) into an sbuf_drain struct and use the s_unused field to point to a caller-supplied storage for the drain data. I didn't go this way since it seemed more awkward long term. There is a need for regression suite against libsbuf. I looked at the existing tests for libutil to try to understand it but the syntax of expected results was beyond my comprehension at this time. Questions? Comments? Bug reports? As I indicate in a comment in sbuf.h, it seems that the buffered printf(2) functionality could be implemented using sbufs as the buffer and different drains depending on which kind of printf is wanted: one drain to a string buffer ala sprintf, one to a FILE* ala fprintf, etc. This seems cleaner than the existing FAKE_FILE hack to get fprintf(2) to print to a string. However, the printf(2) code was also rather obtuse and I haven't had time to untangle it yet. Thanks, matthew