etc/services - sync with NetBSD-8
[minix.git] / minix / servers / mib / mib.h
blob413a109cc899a044a1c2011cf9bfb021e5a47e4e
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>
7 #include <assert.h>
9 #if defined(__i386__)
10 #include "kernel/arch/i386/include/archconst.h"
11 #endif
13 #ifndef CONFIG_MAX_CPUS
14 #define CONFIG_MAX_CPUS 1
15 #endif
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
21 * test87 will fail.
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 */
33 struct mib_oldp;
34 struct mib_newp;
37 * This structure contains a number of less heavily used parameters for handler
38 * functions, mainly to provide extensibility while limiting argument clutter.
40 struct mib_call {
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 */
48 /* Call flags. */
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
89 * flags field.
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
162 * size.
164 struct mib_node;
165 struct mib_dynode;
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 *,
170 size_t);
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"
186 #endif
188 struct mib_node {
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 {
194 struct {
195 uint32_t nvuc_csize; /* number of child slots */
196 uint32_t nvuc_clen; /* number of actual children */
197 } nvu_child;
198 struct {
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 */
203 } nvu_remote;
204 bool nvu_bool; /* immediate boolean */
205 int nvu_int; /* immediate integer */
206 u_quad_t nvu_quad; /* immediate quad */
207 } node_val_u;
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 */
211 } node_ptr_u;
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 */
217 } node_aux_u;
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
242 * description.
244 struct mib_dynode {
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), \
255 .node_scptr = t, \
256 .node_name = n, \
257 .node_desc = d \
259 #define MIB_ENODE(f,n,d) { /* "E"mpty or "E"xternal */ \
260 .node_flags = CTLTYPE_NODE | CTLFLAG_PARENT | f, \
261 .node_name = n, \
262 .node_desc = d \
264 #define MIB_BOOL(f,b,n,d) { \
265 .node_flags = CTLTYPE_BOOL | CTLFLAG_IMMEDIATE | f, \
266 .node_size = sizeof(bool), \
267 .node_bool = b, \
268 .node_name = n, \
269 .node_desc = d \
271 #define MIB_INT(f,i,n,d) { \
272 .node_flags = CTLTYPE_INT | CTLFLAG_IMMEDIATE | f, \
273 .node_size = sizeof(int), \
274 .node_int = i, \
275 .node_name = n, \
276 .node_desc = d \
278 #define MIB_QUAD(f,q,n,d) { \
279 .node_flags = CTLTYPE_QUAD | CTLFLAG_IMMEDIATE | f, \
280 .node_size = sizeof(u_quad_t), \
281 .node_quad = q, \
282 .node_name = n, \
283 .node_desc = d \
285 #define _MIB_DATA(f,s,p,n,d) { \
286 .node_flags = f, \
287 .node_size = s, \
288 .node_data = __UNCONST(p), \
289 .node_name = n, \
290 .node_desc = d \
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) { \
298 .node_flags = f, \
299 .node_size = s, \
300 .node_func = fp, \
301 .node_name = n, \
302 .node_desc = 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), \
308 .node_int = i, \
309 .node_verify = vp, \
310 .node_name = n, \
311 .node_desc = d \
314 /* Finalize a node initialized with MIB_ENODE. */
315 #define MIB_INIT_ENODE(n,t) \
316 do { \
317 (n)->node_size = __arraycount(t); \
318 (n)->node_scptr = t; \
319 } while (0)
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"
333 #endif
335 /* main.c */
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,
339 size_t);
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;
352 /* tree.c */
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;
364 /* remote.c */
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 *);
372 /* proc.c */
373 ssize_t mib_kern_lwp(struct mib_call *, struct mib_node *, struct mib_oldp *,
374 struct mib_newp *);
375 ssize_t mib_kern_proc2(struct mib_call *, struct mib_node *, struct mib_oldp *,
376 struct mib_newp *);
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 */