netbsd32_sysctl.c revision 1.29.4.2 1 1.29.4.2 christos /* $NetBSD: netbsd32_sysctl.c,v 1.29.4.2 2009/01/04 01:56:02 christos Exp $ */
2 1.29.4.2 christos
3 1.29.4.2 christos /*
4 1.29.4.2 christos * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 1.29.4.2 christos * All rights reserved.
6 1.29.4.2 christos *
7 1.29.4.2 christos * This code is derived from software contributed to The NetBSD Foundation
8 1.29.4.2 christos * by Andrew Brown.
9 1.29.4.2 christos *
10 1.29.4.2 christos * Redistribution and use in source and binary forms, with or without
11 1.29.4.2 christos * modification, are permitted provided that the following conditions
12 1.29.4.2 christos * are met:
13 1.29.4.2 christos * 1. Redistributions of source code must retain the above copyright
14 1.29.4.2 christos * notice, this list of conditions and the following disclaimer.
15 1.29.4.2 christos * 2. Redistributions in binary form must reproduce the above copyright
16 1.29.4.2 christos * notice, this list of conditions and the following disclaimer in the
17 1.29.4.2 christos * documentation and/or other materials provided with the distribution.
18 1.29.4.2 christos * 3. The name of the author may not be used to endorse or promote products
19 1.29.4.2 christos * derived from this software without specific prior written permission.
20 1.29.4.2 christos *
21 1.29.4.2 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.29.4.2 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.29.4.2 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.29.4.2 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.29.4.2 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 1.29.4.2 christos * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 1.29.4.2 christos * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 1.29.4.2 christos * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 1.29.4.2 christos * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.29.4.2 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.29.4.2 christos * SUCH DAMAGE.
32 1.29.4.2 christos */
33 1.29.4.2 christos
34 1.29.4.2 christos #include <sys/cdefs.h>
35 1.29.4.2 christos __KERNEL_RCSID(0, "$NetBSD: netbsd32_sysctl.c,v 1.29.4.2 2009/01/04 01:56:02 christos Exp $");
36 1.29.4.2 christos
37 1.29.4.2 christos #if defined(_KERNEL_OPT)
38 1.29.4.2 christos #include "opt_ddb.h"
39 1.29.4.2 christos #endif
40 1.29.4.2 christos
41 1.29.4.2 christos #include <sys/param.h>
42 1.29.4.2 christos #include <sys/systm.h>
43 1.29.4.2 christos #include <sys/kernel.h>
44 1.29.4.2 christos #include <sys/malloc.h>
45 1.29.4.2 christos #include <sys/mount.h>
46 1.29.4.2 christos #include <sys/stat.h>
47 1.29.4.2 christos #include <sys/time.h>
48 1.29.4.2 christos #include <sys/vnode.h>
49 1.29.4.2 christos #include <sys/syscallargs.h>
50 1.29.4.2 christos #include <sys/proc.h>
51 1.29.4.2 christos #include <sys/sysctl.h>
52 1.29.4.2 christos #include <sys/dirent.h>
53 1.29.4.2 christos #include <sys/ktrace.h>
54 1.29.4.2 christos
55 1.29.4.2 christos #include <uvm/uvm_extern.h>
56 1.29.4.2 christos
57 1.29.4.2 christos #include <compat/netbsd32/netbsd32.h>
58 1.29.4.2 christos #include <compat/netbsd32/netbsd32_syscall.h>
59 1.29.4.2 christos #include <compat/netbsd32/netbsd32_syscallargs.h>
60 1.29.4.2 christos #include <compat/netbsd32/netbsd32_conv.h>
61 1.29.4.2 christos #include <compat/netbsd32/netbsd32_sysctl.h>
62 1.29.4.2 christos
63 1.29.4.2 christos #if defined(DDB)
64 1.29.4.2 christos #include <ddb/ddbvar.h>
65 1.29.4.2 christos #endif
66 1.29.4.2 christos
67 1.29.4.2 christos struct sysctlnode netbsd32_sysctl_root = {
68 1.29.4.2 christos .sysctl_flags = SYSCTL_VERSION|CTLFLAG_ROOT|CTLTYPE_NODE,
69 1.29.4.2 christos .sysctl_num = 0,
70 1.29.4.2 christos .sysctl_name = "(netbsd32_root)",
71 1.29.4.2 christos sysc_init_field(_sysctl_size, sizeof(struct sysctlnode)),
72 1.29.4.2 christos };
73 1.29.4.2 christos
74 1.29.4.2 christos static struct sysctllog *netbsd32_clog;
75 1.29.4.2 christos
76 1.29.4.2 christos /*
77 1.29.4.2 christos * sysctl helper routine for netbsd32's kern.boottime node
78 1.29.4.2 christos */
79 1.29.4.2 christos static int
80 1.29.4.2 christos netbsd32_sysctl_kern_boottime(SYSCTLFN_ARGS)
81 1.29.4.2 christos {
82 1.29.4.2 christos struct sysctlnode node;
83 1.29.4.2 christos struct netbsd32_timespec bt32;
84 1.29.4.2 christos
85 1.29.4.2 christos netbsd32_from_timespec(&boottime, &bt32);
86 1.29.4.2 christos
87 1.29.4.2 christos node = *rnode;
88 1.29.4.2 christos node.sysctl_data = &bt32;
89 1.29.4.2 christos return (sysctl_lookup(SYSCTLFN_CALL(&node)));
90 1.29.4.2 christos }
91 1.29.4.2 christos
92 1.29.4.2 christos /*
93 1.29.4.2 christos * sysctl helper routine for netbsd32's vm.loadavg node
94 1.29.4.2 christos */
95 1.29.4.2 christos static int
96 1.29.4.2 christos netbsd32_sysctl_vm_loadavg(SYSCTLFN_ARGS)
97 1.29.4.2 christos {
98 1.29.4.2 christos struct sysctlnode node;
99 1.29.4.2 christos struct netbsd32_loadavg av32;
100 1.29.4.2 christos
101 1.29.4.2 christos netbsd32_from_loadavg(&av32, &averunnable);
102 1.29.4.2 christos
103 1.29.4.2 christos node = *rnode;
104 1.29.4.2 christos node.sysctl_data = &av32;
105 1.29.4.2 christos return (sysctl_lookup(SYSCTLFN_CALL(&node)));
106 1.29.4.2 christos }
107 1.29.4.2 christos
108 1.29.4.2 christos void
109 1.29.4.2 christos netbsd32_sysctl_init(void)
110 1.29.4.2 christos {
111 1.29.4.2 christos const struct sysctlnode *_root = &netbsd32_sysctl_root;
112 1.29.4.2 christos extern const char machine_arch32[];
113 1.29.4.2 christos extern const char machine32[];
114 1.29.4.2 christos
115 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
116 1.29.4.2 christos CTLFLAG_PERMANENT,
117 1.29.4.2 christos CTLTYPE_NODE, "kern", NULL,
118 1.29.4.2 christos NULL, 0, NULL, 0,
119 1.29.4.2 christos CTL_KERN, CTL_EOL);
120 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
121 1.29.4.2 christos CTLFLAG_PERMANENT,
122 1.29.4.2 christos CTLTYPE_STRUCT, "boottime", NULL,
123 1.29.4.2 christos netbsd32_sysctl_kern_boottime, 0, NULL,
124 1.29.4.2 christos sizeof(struct netbsd32_timeval),
125 1.29.4.2 christos CTL_KERN, KERN_BOOTTIME, CTL_EOL);
126 1.29.4.2 christos
127 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
128 1.29.4.2 christos CTLFLAG_PERMANENT,
129 1.29.4.2 christos CTLTYPE_NODE, "vm", NULL,
130 1.29.4.2 christos NULL, 0, NULL, 0,
131 1.29.4.2 christos CTL_VM, CTL_EOL);
132 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
133 1.29.4.2 christos CTLFLAG_PERMANENT,
134 1.29.4.2 christos CTLTYPE_STRUCT, "loadavg", NULL,
135 1.29.4.2 christos netbsd32_sysctl_vm_loadavg, 0, NULL,
136 1.29.4.2 christos sizeof(struct netbsd32_loadavg),
137 1.29.4.2 christos CTL_VM, VM_LOADAVG, CTL_EOL);
138 1.29.4.2 christos
139 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
140 1.29.4.2 christos CTLFLAG_PERMANENT,
141 1.29.4.2 christos CTLTYPE_NODE, "hw", NULL,
142 1.29.4.2 christos NULL, 0, NULL, 0,
143 1.29.4.2 christos CTL_HW, CTL_EOL);
144 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
145 1.29.4.2 christos CTLFLAG_PERMANENT,
146 1.29.4.2 christos CTLTYPE_STRING, "machine", NULL,
147 1.29.4.2 christos NULL, 0, &machine32, 0,
148 1.29.4.2 christos CTL_HW, HW_MACHINE, CTL_EOL);
149 1.29.4.2 christos sysctl_createv(&netbsd32_clog, 0, &_root, NULL,
150 1.29.4.2 christos CTLFLAG_PERMANENT,
151 1.29.4.2 christos CTLTYPE_STRING, "machine_arch", NULL,
152 1.29.4.2 christos NULL, 0, &machine_arch32, 0,
153 1.29.4.2 christos CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
154 1.29.4.2 christos }
155 1.29.4.2 christos
156 1.29.4.2 christos void
157 1.29.4.2 christos netbsd32_sysctl_fini(void)
158 1.29.4.2 christos {
159 1.29.4.2 christos
160 1.29.4.2 christos sysctl_teardown(&netbsd32_clog);
161 1.29.4.2 christos sysctl_free(&netbsd32_sysctl_root);
162 1.29.4.2 christos }
163 1.29.4.2 christos
164 1.29.4.2 christos int
165 1.29.4.2 christos netbsd32___sysctl(struct lwp *l, const struct netbsd32___sysctl_args *uap, register_t *retval)
166 1.29.4.2 christos {
167 1.29.4.2 christos /* {
168 1.29.4.2 christos syscallarg(netbsd32_intp) name;
169 1.29.4.2 christos syscallarg(u_int) namelen;
170 1.29.4.2 christos syscallarg(netbsd32_voidp) old;
171 1.29.4.2 christos syscallarg(netbsd32_size_tp) oldlenp;
172 1.29.4.2 christos syscallarg(netbsd32_voidp) new;
173 1.29.4.2 christos syscallarg(netbsd32_size_t) newlen;
174 1.29.4.2 christos } */
175 1.29.4.2 christos const struct sysctlnode *pnode;
176 1.29.4.2 christos netbsd32_size_t netbsd32_oldlen;
177 1.29.4.2 christos size_t oldlen, *oldlenp, savelen;
178 1.29.4.2 christos int name[CTL_MAXNAME], error, nerror, *namep;
179 1.29.4.2 christos void *newp, *oldp;
180 1.29.4.2 christos
181 1.29.4.2 christos /*
182 1.29.4.2 christos * get and convert 32 bit size_t to native size_t
183 1.29.4.2 christos */
184 1.29.4.2 christos namep = SCARG_P32(uap, name);
185 1.29.4.2 christos oldp = SCARG_P32(uap, old);
186 1.29.4.2 christos newp = SCARG_P32(uap, new);
187 1.29.4.2 christos oldlenp = SCARG_P32(uap, oldlenp);
188 1.29.4.2 christos oldlen = 0;
189 1.29.4.2 christos if (oldlenp != NULL) {
190 1.29.4.2 christos error = copyin(oldlenp, &netbsd32_oldlen,
191 1.29.4.2 christos sizeof(netbsd32_oldlen));
192 1.29.4.2 christos if (error)
193 1.29.4.2 christos return (error);
194 1.29.4.2 christos oldlen = netbsd32_oldlen;
195 1.29.4.2 christos }
196 1.29.4.2 christos savelen = oldlen;
197 1.29.4.2 christos
198 1.29.4.2 christos /*
199 1.29.4.2 christos * retrieve name and see if we need to dispatch this query to
200 1.29.4.2 christos * the shadow tree. if we find it in the shadow tree,
201 1.29.4.2 christos * dispatch to there, otherwise NULL means use the built-in
202 1.29.4.2 christos * default main tree.
203 1.29.4.2 christos */
204 1.29.4.2 christos if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 1)
205 1.29.4.2 christos return (EINVAL);
206 1.29.4.2 christos error = copyin(namep, &name[0], SCARG(uap, namelen) * sizeof(int));
207 1.29.4.2 christos if (error)
208 1.29.4.2 christos return (error);
209 1.29.4.2 christos
210 1.29.4.2 christos ktrmib(name, SCARG(uap, namelen));
211 1.29.4.2 christos
212 1.29.4.2 christos sysctl_lock(newp != NULL);
213 1.29.4.2 christos pnode = &netbsd32_sysctl_root;
214 1.29.4.2 christos error = sysctl_locate(l, &name[0], SCARG(uap, namelen), &pnode, NULL);
215 1.29.4.2 christos pnode = (error == 0) ? &netbsd32_sysctl_root : NULL;
216 1.29.4.2 christos error = sysctl_dispatch(&name[0], SCARG(uap, namelen),
217 1.29.4.2 christos oldp, &oldlen,
218 1.29.4.2 christos newp, SCARG(uap, newlen),
219 1.29.4.2 christos &name[0], l, pnode);
220 1.29.4.2 christos sysctl_unlock();
221 1.29.4.2 christos
222 1.29.4.2 christos /*
223 1.29.4.2 christos * reset caller's oldlen, even if we got an error
224 1.29.4.2 christos */
225 1.29.4.2 christos if (oldlenp) {
226 1.29.4.2 christos netbsd32_oldlen = oldlen;
227 1.29.4.2 christos nerror = copyout(&netbsd32_oldlen, oldlenp,
228 1.29.4.2 christos sizeof(netbsd32_oldlen));
229 1.29.4.2 christos if (error == 0)
230 1.29.4.2 christos error = nerror;
231 1.29.4.2 christos }
232 1.29.4.2 christos
233 1.29.4.2 christos /*
234 1.29.4.2 christos * if the only problem is that we weren't given enough space,
235 1.29.4.2 christos * that's an ENOMEM error
236 1.29.4.2 christos */
237 1.29.4.2 christos if (error == 0 && oldp != NULL && savelen < oldlen)
238 1.29.4.2 christos error = ENOMEM;
239 1.29.4.2 christos
240 1.29.4.2 christos return (error);
241 1.29.4.2 christos }
242