Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SYSCTL(9)		 BSD Kernel Developer's	Manual		     SYSCTL(9)

     sysctl -- system variable control interfaces

     #include <sys/param.h>
     #include <sys/sysctl.h>

     Primary external interfaces:


     sysctl_lock(struct	lwp *l,	void *oldp, size_t savelen);

     sysctl_dispatch(const int *name, u_int namelen, void *oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_unlock(struct lwp *l);

     sysctl_createv(struct sysctllog **log, int	cflags,
	 const struct sysctlnode **rnode, const	struct sysctlnode **cnode,
	 int flags, int	type, const char *namep, const char *desc,
	 sysctlfn func,	u_quad_t qv, void *newp, size_t	newlen,	...);

     sysctl_destroyv(struct sysctlnode *rnode, ...);

     sysctl_free(struct	sysctlnode *rnode);

     sysctl_teardown(struct sysctllog **);

     old_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
	 void *newp, size_t newlen, struct lwp *l);

     Core internal functions:

     sysctl_locate(struct lwp *l, const	int *name, u_int namelen,
	 const struct sysctlnode **rnode, int *nip);

     sysctl_lookup(const int *name, u_int namelen, void	*oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_create(const int *name, u_int namelen, void	*oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_destroy(const int *name, u_int namelen, void *oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_query(const	int *name, u_int namelen, void *oldp, size_t *oldlenp,
	 const void *newp, size_t newlen, const	int *oname, struct lwp *l,
	 const struct sysctlnode *rnode);

     Simple "helper" functions:

     sysctl_needfunc(const int *name, u_int namelen, void *oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_notavail(const int *name, u_int namelen, void *oldp,
	 size_t	*oldlenp, const	void *newp, size_t newlen, const int *oname,
	 struct	lwp *l,	const struct sysctlnode	*rnode);

     sysctl_null(const int *name, u_int	namelen, void *oldp, size_t *oldlenp,
	 const void *newp, size_t newlen, const	int *oname, struct lwp *l,
	 const struct sysctlnode *rnode);

     The SYSCTL	subsystem instruments a	number of kernel tunables and other
     data structures via a simple MIB-like interface, primarily	for consump-
     tion by userland programs,	but also for use internally by the kernel.

     All operations on the SYSCTL tree must be protected by acquiring the main
     SYSCTL lock.  The only functions that can be called when the lock is not
     held are sysctl_lock(), sysctl_createv(), sysctl_destroyv(), and
     old_sysctl().  All	other functions	require	the tree to be locked.	This
     is	to prevent other users of the tree from	moving nodes around during an
     add operation, or from destroying nodes or	subtrees that are actively be-
     ing used.	The lock is acquired by	calling	sysctl_lock() with a pointer
     to	the process's lwp l (NULL may be passed	to all functions as the	lwp
     pointer if	no lwp is appropriate, though any changes made via
     sysctl_create(), sysctl_destroy(),	sysctl_lookup(), or by any helper
     function will be done with	effective superuser privileges).

     The oldp and savelen arguments are	a pointer to and the size of the mem-
     ory region	the caller will	be using to collect data from SYSCTL.  These
     may also be NULL and 0, respectively.

     The memory	region will be locked via uvm_vslock() if it is	a region in
     userspace.	 The address and size of the region are	recorded so that when
     the SYSCTL	lock is	to be released via sysctl_unlock(), only the lwp
     pointer l is required.

     Once the lock has been acquired, it is typical to call sysctl_dispatch()
     to	handle the request.  sysctl_dispatch() will examine the	contents of
     name, an array of integers	at least namelen long, which is	to be located
     in	kernel space, in order to determine which function to call to handle
     the specific request.

     The following algorithm is	used by	sysctl_dispatch() to determine the
     function to call:

	   +o   Scan the	tree using sysctl_locate().

	   +o   If the node returned has	a "helper" function, call it.

	   +o   If the requested	node was found but has no function, call

	   +o   If the node was not found and name specifies one	of
	       sysctl_query(), sysctl_create(),	or sysctl_destroy(), call the
	       appropriate function.

	   +o   If none of these	options	applies	and no other error was yet
	       recorded, return	EOPNOTSUPP.

     The oldp and oldlenp arguments to sysctl_dispatch(), as with all the
     other core	functions, describe an area into which the current or re-
     quested value may be copied.  oldp	may or may not be a pointer into
     userspace (as dictated by whether l is NULL or not).  oldlenp is a
     non-NULL pointer to a size_t.  newp and newlen describe an	area where the
     new value for the request may be found; newp may also be a	pointer	into
     userspace.	 The oname argument is a non-NULL pointer to the base of the
     request currently being processed.	 By simple arithmetic on name,
     namelen, and oname, one can easily	determine the entire original request
     and namelen values, if needed.  The rnode value, as passed	to
     sysctl_dispatch() represents the root of the tree into which the current
     request is	to be dispatched.  If NULL, the	main tree will be used.

     The sysctl_locate() function scans	a tree for the node most specific to a
     request.  If the pointer referenced by rnode is not NULL, the tree	indi-
     cated is searched,	otherwise the main tree	will be	used.  The address of
     the most relevant node will be returned via rnode and the number of MIB
     entries consumed will be returned via nip,	if it is not NULL.

     The sysctl_lookup() function takes	the same arguments as
     sysctl_dispatch() with the	caveat that the	value for namelen must be zero
     in	order to indicate that the node	referenced by the rnode	argument is
     the one to	which the lookup is being applied.

     New nodes are created and destroyed by the	sysctl_create()	and
     sysctl_destroy() functions.  These	functions take the same	arguments as
     sysctl_dispatch() with the	additional requirement that the	namelen	argu-
     ment must be 1 and	the name argument must point to	an integer valued ei-
     ther CTL_CREATE or	CTL_CREATESYM when creating a new node,	or CTL_DESTROY
     when destroying a node.

     The newp and newlen arguments should point	to a copy of the node to be
     created or	destroyed.  If the create or destroy operation was successful,
     a copy of the node	created	or destroyed will be placed in the space indi-
     cated by oldp and oldlenp.	 If the	create operation fails because of a
     conflict with an existing node, a copy of that node will be returned in-

     In	order to facilitate the	creation and destruction of nodes from a given
     tree by kernel subsystems,	the functions sysctl_createv() and
     sysctl_destroyv() are provided.  These functions take care	of the over-
     head of filling in	the contents of	the create or destroy request, dealing
     with locking, locating the	appropriate parent node, etc.

     The arguments to sysctl_createv() are used	to construct the new node.  If
     the log argument is not NULL, a sysctllog structure will be allocated and
     the pointer referenced will be changed to address it.  The	same log may
     be	used for any number of nodes, provided they are	all inserted into the
     same tree.	 This allows for a series of nodes to be created and later re-
     moved from	the tree in a single transaction (via sysctl_teardown()) with-
     out the need for any record keeping on the	caller's part.

     The cflags	argument is currently unused and must be zero.	The rnode ar-
     gument must either	be NULL	or a valid pointer to a	reference to the root
     of	the tree into which the	new node must be placed.  If it	is NULL, the
     main tree will be used.  It is illegal for	rnode to refer to a NULL
     pointer.  If the cnode argument is	not NULL, on return it will be ad-
     justed to point to	the address of the new node.

     The flags and type	arguments are combined into the	sysctl_flags field,
     and the current value for SYSCTL_VERSION is added in.  The	following
     types are defined:

	   CTLTYPE_NODE	   A node intended to be a parent for other nodes.

	   CTLTYPE_INT	   A signed integer.

	   CTLTYPE_STRING  A NUL-terminated string.

	   CTLTYPE_QUAD	   An unsigned 64-bit integer.

	   CTLTYPE_STRUCT  A structure.

	   CTLTYPE_BOOL	   A boolean.

     The namep argument	is copied into the sysctl_name field and must be less
     than SYSCTL_NAMELEN characters in length.	The string indicated by	desc
     will be copied if the CTLFLAG_OWNDESC flag	is set,	and will be used as
     the node's	description.

     Two additional remarks:

	   1.	The CTLFLAG_PERMANENT flag can only be set from	SYSCTL setup
		routines (see SETUP FUNCTIONS) as called by sysctl_init().

	   2.	If sysctl_destroyv() attempts to delete	a node that does not
		own its	own description	(and is	not marked as permanent), but
		the deletion fails, the	description will be copied and
		sysctl_destroyv() will set the CTLFLAG_OWNDESC flag.

     The func argument is the name of a	"helper" function (see HELPER
     FUNCTIONS AND MACROS).  If	the CTLFLAG_IMMEDIATE flag is set, the qv ar-
     gument will be interpreted	as the initial value for the new "bool", "int"
     or	"quad" node.  This flag	does not apply to any other type of node.  The
     newp and newlen arguments describe	the data external to SYSCTL that is to
     be	instrumented.  One of func, qv and the CTLFLAG_IMMEDIATE flag, or newp
     and newlen	must be	given for nodes	that instrument	data, otherwise	an er-
     ror is returned.

     The remaining arguments are a list	of integers specifying the path
     through the MIB to	the node being created.	 The list must be terminated
     by	the CTL_EOL value.  The	penultimate value in the list may be
     CTL_CREATE	if a dynamic MIB entry is to be	made for this node.
     sysctl_createv() specifically does	not support CTL_CREATESYM, since setup
     routines are expected to be able to use the in-kernel ksyms(4) interface
     to	discover the location of the data to be	instrumented.  If the node to
     be	created	matches	a node that already exists, a return code of 0 is
     given, indicating success.

     When using	sysctl_destroyv() to destroy a given node, the rnode argument,
     if	not NULL, is taken to be the root of the tree from which the node is
     to	be destroyed, otherwise	the main tree is used.	The rest of the	argu-
     ments are a list of integers specifying the path through the MIB to the
     node being	destroyed.  If the node	being destroyed	does not exist,	a suc-
     cessful return code is given.  Nodes marked with the CTLFLAG_PERMANENT
     flag cannot be destroyed.

     Helper functions are invoked with the same	common argument	set as
     sysctl_dispatch() except that the rnode argument will never be NULL.  It
     will be set to point to the node that corresponds most closely to the
     current request.  Helpers are forbidden from modifying the	node they are
     passed; they should instead copy the structure if changes are required in
     order to effect access control or other checks.  The "helper" prototype
     and function that needs to	ensure that a newly assigned value is within a
     certain range (presuming external data) would look	like the following:

	   static int sysctl_helper(SYSCTLFN_PROTO);

	   static int
		   struct sysctlnode node;
		   int t, error;

		   t = *(int *)rnode->sysctl_data;

		   node	= *rnode;
		   node.sysctl_data = &t;
		   error = sysctl_lookup(SYSCTLFN_CALL(&node));
		   if (error ||	newp ==	NULL)
			   return (error);

		   if (t < 0 ||	t > 20)
			   return (EINVAL);

		   *(int *)rnode->sysctl_data =	t;
		   return (0);

      macros ensure that all arguments are passed properly.  The single	argu-
     ment to the SYSCTLFN_CALL macro is	the pointer to the node	being exam-

     Three basic helper	functions are available	for use.  sysctl_needfunc()
     will emit a warning to the	system console whenever	it is invoked and pro-
     vides a simplistic	read-only interface to the given node.
     sysctl_notavail() will forward "queries" to sysctl_query()	so that	sub-
     trees can be discovered, but will return EOPNOTSUPP for any other condi-
     tion.  sysctl_null() specifically ignores any arguments given, sets the
     value indicated by	oldlenp	to zero, and returns success.

     Though nodes can be added to the SYSCTL tree at any time, in order	to add
     nodes during the kernel bootstrap phase, a	proper "setup" function	must
     be	used.  Setup functions are declared using the SYSCTL_SETUP macro,
     which takes the name of the function and a	short string description of
     the function as arguments.	 (See the SYSCTL_DEBUG_SETUP kernel
     configuration in options(4).)  The	address	of the function	is added to a
     list of functions that sysctl_init() traverses during initialization.

     Setup functions do	not have to add	nodes to the main tree,	but can	set up
     their own trees for emulation or other purposes.  Emulations that require
     use of a main tree	but with some nodes changed to suit their own purposes
     can arrange to overlay a sparse private tree onto their main tree by mak-
     ing the e_sysctlovly member of their struct emul definition point to the
     overlaid tree.

     Setup functions should take care to create	all nodes from the root	down
     to	the subtree they are creating, since the order in which	setup func-
     tions are called is arbitrary (the	order in which setup functions are
     called is only determined by the ordering of the object files as passed
     to	the linker when	the kernel is built).

     sysctl_init() is called early in the kernel bootstrap process.  It	ini-
     tializes the SYSCTL lock, calls all the registered	setup functions, and
     marks the tree as permanent.

     sysctl_free() will	unconditionally	delete any and all nodes below the
     given node.  Its intended use is for the deletion of entire trees,	not
     subtrees.	If a subtree is	to be removed, sysctl_destroy()	or
     sysctl_destroyv() should be used to ensure	that nodes not owned by	the
     sub-system	being deactivated are not mistakenly destroyed.	 The SYSCTL
     lock must be held when calling this function.

     sysctl_teardown() unwinds a sysctllog and deletes the nodes in the	oppo-
     site order	in which they were created.

     old_sysctl() provides an interface	similar	to the old SYSCTL implementa-
     tion, with	the exception that access checks on a per-node basis are per-
     formed if the l argument is non-NULL.  If called with a NULL argument,
     the values	for newp and oldp are interpreted as kernel addresses, and ac-
     cess is performed as for the superuser.

     It	is expected that nodes will be added to	(or removed from) the tree
     during the	following stages of a machine's	lifetime:

     +o	 initialization	-- when	the kernel is booting
     +o	 autoconfiguration -- when devices are being probed at boot time
     +o	 "plug and play" device	attachment -- when a PC-Card, USB, or other
	 device	is plugged in or attached
     +o	 module	initialization -- when a module	is being loaded
     +o	 "run-time" -- when a process creates a	node via the sysctl(3) inter-

     Nodes marked with CTLFLAG_PERMANENT can only be added to a	tree during
     the first or initialization phase,	and can	never be removed.  The ini-
     tialization phase terminates when the main	tree's root is marked with the
     CTLFLAG_PERMANENT flag.  Once the main tree is marked in this manner, no
     nodes can be added	to any tree that is marked with	CTLFLAG_READONLY at
     its root, and no nodes can	be added at all	if the main tree's root	is so

     Nodes added by device drivers, modules, and at device insertion time can
     be	added to (and removed from) "read-only"	parent nodes.

     Nodes created by processes	can only be added to "writable"	parent nodes.
     See sysctl(3) for a description of	the flags that are allowed to be used
     by	when creating nodes.


     The dynamic SYSCTL	implementation first appeared in NetBSD	2.0.

     Andrew Brown <> designed and implemented the dynamic
     SYSCTL implementation.

BSD			       December	4, 2011				   BSD


Want to link to this manual page? Use this URL:

home | help