Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/share/examples/kld/dyn_sysctl/dyn_sysctl.c
39534 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2000 Andrzej Bialecki <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/types.h>
30
#include <sys/param.h>
31
#include <sys/systm.h>
32
#include <sys/module.h>
33
#include <sys/sysctl.h>
34
#include <sys/kernel.h>
35
36
37
/* Some example data */
38
static long a = 100;
39
static int b = 200;
40
static char *c = "hi there from dyn_sysctl";
41
static struct sysctl_oid *a_root, *a_root1, *b_root;
42
static struct sysctl_ctx_list clist, clist1, clist2;
43
44
static int
45
sysctl_dyn_sysctl_test(SYSCTL_HANDLER_ARGS)
46
{
47
char *buf = "let's produce some text...";
48
49
return (sysctl_handle_string(oidp, buf, strlen(buf), req));
50
}
51
52
/*
53
* The function called at load/unload.
54
*/
55
static int
56
load(module_t mod, int cmd, void *arg)
57
{
58
int error;
59
60
error = 0;
61
switch (cmd) {
62
case MOD_LOAD:
63
/* Initialize the contexts */
64
printf("Initializing contexts and creating subtrees.\n\n");
65
sysctl_ctx_init(&clist);
66
sysctl_ctx_init(&clist1);
67
sysctl_ctx_init(&clist2);
68
/*
69
* Create two partially overlapping subtrees, belonging
70
* to different contexts.
71
*/
72
printf("TREE ROOT NAME\n");
73
a_root = SYSCTL_ADD_ROOT_NODE(&clist,
74
OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0,
75
"dyn_sysctl root node");
76
a_root = SYSCTL_ADD_ROOT_NODE(&clist1,
77
OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0,
78
"dyn_sysctl root node");
79
if (a_root == NULL) {
80
printf("SYSCTL_ADD_NODE failed!\n");
81
return (EINVAL);
82
}
83
SYSCTL_ADD_LONG(&clist, SYSCTL_CHILDREN(a_root),
84
OID_AUTO, "long_a", CTLFLAG_RW, &a, "just to try");
85
SYSCTL_ADD_INT(&clist, SYSCTL_CHILDREN(a_root),
86
OID_AUTO, "int_b", CTLFLAG_RW, &b, 0, "just to try 1");
87
a_root1 = SYSCTL_ADD_NODE(&clist, SYSCTL_CHILDREN(a_root),
88
OID_AUTO, "nextlevel", CTLFLAG_RD, 0, "one level down");
89
SYSCTL_ADD_STRING(&clist, SYSCTL_CHILDREN(a_root1),
90
OID_AUTO, "string_c", CTLFLAG_RD, c, 0, "just to try 2");
91
printf("1. (%p) / dyn_sysctl\n", &clist);
92
93
/* Add a subtree under already existing category */
94
a_root1 = SYSCTL_ADD_NODE(&clist, SYSCTL_STATIC_CHILDREN(_kern),
95
OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0, "dyn_sysctl root node");
96
if (a_root1 == NULL) {
97
printf("SYSCTL_ADD_NODE failed!\n");
98
return (EINVAL);
99
}
100
SYSCTL_ADD_PROC(&clist, SYSCTL_CHILDREN(a_root1),
101
OID_AUTO, "procedure", CTLTYPE_STRING | CTLFLAG_RD,
102
NULL, 0, sysctl_dyn_sysctl_test, "A",
103
"I can be here, too");
104
printf(" (%p) /kern dyn_sysctl\n", &clist);
105
106
/* Overlap second tree with the first. */
107
b_root = SYSCTL_ADD_NODE(&clist1, SYSCTL_CHILDREN(a_root),
108
OID_AUTO, "nextlevel", CTLFLAG_RD, 0, "one level down");
109
SYSCTL_ADD_STRING(&clist1, SYSCTL_CHILDREN(b_root),
110
OID_AUTO, "string_c1", CTLFLAG_RD, c, 0, "just to try 2");
111
printf("2. (%p) / dyn_sysctl (overlapping #1)\n", &clist1);
112
113
/*
114
* And now do something stupid. Connect another subtree to
115
* dynamic oid.
116
* WARNING: this is an example of WRONG use of dynamic sysctls.
117
*/
118
b_root=SYSCTL_ADD_NODE(&clist2, SYSCTL_CHILDREN(a_root1),
119
OID_AUTO, "bad", CTLFLAG_RW, 0, "dependent node");
120
SYSCTL_ADD_STRING(&clist2, SYSCTL_CHILDREN(b_root),
121
OID_AUTO, "string_c", CTLFLAG_RD, c, 0, "shouldn't panic");
122
printf("3. (%p) /kern/dyn_sysctl bad (WRONG!)\n", &clist2);
123
break;
124
case MOD_UNLOAD:
125
printf("1. Try to free ctx1 (%p): ", &clist);
126
if (sysctl_ctx_free(&clist) != 0)
127
printf("failed: expected. Need to remove ctx3 first.\n");
128
else
129
printf("HELP! sysctl_ctx_free(%p) succeeded. EXPECT PANIC!!!\n", &clist);
130
printf("2. Try to free ctx3 (%p): ", &clist2);
131
if (sysctl_ctx_free(&clist2) != 0) {
132
printf("sysctl_ctx_free(%p) failed!\n", &clist2);
133
/* Remove subtree forcefully... */
134
sysctl_remove_oid(b_root, 1, 1);
135
printf("sysctl_remove_oid(%p) succeeded\n", b_root);
136
} else
137
printf("Ok\n");
138
printf("3. Try to free ctx1 (%p) again: ", &clist);
139
if (sysctl_ctx_free(&clist) != 0) {
140
printf("sysctl_ctx_free(%p) failed!\n", &clist);
141
/* Remove subtree forcefully... */
142
sysctl_remove_oid(a_root1, 1, 1);
143
printf("sysctl_remove_oid(%p) succeeded\n", a_root1);
144
} else
145
printf("Ok\n");
146
printf("4. Try to free ctx2 (%p): ", &clist1);
147
if (sysctl_ctx_free(&clist1) != 0) {
148
printf("sysctl_ctx_free(%p) failed!\n", &clist1);
149
/* Remove subtree forcefully... */
150
sysctl_remove_oid(a_root, 1, 1);
151
} else
152
printf("Ok\n");
153
break;
154
default:
155
error = EOPNOTSUPP;
156
break;
157
}
158
return (error);
159
}
160
161
static moduledata_t mod_data = {
162
"dyn_sysctl",
163
load,
164
0
165
};
166
167
DECLARE_MODULE(dyn_sysctl, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
168
169