Subject: Re: Replacing the sysctl() interface.
To: Simon Burge <simonb@netbsd.org>
From: Luke Mewburn <lukem@cs.rmit.edu.au>
List: tech-kern
Date: 06/07/2000 23:21:37
Simon Burge writes:
> That's a rough summary, I'll see if I can dig up some of our notes
> on it.
Here's those said notes.
Note that these were just a work in progress `idea after a couple of
beers at a pub' type thing. [And it shows ;]
--- cut here --- file: newsysctl
newsysctl - a revised sysctl interface for netbsd
-------------------------------------------------
data structures:
/* total length of full sysctl name shouldn't exceed this */
#define MAXSYSCTLNAMELEN 256
enum {
EMPTY = 0,
CHILD,
INT32, /* same as `integer' in sysctl(3) */
INT64,
STRING = 10,
OPAQUE,
READONLY = 0x80000000,
} sysctltype_t;
typedef struct {
const char *name; /* e.g ``kern'' */
int mibnode; /* numeric equiv of name
for compat */
sysctltype_t type;
void *data; /* pointer to object */
size_t datalen; /* size of data */
int (*accessor)(sysctlnode_t *node, const char *name,
void *oldp, size_t *oldlenp,
void *newp, size_t *newlenp); /* see below */
sysctlnode_t *next;
} sysctlnode_t;
the accessor function is defined as:
- int accessor(sysctlnode_t *node, const char *name,
void *oldp, size_t *oldlenp,
void *newp, size_t *newlenp);
this is called similar to the way that sysctl(3) currently is;
node is a pointer to the current node, and name is the full
name to that node (so that a generic accessor can be used for
multiple nodes).
if accessor is NULL then copyin/copyout is used, with the
readonly bit honoured if set. otherwise it's used to
enforce the get/set. standard accessor functions (e.g,
`ensure positive int', `only boolean', etc) could be
provided.
you could have a tree like this (given `int rfc666setting'):
"" /* root node */
data -> NULL
type = EMPTY
next
|
v
"net" "icmp"
data ---------> data -> NULL
type = CHILD type = EMPTY
next next
| |
v v
NULL "tcp" "rfc666"
data ---------> data --------> &rfc666setting;
type = CHILD type = INT32
next = NULL next = NULL
functions:
- int sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen);
- a wrapper to
sysctl_bymib(name, namelen, oldp, oldlenp, newp,
newlen, NULL, NULL);
- int sysctl_bymib(int *name, u_int namelen,
void *oldp, size_t *oldlenp,
void *newp, size_t *newlenp,
int *mibnode, int *type);
- as per existing sysctl(3). searchs tree using the `mibnode' elems
of sysctlnode_t.
- if mibnode isn't null, returns the mibnode element of the found node.
- if type isn't null, returns the type element of the found node.
- if node type == CHILD, return the child's name in newp (rather than
the pointer to the node, which would be useless to userland)
- int sysctl_byname(const char *name,
void *oldp, size_t *oldlenp,
void *newp, size_t *newlenp,
int *mibnode, int *type);
- as per sysctl(3), but using a string rather than a MIB array of ints.
- if mibnode isn't null, returns the mibnode element of the found node.
- if type isn't null, returns the type element of the found node.
- if node type == CHILD, return the child's name in newp (rather than
the pointer to the node, which would be useless to userland)
- int sysctl_register(const char *node, int mibtype, sysctltype_t type,
void *data, int datalen, int (*accessor)());
- create a node at "node".
- mibtype must be a defined type (in <sys/sysctl.h>), or -1.
- if mibtype is -1, sysctl_register() will allocate the next available
slot in the SYSCTL_RESERVED range. note that if this is used the
number could change between boots.
- parent must exist (e.g, creating "net.inet" requires "net" to exist.)
- may be prohibited by securelevel.
- kernel/lkms only
- int sysctl_unregister(const char *node);
- remove node at "node".
- no children must exist.
- may be prohibited by securelevel.
- kernel/lkms only
- int sysctl_nextname(const char *name, char *nextname, int nextnamesize)
- returns the name of the next element in the tree after name
into nextname, which is nextnamesize long (which should be
at least MAXSYSCTLNAMELEN).
e.g, if called on the data structure above with "net.icmp",
it will return "net.tcp"
todo
- work out how to define setup sysctl types within kernel at boot time
(call sysctl_register() many times?)
- support enumerated types? (bill sommerfeld)
--- cut here ---