502 lines
13 KiB
Groff
502 lines
13 KiB
Groff
.\"
|
|
.\" Copyright (c) 2000, Andrzej Bialecki <abial@FreeBSD.org>
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. The name of the author may not be used to endorse or promote products
|
|
.\" derived from this software without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd July 15, 2000
|
|
.Dt SYSCTL_ADD_OID 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm sysctl_add_oid ,
|
|
.Nm sysctl_remove_oid
|
|
.Nd runtime sysctl tree manipulation
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In sys/sysctl.h
|
|
.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 int
|
|
.Fo sysctl_remove_oid
|
|
.Fa "struct sysctl_oid *oidp"
|
|
.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_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
|
|
.Aq 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.
|
|
.Pp
|
|
Dynamic oids of type
|
|
.Dv CTLTYPE_NODE
|
|
are reusable
|
|
so that several code sections can create and delete them,
|
|
but in reality they are allocated and freed
|
|
based on their reference count.
|
|
As a consequence,
|
|
it is possible for two or more code sections
|
|
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
|
|
.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 bitmask of the type and access values defined in the
|
|
.Aq sys/sysctl.h
|
|
header file.
|
|
Oids created dynamically always have the
|
|
.Dv CTLTYPE_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
|
|
.Pp
|
|
The
|
|
.Fn sysctl_remove_oid
|
|
function removes a dynamically created oid from the tree,
|
|
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
|
|
.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.
|
|
However, if
|
|
.Fa del
|
|
is set to 0,
|
|
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.
|
|
.It Fa recurse
|
|
If non-zero, attempt to remove the node and all its children.
|
|
If
|
|
.Pa recurse
|
|
is set to 0,
|
|
any attempt to remove a node that contains any children
|
|
will result in a
|
|
.Er ENOTEMPTY
|
|
error.
|
|
.Em WARNING : "use recursive deletion with extreme caution" !
|
|
Normally it should not be needed if contexts are used.
|
|
Contexts take care of tracking inter-dependencies
|
|
between users of the tree.
|
|
However, in some extreme cases it might be necessary
|
|
to remove part of the subtree no matter how it was created,
|
|
in order to free some other resources.
|
|
Be aware, though, that this may result in a system
|
|
.Xr panic 9
|
|
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,
|
|
and to delete them later in orderly fashion.
|
|
.Pp
|
|
There is a set of macros defined
|
|
that helps to create oids of given type.
|
|
.Bl -tag -width SYSCTL_ADD_STRINGXX
|
|
They are as follows:
|
|
.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_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_ctx_free 9 ,
|
|
.Xr sysctl_ctx_init 9
|
|
.Sh HISTORY
|
|
These functions first appeared in
|
|
.Fx 4.2 .
|
|
.Sh AUTHORS
|
|
.An Andrzej Bialecki Aq abial@FreeBSD.org
|
|
.Sh BUGS
|
|
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.
|
|
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.
|