/share/man/man9/sysctl_add_oid.9
https://bitbucket.org/freebsd/freebsd-head/ · Unknown · 530 lines · 529 code · 1 blank · 0 comment · 0 complexity · bd5135a7b2491bbdd48a72bc9e9e1fdd MD5 · raw file
- .\"
- .\" 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_move_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_move_oid
- .Fa "struct sysctl_oid *oidp"
- .Fa "struct sysctl_oid_list *parent"
- .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_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_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.
- .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 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
- .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
- .Fa number
- set to
- .Dv OID_AUTO .
- .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.
- 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 ,
- .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.