[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-hackers
Subject:    Re: Why is TUNABLE_INT discouraged?
From:       Garrett Cooper <gcooper () freebsd ! org>
Date:       2010-10-24 4:20:55
Message-ID: AANLkTimEejt2Gd+QEiGWXXsJfpUUY8ayygkMP48PcYpj () mail ! gmail ! com
[Download RAW message or body]

2010/10/23 Garrett Cooper <gcooper@freebsd.org>:
> 2010/10/18 Dag-Erling Sm=F8rgrav <des@des.no>:
>> Garrett Cooper <gcooper@FreeBSD.org> writes:
>>> PS I added uquad_t for consistency in the APIs, even though quad_t was
>>> deprecated, but I didn't bump __FreeBSD_version__ -- wasn't sure if I
>>> should have done that).
>>
>> You should bump __FreeBSD_version__ anyway so third-party or shared code
>> can use the new API if it is available and the old one if it isn't.
>>
>>> Let's try with the patch attached...
>>
>> Mailman strips binary attachments. =A0The correct MIME type is
>> text/x-patch.
>
> =A0 =A0Ok. Let's retry with a .patch extension and by bumping __FreeBSD_v=
ersion__.

Sorry.. forgot the uquad_t addition to sys/types.h :(...

["tunables-enhancement.patch" (text/x-patch)]

Index: sys/kern/kern_environment.c
===================================================================
--- sys/kern/kern_environment.c	(revision 214258)
+++ sys/kern/kern_environment.c	(working copy)
@@ -50,6 +50,7 @@
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/libkern.h>
+#include <sys/limits.h>
 #include <sys/kenv.h>
 
 #include <security/mac/mac_framework.h>
@@ -442,32 +443,115 @@
 }
 
 /*
- * Return a string value from an environment variable.
+ * Return the multiplier for a user specified suffix from a getenv call.
  */
+uintmax_t
+getenv_parse_suffix(const char suffix)
+{
+	uintmax_t multiplier = 1;
+
+	switch (suffix) {
+	case 't': case 'T':
+		multiplier *= 1024;
+	case 'g': case 'G':
+		multiplier *= 1024;
+	case 'm': case 'M':
+		multiplier *= 1024;
+	case 'k': case 'K':
+		multiplier *= 1024;
+	case '\0':
+		break;
+	default:
+		multiplier = 0;
+	}
+
+	return (multiplier);
+}
+
+/*
+ * Return a signed quantity from an environment variable.
+ */
 int
