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
Copyright © 2010-2025 Platon Technologies, s.r.o.           Home | Man pages | tLDP | Documents | Utilities | About
Design by styleshout