- Updated SYSCTL manual pages after recent changes to the kernel

SYSCTL code. Added description of new macros and functions.
- Merged dynamic and static SYSCTL related content into a single
manual page, hence parameters and functionality is very much the same.
- Uppercased all occurrences of "OID".
- Updated all SYSCTL examples.

PR:	192101
This commit is contained in:
Hans Petter Selasky 2014-07-31 17:18:40 +00:00
parent f3a4b7f73b
commit 5eb1caa8c8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=269344
4 changed files with 514 additions and 482 deletions

View File

@ -1351,33 +1351,36 @@ MLINKS+=sx.9 sx_assert.9 \
sx.9 sx_xlocked.9 \
sx.9 sx_xunlock.9
MLINKS+=sysctl.9 SYSCTL_DECL.9 \
sysctl.9 SYSCTL_ADD_INT.9 \
sysctl.9 SYSCTL_ADD_LONG.9 \
sysctl.9 SYSCTL_ADD_NODE.9 \
sysctl.9 SYSCTL_ADD_OPAQUE.9 \
sysctl.9 SYSCTL_ADD_PROC.9 \
sysctl.9 SYSCTL_ADD_QUAD.9 \
sysctl.9 SYSCTL_ADD_ROOT_NODE.9 \
sysctl.9 SYSCTL_ADD_STRING.9 \
sysctl.9 SYSCTL_ADD_STRUCT.9 \
sysctl.9 SYSCTL_ADD_UINT.9 \
sysctl.9 SYSCTL_ADD_ULONG.9 \
sysctl.9 SYSCTL_ADD_UQUAD.9 \
sysctl.9 SYSCTL_CHILDREN.9 \
sysctl.9 SYSCTL_STATIC_CHILDREN.9 \
sysctl.9 SYSCTL_NODE_CHILDREN.9 \
sysctl.9 SYSCTL_PARENT.9 \
sysctl.9 SYSCTL_INT.9 \
sysctl.9 SYSCTL_LONG.9 \
sysctl.9 SYSCTL_NODE.9 \
sysctl.9 SYSCTL_OPAQUE.9 \
sysctl.9 SYSCTL_PROC.9 \
sysctl.9 SYSCTL_QUAD.9 \
sysctl.9 SYSCTL_ROOT_NODE.9 \
sysctl.9 SYSCTL_STRING.9 \
sysctl.9 SYSCTL_STRUCT.9 \
sysctl.9 SYSCTL_UINT.9 \
sysctl.9 SYSCTL_ULONG.9 \
sysctl.9 SYSCTL_UQUAD.9
MLINKS+=sysctl_add_oid.9 SYSCTL_ADD_INT.9 \
sysctl_add_oid.9 SYSCTL_ADD_LONG.9 \
sysctl_add_oid.9 SYSCTL_ADD_NODE.9 \
sysctl_add_oid.9 SYSCTL_ADD_OID.9 \
sysctl_add_oid.9 SYSCTL_ADD_OPAQUE.9 \
sysctl_add_oid.9 SYSCTL_ADD_PROC.9 \
sysctl_add_oid.9 SYSCTL_ADD_QUAD.9 \
sysctl_add_oid.9 SYSCTL_ADD_STRING.9 \
sysctl_add_oid.9 SYSCTL_ADD_STRUCT.9 \
sysctl_add_oid.9 SYSCTL_ADD_UINT.9 \
sysctl_add_oid.9 SYSCTL_ADD_ULONG.9 \
sysctl_add_oid.9 SYSCTL_ADD_UQUAD.9 \
sysctl_add_oid.9 SYSCTL_CHILDREN.9 \
sysctl_add_oid.9 sysctl_move_oid.9 \
sysctl_add_oid.9 sysctl_remove_oid.9 \
sysctl_add_oid.9 SYSCTL_STATIC_CHILDREN.9
MLINKS+=sysctl_add_oid.9 sysctl_move_oid.9 \
sysctl_add_oid.9 sysctl_remove_oid.9
MLINKS+=sysctl_ctx_init.9 sysctl_ctx_entry_add.9 \
sysctl_ctx_init.9 sysctl_ctx_entry_del.9 \
sysctl_ctx_init.9 sysctl_ctx_entry_find.9 \

View File

