From owner-freebsd-bugs@FreeBSD.ORG Mon Jun 15 21:10:07 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 677851065830 for ; Mon, 15 Jun 2009 21:10:07 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 3F8A18FC12 for ; Mon, 15 Jun 2009 21:10:07 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n5FLA7qR045308 for ; Mon, 15 Jun 2009 21:10:07 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n5FLA7UI045306; Mon, 15 Jun 2009 21:10:07 GMT (envelope-from gnats) Resent-Date: Mon, 15 Jun 2009 21:10:07 GMT Resent-Message-Id: <200906152110.n5FLA7UI045306@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Kirill Stepanchuk Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B08921065893 for ; Mon, 15 Jun 2009 21:07:17 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id C47A08FC34 for ; Mon, 15 Jun 2009 21:07:15 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n5FL7FJO071484 for ; Mon, 15 Jun 2009 21:07:15 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id n5FL7FBU071482; Mon, 15 Jun 2009 21:07:15 GMT (envelope-from nobody) Message-Id: <200906152107.n5FL7FBU071482@www.freebsd.org> Date: Mon, 15 Jun 2009 21:07:15 GMT From: Kirill Stepanchuk To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/135608: sysctl should be able to handle byte values X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Jun 2009 21:10:12 -0000 >Number: 135608 >Category: kern >Synopsis: sysctl should be able to handle byte values >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Jun 15 21:10:06 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Kirill Stepanchuk >Release: HEAD >Organization: Sandvine >Environment: >Description: Here is a patch to allow the sysctl interface to export byte values properly. This is sometimes needed if certain hardware needs to store a value as a byte in a struct. The sysctl interface would assume that the value is an 'int', with extraneous bits coming from neighbouring fields. This change adds a byte handler that internally converts unsigned bytes to ints, and then exports them to sysctl like a regular unsigned integer. >How-To-Repeat: >Fix: Patch attached with submission follows: --- sysctl.h.orig 2009-06-15 16:58:07.961115600 -0400 +++ sysctl.h 2009-06-15 16:57:49.007384100 -0400 @@ -170,6 +170,7 @@ #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l) #define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l) +int sysctl_handle_byte(SYSCTL_HANDLER_ARGS); int sysctl_handle_int(SYSCTL_HANDLER_ARGS); int sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS); int sysctl_handle_long(SYSCTL_HANDLER_ARGS); @@ -287,6 +288,15 @@ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ arg, len, sysctl_handle_string, "A", __DESCR(descr)) +/* Oid for an unsigned byte. If ptr is NULL, val is returned. */ +#define SYSCTL_BYTE(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \ + ptr, val, sysctl_handle_byte, "IU", descr) + +#define SYSCTL_ADD_BYTE(ctx, parent, nbr, name, access, ptr, val, descr) \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \ + ptr, val, sysctl_handle_byte, "IU", descr) + /* Oid for an int. If ptr is NULL, val is returned. */ #define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \ --- kern_sysctl.c.orig 2009-06-15 16:59:21.041579100 -0400 +++ kern_sysctl.c 2009-06-15 16:59:03.103505100 -0400 @@ -906,6 +906,45 @@ */ /* + * Handle an unsigned byte, converting to an int in the process + * Two cases: + * a variable: point arg1 at it. + * a constant: pass it in arg2. + */ + +int +sysctl_handle_byte(SYSCTL_HANDLER_ARGS) +{ + int tmp, error = 0; + + /* + * Attempt to get a coherent snapshot by making a copy of the data. + * Convert unsigned byte to int + */ + if (arg1) + tmp = *(uint8_t *)arg1; + else + tmp = arg2; + error = SYSCTL_OUT(req, &tmp, sizeof(int)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else { + error = SYSCTL_IN(req, &tmp, sizeof(int)); + if (!error) { + if (tmp > 255 || tmp < 0) + error = EINVAL; + else + *(uint8_t*)arg1 = (uint8_t)tmp; + } + } + return (error); +} + +/* * Handle an int, signed or unsigned. * Two cases: * a variable: point arg1 at it. >Release-Note: >Audit-Trail: >Unformatted: