kern/135608: sysctl should be able to handle byte values

Kirill Stepanchuk kstepanchuk at sandvine.com
Mon Jun 15 21:10:12 UTC 2009


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


More information about the freebsd-bugs mailing list