-getenv_string(const char *name, char *data, int size)
+getenv_signed(const char *name, intmax_t *data, const intmax_t min,
+    const intmax_t max)
 {
-	char *tmp;
+	uintmax_t	multiplier;
+	intmax_t	iv;
+	int		ret_code;
+	char		*value;
+	char		*vtp;
 
-	tmp = getenv(name);
-	if (tmp != NULL) {
-		strlcpy(data, tmp, size);
-		freeenv(tmp);
-		return (1);
-	} else
-		return (0);
+	ret_code = 0;
+
+	value = getenv(name);
+	if (value == NULL)
+		return (ret_code);
+	iv = strtoq(value, &vtp, 0);
+	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0') ||
+	    (multiplier = getenv_parse_suffix(vtp[0])) == 0) {
+		/* 
+		 * Catch errors in parsing the number, bad input, or the
+		 * suffix if one was specified.
+		 */
+		;
+	} else {
+		iv *= multiplier;
+		if (min <= iv && iv <= max) {
+			*data = iv;
+			ret_code = 1;
+		}
+	}
+	freeenv(value);
+	return (ret_code);
 }
 
 /*
+ * Return an unsigned quantity from an environment variable.
+ */
+int
+getenv_unsigned(const char *name, uintmax_t *data, const uintmax_t min,
+    const uintmax_t max)
+{
+	uintmax_t	multiplier;
+	uintmax_t	uiv;
+	int		ret_code;
+	char		*value;
+	char		*vtp;
+
+	ret_code = 0;
+
+	value = getenv(name);
+	if (value == NULL)
+		return (ret_code);
+	uiv = strtouq(value, &vtp, 0);
+	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0') ||
+	    (multiplier = getenv_parse_suffix(vtp[0])) == 0) {
+		/* 
+		 * Catch errors in parsing the number, bad input, or the
+		 * suffix if one was specified.
+		 */
+		;
+	} else {
+		uiv *= multiplier;
+		if (min <= uiv && uiv <= max) {
+			*data = uiv;
+			ret_code = 1;
+		}
+	}
+	freeenv(value);
+	return (ret_code);
+}
+
+/*
  * Return an integer value from an environment variable.
  */
 int
 getenv_int(const char *name, int *data)
 {
-	quad_t tmp;
+	intmax_t tmp;
 	int rval;
 
-	rval = getenv_quad(name, &tmp);
+	rval = getenv_signed(name, &tmp, INT_MIN, INT_MAX);
 	if (rval)
 		*data = (int) tmp;
 	return (rval);
@@ -479,10 +563,10 @@
 int
 getenv_uint(const char *name, unsigned int *data)
 {
-	quad_t tmp;
+	intmax_t tmp;
 	int rval;
 
-	rval = getenv_quad(name, &tmp);
+	rval = getenv_unsigned(name, &tmp, 0, UINT_MAX);
 	if (rval)
 		*data = (unsigned int) tmp;
 	return (rval);
@@ -494,10 +578,10 @@
 int
 getenv_long(const char *name, long *data)
 {
-	quad_t tmp;
+	intmax_t tmp;
 	int rval;
 
-	rval = getenv_quad(name, &tmp);
+	rval = getenv_signed(name, &tmp, LONG_MIN, LONG_MAX);
 	if (rval)
 		*data = (long) tmp;
 	return (rval);
@@ -509,51 +593,90 @@
 int
 getenv_ulong(const char *name, unsigned long *data)
 {
-	quad_t tmp;
+	intmax_t tmp;
 	int rval;
 
-	rval = getenv_quad(name, &tmp);
+	rval = getenv_unsigned(name, &tmp, 0, ULONG_MAX);
 	if (rval)
 		*data = (unsigned long) tmp;
 	return (rval);
 }
 
 /*
+ * Return a pointer from an environment variable.
+ */
+int
+getenv_pointer(const char *name, uintptr_t *data)
+{
+	intmax_t tmp;
+	int rval;
+
+	rval = getenv_unsigned(name, &tmp, 0, UINTPTR_MAX);
+	if (rval)
+		*data = (uintptr_t) tmp;
+	return (rval);
+}
+
+/*
  * Return a quad_t value from an environment variable.
  */
 int
 getenv_quad(const char *name, quad_t *data)
 {
-	char	*value;
-	char	*vtp;
-	quad_t	iv;
+	intmax_t tmp;
+	int rval;
 
-	value = getenv(name);
-	if (value == NULL)
+	rval = getenv_signed(name, &tmp, QUAD_MIN, QUAD_MAX);
+	if (rval)
+		*data = (quad_t) tmp;
+	return (rval);
+}
+
+/*
+ * Return a uquad_t value from an environment variable.
+ */
+int
+getenv_uquad(const char *name, uquad_t *data)
+{
+	intmax_t tmp;
+	int rval;
+
+	rval = getenv_unsigned(name, &tmp, 0, UQUAD_MAX);
+	if (rval)
+		*data = (uquad_t) tmp;
+	return (rval);
+}
+
+/*
+ * Return a size_t value from an environment variable.
+ */
+int
+getenv_size(const char *name, size_t *data)
+{
+	intmax_t tmp;
+	int rval;
+
+	rval = getenv_unsigned(name, &tmp, 0, SIZE_MAX);
+	if (rval)
+		*data = (size_t) tmp;
+	return (rval);
+}
+
+/*
+ * Return a string value from an environment variable.
+ */
+int
+getenv_string(const char *name, char *data, size_t size)
+{
+	char *tmp;
+
+	tmp = getenv(name);
+	if (tmp != NULL) {
+		strlcpy(data, tmp, size);
+		freeenv(tmp);
+		return (1);
+	} else
 		return (0);
-	iv = strtoq(value, &vtp, 0);
-	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
-		freeenv(value);
-		return (0);
-	}
-	switch (vtp[0]) {
-	case 't': case 'T':
-		iv *= 1024;
-	case 'g': case 'G':
-		iv *= 1024;
-	case 'm': case 'M':
-		iv *= 1024;
-	case 'k': case 'K':
-		iv *= 1024;
-	case '\0':
-		break;
-	default:
-		freeenv(value);
-		return (0);
-	}
-	*data = iv;
-	freeenv(value);
-	return (1);
 }
 
 /*
@@ -583,6 +706,14 @@
 }
 
 void
+tunable_uint_init(void *data)
+{
+	struct tunable_uint *d = (struct tunable_uint *)data;
+
+	TUNABLE_UINT_FETCH(d->path, d->var);
+}
+
+void
 tunable_long_init(void *data)
 {
 	struct tunable_long *d = (struct tunable_long *)data;
@@ -599,6 +730,14 @@
 }
 
 void
+tunable_pointer_init(void *data)
+{
+	struct tunable_pointer *d = (struct tunable_pointer *)data;
+
+	TUNABLE_POINTER_FETCH(d->path, d->var);
+}
+
+void
 tunable_quad_init(void *data)
 {
 	struct tunable_quad *d = (struct tunable_quad *)data;
@@ -607,6 +746,22 @@
 }
 
 void
+tunable_uquad_init(void *data)
+{
+	struct tunable_uquad *d = (struct tunable_uquad *)data;
+
+	TUNABLE_UQUAD_FETCH(d->path, d->var);
+}
+
+void
+tunable_size_init(void *data)
+{
+	struct tunable_size *d = (struct tunable_size *)data;
+
+	TUNABLE_SIZE_FETCH(d->path, d->var);
+}
+
+void
 tunable_str_init(void *data)
 {
 	struct tunable_str *d = (struct tunable_str *)data;
Index: sys/sys/kernel.h
===================================================================
--- sys/sys/kernel.h	(revision 214258)
+++ sys/sys/kernel.h	(working copy)
@@ -275,7 +275,9 @@
 
 /*
  * int
- * please avoid using for new tunables!
+ *
+ * Please do not use for addresses or pointers (use the pointer tunable
+ * instead), or sizes (use the size tunable instead).
  */
 extern void tunable_int_init(void *);
 struct tunable_int {
@@ -294,6 +296,28 @@
 #define	TUNABLE_INT_FETCH(path, var)	getenv_int((path), (var))
 
 /*
+ * unsigned int
+ *
+ * Please do not use for addresses or pointers (use the pointer tunable
+ * instead), or sizes (use the size tunable instead).
+ */
+extern void tunable_uint_init(void *);
+struct tunable_uint {
+	const char *path;
+	unsigned int *var;
+};
+#define	TUNABLE_UINT(path, var)					\
+	static struct tunable_uint __CONCAT(__tunable_uint_, __LINE__) = { \
+		(path),						\
+		(var),						\
+	};							\
+	SYSINIT(__CONCAT(__Tunable_init_, __LINE__),		\
+	    SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_uint_init, \
+	    &__CONCAT(__tunable_uint_, __LINE__))
+
+#define	TUNABLE_UINT_FETCH(path, var)	getenv_uint((path), (var))
+
+/*
  * long
  */
 extern void tunable_long_init(void *);
@@ -332,8 +356,28 @@
 #define	TUNABLE_ULONG_FETCH(path, var)	getenv_ulong((path), (var))
 
 /*
- * quad
+ * pointer
  */
+extern void tunable_pointer_init(void *);
+struct tunable_pointer {
+	const char *path;
+	uintptr_t *var;
+};
+#define	TUNABLE_POINTER(path, var)				\
+	static struct tunable_pointer __CONCAT(__tunable_pointer_, __LINE__) = { \
+		(path),						\
+		(var),						\
+	};							\
+	SYSINIT(__CONCAT(__Tunable_init_, __LINE__),		\
+	    SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_pointer_init, \
+	    &__CONCAT(__tunable_pointer_, __LINE__))
+
+#define	TUNABLE_POINTER_FETCH(path, var)			\
+	getenv_pointer((path), (var))
+
+/*
+ * quad_t
+ */
 extern void tunable_quad_init(void *);
 struct tunable_quad {
 	const char *path;
@@ -350,6 +394,28 @@
 
 #define	TUNABLE_QUAD_FETCH(path, var)	getenv_quad((path), (var))
 
+/*
+ * size_t
+ */
+extern void tunable_size_init(void *);
+struct tunable_size {
+	const char *path;
+	size_t *var;
+};
+#define	TUNABLE_SIZE(path, var)					\
+	static struct tunable_size __CONCAT(__tunable_size_, __LINE__) = { \
+		(path),						\
+		(var),						\
+	};							\
+	SYSINIT(__CONCAT(__Tunable_init_, __LINE__),		\
+	    SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_size_init, \
+	    &__CONCAT(__tunable_size_, __LINE__))
+
+#define	TUNABLE_SIZE_FETCH(path, var)	getenv_size((path), (var))
+
+/*
+ * strings
+ */
 extern void tunable_str_init(void *);
 struct tunable_str {
 	const char *path;
@@ -369,6 +435,25 @@
 #define	TUNABLE_STR_FETCH(path, var, size)			\
 	getenv_string((path), (var), (size))
 
+/*
+ * uquad_t
+ */
+extern void tunable_uquad_init(void *);
+struct tunable_uquad {
+	const char *path;
+	uquad_t *var;
+};
+#define	TUNABLE_UQUAD(path, var)					\
+	static struct tunable_uquad __CONCAT(__tunable_uquad_, __LINE__) = { \
+		(path),						\
+		(var),						\
+	};							\
+	SYSINIT(__CONCAT(__Tunable_init_, __LINE__),		\
+	    SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_uquad_init, \
+	    &__CONCAT(__tunable_uquad_, __LINE__))
+
+#define	TUNABLE_UQUAD_FETCH(path, var)	getenv_uquad((path), (var))
+
 struct intr_config_hook {
 	TAILQ_ENTRY(intr_config_hook) ich_links;
 	void	(*ich_func)(void *arg);
Index: sys/sys/param.h
===================================================================
--- sys/sys/param.h	(revision 214258)
+++ sys/sys/param.h	(working copy)
@@ -58,7 +58,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 900023	/* Master, propagated to newvers */
+#define __FreeBSD_version 900024	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>
Index: sys/sys/systm.h
===================================================================
--- sys/sys/systm.h	(revision 214258)
+++ sys/sys/systm.h	(working copy)
@@ -260,12 +260,20 @@
 
 char	*getenv(const char *name);
 void	freeenv(char *env);
+uintmax_t getenv_parse_suffix(const char suffix);
+int	getenv_signed(const char *name, intmax_t *data, const intmax_t min,
+	    const intmax_t max);
+int	getenv_unsigned(const char *name, uintmax_t *data,
+	    const uintmax_t min, const uintmax_t max);
 int	getenv_int(const char *name, int *data);
 int	getenv_uint(const char *name, unsigned int *data);
 int	getenv_long(const char *name, long *data);
 int	getenv_ulong(const char *name, unsigned long *data);
-int	getenv_string(const char *name, char *data, int size);
+int	getenv_pointer(const char *name, uintptr_t *data);
 int	getenv_quad(const char *name, quad_t *data);
+int	getenv_uquad(const char *name, uquad_t *data);
+int	getenv_size(const char *name, size_t *data);
+int	getenv_string(const char *name, char *data, size_t size);
 int	setenv(const char *name, const char *value);
 int	unsetenv(const char *name);
 int	testenv(const char *name);
Index: sys/sys/types.h
===================================================================
--- sys/sys/types.h	(revision 214258)
+++ sys/sys/types.h	(working copy)
@@ -112,6 +112,7 @@
 typedef __uint64_t	u_int64_t;
 
 typedef	__uint64_t	u_quad_t;	/* quads (deprecated) */
+typedef	__uint64_t	uquad_t;
 typedef	__int64_t	quad_t;
 typedef	quad_t *	qaddr_t;
 
Index: tools/regression/tunables/uquad/test_uquad_tunable.sh
===================================================================
--- tools/regression/tunables/uquad/test_uquad_tunable.sh	(revision 0)
+++ tools/regression/tunables/uquad/test_uquad_tunable.sh	(revision 0)
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)    :           0
+#      -1    :   ULONG_MAX
+#       0    :           0
+#      42    :          42
+# asdf1234   :           0 (reject)
+# LONG_MAX+1 :  LONG_MAX+1
+# ULONG_MAX-1: ULONG_MAX-1
+# ULONG_MAX+1:   ULONG_MAX
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+case "$($(dirname "$0")/../tools/getwordsize)" in
+32)
+	LONG_MAX_PLUS_1=2147483649
+	ULONG_MAX_MINUS_1=4294967295
+	ULONG_MAX_PLUS_1=4294967297
+	;;
+64)
+	LONG_MAX_PLUS_1=9223372036854775808
+	ULONG_MAX_MINUS_1=18446744073709551614
+	ULONG_MAX_PLUS_1=18446744073709551616
+	;;
+esac
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 42 asdf1234 $LONG_MAX_PLUS_1 $ULONG_MAX_MINUS_1 $ULONG_MAX_PLUS_1; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/uquad/test_uquad_tunable.c
===================================================================
--- tools/regression/tunables/uquad/test_uquad_tunable.c	(revision 0)
+++ tools/regression/tunables/uquad/test_uquad_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_uquad_tunable"
+
+static uquad_t tunable = 0;
+
+TUNABLE_UQUAD("test_uquad_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %lu\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_uquad_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_uquad_tunable, test_uquad_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_uquad_tunable, 1);
Index: tools/regression/tunables/uquad/Makefile
===================================================================
--- tools/regression/tunables/uquad/Makefile	(revision 0)
+++ tools/regression/tunables/uquad/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_uquad_tunable
+SRCS=	test_uquad_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/uint/test_uint_tunable.sh
===================================================================
--- tools/regression/tunables/uint/test_uint_tunable.sh	(revision 0)
+++ tools/regression/tunables/uint/test_uint_tunable.sh	(revision 0)
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)   :          0
+#      -1   :          0 (reject) 
+#       0   :          0
+#      42   :         42
+# asdf1234  :          0 (reject)
+# INT_MAX+1 :  INT_MAX+1
+# UINT_MAX-1: UINT_MAX-1
+# UINT_MAX+1:          0 (reject)
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+INT_MAX_PLUS_ONE=2147483648
+UINT_MAX_MINUS_ONE=4294967294
+UINT_MAX_PLUS_ONE=4294967296
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 42 asdf1234 $INT_MAX_PLUS_ONE $UINT_MAX_MINUS_ONE $UINT_MAX_PLUS_ONE; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/uint/test_uint_tunable.c
===================================================================
--- tools/regression/tunables/uint/test_uint_tunable.c	(revision 0)
+++ tools/regression/tunables/uint/test_uint_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_uint_tunable"
+
+static unsigned int tunable = 0;
+
+TUNABLE_UINT("test_uint_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %u\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_uint_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_uint_tunable, test_uint_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_uint_tunable, 1);
Index: tools/regression/tunables/uint/Makefile
===================================================================
--- tools/regression/tunables/uint/Makefile	(revision 0)
+++ tools/regression/tunables/uint/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_uint_tunable
+SRCS=	test_uint_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/tools/getwordsize.c
===================================================================
--- tools/regression/tunables/tools/getwordsize.c	(revision 0)
+++ tools/regression/tunables/tools/getwordsize.c	(revision 0)
@@ -0,0 +1,9 @@
+#include <sys/elf.h>
+#include <stdio.h>
+
+int
+main(void)
+{
+	printf("%d\n", __ELF_WORD_SIZE);
+	return (0);
+}
Index: tools/regression/tunables/tools/Makefile
===================================================================
--- tools/regression/tunables/tools/Makefile	(revision 0)
+++ tools/regression/tunables/tools/Makefile	(revision 0)
@@ -0,0 +1,7 @@
+PROG=		getwordsize
+
+SRCS=		getwordsize.c
+
+NO_MAN=		1
+
+.include <bsd.prog.mk>
Index: tools/regression/tunables/ulong/test_ulong_tunable.sh
===================================================================
--- tools/regression/tunables/ulong/test_ulong_tunable.sh	(revision 0)
+++ tools/regression/tunables/ulong/test_ulong_tunable.sh	(revision 0)
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)    :           0
+#      -1    :   ULONG_MAX
+#       0    :           0
+#      42    :          42
+# asdf1234   :           0 (reject)
+# LONG_MAX+1 :  LONG_MAX+1
+# ULONG_MAX-1: ULONG_MAX-1
+# ULONG_MAX+1:   ULONG_MAX
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+case "$($(dirname "$0")/../tools/getwordsize)" in
+32)
+	LONG_MAX_PLUS_1=2147483649
+	ULONG_MAX_MINUS_1=4294967295
+	ULONG_MAX_PLUS_1=4294967297
+	;;
+64)
+	LONG_MAX_PLUS_1=9223372036854775808
+	ULONG_MAX_MINUS_1=18446744073709551614
+	ULONG_MAX_PLUS_1=18446744073709551616
+	;;
+esac
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 42 asdf1234 $LONG_MAX_PLUS_1 $ULONG_MAX_MINUS_1 $ULONG_MAX_PLUS_1; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/ulong/Makefile
===================================================================
--- tools/regression/tunables/ulong/Makefile	(revision 0)
+++ tools/regression/tunables/ulong/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_ulong_tunable
+SRCS=	test_ulong_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/ulong/test_ulong_tunable.c
===================================================================
--- tools/regression/tunables/ulong/test_ulong_tunable.c	(revision 0)
+++ tools/regression/tunables/ulong/test_ulong_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_ulong_tunable"
+
+static unsigned long tunable = 0;
+
+TUNABLE_ULONG("test_ulong_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %lu\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_ulong_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_ulong_tunable, test_ulong_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_ulong_tunable, 1);
Index: tools/regression/tunables/suffix/test_tunable_suffixes.c
===================================================================
--- tools/regression/tunables/suffix/test_tunable_suffixes.c	(revision 0)
+++ tools/regression/tunables/suffix/test_tunable_suffixes.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_tunable_suffixes"
+
+static long tunable = 0;
+
+TUNABLE_LONG("test_tunable_suffixes.tunable", &tunable);
+
+static int
+load (struct module *m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %ld\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_tunable_suffixes_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_tunable_suffixes, test_tunable_suffixes_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_tunable_suffixes, 1);
Index: tools/regression/tunables/suffix/Makefile
===================================================================
--- tools/regression/tunables/suffix/Makefile	(revision 0)
+++ tools/regression/tunables/suffix/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_tunable_suffixes
+SRCS=	test_tunable_suffixes.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/suffix/test_tunable_suffixes.sh
===================================================================
--- tools/regression/tunables/suffix/test_tunable_suffixes.sh	(revision 0)
+++ tools/regression/tunables/suffix/test_tunable_suffixes.sh	(revision 0)
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)   :           0
+#         -1:          -1
+#        -1g:     -1024^3
+#        -1G:     -1024^3 (same as 1g) 
+#        -1k:       -1024
+#        -1K:       -1024 (same as 1K)
+#        -1m:     -1024^2
+#        -1M:     -1024^2 (same as 1m)
+#        -1t:     -1024^4
+#        -1T:     -1024^4 (same as 1t)
+#        -1z:           0 (reject)
+#          1:           1
+#         1g:      1024^3
+#         1G:      1024^3 (same as 1g) 
+#         1k:        1024
+#         1K:        1024 (same as 1K)
+#         1m:      1024^2
+#         1M:      1024^2 (same as 1m)
+#         1t:      1024^4
+#         1T:      1024^4 (same as 1t)
+#         1z:           0 (reject)
+#         1T:           0 (reject)
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 1; do
+	for j in '' g G k K m M t T z Z; do
+		kenv $MODNAME.tunable="$i$j"
+		test_module
+	done
+done
Index: tools/regression/tunables/string/test_string_tunable.c
===================================================================
--- tools/regression/tunables/string/test_string_tunable.c	(revision 0)
+++ tools/regression/tunables/string/test_string_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_string_tunable"
+
+static char tunable[10];
+
+TUNABLE_STR("test_string_tunable.tunable", tunable, sizeof(tunable));
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %s\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_string_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_string_tunable, test_string_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_string_tunable, 1);
Index: tools/regression/tunables/string/test_string_tunable.sh
===================================================================
--- tools/regression/tunables/string/test_string_tunable.sh	(revision 0)
+++ tools/regression/tunables/string/test_string_tunable.sh	(revision 0)
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)              :          ""
+# ""                   :          ""
+# asdf1234             :    asdf1234
+# character            :   character
+# asortoflongishstring :   asortoflo
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+test_module
+for i in "" asdf1234 character asortoflongishstring; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/string/Makefile
===================================================================
--- tools/regression/tunables/string/Makefile	(revision 0)
+++ tools/regression/tunables/string/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_string_tunable
+SRCS=	test_string_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/size/test_size_tunable.c
===================================================================
--- tools/regression/tunables/size/test_size_tunable.c	(revision 0)
+++ tools/regression/tunables/size/test_size_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_size_tunable"
+
+static size_t tunable = 0;
+
+TUNABLE_SIZE("test_size_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %zu\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_size_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_size_tunable, test_size_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_size_tunable, 1);
Index: tools/regression/tunables/size/test_size_tunable.sh
===================================================================
--- tools/regression/tunables/size/test_size_tunable.sh	(revision 0)
+++ tools/regression/tunables/size/test_size_tunable.sh	(revision 0)
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)    :           0
+#      -1    :   ULONG_MAX
+#       0    :           0
+#      42    :          42
+# asdf1234   :           0 (reject)
+# LONG_MAX+1 :  LONG_MAX+1
+# ULONG_MAX-1: ULONG_MAX-1
+# ULONG_MAX+1:   ULONG_MAX
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+case "$($(dirname "$0")/../tools/getwordsize)" in
+32)
+	LONG_MAX_PLUS_1=2147483649
+	ULONG_MAX_MINUS_1=4294967295
+	ULONG_MAX_PLUS_1=4294967297
+	;;
+64)
+	LONG_MAX_PLUS_1=9223372036854775808
+	ULONG_MAX_MINUS_1=18446744073709551614
+	ULONG_MAX_PLUS_1=18446744073709551616
+	;;
+esac
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 42 asdf1234 $LONG_MAX_PLUS_1 $ULONG_MAX_MINUS_1 $ULONG_MAX_PLUS_1; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/size/Makefile
===================================================================
--- tools/regression/tunables/size/Makefile	(revision 0)
+++ tools/regression/tunables/size/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_size_tunable
+SRCS=	test_size_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/quad/test_quad_tunable.c
===================================================================
--- tools/regression/tunables/quad/test_quad_tunable.c	(revision 0)
+++ tools/regression/tunables/quad/test_quad_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#define MODULE_NAME	"test_quad_tunable"
+
+static quad_t tunable = 0;
+
+TUNABLE_QUAD("test_quad_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %ld\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_quad_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_quad_tunable, test_quad_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_quad_tunable, 1);
Index: tools/regression/tunables/quad/test_quad_tunable.sh
===================================================================
--- tools/regression/tunables/quad/test_quad_tunable.sh	(revision 0)
+++ tools/regression/tunables/quad/test_quad_tunable.sh	(revision 0)
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)    :           0
+#       0    :           0
+#      42    :          42
+# asdf1234   :           0 (reject)
+# LONG_MIN-1 :  LONG_MIN
+# LONG_MIN+1 :  LONG_MIN+1
+# LONG_MAX-1 :  LONG_MAX-1
+# LONG_MAX+1 :  LONG_MAX
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+case "$($(dirname "$0")/../tools/getwordsize)" in
+32)
+	LONG_MIN_MINUS_1="-2147483649"
+	LONG_MIN_PLUS_1="-2147483647"
+	LONG_MAX_MINUS_1=2147483647
+	LONG_MAX_PLUS_1=2147483649
+	;;
+64)
+	LONG_MIN_MINUS_1="-9223372036854775809"
+	LONG_MIN_PLUS_1="-9223372036854775807"
+	LONG_MAX_MINUS_1=9223372036854775806
+	LONG_MAX_PLUS_1=9223372036854775808
+	;;
+esac
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in 0 42 asdf1234 $LONG_MIN_MINUS_1 $LONG_MIN_PLUS_1 $LONG_MAX_MINUS_1 $LONG_MAX_PLUS_1 ; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/quad/Makefile
===================================================================
--- tools/regression/tunables/quad/Makefile	(revision 0)
+++ tools/regression/tunables/quad/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_quad_tunable
+SRCS=	test_quad_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/int/test_int_tunable.c
===================================================================
--- tools/regression/tunables/int/test_int_tunable.c	(revision 0)
+++ tools/regression/tunables/int/test_int_tunable.c	(revision 0)
@@ -0,0 +1,31 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+
+#define MODULE_NAME	"test_int_tunable"
+
+static int tunable = 0;
+
+TUNABLE_INT("test_int_tunable.tunable", &tunable);
+
+static int
+load (module_t m, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		printf("%s: %d\n", MODULE_NAME, tunable);
+		break;
+	}
+	return (0);
+}
+
+static moduledata_t test_int_tunable_mod = {
+	MODULE_NAME,
+	load,
+};
+DECLARE_MODULE(test_int_tunable, test_int_tunable_mod, SI_SUB_KLD,
+    SI_ORDER_ANY);
+MODULE_VERSION(test_int_tunable, 1);
Index: tools/regression/tunables/int/test_int_tunable.sh
===================================================================
--- tools/regression/tunables/int/test_int_tunable.sh	(revision 0)
+++ tools/regression/tunables/int/test_int_tunable.sh	(revision 0)
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Expected values:
+# (unset)   :           0
+#      -1   :          -1
+#       0   :           0
+#      42   :          42
+# asdf1234  :           0 (reject)
+# INT_MIN+1 :   INT_MIN+1
+# INT_MIN-1 :           0 (reject)
+# INT_MAX-1 :   INT_MAX-1
+# INT_MAX+1 :           0 (reject)
+#
+
+MODNAME="$(basename "$0" .sh)"
+
+test_module() {
+	kldload ./$MODNAME.ko
+	kldunload ./$MODNAME.ko
+}
+
+INT_MIN_PLUS_ONE=-2147483647
+INT_MIN_MINUS_ONE=-2147483649
+INT_MAX_MINUS_ONE=2147483646
+INT_MAX_PLUS_ONE=2147483648
+kenv -u $MODNAME.tunable 2>/dev/null
+test_module
+for i in -1 0 42 asdf1234 $INT_MIN_PLUS_ONE $INT_MIN_MINUS_ONE $INT_MAX_MINUS_ONE $INT_MAX_PLUS_ONE; do
+	kenv $MODNAME.tunable="$i"
+	test_module
+done
Index: tools/regression/tunables/int/Makefile
===================================================================
--- tools/regression/tunables/int/Makefile	(revision 0)
+++ tools/regression/tunables/int/Makefile	(revision 0)
@@ -0,0 +1,4 @@
+KMOD=	test_int_tunable
+SRCS=	test_int_tunable.c
+
+.include <bsd.kmod.mk>
Index: tools/regression/tunables/Makefile
===================================================================
--- tools/regression/tunables/Makefile	(revision 0)
+++ tools/regression/tunables/Makefile	(revision 0)
@@ -0,0 +1,10 @@
+SUBDIR=		tools		\
+		int uint	\
+		long ulong	\
+		pointer		\
+		quad uquad	\
+		size		\
+		string		\
+		suffix		\
+
+.include <bsd.subdir.mk>


_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic