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

FreeBSD Manual Pages


home | help
SYSCTL(3)		 BSD Library Functions Manual		     SYSCTL(3)

     sysctl, sysctlbyname, sysctlgetmibinfo, sysctlnametomib --	get or set
     system information

     Standard C	Library	(libc, -lc)

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

     sysctl(const int *name, u_int namelen, void *oldp,	size_t *oldlenp,
	 const void *newp, size_t newlen);

     sysctlbyname(const	char *sname, void *oldp, size_t	*oldlenp,
	 const void *newp, size_t newlen);

     sysctlgetmibinfo(const char *sname, int *name, u_int *namelenp,
	 char *cname, size_t *csz, struct sysctlnode **rnode, int v);

     sysctlnametomib(const char	*sname,	int *name, size_t *namelenp);

     The sysctl	function retrieves system information and allows processes
     with appropriate privileges to set	system information.  The information
     available from sysctl consists of integers, strings, and tables.  Infor-
     mation may	be retrieved and set from the command interface	using the
     sysctl(8) utility.

     Unless explicitly noted below, sysctl returns a consistent	snapshot of
     the data requested.  Consistency is obtained by locking the destination
     buffer into memory	so that	the data may be	copied out without blocking.
     Calls to sysctl are serialized to avoid deadlock.

     The state is described using a ``Management Information Base'' (MIB)
     style name, listed	in name, which is a namelen length array of integers.

     The sysctlbyname()	function accepts a string representation of a MIB en-
     try and internally	maps it	to the appropriate numeric MIB representation.
     Its semantics are otherwise no different from sysctl().

     The information is	copied into the	buffer specified by oldp.  The size of
     the buffer	is given by the	location specified by oldlenp before the call,
     and that location gives the amount	of data	copied after a successful
     call.  If the amount of data available is greater than the	size of	the
     buffer supplied, the call supplies	as much	data as	fits in	the buffer
     provided and returns with the error code ENOMEM.  If the old value	is not
     desired, oldp and oldlenp should be set to	NULL.

     The size of the available data can	be determined by calling sysctl	with a
     NULL parameter for	oldp.  The size	of the available data will be returned
     in	the location pointed to	by oldlenp.  For some operations, the amount
     of	space may change often.	 For these operations, the system attempts to
     round up so that the returned size	is large enough	for a call to return
     the data shortly thereafter.

     To	set a new value, newp is set to	point to a buffer of length newlen
     from which	the requested value is to be taken.  If	a new value is not to
     be	set, newp should be set	to NULL	and newlen set to 0.

     The sysctlnametomib() function can	be used	to map the string representa-
     tion of a MIB entry to the	numeric	version.  The name argument should
     point to an array of integers large enough	to hold	the MIB, and namelenp
     should indicate the number	of integer slots available.  Following a suc-
     cessful translation, the size_t indicated by namelenp will	be changed to
     show the number of	slots consumed.

     The sysctlgetmibinfo() function performs name translation similar to
     sysctlnametomib(),	but also canonicalizes the name	(or returns the	first
     erroneous token from the string being parsed) into	the space indicated by
     cname and csz.  csz should	indicate the size of the buffer	pointed	to by
     cname and on return, will indicate	the size of the	returned string	in-
     cluding the trailing `nul'	character.

     The rnode and v arguments to sysctlgetmibinfo() are used to provide a
     tree for it to parse into,	and to get back	either a pointer to, or	a copy
     of, the terminal node.  If	rnode is NULL, sysctlgetmibinfo() uses its own
     internal tree for parsing,	and checks it against the kernel at each call,
     to	make sure that the name-to-number mapping is kept up to	date.  The v
     argument is ignored in this case.	If rnode is not	NULL but the pointer
     it	references is, on a successful return, rnode will be adjusted to point
     to	a copy of the terminal node.  The v argument indicates which version
     of	the sysctl node	structure the caller wants.  The application must
     later free() this copy.  If neither rnode nor the pointer it references
     are NULL, the pointer is used as the address of a tree over which the
     parsing is	done.  In this last case, the tree is not checked against the
     kernel, no	refreshing of the mappings is performed, and the value given
     by	v must agree with the version indicated	by the tree.  It is recom-
     mended that applications always use SYSCTL_VERSION	as the value for v, as
     defined in	the include file sys/sysctl.h.

     The numeric and text names	of sysctl variables are	described in
     sysctl(7).	 The numeric names are defined as preprocessor macros.	The
     top level names are defined with a	CTL_ prefix in <sys/sysctl.h>.	The
     next and subsequent levels	down have different prefixes for each subtree.

     For example, the following	retrieves the maximum number of	processes al-
     lowed in the system - the kern.maxproc variable:
	   int mib[2], maxproc;
	   size_t len;

	   mib[0] = CTL_KERN;
	   mib[1] = KERN_MAXPROC;
	   len = sizeof(maxproc);
	   sysctl(mib, 2, &maxproc, &len, NULL,	0);

     To	retrieve the standard search path for the system utilities -
	   int mib[2];
	   size_t len;
	   char	*p;

	   mib[0] = CTL_USER;
	   mib[1] = USER_CS_PATH;
	   sysctl(mib, 2, NULL,	&len, NULL, 0);
	   p = malloc(len);
	   sysctl(mib, 2, p, &len, NULL, 0);

     Several meta-identifiers are provided to perform operations on the	sysctl
     tree itself, or support alternate means of	accessing the data instru-
     mented by the sysctl tree.

     Name		 Description
     CTL_QUERY		 Retrieve a mapping of names to	numbers	below a	given
     CTL_CREATE		 Create	a new node
     CTL_CREATESYM	 Create	a new node by its kernel symbol
     CTL_DESTROY	 Destroy a node
     CTL_DESCRIBE	 Retrieve node descriptions

     The core interface	to all of these	meta-functions is the structure	that
     the kernel	uses to	describe the tree internally, as defined in
     <sys/sysctl.h> as:

     struct sysctlnode {
	     uint32_t sysctl_flags;	     /*	flags and type */
	     int32_t sysctl_num;	     /*	mib number */
	     char sysctl_name[SYSCTL_NAMELEN]; /* node name */
	     uint32_t sysctl_ver;	 /* node's version vs. rest of tree */
	     uint32_t __rsvd;
	     union {
		     struct {
			     uint32_t suc_csize; /* size of child node array */
			     uint32_t suc_clen;	/* number of valid children */
			     struct sysctlnode*	suc_child; /* array of child nodes */
		     } scu_child;
		     struct {
			     void *sud_data; /*	pointer	to external data */
			     size_t sud_offset;	/* offset to data */
		     } scu_data;
		     int32_t scu_alias;	     /*	node this node refers to */
		     int32_t scu_idata;	     /*	immediate "int"	data */
		     u_quad_t scu_qdata;     /*	immediate "u_quad_t" data */
	     } sysctl_un;
	     size_t _sysctl_size;	     /*	size of	instrumented data */
	     sysctlfn _sysctl_func;	     /*	access helper function */
	     struct sysctlnode *sysctl_parent; /* parent of this node */
	     const char	*sysctl_desc;	     /*	description of node */

     #define sysctl_csize    sysctl_un.scu_child.suc_csize
     #define sysctl_clen     sysctl_un.scu_child.suc_clen
     #define sysctl_child    sysctl_un.scu_child.suc_child
     #define sysctl_data     sysctl_un.scu_data.sud_data
     #define sysctl_offset   sysctl_un.scu_data.sud_offset
     #define sysctl_alias    sysctl_un.scu_alias
     #define sysctl_idata    sysctl_un.scu_idata
     #define sysctl_qdata    sysctl_un.scu_qdata

     Querying the tree to discover the name to number mapping permits dynamic
     discovery of all the data that the	tree currently has instrumented.  For
     example, to discover all the nodes	below the CTL_VFS node:

	   struct sysctlnode query, vfs[128];
	   int mib[2];
	   size_t len;

	   mib[0] = CTL_VFS;
	   mib[1] = CTL_QUERY;
	   memset(&query, 0, sizeof(query));
	   query.sysctl_flags =	SYSCTL_VERSION;
	   len = sizeof(vfs);
	   sysctl(mib, 2, &vfs[0], &len, &query, sizeof(query));

     Note that a reference to an empty node with sysctl_flags set to
     SYSCTL_VERSION is passed to sysctl	in order to indicate the version that
     the program is using.  All	dynamic	operations passing nodes into sysctl
     require that the version be explicitly specified.

     Creation and destruction of nodes works by	constructing part of a new
     node description (or a description	of the existing	node) and invoking
     CTL_CREATE	(or CTL_CREATESYM) or CTL_DESTROY at the parent	of the new
     node, with	a pointer to the new node passed via the new and newlen	argu-
     ments.  If	valid values for old and oldlenp are passed, a copy of the new
     node once in the tree will	be returned.  If the create operation fails
     because a node with the same name or MIB number exists, a copy of the
     conflicting node will be returned.

     The minimum requirements for creating a node are setting the sysctl_flags
     to	indicate the new node's	type, sysctl_num to either the new node's num-
     ber (or CTL_CREATE	or CTL_CREATESYM if a dynamically allocated MIB	number
     is	acceptable), sysctl_size to the	size of	the data to be instrumented
     (which must agree with the	given type), and sysctl_name must be set to
     the new node's name.  Nodes that are not of type "node" must also have
     some description of the data to be	instrumented, which will vary depend-
     ing on what is to be instrumented.

     If	existing kernel	data is	to be covered by this new node,	its address
     should be given in	sysctl_data or,	if CTL_CREATESYM is used, sysctl_data
     should be set to a	string containing its name from	the kernel's symbol
     table.  If	new data is to be instrumented and an initial value is avail-
     able, the new integer or quad type	data should be placed into either
     sysctl_idata or sysctl_qdata, respectively, along with the	SYSCTL_IMMEDI-
     ATE flag being set, or sysctl_data	should be set to point to a copy of
     the new data, and the SYSCTL_OWNDATA flag must be set.  This latter
     method is the only	way that new string and	struct type nodes can be ini-
     tialized.	Invalid	kernel addresses are accepted, but any attempt to ac-
     cess those	nodes will return an error.

     The sysctl_csize, sysctl_clen, sysctl_child, sysctl_parent, and
     sysctl_alias members are used by the kernel to link the tree together and
     must be NULL or 0.	 Nodes created in this manner cannot have helper func-
     tions, so sysctl_func must	also be	NULL.  If the sysctl_ver member	is
     non-zero, it must match either the	version	of the parent or the version
     at	the root of the	MIB or an error	is returned.  This can be used to en-
     sure that nodes are only added or removed from a known state of the tree.
     Note: It may not be possible to determine the version at the root of the

     This example creates a new	subtree	and adds a node	to it that controls
     the audiodebug kernel variable, thereby making it tunable at at any time,
     without needing to	use ddb(4) or kvm(3) to	alter the kernel's memory di-

	   struct sysctlnode node;
	   int mib[2];
	   size_t len;

	   mib[0] = CTL_CREATE;		   /* create at	top-level */
	   len = sizeof(node);
	   memset(&node, 0, len);
	   snprintf(node.sysctl_name, sizeof(node.sysctl_name),	"local");
	   node.sysctl_num = CTL_CREATE;   /* request dynamic MIB number */
	   sysctl(&mib[0], 1, &node, &len, &node, len);

	   mib[0] = node.sysctl_num;	   /* use new MIB number */
	   mib[1] = CTL_CREATESYM;	   /* create at	second level */
	   len = sizeof(node);
	   memset(&node, 0, len);
	   snprintf(node.sysctl_name, sizeof(node.sysctl_name),	"audiodebug");
	   node.sysctl_num = CTL_CREATE;
	   node.sysctl_data = "audiodebug"; /* kernel symbol to	be used	*/
	   sysctl(&mib[0], 2, NULL, NULL, &node, len);

     The process for deleting nodes is similar,	but less data needs to be sup-
     plied.  Only the sysctl_num field needs to	be filled in; almost all other
     fields must be left blank.	 The sysctl_name and/or	sysctl_ver fields can
     be	filled in with the name	and version of the existing node as additional
     checks on what will be deleted.  If all the given data fail to match any
     node, nothing will	be deleted.  If	valid values for old and oldlenp are
     supplied and a node is deleted, a copy of what was	in the MIB tree	will
     be	returned.

     This sample code shows the	deletion of the	two nodes created in the above

	   int mib[2];

	   len = sizeof(node);
	   memset(&node, 0, len);
	   node.sysctl_flags = SYSCTL_VERSION;

	   mib[0] = 3214;		   /* assumed number for "local" */
	   mib[1] = CTL_DESTROY;
	   node.sysctl_num = 3215;	   /* assumed number for "audiodebug" */
	   sysctl(&mib[0], 2, NULL, NULL, &node, len);

	   mib[0] = CTL_DESTROY;
	   node.sysctl_num = 3214;	   /* now deleting "local" */
	   sysctl(&mib[0], 1, NULL, NULL, &node, len);

     Descriptions of each of the nodes can also	be retrieved, if they are
     available.	 Descriptions can be retrieved in bulk at each level or	on a
     per-node basis.  The layout of the	buffer into which the descriptions are
     returned is a series of variable length structures, each of which de-
     scribes its own size.  The	length indicated includes the terminating
     `nul' character.  Nodes that have no description or where the description
     is	not available are indicated by an empty	string.	 The descr_ver will
     match the sysctl_ver value	for a given node, so that descriptions for
     nodes whose number	have been recycled can be detected and ignored or dis-

     struct sysctldesc {
	     int32_t	     descr_num;	     /*	mib number of node */
	     uint32_t	     descr_ver;	     /*	version	of node	*/
	     uint32_t	     descr_len;	     /*	length of description string */
	     char	     descr_str[1];   /*	not really 1...see above */

     The NEXT_DESCR() macro can	be used	to skip	to the next description	in the
     retrieved list.

	   struct sysctlnode desc;
	   struct sysctldesc *d;
	   char	buf[1024];
	   int mib[2];
	   size_t len;

	   /* retrieve kern-level descriptions */
	   mib[0] = CTL_KERN;
	   mib[1] = CTL_DESCRIBE;
	   d = (struct sysctldesc *)&buf[0];
	   len = sizeof(buf);
	   sysctl(mib, 2, d, &len, NULL, 0);
	   while ((caddr_t)d < (caddr_t)&buf[len]) {
		   printf("node	%d: %.*s\n", d->descr_num, d->descr_len,
		   d = NEXT_DESCR(d);

	   /* retrieve description for kern.securelevel	*/
	   memset(&desc, 0, sizeof(desc));
	   desc.sysctl_flags = SYSCTL_VERSION;
	   desc.sysctl_num = KERN_SECURELEVEL;
	   d = (struct sysctldesc *)&buf[0];
	   len = sizeof(buf);
	   sysctl(mib, 2, d, &len, &desc, sizeof(desc));
	   printf("kern.securelevel: %.*s\n", d->descr_len, d->descr_str);

     Descriptions can also be set as follows, subject to the following rules:

     +o	 The kernel securelevel	is at zero or lower
     +o	 The caller has	super-user privileges
     +o	 The node does not currently have a description
     +o	 The node is not marked	as "permanent"

	   struct sysctlnode desc;
	   int mib[2];

	   /* presuming	the given top-level node was just added... */
	   mib[0] = 3214; /* mib numbers taken from previous examples */
	   mib[1] = CTL_DESCRIBE;
	   memset(&desc, 0, sizeof(desc));
	   desc.sysctl_flags = SYSCTL_VERSION;
	   desc.sysctl_num = 3215;
	   desc.sysctl_desc = "audio debug control knob";
	   sysctl(mib, 2, NULL,	NULL, &desc, sizeof(desc));

     Upon successfully setting a description, the new description will be re-
     turned in the space indicated by the oldp and oldlenp arguments.

     The sysctl_flags field in the struct sysctlnode contains the sysctl ver-
     sion, node	type information, and a	number of flags.  The macros
     SYSCTL_VERS(), SYSCTL_TYPE(), and SYSCTL_FLAGS() can be used to access
     the different fields.  Valid flags	are:

     Name		     Description
     CTLFLAG_READONLY	     Node is read-only
     CTLFLAG_READWRITE	     Node is writable by the superuser
     CTLFLAG_ANYWRITE	     Node is writable by anyone
     CTLFLAG_PRIVATE	     Node is readable only by the superuser
     CTLFLAG_PERMANENT	     Node cannot be removed (cannot be set by pro-
     CTLFLAG_OWNDATA	     Node owns data and	does not instrument existing
     CTLFLAG_IMMEDIATE	     Node contains instrumented	data and does not in-
			     strument existing data
     CTLFLAG_HEX	     Node's contents should be displayed in a
			     hexadecimal form
     CTLFLAG_ROOT	     Node is the root of a tree	(cannot	be set at any
     CTLFLAG_ANYNUMBER	     Node matches any MIB number (cannot be set	by
     CTLFLAG_HIDDEN	     Node not displayed	by default
     CTLFLAG_ALIAS	     Node refers to a sibling node (cannot be set by
     CTLFLAG_OWNDESC	     Node owns its own description string space

     If	the call to sysctl is successful, 0 is returned.  Otherwise -1 is re-
     turned and	errno is set appropriately.

     <sys/sysctl.h>	    definitions	for top	level identifiers, second
			    level kernel and hardware identifiers, and user
			    level identifiers
     <sys/socket.h>	    definitions	for second level network identifiers
     <sys/gmon.h>	    definitions	for third level	profiling identifiers
     <uvm/uvm_param.h>	    definitions	for second level virtual memory	iden-
     <netinet/in.h>	    definitions	for third level	IPv4/v6	identifiers
			    and	fourth level IPv4/v6 identifiers
     <netinet/icmp_var.h>   definitions	for fourth level ICMP identifiers
     <netinet/icmp6.h>	    definitions	for fourth level ICMPv6	identifiers
     <netinet/tcp_var.h>    definitions	for fourth level TCP identifiers
     <netinet/udp_var.h>    definitions	for fourth level UDP identifiers
     <netinet6/udp6_var.h>  definitions	for fourth level IPv6 UDP identifiers
     <netinet6/ipsec.h>	    definitions	for fourth level IPsec identifiers
     <netkey/key_var.h>	    definitions	for third level	PF_KEY identifiers
     <machine/cpu.h>	    definitions	for second level machdep identifiers

     The following errors may be reported:

     [EFAULT]		The buffer name, oldp, newp, or	length pointer oldlenp
			contains an invalid address, or	the requested value is
			temporarily unavailable.

     [EINVAL]		The name array is zero or greater than CTL_MAXNAME.

     [EINVAL]		A non-null newp	is given and its specified length in
			newlen is too large or too small, or the given value
			is not acceptable for the given	node.

     [EISDIR]		The name array specifies an intermediate rather	than
			terminal name.

     [ENOENT]		The name array specifies a node	that does not exist in
			the tree.

     [ENOENT]		An attempt was made to destroy a node that does	not
			exist, or to create or destroy a node below a node
			that does not exist.

     [ENOMEM]		The length pointed to by oldlenp is too	short to hold
			the requested value.

     [ENOTDIR]		The name array specifies a node	below a	node that ad-
			dresses	data.

     [ENOTEMPTY]	An attempt was made to destroy a node that still has

     [EOPNOTSUPP]	The name array specifies a value that is unknown or a
			meta-operation was attempted that the requested	node
			does not support.

     [EPERM]		An attempt is made to set a read-only value.

     [EPERM]		A process without appropriate privilege	attempts to
			set a value or to create or destroy a node.

     [EPERM]		An attempt to change a value protected by the current
			kernel security	level is made.

     sysctl(7),	sysctl(8), secmodel_securelevel(9)

     The sysctl	function first appeared	in 4.4BSD.

BSD			      September	26, 2009			   BSD


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

home | help