sysctl_add_oid(9)
NAME
- sysctl_add_oid, sysctl_move_oid, sysctl_remove_oid - runtime
- sysctl tree
manipulation
SYNOPSIS
#include <sys/types.h>
#include <sys/sysctl.h>
struct sysctl_oid *
sysctl_add_oid(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int kind, void *arg1, int arg2,
int (*handler) (SYSCTL_HANDLER_ARGS), const char
*format,
const char *descr);
int
sysctl_move_oid(struct sysctl_oid *oidp, struct
sysctl_oid_list *parent);
int
sysctl_remove_oid(struct sysctl_oid *oidp, int del, int
recurse);
struct sysctl_oid_list *
SYSCTL_CHILDREN(struct sysctl_oid *oidp);
struct sysctl_oid_list *
SYSCTL_STATIC_CHILDREN(struct sysctl_oid_list OID_NAME);
struct sysctl_oid *
SYSCTL_ADD_OID(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int kind, void *arg1, int arg2,
int (*handler) (SYSCTL_HANDLER_ARGS), const char
*format,
const char *descr);
struct sysctl_oid *
SYSCTL_ADD_NODE(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, int (*handler) (SYSCTL_HANDLER_ARGS),
const char *descr);
struct sysctl_oid *
SYSCTL_ADD_STRING(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, char *arg, int len, const char *descr);
struct sysctl_oid *
SYSCTL_ADD_INT(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, int *arg, int len, const char *descr);
struct sysctl_oid *
SYSCTL_ADD_UINT(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, unsigned int *arg, int len, const char
*descr);
struct sysctl_oid *
SYSCTL_ADD_LONG(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, long *arg, const char *descr);
struct sysctl_oid *
SYSCTL_ADD_ULONG(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, unsigned long *arg, const char *descr);
struct sysctl_oid *
SYSCTL_ADD_OPAQUE(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, void *arg, int len, const char *format,
const char *descr);
struct sysctl_oid *
SYSCTL_ADD_STRUCT(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, void *arg, STRUCT_NAME, const char
*descr);
struct sysctl_oid *
SYSCTL_ADD_PROC(struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *parent, int number, const
char *name,
int access, void *arg1, int arg2,
int (*handler) (SYSCTL_HANDLER_ARGS), const char
*format,
const char *descr);
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 #include
- <sys/linker_set.h>
and src/sys/kern/kern_sysctl.c for details), only allows - creation and
deletion on module load and unload respectively. - Dynamic oids of type CTLTYPE_NODE are reusable so that sev
- eral 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 overlap - ping 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 par - ent.
- Newly created oids are connected to their parent nodes. In
- all these
functions and macros (with the exception of - sysctl_remove_oid()), one of
the required parameters is parent, which points to the head - of the parent's list of children.
- Most top level categories are created statically. When con
- necting to
existing static oids, this pointer can be obtained with the
SYSCTL_STATIC_CHILDREN() macro, where the OID_NAME argument - is name of
the parent oid of type CTLTYPE_NODE (i.e., the name dis - played by
sysctl(8), preceded by underscore, and with all dots re - placed with underscores).
- When connecting to an existing dynamic oid, this pointer can
- be obtained
with the SYSCTL_CHILDREN() macro, where the oidp argument - points to the
parent oid of type CTLTYPE_NODE. - The 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 NULL. Many of the arguments for sysctl_add_oid() - are common
to the macros. The arguments are as follows: - ctx A pointer to an optional sysctl context, or NULL.
- See
- 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 se - quences are
required. If ctx is not NULL, the newly created - oid will be
added to this context as its first entry. - parent A pointer to a struct sysctl_oid_list, which is the
- head of the
- parent's list of children.
- number The oid number that will be assigned to this oid.
- In almost all
- cases this should be set to OID_AUTO, which will
- result in the
assignment of the next available oid number. - name The name of the oid. The newly created oid will
- contain a copy
- of the name.
- kind The kind of oid, specified as a bit mask of the
- type and access
- values defined in the #include <sys/sysctl.h> header file. Oids created dynamically always have
- the
CTLFLAG_DYN flag set. Access flags specify whether - this oid is
read-only or read-write, and whether it may be mod - ified by all
users or by the superuser only. - arg1 A pointer to any data that the oid should refer
- ence, or NULL.
- arg2 The size of arg1, or 0 if arg1 is NULL.
- 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 SYSCTL_ADD_PROC() macro. - format A pointer to a string which specifies the format of
- the oid sym
- bolically. This format is used as a hint by
- sysctl(8) to apply
proper data formatting for display purposes. Cur - rently used
format names are: ``N'' for node, ``A'' for char *, - ``I'' for
int, ``IU'' for unsigned int, ``L'' for long, - ``LU'' for
unsigned long and ``S,TYPE'' for struct TYPE struc - tures.
- descr A pointer to a textual description of the oid.
- The sysctl_move_oid() function reparents an existing oid.
- The oid is
assigned a new number as if it had been created with number - set to
OID_AUTO. - The sysctl_remove_oid() function removes a dynamically cre
- ated oid from
the tree, optionally freeing its resources. It takes the - following arguments:
- oidp A pointer to the dynamic oid to be removed. If the
- oid is not
- dynamic, or the pointer is NULL, the function re
- turns EINVAL.
- del If non-zero, sysctl_remove_oid() will try to free
- the oid's
- resources when the reference count of the oid be
- comes zero.
However, if del is set to 0, the routine will only - deregister
the oid from the tree, without freeing its re - sources. This
behaviour is useful when the caller expects to - rollback (possibly partially failed) deletion of many oids later.
- recurse If non-zero, attempt to remove the node and all its
- children.
- If recurse is set to 0, any attempt to remove a
- node that contains any children will result in a ENOTEMPTY er
- ror. WARNING:
use recursive deletion with extreme caution! Nor - mally 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 re - move 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 panic(9) if other code sections continue to - use removed
subtrees. - Again, in most cases the programmer should use contexts, as
- described in
sysctl_ctx_init(9), to keep track of created oids, and to - delete them
later in orderly fashion. - There is a set of macros defined that helps to create oids
- of given type.
They are as follows: - SYSCTL_ADD_OID() creates a raw oid. This macro is func
- tionally
- equivalent to the sysctl_add_oid()
- function.
- SYSCTL_ADD_NODE() creates an oid of type CTLTYPE_NODE, to
- which child
- oids may be added.
- SYSCTL_ADD_STRING() creates an oid that handles a zero-ter
- minated char
- acter string.
- SYSCTL_ADD_INT() creates an oid that handles an int
- variable.
- SYSCTL_ADD_UINT() creates an oid that handles an unsigned
- int vari
- able.
- SYSCTL_ADD_LONG() creates an oid that handles a long
- variable.
- SYSCTL_ADD_ULONG() creates an oid that handles an unsigned
- long vari
- able.
- SYSCTL_ADD_OPAQUE() creates an oid that handles any chunk
- of opaque data
- of the size specified by the len argu
- ment, which is
a pointer to a size_t *. - SYSCTL_ADD_STRUCT() creates an oid that handles a struct
- TYPE structure.
- The format parameter will be set to
- ``S,TYPE'' to
provide proper hints to the sysctl(8) - utility.
- SYSCTL_ADD_PROC() creates an oid with the specified
- 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.
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:
- #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(_de
- bug),
- 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");
- This example creates the following subtrees:
debug.newtree.newstring
newtree.newint- Care should be taken to free all oids once they are no
- longer needed!
SEE ALSO
sysctl(8), sysctl_ctx_free(9), sysctl_ctx_init(9)
HISTORY
These functions first appeared in FreeBSD 4.2.
AUTHORS
Andrzej Bialecki <abial@FreeBSD.org>
BUGS
- Sharing nodes between many code sections causes interdepen
- dencies 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 un - able to delete
that oid. These issues are handled properly by sysctl con - texts.
- Many operations on the tree involve traversing linked lists.
- For this
reason, oid creation and removal is relatively costly. - BSD July 15, 2000