@ -25,79 +25,421 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 12, 2013
.Dd July 31, 2014
.Dt SYSCTL 9
.Os
.Sh NAME
.Nm SYSCTL_DECL ,
.Nm SYSCTL_ADD_INT ,
.Nm SYSCTL_ADD_LONG ,
.Nm SYSCTL_ADD_NODE ,
.Nm SYSCTL_ADD_OPAQUE ,
.Nm SYSCTL_ADD_PROC ,
.Nm SYSCTL_ADD_QUAD ,
.Nm SYSCTL_ADD_ROOT_NODE ,
.Nm SYSCTL_ADD_STRING ,
.Nm SYSCTL_ADD_STRUCT ,
.Nm SYSCTL_ADD_UINT ,
.Nm SYSCTL_ADD_ULONG ,
.Nm SYSCTL_ADD_UQUAD ,
.Nm SYSCTL_CHILDREN ,
.Nm SYSCTL_STATIC_CHILDREN ,
.Nm SYSCTL_NODE_CHILDREN ,
.Nm SYSCTL_PARENT ,
.Nm SYSCTL_INT ,
.Nm SYSCTL_LONG ,
.Nm SYSCTL_NODE ,
.Nm SYSCTL_OPAQUE ,
.Nm SYSCTL_PROC ,
.Nm SYSCTL_QUAD ,
.Nm SYSCTL_ROOT_NODE ,
.Nm SYSCTL_STRING ,
.Nm SYSCTL_STRUCT ,
.Nm SYSCTL_UINT ,
.Nm SYSCTL_ULONG ,
.Nm SYSCTL_UQUAD
.Nd Static sysctl declaration functions
.Nd Dynamic and static sysctl MIB creation functions
.Sh SYNOPSIS
.In sys/types.h
.In sys/sysctl.h
.Fn SYSCTL_DECL name
.Fn SYSCTL_INT parent nbr name access ptr val descr
.Fn SYSCTL_LONG parent nbr name access ptr val descr
.Fn SYSCTL_NODE parent nbr name access handler descr
.Fn SYSCTL_OPAQUE parent nbr name access ptr len fmt descr
.Fn SYSCTL_PROC parent nbr name access ptr arg handler fmt descr
.Fn SYSCTL_QUAD parent nbr name access ptr val descr
.Fn SYSCTL_STRING parent nbr name access arg len descr
.Fn SYSCTL_STRUCT parent nbr name access ptr type descr
.Fn SYSCTL_UINT parent nbr name access ptr val descr
.Fn SYSCTL_ULONG parent nbr name access ptr val descr
.Fn SYSCTL_UQUAD parent nbr name access ptr val descr
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_INT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "int *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_LONG
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "long *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_NODE
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "int (*handler)(SYSCTL_HANDLER_ARGS)"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_OPAQUE
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "void *ptr"
.Fa "intptr_t len"
.Fa "const char *format"
.Fa "const char *descr
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_PROC
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "void *arg1"
.Fa "intptr_t arg2"
.Fa "int (*handler) (SYSCTL_HANDLERARGS)"
.Fa "const char *format"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_QUAD
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "quad_t *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_ROOT_NODE
.Fa "struct sysctl_ctx_list *ctx"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "int (*handler)(SYSCTL_HANDLER_ARGS)"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_STRING
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "char *ptr"
.Fa "intptr_t len"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_STRUCT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "void *ptr"
.Fa struct_type
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_UINT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "unsigned int *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_ULONG
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "unsigned long *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_UQUAD
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int ctlflags"
.Fa "u_quad_t *ptr"
.Fa "intptr_t val"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid_list *
.Fo SYSCTL_CHILDREN
.Fa "struct sysctl_oid *oidp"
.Fc
.Ft struct sysctl_oid_list *
.Fo SYSCTL_STATIC_CHILDREN
.Fa "struct sysctl_oid_list OID_NAME"
.Fc
.Ft struct sysctl_oid_list *
.Fo SYSCTL_NODE_CHILDREN
.Fa "parent"
.Fa "name"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_PARENT
.Fa "struct sysctl_oid *oid"
.Fc
.Fn SYSCTL_INT parent number name ctlflags ptr val descr
.Fn SYSCTL_LONG parent number name ctlflags ptr val descr
.Fn SYSCTL_NODE parent number name ctlflags handler descr
.Fn SYSCTL_OPAQUE parent number name ctlflags ptr len format descr
.Fn SYSCTL_PROC parent number name ctlflags arg1 arg2 handler format descr
.Fn SYSCTL_QUAD parent number name ctlflags ptr val descr
.Fn SYSCTL_STRING parent number name ctlflags arg len descr
.Fn SYSCTL_STRUCT parent number name ctlflags ptr struct_type descr
.Fn SYSCTL_ROOT_NODE number name ctlflags handler descr
.Fn SYSCTL_UINT parent number name ctlflags ptr val descr
.Fn SYSCTL_ULONG parent number name ctlflags ptr val descr
.Fn SYSCTL_UQUAD parent number name ctlflags ptr val descr
.Sh DESCRIPTION
The
.Nm SYSCTL
kernel interfaces allow code to statically declare
kernel interface allows dynamic or static creation of
.Xr sysctl 8
MIB entries, which will be initialized when the kernel module containing the
declaration is initialized.
When the module is unloaded, the sysctl will be automatically destroyed.
.Pp
Sysctl nodes are created in a hierarchical tree, with all static nodes being
represented by named C data structures; in order to create a new node under
an existing node in the tree, the structure representing the desired parent
node must be declared in the current context using
.Fn SYSCTL_DECL .
.Pp
New nodes are declared using one of
MIB entries.
All static sysctls are automatically destroyed when the module which
they are part of is unloaded.
Most top level categories are created statically and are available to
all kernel code and its modules.
.Sh DESCRIPTION OF ARGUMENTS
.Bl -tag -width ctlflags
.It Fa ctx
Pointer to sysctl context or NULL, if no context.
See
.Xr sysctl_ctx_init 9
for how to create a new sysctl context.
Programmers are strongly advised to use contexts to organize the
dynamic OIDs which they create because when a context is destroyed all
belonging sysctls are destroyed aswell.
This makes the sysctl cleanup code much simpler.
Else deletion of all created OIDs is required at module unload typically.
.It Fa parent
A pointer to a
.Li struct sysctl_oid_list ,
which is the head of the parent's list of children.
This pointer is retrieved by using the
.Fn SYSCTL_STATIC_CHILDREN
macro for static sysctls and the
.Fn SYSCTL_CHILDREN
macro for dynamic sysctls.
To get the parent of an OID the
.Fn SYSCTL_PARENT
macro shall be used.
If there is no parent this macro returns NULL.
.It Fa number
The OID number that will be assigned to this OID.
In almost all cases this should be set to
.Dv OID_AUTO ,
which will result in the assignment of the next available OID number.
.It Fa name
The name of the OID.
The newly created OID will contain a copy of the name.
.It Fa ctlflags
A bit mask of sysctl control flags.
See the section below describing all the control flags.
.It Fa arg1
First callback argument for procedure sysctls.
.It Fa arg2
Second callback argument for procedure sysctls.
.It Fa len
The length of the data pointed to by the
.Fa ptr
argument.
For string type OIDs a length of zero means that
.Xr strlen 3
will be used to get the length of the string at each access to the OID.
.It Fa ptr
Pointer to sysctl variable or string data.
For sysctl values the pointer can be NULL which means the OID is read-only and the returned value should be taken from the
.Fa val
argument.
.It Fa val
If the
.Fa ptr
argument is NULL, gives the constant value returned by this OID.
Else this argument is not used.
.It Fa struct_type
Name of structure type.
.It Fa handler
A pointer to the function
that is responsible for handling read and write requests
to this OID.
There are several standard handlers
that support operations on nodes,
integers, strings and opaque objects.
It is possible to define custom handlers using the
.Fn SYSCTL_PROC
macro or the
.Fn SYSCTL_ADD_PROC
function.
.It Fa format
A pointer to a string
which specifies the format of the OID in a symbolic way.
This format is used as a hint by
.Xr sysctl 8
to apply proper data formatting for display purposes.
Currently used format names are:
.Dq N
for node,
.Dq A
for
.Li "char *" ,
.Dq I
for
.Li "int" ,
.Dq IU
for
.Li "unsigned int" ,
.Dq L
for
.Li "long" ,
.Dq LU
for
.Li "unsigned long" ,
.Dq Q
for
.Li "quad_t" ,
.Dq QU
for
.Li "u_quad_t"
and
.Dq S,TYPE
for
.Li "struct TYPE"
structures.
.It Fa descr
A pointer to a textual description of the OID.
.El
.Sh CREATING ROOT NODES
Sysctl MIBs or OIDs are created in a hierarchical tree.
The nodes at the bottom of the tree are called root nodes, and have no
parent OID.
To create bottom tree nodes the
.Fn SYSCTL_ROOT_NODE
macro or the
.Fn SYSCTL_ADD_ROOT_NODE
function needs to be used.
By default all static sysctl node OIDs are global and need a
.Fn SYSCTL_DECL
statement prior to their
.Fn SYSCTL_NODE
definition statement, typically in a so-called header file.
.Sh CREATING SYSCTL STRINGS
Zero terminated character strings sysctls are created either using the
.Fn SYSCTL_STRING
macro or the
.Fn SYSCTL_ADD_STRING
function.
If the
.Fa len
argument in zero, the string length is computed at every access to the OID using
.Xr strlen 3 .
.Sh CREATING OPAQUE SYSCTLS
The
.Fn SYSCTL_OPAQUE
or
.Fn SYSCTL_STRUCT
macros or the
.Fn SYSCTL_ADD_OPAQUE
or
.Fn SYSCTL_ADD_STRUCT
functions create an OID that handle any chunk of data
of the size specified by the
.Fa len
argument and data pointed to by the
.Fa ptr
argument.
When using the structure version the type is encoded as part of the
created sysctl.
.Sh CREATING CUSTOM SYSCTLS
The
.Fn SYSCTL_PROC
macro and the
.Fn SYSCTL_ADD_PROC
function
create OIDs with the specified
.Pa handler
function.
The handler is responsible for handling all read and write requests to
the OID.
This OID type is especially useful if the kernel data is not easily
accessible, or needs to be processed before exporting.
.Sh CREATING A STATIC SYSCTL
Static sysctls are declared using one of the
.Fn SYSCTL_INT ,
.Fn SYSCTL_LONG ,
.Fn SYSCTL_NODE ,
.Fn SYSCTL_OPAQUE ,
.Fn SYSCTL_PROC ,
.Fn SYSCTL_QUAD ,
.Fn SYSCTL_ROOT_NODE ,
.Fn SYSCTL_STRING ,
.Fn SYSCTL_STRUCT ,
.Fn SYSCTL_UINT ,
.Fn SYSCTL_ULONG ,
and
.Fn SYSCTL_UQUAD .
Each macro accepts a parent name, as declared using
.Fn SYSCTL_DECL ,
an OID number, typically
.Dv OID_AUTO ,
a node name, a set of control and access flags, and a description.
Depending on the macro, a pointer to a variable supporting the MIB entry, a
size, a value, and a function pointer implementing the MIB entry may also be
present.
.Pp
For most of the above macros, declaring a type as part of the access flags is
not necessary \[em] however, when declaring a sysctl implemented by a function,
including a type in the access mask is required:
.Bl -tag -width ".Dv CTLTYPE_STRING"
.Fn SYSCTL_ULONG
or
.Fn SYSCTL_UQUAD
macros.
.Sh CREATING A DYNAMIC SYSCTL
Dynamic nodes are created using one of the
.Fn SYSCTL_ADD_INT ,
.Fn SYSCTL_ADD_LONG ,
.Fn SYSCTL_ADD_NODE ,
.Fn SYSCTL_ADD_OPAQUE ,
.Fn SYSCTL_ADD_PROC ,
.Fn SYSCTL_ADD_QUAD ,
.Fn SYSCTL_ADD_ROOT_NODE ,
.Fn SYSCTL_ADD_STRING ,
.Fn SYSCTL_ADD_STRUCT ,
.Fn SYSCTL_ADD_UINT ,
.Fn SYSCTL_ADD_ULONG
or
.Fn SYSCTL_UQUAD
functions.
See
.Xr sysctl_remove_oid 9
or
.Xr sysctl_ctx_free 9
for more information on how to destroy a dynamically created OID.
.Sh CONTROL FLAGS
For most of the above functions and macros, declaring a type as part
of the access flags is not necessary \[em] however, when declaring a
sysctl implemented by a function, including a type in the access mask
is required:
.Bl -tag -width ".Dv CTLTYPE_NOFETCH"
.It Dv CTLTYPE_NODE
This is a node intended to be a parent for other nodes.
.It Dv CTLTYPE_INT
@ -127,13 +469,21 @@ flags to be set indicating the read and write disposition of the sysctl:
.It Dv CTLFLAG_RD
This is a read-only sysctl.
.It Dv CTLFLAG_RDTUN
This is a read-only sysctl which can be set by a system tunable.
This is a read-only sysctl and tunable which is tried fetched once
from the system enviroment early during module load or system boot.
.It Dv CTLFLAG_WR
This is a writable sysctl.
.It Dv CTLFLAG_RW
This sysctl is readable and writable.
.It Dv CTLFLAG_RWTUN
This sysctl is readable and writable and can also be set by a system tunable.
This is a readable and writeable sysctl and tunable which is tried
fetched once from the system enviroment early during module load or
system boot.
.It Dv CTLFLAG_NOFETCH
In case the node is marked as a tunable using the CTLFLAG_[XX]TUN,
this flag will prevent fetching the initial value from the system
environment. Typically this flag should only be used for very early
low level system setup code, and not by common drivers and modules.
.El
.Pp
Additionally, any of the following optional flags may also be specified:
@ -150,8 +500,12 @@ This sysctl can be written to by processes in
When iterating the sysctl name space, do not list this sysctl.
.It Dv CTLFLAG_TUN
Advisory flag that a system tunable also exists for this variable.
The initial sysctl value is tried fetched once from the system
enviroment early during module load or system boot.
.It Dv CTLFLAG_DYN
Dynamically created OIDs automatically get this flag set.
.El
.Pp
.Sh SECURITY CONSIDERATIONS
When creating new sysctls, careful attention should be paid to the security
implications of the monitoring or management interface being created.
Most sysctls present in the kernel are read-only or writable only by the
@ -252,6 +606,45 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING |
CTLFLAG_RW, NULL, 0, sysctl_kern_timecounter_hardware, "A",
"");
.Ed
.Pp
The following is an example of
how to create a new top-level category
and how to hook up another subtree to an existing static node.
This example does not use contexts,
which results in tedious management of all intermediate oids,
as they need to be freed later on:
.Bd -literal -offset indent
#include <sys/sysctl.h>
...
/*
* Need to preserve pointers to newly created subtrees,
* to be able to free them later:
*/
static struct sysctl_oid *root1;
static struct sysctl_oid *root2;
static struct sysctl_oid *oidp;
static int a_int;
static char *string = "dynamic sysctl";
...
root1 = SYSCTL_ADD_ROOT_NODE(NULL,
OID_AUTO, "newtree", CTLFLAG_RW, 0, "new top level tree");
oidp = SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(root1),
OID_AUTO, "newint", CTLFLAG_RW, &a_int, 0, "new int leaf");
...
root2 = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_debug),
OID_AUTO, "newtree", CTLFLAG_RW, 0, "new tree under debug");
oidp = SYSCTL_ADD_STRING(NULL, SYSCTL_CHILDREN(root2),
OID_AUTO, "newstring", CTLFLAG_RD, string, 0, "new string leaf");
.Ed
.Pp
This example creates the following subtrees:
.Bd -literal -offset indent
debug.newtree.newstring
newtree.newint
.Ed
.Pp
.Em "Care should be taken to free all OIDs once they are no longer needed!"
.Sh SYSCTL NAMING
When adding, modifying, or removing sysctl names, it is important to be
aware that these interfaces may be used by users, libraries, applications,
@ -281,8 +674,8 @@ Use positive logic instead:
.Va foobar ,
.Va foobar_enable .
.Pp
A temporary sysctl node that should not be relied upon must be designated
as such by a leading underscore character in its name. For example:
A temporary sysctl node OID that should not be relied upon must be designated
as such by a leading underscore character in its name. For example:
.Va _dirty_hack .
.Sh SEE ALSO
.Xr sysctl 3 ,

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 12, 2013
.Dd July 31, 2014
.Dt SYSCTL_ADD_OID 9
.Os
.Sh NAME
@ -46,7 +46,7 @@
.Fa "const char *name"
.Fa "int kind"
.Fa "void *arg1"
.Fa "int arg2"
.Fa "intptr_t arg2"
.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)"
.Fa "const char *format"
.Fa "const char *descr"
@ -62,160 +62,16 @@
.Fa "int del"
.Fa "int recurse"
.Fc
.Ft struct sysctl_oid_list *
.Fo SYSCTL_CHILDREN
.Fa "struct sysctl_oid *oidp"
.Fc
.Ft struct sysctl_oid_list *
.Fo SYSCTL_STATIC_CHILDREN
.Fa "struct sysctl_oid_list OID_NAME"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_OID
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int kind"
.Fa "void *arg1"
.Fa "int arg2"
.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)"
.Fa "const char *format"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_NODE
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_STRING
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "char *arg"
.Fa "int len"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_INT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "int *arg"
.Fa "int len"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_UINT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "unsigned int *arg"
.Fa "int len"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_LONG
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "long *arg"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_ULONG
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "unsigned long *arg"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_QUAD
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "int64_t *arg"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_UQUAD
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "uint64_t *arg"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_OPAQUE
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "void *arg"
.Fa "int len"
.Fa "const char *format"
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_STRUCT
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "void *arg"
.Fa STRUCT_NAME
.Fa "const char *descr"
.Fc
.Ft struct sysctl_oid *
.Fo SYSCTL_ADD_PROC
.Fa "struct sysctl_ctx_list *ctx"
.Fa "struct sysctl_oid_list *parent"
.Fa "int number"
.Fa "const char *name"
.Fa "int access"
.Fa "void *arg1"
.Fa "int arg2"
.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)"
.Fa "const char *format"
.Fa "const char *descr"
.Fc
.Sh DESCRIPTION
These functions and macros provide an interface
for creating and deleting sysctl oids at runtime
(e.g.\& during lifetime of a module).
The alternative method,
based on linker sets (see
.In sys/linker_set.h
and
.\" XXX Manual pages should avoid referencing source files
.Pa src/sys/kern/kern_sysctl.c
for details), only allows creation and deletion
on module load and unload respectively.
These functions provide the interface for creating and deleting sysctl
OIDs at runtime for example during the lifetime of a module.
The wrapper macros defined by
.Xr sysctl 9
are recommended when creating new OIDs.
.Fn sysctl_add_oid
should not be called directly from the code.
.Pp
Dynamic oids of type
Dynamic OIDs of type
.Dv CTLTYPE_NODE
are reusable
so that several code sections can create and delete them,
@ -227,170 +83,51 @@ to create partially overlapping trees that they both can use.
It is not possible to create overlapping leaves,
nor to create different child types with the same name and parent.
.Pp
Newly created oids are connected to their parent nodes.
In all these functions and macros
(with the exception of
.Fn sysctl_remove_oid ) ,
one of the required parameters is
.Fa parent ,
which points to the head of the parent's list of children.
.Pp
Most top level categories are created statically.
When connecting to existing static oids,
this pointer can be obtained with the
.Fn SYSCTL_STATIC_CHILDREN
macro, where the
.Fa OID_NAME
argument is name of the parent oid of type
.Dv CTLTYPE_NODE
(i.e., the name displayed by
.Xr sysctl 8 ,
preceded by underscore, and with all dots replaced with underscores).
.Pp
When connecting to an existing dynamic oid, this pointer
can be obtained with the
.Fn SYSCTL_CHILDREN
macro, where the
.Fa oidp
argument points to the parent oid of type
.Dv CTLTYPE_NODE .
.Pp
The
.Fn sysctl_add_oid
function creates raw oids of any type.
If the oid is successfully created,
the function returns a pointer to it;
otherwise it returns
function creates a raw OID of any type and connects it to its parent node, if any.
If the OID is successfully created,
the function returns a pointer to it else
it returns
.Dv NULL .
Many of the arguments for
.Fn sysctl_add_oid
are common to the macros.
The arguments are as follows:
.Bl -tag -width handler
.It Fa ctx
A pointer to an optional sysctl context, or
.Dv NULL .
See
.Xr sysctl_ctx_init 9
for details.
Programmers are strongly advised to use contexts
to organize the dynamic oids which they create,
unless special creation and deletion sequences are required.
If
.Fa ctx
is not
.Dv NULL ,
the newly created oid will be added to this context
as its first entry.
.It Fa parent
A pointer to a
.Li struct sysctl_oid_list ,
which is the head of the parent's list of children.
.It Fa number
The oid number that will be assigned to this oid.
In almost all cases this should be set to
.Dv OID_AUTO ,
which will result in the assignment of the next available oid number.
.It Fa name
The name of the oid.
The newly created oid will contain a copy of the name.
.It Fa kind
The kind of oid,
specified as a bit mask of the type and access values defined in the
.In sys/sysctl.h
header file.
Oids created dynamically always have the
.Dv CTLFLAG_DYN
flag set.
Access flags specify whether this oid is read-only or read-write,
and whether it may be modified by all users
or by the superuser only.
.It Fa arg1
A pointer to any data that the oid should reference, or
.Dv NULL .
.It Fa arg2
The size of
.Fa arg1 ,
or 0 if
.Fa arg1
is
.Dv NULL .
.It Fa handler
A pointer to the function
that is responsible for handling read and write requests
to this oid.
There are several standard handlers
that support operations on nodes,
integers, strings and opaque objects.
It is possible also to define new handlers using the
.Fn SYSCTL_ADD_PROC
macro.
.It Fa format
A pointer to a string
which specifies the format of the oid symbolically.
This format is used as a hint by
.Xr sysctl 8
to apply proper data formatting for display purposes.
Currently used format names are:
.Dq N
for node,
.Dq A
for
.Li "char *" ,
.Dq I
for
.Li "int" ,
.Dq IU
for
.Li "unsigned int" ,
.Dq L
for
.Li "long" ,
.Dq LU
for
.Li "unsigned long"
and
.Dq S,TYPE
for
.Li "struct TYPE"
structures.
.It Fa descr
A pointer to a textual description of the oid.
.El
are common to the wrapper macros defined by
.Xr sysctl 9 .
.Pp
The
.Fn sysctl_move_oid
function reparents an existing oid.
The oid is assigned a new number as if it had been created with
function reparents an existing OID.
The OID is assigned a new number as if it had been created with
.Fa number
set to
.Dv OID_AUTO .
.Pp
The
.Fn sysctl_remove_oid
function removes a dynamically created oid from the tree,
function removes a dynamically created OID from the tree and
optionally freeing its resources.
It takes the following arguments:
.Bl -tag -width recurse
.It Fa oidp
A pointer to the dynamic oid to be removed.
If the oid is not dynamic, or the pointer is
A pointer to the dynamic OID to be removed.
If the OID is not dynamic, or the pointer is
.Dv NULL ,
the function returns
.Er EINVAL .
.It Fa del
If non-zero,
.Fn sysctl_remove_oid
will try to free the oid's resources
when the reference count of the oid becomes zero.
will try to free the OID's resources
when the reference count of the OID becomes zero.
However, if
.Fa del
is set to 0,
the routine will only deregister the oid from the tree,
the routine will only deregister the OID from the tree,
without freeing its resources.
This behaviour is useful when the caller expects to rollback
(possibly partially failed)
deletion of many oids later.
deletion of many OIDs later.
.It Fa recurse
If non-zero, attempt to remove the node and all its children.
If
@ -412,112 +149,11 @@ Be aware, though, that this may result in a system
if other code sections continue to use removed subtrees.
.El
.Pp
.\" XXX sheldonh finished up to here
Again, in most cases the programmer should use contexts,
as described in
.Xr sysctl_ctx_init 9 ,
to keep track of created oids,
to keep track of created OIDs,
and to delete them later in orderly fashion.
.Pp
There is a set of macros defined
that helps to create oids of given type.
They are as follows:
.Bl -tag -width SYSCTL_ADD_STRINGXX
.It Fn SYSCTL_ADD_OID
creates a raw oid.
This macro is functionally equivalent to the
.Fn sysctl_add_oid
function.
.It Fn SYSCTL_ADD_NODE
creates an oid of type
.Dv CTLTYPE_NODE ,
to which child oids may be added.
.It Fn SYSCTL_ADD_STRING
creates an oid that handles a zero-terminated character string.
.It Fn SYSCTL_ADD_INT
creates an oid that handles an
.Li int
variable.
.It Fn SYSCTL_ADD_UINT
creates an oid that handles an
.Li unsigned int
variable.
.It Fn SYSCTL_ADD_LONG
creates an oid that handles a
.Li long
variable.
.It Fn SYSCTL_ADD_ULONG
creates an oid that handles an
.Li unsigned long
variable.
.It Fn SYSCTL_ADD_QUAD
creates an oid that handles an
.Li int64_t
variable.
.It Fn SYSCTL_ADD_OPAQUE
creates an oid that handles any chunk of opaque data
of the size specified by the
.Fa len
argument,
which is a pointer to a
.Li "size_t *" .
.It Fn SYSCTL_ADD_STRUCT
creates an oid that handles a
.Li "struct TYPE"
structure.
The
.Fa format
parameter will be set to
.Dq S,TYPE
to provide proper hints to the
.Xr sysctl 8
utility.
.It Fn SYSCTL_ADD_PROC
creates an oid with the specified
.Pa handler
function.
The handler is responsible for handling read and write requests
to the oid.
This oid type is especially useful
if the kernel data is not easily accessible,
or needs to be processed before exporting.
.El
.Sh EXAMPLES
The following is an example of
how to create a new top-level category
and how to hook up another subtree to an existing static node.
This example does not use contexts,
which results in tedious management of all intermediate oids,
as they need to be freed later on:
.Bd -literal
#include <sys/sysctl.h>
...
/* Need to preserve pointers to newly created subtrees, to be able
* to free them later.
*/
struct sysctl_oid *root1, *root2, *oidp;
int a_int;
char *string = "dynamic sysctl";
...
root1 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(/* tree top */),
OID_AUTO, "newtree", CTLFLAG_RW, 0, "new top level tree");
oidp = SYSCTL_ADD_INT( NULL, SYSCTL_CHILDREN(root1),
OID_AUTO, "newint", CTLFLAG_RW, &a_int, 0, "new int leaf");
...
root2 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(_debug),
OID_AUTO, "newtree", CTLFLAG_RW, 0, "new tree under debug");
oidp = SYSCTL_ADD_STRING( NULL, SYSCTL_CHILDREN(root2),
OID_AUTO, "newstring", CTLFLAG_RD, string, 0, "new string leaf");
.Ed
.Pp
This example creates the following subtrees:
.Bd -literal -offset indent
debug.newtree.newstring
newtree.newint
.Ed
.Pp
.Em "Care should be taken to free all oids once they are no longer needed!"
.Sh SEE ALSO
.Xr sysctl 8 ,
.Xr sysctl 9 ,
@ -532,9 +168,9 @@ These functions first appeared in
Sharing nodes between many code sections
causes interdependencies that sometimes may lock the resources.
For example,
if module A hooks up a subtree to an oid created by module B,
module B will be unable to delete that oid.
if module A hooks up a subtree to an OID created by module B,
module B will be unable to delete that OID.
These issues are handled properly by sysctl contexts.
.Pp
Many operations on the tree involve traversing linked lists.
For this reason, oid creation and removal is relatively costly.
For this reason, OID creation and removal is relatively costly.

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 15, 2000
.Dd July 31, 2014
.Dt SYSCTL_CTX_INIT 9
.Os
.Sh NAME
@ -36,7 +36,7 @@
.Nm sysctl_ctx_entry_add ,
.Nm sysctl_ctx_entry_find ,
.Nm sysctl_ctx_entry_del
.Nd "sysctl context for managing dynamically created sysctl oids"
.Nd "sysctl context for managing dynamically created sysctl OIDs"
.Sh SYNOPSIS
.In sys/types.h
.In sys/sysctl.h
@ -65,10 +65,10 @@
.Fc
.Sh DESCRIPTION
These functions provide an interface
for managing dynamically created oids.
The sysctl context is responsible for keeping track of created oids,
for managing dynamically created OIDs.
The sysctl context is responsible for keeping track of created OIDs,
as well as their proper removal when needed.
It adds a simple transactional aspect to oid removal operations;
It adds a simple transactional aspect to OID removal operations;
i.e., if a removal operation fails part way,
it is possible to roll back the sysctl tree
to its previous state.
@ -87,7 +87,7 @@ a pointer to the context can be passed as an argument to all the
.Fa SYSCTL_ADD_*
macros (see
.Xr sysctl_add_oid 9 ) ,
and it will be updated with entries pointing to newly created oids.
and it will be updated with entries pointing to newly created OIDS.
.Pp
Internally, the context is represented as a
.Xr queue 3
@ -104,14 +104,14 @@ struct sysctl_ctx_entry {
TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
.Ed
.Pp
Each context entry points to one dynamic oid that it manages.
Newly created oids are always inserted in the front of the list.
Each context entry points to one dynamic OID that it manages.
Newly created OIDs are always inserted in the front of the list.
.Pp
The
.Fn sysctl_ctx_free
function removes the context and associated oids it manages.
function removes the context and associated OIDs it manages.
If the function completes successfully,
all managed oids have been unregistered
all managed OIDs have been unregistered
(removed from the tree)
and freed,
together with all their allocated memory,
@ -127,34 +127,34 @@ If there are no errors during this step,
.Fn sysctl_ctx_free
proceeds to the next step.
If the first step fails,
all unregistered oids associated with the context are registered again.
all unregistered OIDs associated with the context are registered again.
.Pp
.Em Note :
in most cases, the programmer specifies
.Dv OID_AUTO
as the oid number when creating an oid.
However, during registration of the oid in the tree,
as the OID number when creating an OID.
However, during registration of the OID in the tree,
this number is changed to the first available number
greater than or equal to
.Dv CTL_AUTO_START .
If the first step of context deletion fails,
re-registration of the oid does not change the already assigned oid number
re-registration of the OID does not change the already assigned OID number
(which is different from OID_AUTO).
This ensures that re-registered entries
maintain their original positions in the tree.
.Pp
The second step actually performs the deletion of the dynamic oids.
The second step actually performs the deletion of the dynamic OIDs.
.Xr sysctl_remove_oid 9
iterates through the context list,
starting from beginning (i.e., the newest entries).
.Em Important :
this time, the function not only deletes the oids from the tree,
this time, the function not only deletes the OIDs from the tree,
but also frees their memory (provided that oid_refcnt == 0),
as well as the memory of all context entries.
.Pp
The
.Fn sysctl_ctx_entry_add
function allows the addition of an existing dynamic oid to a context.
function allows the addition of an existing dynamic OID to a context.
.Pp
The
.Fn sysctl_ctx_entry_del
@ -166,7 +166,7 @@ is freed, but the
.Fa oidp
pointer remains intact.
Thereafter, the programmer is responsible for managing the resources
allocated to this oid.
allocated to this OID.
.Pp
The
.Fn sysctl_ctx_entry_find
@ -181,18 +181,18 @@ or
.Sh EXAMPLES
The following is an example of how to create a new top-level category
and how to hook up another subtree to an existing static node.
This example uses contexts to keep track of the oids.
This example uses contexts to keep track of the OIDs.
.Bd -literal
#include <sys/sysctl.h>
...
struct sysctl_ctx_list clist;
struct sysctl_oid *oidp;
int a_int;
const char *string = "dynamic sysctl";
static struct sysctl_ctx_list clist;
static struct sysctl_oid *oidp;
static int a_int;
static const char *string = "dynamic sysctl";
...
sysctl_ctx_init(&clist);
oidp = SYSCTL_ADD_NODE(&clist, SYSCTL_STATIC_CHILDREN(/* tree top */),
oidp = SYSCTL_ADD_ROOT_NODE(&clist,
OID_AUTO, "newtree", CTLFLAG_RW, 0, "new top level tree");
oidp = SYSCTL_ADD_INT(&clist, SYSCTL_CHILDREN(oidp),
OID_AUTO, "newint", CTLFLAG_RW, &a_int, 0, "new int leaf");
@ -202,9 +202,9 @@ oidp = SYSCTL_ADD_NODE(&clist, SYSCTL_STATIC_CHILDREN(_debug),
oidp = SYSCTL_ADD_STRING(&clist, SYSCTL_CHILDREN(oidp),
OID_AUTO, "newstring", CTLFLAG_RD, string, 0, "new string leaf");
...
/* Now we can free up the oids */
/* Now we can free up the OIDs */
if (sysctl_ctx_free(&clist)) {
printf("can't free this context - other oids depend on it");
printf("can't free this context - other OIDs depend on it");
return (ENOTEMPTY);
} else {
printf("Success!\\n");
@ -237,7 +237,7 @@ These functions first appeared in
.Sh BUGS
The current removal algorithm is somewhat heavy.
In the worst case,
all oids need to be unregistered, registered again,
all OIDs need to be unregistered, registered again,
and then unregistered and deleted.
However, the algorithm does guarantee transactional properties
for removal operations.