1 #ifndef _MINIX_MIB_MIB_H
2 #define _MINIX_MIB_MIB_H
4 #include <minix/drivers.h>
5 #include <minix/sysctl.h>
6 #include <machine/vmparam.h>
10 #include "kernel/arch/i386/include/archconst.h"
13 #ifndef CONFIG_MAX_CPUS
14 #define CONFIG_MAX_CPUS 1
18 * The following setting toggles the existence of the minix.test subtree. For
19 * production environments, it should probably be disabled, although it should
20 * do no harm either. For development platforms, it should be enabled, or
23 #define MINIX_TEST_SUBTREE 1 /* include the minix.test subtree? */
26 * By default, mount request failures will be silently discarded, because the
27 * requests themselves are one-way. For service authors, a bit more output may
28 * be helpful. Set the following defininition to "printf s" in order to
29 * include more information about mount requests and failures.
31 #define MIB_DEBUG_MOUNT(s) /* printf s */
37 * This structure contains a number of less heavily used parameters for handler
38 * functions, mainly to provide extensibility while limiting argument clutter.
41 endpoint_t call_endpt
; /* endpoint of the user process */
42 const int *call_name
; /* remaining part of the name */
43 unsigned int call_namelen
; /* length of the remaining name part */
44 unsigned int call_flags
; /* internal call processing flags */
45 size_t call_reslen
; /* resulting oldlen value on error */
49 #define MIB_FLAG_AUTH 0x01 /* user verified to be superuser */
50 #define MIB_FLAG_NOAUTH 0x02 /* user verified to be regular user */
53 * We reassign new meaning to three NetBSD node flags, because we do not use
54 * the flags in the way NetBSD does:
56 * - On NetBSD, CTLFLAG_ROOT is used to mark the root of the sysctl tree. The
57 * entire root node is not exposed to userland, and thus, neither is this
58 * flag. We do not need the flag as we do not have parent pointers.
59 * - On NetBSD, CTLFLAG_ALIAS is used to mark one node as an alias of another
60 * node, presumably to avoid having to duplicate entire subtrees. We can
61 * simply have two nodes point to the same subtree instead, and thus, we do
62 * not need to support this functionality at all.
63 * - On NetBSD, CTLFLAG_MMAP is defined for future support for memory-mapping
64 * node data with CTL_MMAP. It is not yet clear where or why this feature
65 * would be used in practice. For as long as NetBSD does not actually use
66 * this flag *for node-type nodes*, we can reuse it for our own purposes.
68 * The meaning of our replacement flags is explained further below. We ensure
69 * that none of these flags are ever exposed to userland. As such, our own
70 * definitions can be changed as necessary without breaking anything.
72 #define CTLFLAG_PARENT CTLFLAG_ROOT /* node is a real parent node */
73 #define CTLFLAG_VERIFY CTLFLAG_ALIAS /* node has verification function */
74 #define CTLFLAG_REMOTE CTLFLAG_MMAP /* node is root of remote subtree */
77 * The following node structure definition aims to meet several goals at once:
79 * 1) it can be used for static and dynamic nodes;
80 * 2) it can be used to point to both static and dynamic child arrays at once;
81 * 3) it allows for embedded, pointed-to, and function-generated data;
82 * 4) it allows both temporary and obscuring mount points for remote subtrees;
83 * 5) its unions are compatible with magic instrumentation;
84 * 6) it is optimized for size, assuming many static and few dynamic nodes.
86 * All nodes have flags, a size, a version, a parent (except the root node), a
87 * name, and optionally a description. The use of the rest of the fields
88 * depends on the type of the node, which is defined as part of the node's
91 * Data nodes, that is, nodes of type CTLTYPE_{BOOL,INT,QUAD,STRING,STRUCT},
92 * have associated data. For types CTLTYPE_{BOOL,INT,QUAD}, the node may have
93 * immediate data (CTLFLAG_IMMEDIATE), in which case the value of the node is
94 * stored in the node structure itself (node_bool, node_int, node_quad). These
95 * node types may instead also have a pointer to data. This is always the case
96 * for types CTLTYPE_STRING and CTLTYPE_STRUCT. In that case, node_data is a
97 * valid pointer, and CTLFLAG_IMMEDIATE is not set. Either way, node_size is
98 * the size of the data, which for strings is the maximum string size; for
99 * other types, it defines the exact field size. In addition, data nodes may
100 * have the CTLFLAG_VERIFY flag set, which indicates that node_valid points
101 * to a callback function that verifies whether a newly written value is valid
102 * for the node. If this flag is not set, data nodes may have an associated
103 * function, in which case node_func is not NULL, which will be called to read
104 * and write data instead. The function may optionally use the node's regular
105 * (size, immediate and/or pointer) data fields as it sees fit.
107 * Node-type nodes, of type CTLTYPE_NODE, behave differently. Such nodes may
108 * have static and dynamic child nodes, or have an associated function, or be
109 * a mount point for a subtree handled by a remote process. The exact case is
110 * defined by the combination of the CTLFLAG_PARENT and CTLFLAG_REMOTE flags,
111 * yielding four possible cases:
113 * CTLFLAG_PARENT CTLFLAG_REMOTE Meaning
114 * not set not set The node has an associated function which
115 * handles all access to the entire subtree.
116 * set not set The node is the root of a real, local
117 * subtree with static and/or dynamic children.
118 * not set set The node is a temporarily created mount
119 * point for a remote tree. A remote service
120 * handles all access to the entire subtree.
121 * Unmounting the node also destroys the node.
122 * set set The node is a mount point that obscures a
123 * real, local subtree. A remote service
124 * handles all access to the entire subtree.
125 * Unmounting makes the original node visible.
127 * If the CTLFLAG_PARENT flag is set, the node is the root of a real sutree.
128 * For such nodes, node_size is the number (not size!) of the array of static
129 * child nodes, which is pointed to by node_scptr and indexed by child
130 * identifier. Within the static array, child nodes with zeroed flags fields
131 * are not in use. The node_dcptr field points to a linked list of dynamic
132 * child nodes. The node_csize field is set to the size of the static array
133 * plus the number of dynamic nodes; node_clen is set to the number of valid
134 * entries in the static array plus the number of dynamic nodes.
136 * If a function is set, and thus neither CTLFLAG_PARENT and CTLFLAG_REMOTE are
137 * set, none of the aforementioned fields are used, and the node_size field is
138 * typically (but not necessarily) set to zero.
140 * A remote service can mount its own subtree into the central MIB tree. The
141 * MIB service will then relay any requests for that subtree to the remote
142 * service. Both the mountpoint and the root of the remote subtree must be of
143 * type CTLTYPE_NODE; thus, no individual leaf nodes may be mounted. The mount
144 * point may either be created temporarily for the purpose of mounting (e.g.,
145 * net.inet), or it may override a preexisting node (e.g., kern.ipc). In the
146 * first case, the parent node must exist and be a node type (net). In the
147 * second case, the preexisting target node (the MIB service's kern.ipc) may
148 * not have an associated function and may only have static children. While
149 * being used as a mountpoint (i.e., have CTLFLAG_REMOTE set), the local node's
150 * node_csize and node_clen fields must not be used. Instead, the same space
151 * in the node structure is used to store information about the remote node:
152 * node_rid, node_tid, and the smaller node_rcsize and node_rclen which contain
153 * information about the root of the remote subtree. Remote nodes are also
154 * part of a linked list for administration purposes, using the node_next
155 * field. When a preexisting (CTLFLAG_PARENT) node is unmounted, its original
156 * node_csize and node_clen fields are recomputed.
158 * The structure uses unions for either only pointers or only non-pointers, to
159 * simplify live update support. However, this does not mean the structure is
160 * not fully used: real node-type nodes use node_{flags,size,ver,parent,csize,
161 * clen,scptr,dcptr,name,desc}, which together add up to the full structure
167 typedef ssize_t (*mib_func_ptr
)(struct mib_call
*, struct mib_node
*,
168 struct mib_oldp
*, struct mib_newp
*);
169 typedef int (*mib_verify_ptr
)(struct mib_call
*, struct mib_node
*, void *,
173 * To save space for the maintenance of remote nodes, we split up one uint32_t
174 * field into three subfields:
175 * - node_eid ("endpoint ID"), which is an index into the table of endpoints;
176 * - node_rcsize ("child size"), the number of child slots of the remote root;
177 * - node_rclen ("child length"), the number of children of the remote root.
178 * These fields impose limits on the number of endpoints known in the MIB
179 * service, and the maximum size of the remote subtree root.
181 #define MIB_EID_BITS 5 /* up to 32 services can set remote subtrees */
182 #define MIB_RC_BITS 12 /* remote root may have up to 4096 children */
184 #if MIB_EID_BITS + 2 * MIB_RC_BITS > 32
185 #error "Sum of remote ID and remote children bit fields exceeds uint32_t size"
189 uint32_t node_flags
; /* CTLTYPE_ type and CTLFLAG_ flags */
190 size_t node_size
; /* size of associated data (bytes) */
191 uint32_t node_ver
; /* node version */
192 struct mib_node
*node_parent
; /* pointer to parent node */
193 union ixfer_node_val_u
{
195 uint32_t nvuc_csize
; /* number of child slots */
196 uint32_t nvuc_clen
; /* number of actual children */
199 uint32_t nvur_eid
:MIB_EID_BITS
; /* endpoint index */
200 uint32_t nvur_csize
:MIB_RC_BITS
;/* remote ch. slots */
201 uint32_t nvur_clen
:MIB_RC_BITS
; /* remote children */
202 uint32_t nvur_rid
; /* opaque ID of remote root */
204 bool nvu_bool
; /* immediate boolean */
205 int nvu_int
; /* immediate integer */
206 u_quad_t nvu_quad
; /* immediate quad */
208 union pxfer_node_ptr_u
{
209 void *npu_data
; /* struct or string data pointer */
210 struct mib_node
*npu_scptr
; /* static child node array */
212 union pxfer_node_aux_u
{
213 struct mib_dynode
*nau_dcptr
; /* dynamic child node list */
214 mib_func_ptr nau_func
; /* handler function */
215 mib_verify_ptr nau_verify
; /* verification function */
216 struct mib_node
*nau_next
; /* next remote node in list */
218 const char *node_name
; /* node name string */
219 const char *node_desc
; /* node description (may be NULL) */
221 #define node_csize node_val_u.nvu_child.nvuc_csize
222 #define node_clen node_val_u.nvu_child.nvuc_clen
223 #define node_eid node_val_u.nvu_remote.nvur_eid
224 #define node_rcsize node_val_u.nvu_remote.nvur_csize
225 #define node_rclen node_val_u.nvu_remote.nvur_clen
226 #define node_rid node_val_u.nvu_remote.nvur_rid
227 #define node_bool node_val_u.nvu_bool
228 #define node_int node_val_u.nvu_int
229 #define node_quad node_val_u.nvu_quad
230 #define node_data node_ptr_u.npu_data
231 #define node_scptr node_ptr_u.npu_scptr
232 #define node_dcptr node_aux_u.nau_dcptr
233 #define node_func node_aux_u.nau_func
234 #define node_verify node_aux_u.nau_verify
235 #define node_next node_aux_u.nau_next
238 * This structure is used for dynamically allocated nodes, that is, nodes
239 * created by userland at run time. It contains not only the fields below, but
240 * also the full name and, for leaf nodes with non-immediate data, the actual
241 * data area, or, for temporary mount points for remote subtrees, the node's
245 struct mib_dynode
*dynode_next
; /* next in linked dynamic node list */
246 int dynode_id
; /* identifier of this node */
247 struct mib_node dynode_node
; /* actual node */
248 char dynode_name
[1]; /* node name data (variable size) */
251 /* Static node initialization macros. */
252 #define MIB_NODE(f,t,n,d) { \
253 .node_flags = CTLTYPE_NODE | CTLFLAG_PARENT | f, \
254 .node_size = __arraycount(t), \
259 #define MIB_ENODE(f,n,d) { /* "E"mpty or "E"xternal */ \
260 .node_flags = CTLTYPE_NODE | CTLFLAG_PARENT | f, \
264 #define MIB_BOOL(f,b,n,d) { \
265 .node_flags = CTLTYPE_BOOL | CTLFLAG_IMMEDIATE | f, \
266 .node_size = sizeof(bool), \
271 #define MIB_INT(f,i,n,d) { \
272 .node_flags = CTLTYPE_INT | CTLFLAG_IMMEDIATE | f, \
273 .node_size = sizeof(int), \
278 #define MIB_QUAD(f,q,n,d) { \
279 .node_flags = CTLTYPE_QUAD | CTLFLAG_IMMEDIATE | f, \
280 .node_size = sizeof(u_quad_t), \
285 #define _MIB_DATA(f,s,p,n,d) { \
288 .node_data = __UNCONST(p), \
292 #define MIB_BOOLPTR(f,p,n,d) _MIB_DATA(CTLTYPE_BOOL | f, sizeof(*p), p, n, d)
293 #define MIB_INTPTR(f,p,n,d) _MIB_DATA(CTLTYPE_INT | f, sizeof(*p), p, n, d)
294 #define MIB_QUADTR(f,p,n,d) _MIB_DATA(CTLTYPE_QUAD | f, sizeof(*p), p, n, d)
295 #define MIB_STRING(f,p,n,d) _MIB_DATA(CTLTYPE_STRING | f, sizeof(p), p, n, d)
296 #define MIB_STRUCT(f,s,p,n,d) _MIB_DATA(CTLTYPE_STRUCT | f, s, p, n, d)
297 #define MIB_FUNC(f,s,fp,n,d) { \
304 #define MIB_INTV(f,i,vp,n,d) { \
305 .node_flags = CTLTYPE_INT | CTLFLAG_IMMEDIATE | \
306 CTLFLAG_VERIFY | f, \
307 .node_size = sizeof(int), \
314 /* Finalize a node initialized with MIB_ENODE. */
315 #define MIB_INIT_ENODE(n,t) \
317 (n)->node_size = __arraycount(t); \
318 (n)->node_scptr = t; \
321 /* Some convenient shortcuts for highly common flags. */
322 #define _RO CTLFLAG_READONLY
323 #define _RW CTLFLAG_READWRITE
324 #define _P CTLFLAG_PERMANENT
327 * If this check fails, all uses of "struct sysctlnode" and "struct sysctldesc"
328 * need to be revised, and translation between different versions of those
329 * structures may have to be added for backward compatibility.
331 #if SYSCTL_VERSION != SYSCTL_VERS_1
332 #error "NetBSD sysctl headers are ahead of our implementation"
336 int mib_inrange(struct mib_oldp
*, size_t);
337 size_t mib_getoldlen(struct mib_oldp
*);
338 ssize_t
mib_copyout(struct mib_oldp
*, size_t, const void * __restrict
,
340 void mib_setoldlen(struct mib_call
*, size_t);
341 size_t mib_getnewlen(struct mib_newp
*);
342 int mib_copyin(struct mib_newp
* __restrict
, void * __restrict
, size_t);
343 int mib_copyin_aux(struct mib_newp
* __restrict
, vir_bytes
,
344 void * __restrict
, size_t);
345 int mib_relay_oldp(endpoint_t
, struct mib_oldp
* __restrict
, cp_grant_id_t
*,
346 size_t * __restrict
);
347 int mib_relay_newp(endpoint_t
, struct mib_newp
* __restrict
, cp_grant_id_t
*,
348 size_t * __restrict
);
349 int mib_authed(struct mib_call
*);
350 extern struct mib_node mib_root
;
353 ssize_t
mib_readwrite(struct mib_call
*, struct mib_node
*, struct mib_oldp
*,
354 struct mib_newp
*, mib_verify_ptr
);
355 ssize_t
mib_dispatch(struct mib_call
*, struct mib_oldp
*, struct mib_newp
*);
356 void mib_tree_init(void);
357 int mib_mount(const int *, unsigned int, unsigned int, uint32_t, uint32_t,
358 unsigned int, unsigned int, struct mib_node
**);
359 void mib_unmount(struct mib_node
*);
360 extern unsigned int mib_nodes
;
361 extern unsigned int mib_objects
;
362 extern unsigned int mib_remotes
;
365 void mib_remote_init(void);
366 int mib_register(const message
*, int);
367 int mib_deregister(const message
*, int);
368 int mib_remote_info(unsigned int, uint32_t, char *, size_t, char *, size_t);
369 ssize_t
mib_remote_call(struct mib_call
*, struct mib_node
*,
370 struct mib_oldp
*, struct mib_newp
*);
373 ssize_t
mib_kern_lwp(struct mib_call
*, struct mib_node
*, struct mib_oldp
*,
375 ssize_t
mib_kern_proc2(struct mib_call
*, struct mib_node
*, struct mib_oldp
*,
377 ssize_t
mib_kern_proc_args(struct mib_call
*, struct mib_node
*,
378 struct mib_oldp
*, struct mib_newp
*);
379 ssize_t
mib_minix_proc_list(struct mib_call
*, struct mib_node
*,
380 struct mib_oldp
*, struct mib_newp
*);
381 ssize_t
mib_minix_proc_data(struct mib_call
*, struct mib_node
*,
382 struct mib_oldp
*, struct mib_newp
*);
384 /* subtree modules */
385 void mib_kern_init(struct mib_node
*);
386 void mib_vm_init(struct mib_node
*);
387 void mib_hw_init(struct mib_node
*);
388 void mib_minix_init(struct mib_node
*);
390 #endif /* !_MINIX_MIB_MIB_H */