From nobody@FreeBSD.org  Mon Jun 15 21:07:17 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id B08921065893
	for <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <kstepanchuk@sandvine.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: sysctl should be able to handle byte values
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         135608
>Category:       kern
>Synopsis:       [patch] sysctl(8) 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:  Sun Aug 23 07:21:28 UTC 2009
>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:

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org, kstepanchuk@sandvine.com
Cc:  
Subject: Re: kern/135608: sysctl should be able to handle byte values
Date: Wed, 17 Jun 2009 14:28:37 +0000 (UTC)

 Whomever will put that into the tree at one point (perhaps with a
 consumer), needs to to the V_irtualizing first.
 
 -- 
 Bjoern A. Zeeb                      The greatest risk is not taking one.
>Unformatted:
