init_sysctl.c revision 1.81.4.7 1 /* $NetBSD: init_sysctl.c,v 1.81.4.7 2007/01/12 01:04:06 ad Exp $ */
2
3 /*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.81.4.7 2007/01/12 01:04:06 ad Exp $");
41
42 #include "opt_sysv.h"
43 #include "opt_multiprocessor.h"
44 #include "opt_posix.h"
45 #include "opt_compat_netbsd32.h"
46 #include "opt_ktrace.h"
47 #include "pty.h"
48 #include "rnd.h"
49
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/sysctl.h>
53 #include <sys/errno.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/unistd.h>
57 #include <sys/disklabel.h>
58 #include <sys/rnd.h>
59 #include <sys/vnode.h>
60 #include <sys/mount.h>
61 #include <sys/namei.h>
62 #include <sys/msgbuf.h>
63 #include <dev/cons.h>
64 #include <sys/socketvar.h>
65 #include <sys/file.h>
66 #include <sys/filedesc.h>
67 #include <sys/tty.h>
68 #include <sys/malloc.h>
69 #include <sys/resource.h>
70 #include <sys/resourcevar.h>
71 #include <sys/exec.h>
72 #include <sys/conf.h>
73 #include <sys/device.h>
74 #include <sys/stat.h>
75 #include <sys/kauth.h>
76 #ifdef KTRACE
77 #include <sys/ktrace.h>
78 #endif
79
80 #ifdef COMPAT_NETBSD32
81 #include <compat/netbsd32/netbsd32.h>
82 #endif
83
84 #include <machine/cpu.h>
85
86 /* XXX this should not be here */
87 int security_setidcore_dump;
88 char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core";
89 uid_t security_setidcore_owner = 0;
90 gid_t security_setidcore_group = 0;
91 mode_t security_setidcore_mode = (S_IRUSR|S_IWUSR);
92
93 static const u_int sysctl_flagmap[] = {
94 P_ADVLOCK, KP_ADVLOCK,
95 P_EXEC, KP_EXEC,
96 P_NOCLDWAIT, KP_NOCLDWAIT,
97 P_32, KP_32,
98 P_CLDSIGIGN, KP_CLDSIGIGN,
99 P_PAXMPROTECT, KP_PAXMPROTECT,
100 P_PAXNOMPROTECT, KP_PAXNOMPROTECT,
101 P_SYSTRACE, KP_SYSTRACE,
102 P_SUGID, KP_SUGID,
103 0
104 };
105
106 static const u_int sysctl_sflagmap[] = {
107 PS_NOCLDSTOP, KP_NOCLDSTOP,
108 PS_PPWAIT, KP_PPWAIT,
109 PS_WEXIT, KP_WEXIT,
110 PS_STOPFORK, KP_STOPFORK,
111 PS_STOPEXEC, KP_STOPEXEC,
112 PS_STOPEXIT, KP_STOPEXIT,
113 0
114 };
115
116 static const u_int sysctl_slflagmap[] = {
117 PSL_TRACED, KP_TRACED,
118 PSL_FSTRACE, KP_FSTRACE,
119 PSL_CHTRACED, KP_CHTRACED,
120 PSL_SYSCALL, KP_SYSCALL,
121 0
122 };
123
124 static const u_int sysctl_lflagmap[] = {
125 PL_CONTROLT, KP_CONTROLT,
126 0
127 };
128
129 static const u_int sysctl_stflagmap[] = {
130 PST_PROFIL, KP_PROFIL,
131 0
132
133 };
134
135 static const u_int sysctl_lwpflagmap[] = {
136 L_INMEM, KP_INMEM,
137 L_SELECT, KP_SELECT,
138 L_SINTR, KP_SINTR,
139 L_SYSTEM, KP_SYSTEM,
140 L_SA, KP_SA,
141 0
142 };
143
144
145 /*
146 * try over estimating by 5 procs/lwps
147 */
148 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
149 #define KERN_LWPSLOP (5 * sizeof(struct kinfo_lwp))
150
151 #ifdef KTRACE
152 int dcopyout(struct lwp *, const void *, void *, size_t);
153
154 int
155 dcopyout(l, kaddr, uaddr, len)
156 struct lwp *l;
157 const void *kaddr;
158 void *uaddr;
159 size_t len;
160 {
161 int error;
162
163 error = copyout(kaddr, uaddr, len);
164 if (!error && KTRPOINT(l->l_proc, KTR_MIB)) {
165 struct iovec iov;
166
167 iov.iov_base = uaddr;
168 iov.iov_len = len;
169 ktrgenio(l, -1, UIO_READ, &iov, len, 0);
170 }
171 return error;
172 }
173 #else /* !KTRACE */
174 #define dcopyout(l, kaddr, uaddr, len) copyout(kaddr, uaddr, len)
175 #endif /* KTRACE */
176 #ifndef MULTIPROCESSOR
177 #define sysctl_ncpus() (1)
178 #else /* MULTIPROCESSOR */
179 #ifndef CPU_INFO_FOREACH
180 #define CPU_INFO_ITERATOR int
181 #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL
182 #endif
183 static int
184 sysctl_ncpus(void)
185 {
186 struct cpu_info *ci;
187 CPU_INFO_ITERATOR cii;
188
189 int ncpus = 0;
190 for (CPU_INFO_FOREACH(cii, ci))
191 ncpus++;
192 return (ncpus);
193 }
194 #endif /* MULTIPROCESSOR */
195
196 #ifdef DIAGNOSTIC
197 static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO);
198 #endif
199 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
200 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
201 static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
202 static int sysctl_kern_hostid(SYSCTLFN_PROTO);
203 static int sysctl_setlen(SYSCTLFN_PROTO);
204 static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
205 static int sysctl_kern_file(SYSCTLFN_PROTO);
206 static int sysctl_kern_autonice(SYSCTLFN_PROTO);
207 static int sysctl_msgbuf(SYSCTLFN_PROTO);
208 static int sysctl_kern_defcorename(SYSCTLFN_PROTO);
209 static int sysctl_kern_cptime(SYSCTLFN_PROTO);
210 #if NPTY > 0
211 static int sysctl_kern_maxptys(SYSCTLFN_PROTO);
212 #endif /* NPTY > 0 */
213 static int sysctl_kern_sbmax(SYSCTLFN_PROTO);
214 static int sysctl_kern_urnd(SYSCTLFN_PROTO);
215 static int sysctl_kern_arnd(SYSCTLFN_PROTO);
216 static int sysctl_kern_lwp(SYSCTLFN_PROTO);
217 static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
218 static int sysctl_kern_root_partition(SYSCTLFN_PROTO);
219 static int sysctl_kern_drivers(SYSCTLFN_PROTO);
220 static int sysctl_kern_file2(SYSCTLFN_PROTO);
221 static int sysctl_security_setidcore(SYSCTLFN_PROTO);
222 static int sysctl_security_setidcorename(SYSCTLFN_PROTO);
223 static int sysctl_kern_cpid(SYSCTLFN_PROTO);
224 static int sysctl_doeproc(SYSCTLFN_PROTO);
225 static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
226 static int sysctl_hw_usermem(SYSCTLFN_PROTO);
227 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO);
228 static int sysctl_hw_ncpu(SYSCTLFN_PROTO);
229
230 static u_int sysctl_map_flags(const u_int *, u_int);
231 static void fill_kproc2(struct proc *, struct kinfo_proc2 *);
232 static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl);
233 static void fill_file(struct kinfo_file *, const struct file *, struct proc *,
234 int);
235
236 /*
237 * ********************************************************************
238 * section 1: setup routines
239 * ********************************************************************
240 * these functions are stuffed into a link set for sysctl setup
241 * functions. they're never called or referenced from anywhere else.
242 * ********************************************************************
243 */
244
245 /*
246 * sets up the base nodes...
247 */
248 SYSCTL_SETUP(sysctl_root_setup, "sysctl base setup")
249 {
250
251 sysctl_createv(clog, 0, NULL, NULL,
252 CTLFLAG_PERMANENT,
253 CTLTYPE_NODE, "kern",
254 SYSCTL_DESCR("High kernel"),
255 NULL, 0, NULL, 0,
256 CTL_KERN, CTL_EOL);
257 sysctl_createv(clog, 0, NULL, NULL,
258 CTLFLAG_PERMANENT,
259 CTLTYPE_NODE, "vm",
260 SYSCTL_DESCR("Virtual memory"),
261 NULL, 0, NULL, 0,
262 CTL_VM, CTL_EOL);
263 sysctl_createv(clog, 0, NULL, NULL,
264 CTLFLAG_PERMANENT,
265 CTLTYPE_NODE, "vfs",
266 SYSCTL_DESCR("Filesystem"),
267 NULL, 0, NULL, 0,
268 CTL_VFS, CTL_EOL);
269 sysctl_createv(clog, 0, NULL, NULL,
270 CTLFLAG_PERMANENT,
271 CTLTYPE_NODE, "net",
272 SYSCTL_DESCR("Networking"),
273 NULL, 0, NULL, 0,
274 CTL_NET, CTL_EOL);
275 sysctl_createv(clog, 0, NULL, NULL,
276 CTLFLAG_PERMANENT,
277 CTLTYPE_NODE, "debug",
278 SYSCTL_DESCR("Debugging"),
279 NULL, 0, NULL, 0,
280 CTL_DEBUG, CTL_EOL);
281 sysctl_createv(clog, 0, NULL, NULL,
282 CTLFLAG_PERMANENT,
283 CTLTYPE_NODE, "hw",
284 SYSCTL_DESCR("Generic CPU, I/O"),
285 NULL, 0, NULL, 0,
286 CTL_HW, CTL_EOL);
287 sysctl_createv(clog, 0, NULL, NULL,
288 CTLFLAG_PERMANENT,
289 CTLTYPE_NODE, "machdep",
290 SYSCTL_DESCR("Machine dependent"),
291 NULL, 0, NULL, 0,
292 CTL_MACHDEP, CTL_EOL);
293 /*
294 * this node is inserted so that the sysctl nodes in libc can
295 * operate.
296 */
297 sysctl_createv(clog, 0, NULL, NULL,
298 CTLFLAG_PERMANENT,
299 CTLTYPE_NODE, "user",
300 SYSCTL_DESCR("User-level"),
301 NULL, 0, NULL, 0,
302 CTL_USER, CTL_EOL);
303 sysctl_createv(clog, 0, NULL, NULL,
304 CTLFLAG_PERMANENT,
305 CTLTYPE_NODE, "ddb",
306 SYSCTL_DESCR("In-kernel debugger"),
307 NULL, 0, NULL, 0,
308 CTL_DDB, CTL_EOL);
309 sysctl_createv(clog, 0, NULL, NULL,
310 CTLFLAG_PERMANENT,
311 CTLTYPE_NODE, "proc",
312 SYSCTL_DESCR("Per-process"),
313 NULL, 0, NULL, 0,
314 CTL_PROC, CTL_EOL);
315 sysctl_createv(clog, 0, NULL, NULL,
316 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
317 CTLTYPE_NODE, "vendor",
318 SYSCTL_DESCR("Vendor specific"),
319 NULL, 0, NULL, 0,
320 CTL_VENDOR, CTL_EOL);
321 sysctl_createv(clog, 0, NULL, NULL,
322 CTLFLAG_PERMANENT,
323 CTLTYPE_NODE, "emul",
324 SYSCTL_DESCR("Emulation settings"),
325 NULL, 0, NULL, 0,
326 CTL_EMUL, CTL_EOL);
327 sysctl_createv(clog, 0, NULL, NULL,
328 CTLFLAG_PERMANENT,
329 CTLTYPE_NODE, "security",
330 SYSCTL_DESCR("Security"),
331 NULL, 0, NULL, 0,
332 CTL_SECURITY, CTL_EOL);
333 }
334
335 /*
336 * this setup routine is a replacement for kern_sysctl()
337 */
338 SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup")
339 {
340 extern int kern_logsigexit; /* defined in kern/kern_sig.c */
341 extern fixpt_t ccpu; /* defined in kern/kern_synch.c */
342 extern int dumponpanic; /* defined in kern/subr_prf.c */
343 const struct sysctlnode *rnode;
344
345 sysctl_createv(clog, 0, NULL, NULL,
346 CTLFLAG_PERMANENT,
347 CTLTYPE_NODE, "kern", NULL,
348 NULL, 0, NULL, 0,
349 CTL_KERN, CTL_EOL);
350
351 sysctl_createv(clog, 0, NULL, NULL,
352 CTLFLAG_PERMANENT,
353 CTLTYPE_STRING, "ostype",
354 SYSCTL_DESCR("Operating system type"),
355 NULL, 0, &ostype, 0,
356 CTL_KERN, KERN_OSTYPE, CTL_EOL);
357 sysctl_createv(clog, 0, NULL, NULL,
358 CTLFLAG_PERMANENT,
359 CTLTYPE_STRING, "osrelease",
360 SYSCTL_DESCR("Operating system release"),
361 NULL, 0, &osrelease, 0,
362 CTL_KERN, KERN_OSRELEASE, CTL_EOL);
363 sysctl_createv(clog, 0, NULL, NULL,
364 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
365 CTLTYPE_INT, "osrevision",
366 SYSCTL_DESCR("Operating system revision"),
367 NULL, __NetBSD_Version__, NULL, 0,
368 CTL_KERN, KERN_OSREV, CTL_EOL);
369 sysctl_createv(clog, 0, NULL, NULL,
370 CTLFLAG_PERMANENT,
371 CTLTYPE_STRING, "version",
372 SYSCTL_DESCR("Kernel version"),
373 NULL, 0, &version, 0,
374 CTL_KERN, KERN_VERSION, CTL_EOL);
375 sysctl_createv(clog, 0, NULL, NULL,
376 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
377 CTLTYPE_INT, "maxvnodes",
378 SYSCTL_DESCR("Maximum number of vnodes"),
379 sysctl_kern_maxvnodes, 0, NULL, 0,
380 CTL_KERN, KERN_MAXVNODES, CTL_EOL);
381 sysctl_createv(clog, 0, NULL, NULL,
382 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
383 CTLTYPE_INT, "maxproc",
384 SYSCTL_DESCR("Maximum number of simultaneous processes"),
385 sysctl_kern_maxproc, 0, NULL, 0,
386 CTL_KERN, KERN_MAXPROC, CTL_EOL);
387 sysctl_createv(clog, 0, NULL, NULL,
388 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
389 CTLTYPE_INT, "maxfiles",
390 SYSCTL_DESCR("Maximum number of open files"),
391 NULL, 0, &maxfiles, 0,
392 CTL_KERN, KERN_MAXFILES, CTL_EOL);
393 sysctl_createv(clog, 0, NULL, NULL,
394 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
395 CTLTYPE_INT, "argmax",
396 SYSCTL_DESCR("Maximum number of bytes of arguments to "
397 "execve(2)"),
398 NULL, ARG_MAX, NULL, 0,
399 CTL_KERN, KERN_ARGMAX, CTL_EOL);
400 sysctl_createv(clog, 0, NULL, NULL,
401 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
402 CTLTYPE_STRING, "hostname",
403 SYSCTL_DESCR("System hostname"),
404 sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN,
405 CTL_KERN, KERN_HOSTNAME, CTL_EOL);
406 sysctl_createv(clog, 0, NULL, NULL,
407 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
408 CTLTYPE_INT, "hostid",
409 SYSCTL_DESCR("System host ID number"),
410 sysctl_kern_hostid, 0, NULL, 0,
411 CTL_KERN, KERN_HOSTID, CTL_EOL);
412 sysctl_createv(clog, 0, NULL, NULL,
413 CTLFLAG_PERMANENT,
414 CTLTYPE_STRUCT, "clockrate",
415 SYSCTL_DESCR("Kernel clock rates"),
416 sysctl_kern_clockrate, 0, NULL,
417 sizeof(struct clockinfo),
418 CTL_KERN, KERN_CLOCKRATE, CTL_EOL);
419 sysctl_createv(clog, 0, NULL, NULL,
420 CTLFLAG_PERMANENT,
421 CTLTYPE_INT, "hardclock_ticks",
422 SYSCTL_DESCR("Number of hardclock ticks"),
423 NULL, 0, &hardclock_ticks, sizeof(hardclock_ticks),
424 CTL_KERN, KERN_HARDCLOCK_TICKS, CTL_EOL);
425 sysctl_createv(clog, 0, NULL, NULL,
426 CTLFLAG_PERMANENT,
427 CTLTYPE_STRUCT, "vnode",
428 SYSCTL_DESCR("System vnode table"),
429 sysctl_kern_vnode, 0, NULL, 0,
430 CTL_KERN, KERN_VNODE, CTL_EOL);
431 sysctl_createv(clog, 0, NULL, NULL,
432 CTLFLAG_PERMANENT,
433 CTLTYPE_STRUCT, "file",
434 SYSCTL_DESCR("System open file table"),
435 sysctl_kern_file, 0, NULL, 0,
436 CTL_KERN, KERN_FILE, CTL_EOL);
437 #ifndef GPROF
438 sysctl_createv(clog, 0, NULL, NULL,
439 CTLFLAG_PERMANENT,
440 CTLTYPE_NODE, "profiling",
441 SYSCTL_DESCR("Profiling information (not available)"),
442 sysctl_notavail, 0, NULL, 0,
443 CTL_KERN, KERN_PROF, CTL_EOL);
444 #endif
445 sysctl_createv(clog, 0, NULL, NULL,
446 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
447 CTLTYPE_INT, "posix1version",
448 SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) "
449 "with which the operating system attempts "
450 "to comply"),
451 NULL, _POSIX_VERSION, NULL, 0,
452 CTL_KERN, KERN_POSIX1, CTL_EOL);
453 sysctl_createv(clog, 0, NULL, NULL,
454 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
455 CTLTYPE_INT, "ngroups",
456 SYSCTL_DESCR("Maximum number of supplemental groups"),
457 NULL, NGROUPS_MAX, NULL, 0,
458 CTL_KERN, KERN_NGROUPS, CTL_EOL);
459 sysctl_createv(clog, 0, NULL, NULL,
460 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
461 CTLTYPE_INT, "job_control",
462 SYSCTL_DESCR("Whether job control is available"),
463 NULL, 1, NULL, 0,
464 CTL_KERN, KERN_JOB_CONTROL, CTL_EOL);
465 sysctl_createv(clog, 0, NULL, NULL,
466 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
467 CTLTYPE_INT, "saved_ids",
468 SYSCTL_DESCR("Whether POSIX saved set-group/user ID is "
469 "available"), NULL,
470 #ifdef _POSIX_SAVED_IDS
471 1,
472 #else /* _POSIX_SAVED_IDS */
473 0,
474 #endif /* _POSIX_SAVED_IDS */
475 NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL);
476 sysctl_createv(clog, 0, NULL, NULL,
477 CTLFLAG_PERMANENT,
478 CTLTYPE_STRUCT, "boottime",
479 SYSCTL_DESCR("System boot time"),
480 NULL, 0, &boottime, sizeof(boottime),
481 CTL_KERN, KERN_BOOTTIME, CTL_EOL);
482 sysctl_createv(clog, 0, NULL, NULL,
483 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
484 CTLTYPE_STRING, "domainname",
485 SYSCTL_DESCR("YP domain name"),
486 sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN,
487 CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
488 sysctl_createv(clog, 0, NULL, NULL,
489 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
490 CTLTYPE_INT, "maxpartitions",
491 SYSCTL_DESCR("Maximum number of partitions allowed per "
492 "disk"),
493 NULL, MAXPARTITIONS, NULL, 0,
494 CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL);
495 sysctl_createv(clog, 0, NULL, NULL,
496 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
497 CTLTYPE_INT, "rawpartition",
498 SYSCTL_DESCR("Raw partition of a disk"),
499 NULL, RAW_PART, NULL, 0,
500 CTL_KERN, KERN_RAWPARTITION, CTL_EOL);
501 sysctl_createv(clog, 0, NULL, NULL,
502 CTLFLAG_PERMANENT,
503 CTLTYPE_STRUCT, "timex", NULL,
504 sysctl_notavail, 0, NULL, 0,
505 CTL_KERN, KERN_TIMEX, CTL_EOL);
506 sysctl_createv(clog, 0, NULL, NULL,
507 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
508 CTLTYPE_INT, "autonicetime",
509 SYSCTL_DESCR("CPU clock seconds before non-root "
510 "process priority is lowered"),
511 sysctl_kern_autonice, 0, &autonicetime, 0,
512 CTL_KERN, KERN_AUTONICETIME, CTL_EOL);
513 sysctl_createv(clog, 0, NULL, NULL,
514 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
515 CTLTYPE_INT, "autoniceval",
516 SYSCTL_DESCR("Automatic reniced non-root process "
517 "priority"),
518 sysctl_kern_autonice, 0, &autoniceval, 0,
519 CTL_KERN, KERN_AUTONICEVAL, CTL_EOL);
520 sysctl_createv(clog, 0, NULL, NULL,
521 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
522 CTLTYPE_INT, "rtc_offset",
523 SYSCTL_DESCR("Offset of real time clock from UTC in "
524 "minutes"),
525 sysctl_kern_rtc_offset, 0, &rtc_offset, 0,
526 CTL_KERN, KERN_RTC_OFFSET, CTL_EOL);
527 sysctl_createv(clog, 0, NULL, NULL,
528 CTLFLAG_PERMANENT,
529 CTLTYPE_STRING, "root_device",
530 SYSCTL_DESCR("Name of the root device"),
531 sysctl_root_device, 0, NULL, 0,
532 CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL);
533 sysctl_createv(clog, 0, NULL, NULL,
534 CTLFLAG_PERMANENT,
535 CTLTYPE_INT, "msgbufsize",
536 SYSCTL_DESCR("Size of the kernel message buffer"),
537 sysctl_msgbuf, 0, NULL, 0,
538 CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL);
539 sysctl_createv(clog, 0, NULL, NULL,
540 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
541 CTLTYPE_INT, "fsync",
542 SYSCTL_DESCR("Whether the POSIX 1003.1b File "
543 "Synchronization Option is available on "
544 "this system"),
545 NULL, 1, NULL, 0,
546 CTL_KERN, KERN_FSYNC, CTL_EOL);
547 sysctl_createv(clog, 0, NULL, NULL,
548 CTLFLAG_PERMANENT,
549 CTLTYPE_NODE, "ipc",
550 SYSCTL_DESCR("SysV IPC options"),
551 NULL, 0, NULL, 0,
552 CTL_KERN, KERN_SYSVIPC, CTL_EOL);
553 sysctl_createv(clog, 0, NULL, NULL,
554 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
555 CTLTYPE_INT, "sysvmsg",
556 SYSCTL_DESCR("System V style message support available"),
557 NULL,
558 #ifdef SYSVMSG
559 1,
560 #else /* SYSVMSG */
561 0,
562 #endif /* SYSVMSG */
563 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_MSG, CTL_EOL);
564 sysctl_createv(clog, 0, NULL, NULL,
565 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
566 CTLTYPE_INT, "sysvsem",
567 SYSCTL_DESCR("System V style semaphore support "
568 "available"), NULL,
569 #ifdef SYSVSEM
570 1,
571 #else /* SYSVSEM */
572 0,
573 #endif /* SYSVSEM */
574 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SEM, CTL_EOL);
575 sysctl_createv(clog, 0, NULL, NULL,
576 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
577 CTLTYPE_INT, "sysvshm",
578 SYSCTL_DESCR("System V style shared memory support "
579 "available"), NULL,
580 #ifdef SYSVSHM
581 1,
582 #else /* SYSVSHM */
583 0,
584 #endif /* SYSVSHM */
585 NULL, 0, CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SHM, CTL_EOL);
586 sysctl_createv(clog, 0, NULL, NULL,
587 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
588 CTLTYPE_INT, "synchronized_io",
589 SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized "
590 "I/O Option is available on this system"),
591 NULL, 1, NULL, 0,
592 CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL);
593 sysctl_createv(clog, 0, NULL, NULL,
594 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
595 CTLTYPE_INT, "iov_max",
596 SYSCTL_DESCR("Maximum number of iovec structures per "
597 "process"),
598 NULL, IOV_MAX, NULL, 0,
599 CTL_KERN, KERN_IOV_MAX, CTL_EOL);
600 sysctl_createv(clog, 0, NULL, NULL,
601 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
602 CTLTYPE_INT, "mapped_files",
603 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped "
604 "Files Option is available on this system"),
605 NULL, 1, NULL, 0,
606 CTL_KERN, KERN_MAPPED_FILES, CTL_EOL);
607 sysctl_createv(clog, 0, NULL, NULL,
608 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
609 CTLTYPE_INT, "memlock",
610 SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory "
611 "Locking Option is available on this "
612 "system"),
613 NULL, 1, NULL, 0,
614 CTL_KERN, KERN_MEMLOCK, CTL_EOL);
615 sysctl_createv(clog, 0, NULL, NULL,
616 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
617 CTLTYPE_INT, "memlock_range",
618 SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory "
619 "Locking Option is available on this "
620 "system"),
621 NULL, 1, NULL, 0,
622 CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL);
623 sysctl_createv(clog, 0, NULL, NULL,
624 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
625 CTLTYPE_INT, "memory_protection",
626 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory "
627 "Protection Option is available on this "
628 "system"),
629 NULL, 1, NULL, 0,
630 CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL);
631 sysctl_createv(clog, 0, NULL, NULL,
632 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
633 CTLTYPE_INT, "login_name_max",
634 SYSCTL_DESCR("Maximum login name length"),
635 NULL, LOGIN_NAME_MAX, NULL, 0,
636 CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL);
637 sysctl_createv(clog, 0, NULL, NULL,
638 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
639 CTLTYPE_STRING, "defcorename",
640 SYSCTL_DESCR("Default core file name"),
641 sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN,
642 CTL_KERN, KERN_DEFCORENAME, CTL_EOL);
643 sysctl_createv(clog, 0, NULL, NULL,
644 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
645 CTLTYPE_INT, "logsigexit",
646 SYSCTL_DESCR("Log process exit when caused by signals"),
647 NULL, 0, &kern_logsigexit, 0,
648 CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL);
649 sysctl_createv(clog, 0, NULL, NULL,
650 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
651 CTLTYPE_INT, "fscale",
652 SYSCTL_DESCR("Kernel fixed-point scale factor"),
653 NULL, FSCALE, NULL, 0,
654 CTL_KERN, KERN_FSCALE, CTL_EOL);
655 sysctl_createv(clog, 0, NULL, NULL,
656 CTLFLAG_PERMANENT,
657 CTLTYPE_INT, "ccpu",
658 SYSCTL_DESCR("Scheduler exponential decay value"),
659 NULL, 0, &ccpu, 0,
660 CTL_KERN, KERN_CCPU, CTL_EOL);
661 sysctl_createv(clog, 0, NULL, NULL,
662 CTLFLAG_PERMANENT,
663 CTLTYPE_STRUCT, "cp_time",
664 SYSCTL_DESCR("Clock ticks spent in different CPU states"),
665 sysctl_kern_cptime, 0, NULL, 0,
666 CTL_KERN, KERN_CP_TIME, CTL_EOL);
667 sysctl_createv(clog, 0, NULL, NULL,
668 CTLFLAG_PERMANENT,
669 CTLTYPE_INT, "msgbuf",
670 SYSCTL_DESCR("Kernel message buffer"),
671 sysctl_msgbuf, 0, NULL, 0,
672 CTL_KERN, KERN_MSGBUF, CTL_EOL);
673 sysctl_createv(clog, 0, NULL, NULL,
674 CTLFLAG_PERMANENT,
675 CTLTYPE_STRUCT, "consdev",
676 SYSCTL_DESCR("Console device"),
677 sysctl_consdev, 0, NULL, sizeof(dev_t),
678 CTL_KERN, KERN_CONSDEV, CTL_EOL);
679 #if NPTY > 0
680 sysctl_createv(clog, 0, NULL, NULL,
681 CTLFLAG_PERMANENT,
682 CTLTYPE_INT, "maxptys",
683 SYSCTL_DESCR("Maximum number of pseudo-ttys"),
684 sysctl_kern_maxptys, 0, NULL, 0,
685 CTL_KERN, KERN_MAXPTYS, CTL_EOL);
686 #endif /* NPTY > 0 */
687 sysctl_createv(clog, 0, NULL, NULL,
688 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
689 CTLTYPE_INT, "maxphys",
690 SYSCTL_DESCR("Maximum raw I/O transfer size"),
691 NULL, MAXPHYS, NULL, 0,
692 CTL_KERN, KERN_MAXPHYS, CTL_EOL);
693 sysctl_createv(clog, 0, NULL, NULL,
694 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
695 CTLTYPE_INT, "sbmax",
696 SYSCTL_DESCR("Maximum socket buffer size"),
697 sysctl_kern_sbmax, 0, NULL, 0,
698 CTL_KERN, KERN_SBMAX, CTL_EOL);
699 sysctl_createv(clog, 0, NULL, NULL,
700 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
701 CTLTYPE_INT, "monotonic_clock",
702 SYSCTL_DESCR("Implementation version of the POSIX "
703 "1003.1b Monotonic Clock Option"),
704 /* XXX _POSIX_VERSION */
705 NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0,
706 CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL);
707 sysctl_createv(clog, 0, NULL, NULL,
708 CTLFLAG_PERMANENT,
709 CTLTYPE_INT, "urandom",
710 SYSCTL_DESCR("Random integer value"),
711 sysctl_kern_urnd, 0, NULL, 0,
712 CTL_KERN, KERN_URND, CTL_EOL);
713 sysctl_createv(clog, 0, NULL, NULL,
714 CTLFLAG_PERMANENT,
715 CTLTYPE_INT, "arandom",
716 SYSCTL_DESCR("n bytes of random data"),
717 sysctl_kern_arnd, 0, NULL, 0,
718 CTL_KERN, KERN_ARND, CTL_EOL);
719 sysctl_createv(clog, 0, NULL, NULL,
720 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
721 CTLTYPE_INT, "labelsector",
722 SYSCTL_DESCR("Sector number containing the disklabel"),
723 NULL, LABELSECTOR, NULL, 0,
724 CTL_KERN, KERN_LABELSECTOR, CTL_EOL);
725 sysctl_createv(clog, 0, NULL, NULL,
726 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
727 CTLTYPE_INT, "labeloffset",
728 SYSCTL_DESCR("Offset of the disklabel within the "
729 "sector"),
730 NULL, LABELOFFSET, NULL, 0,
731 CTL_KERN, KERN_LABELOFFSET, CTL_EOL);
732 sysctl_createv(clog, 0, NULL, NULL,
733 CTLFLAG_PERMANENT,
734 CTLTYPE_NODE, "lwp",
735 SYSCTL_DESCR("System-wide LWP information"),
736 sysctl_kern_lwp, 0, NULL, 0,
737 CTL_KERN, KERN_LWP, CTL_EOL);
738 sysctl_createv(clog, 0, NULL, NULL,
739 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
740 CTLTYPE_INT, "forkfsleep",
741 SYSCTL_DESCR("Milliseconds to sleep on fork failure due "
742 "to process limits"),
743 sysctl_kern_forkfsleep, 0, NULL, 0,
744 CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
745 sysctl_createv(clog, 0, NULL, NULL,
746 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
747 CTLTYPE_INT, "posix_threads",
748 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
749 "Threads option to which the system "
750 "attempts to conform"),
751 /* XXX _POSIX_VERSION */
752 NULL, _POSIX_THREADS, NULL, 0,
753 CTL_KERN, KERN_POSIX_THREADS, CTL_EOL);
754 sysctl_createv(clog, 0, NULL, NULL,
755 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
756 CTLTYPE_INT, "posix_semaphores",
757 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
758 "Semaphores option to which the system "
759 "attempts to conform"), NULL,
760 #ifdef P1003_1B_SEMAPHORE
761 200112,
762 #else /* P1003_1B_SEMAPHORE */
763 0,
764 #endif /* P1003_1B_SEMAPHORE */
765 NULL, 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL);
766 sysctl_createv(clog, 0, NULL, NULL,
767 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
768 CTLTYPE_INT, "posix_barriers",
769 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
770 "Barriers option to which the system "
771 "attempts to conform"),
772 /* XXX _POSIX_VERSION */
773 NULL, _POSIX_BARRIERS, NULL, 0,
774 CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL);
775 sysctl_createv(clog, 0, NULL, NULL,
776 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
777 CTLTYPE_INT, "posix_timers",
778 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
779 "Timers option to which the system "
780 "attempts to conform"),
781 /* XXX _POSIX_VERSION */
782 NULL, _POSIX_TIMERS, NULL, 0,
783 CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL);
784 sysctl_createv(clog, 0, NULL, NULL,
785 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
786 CTLTYPE_INT, "posix_spin_locks",
787 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin "
788 "Locks option to which the system attempts "
789 "to conform"),
790 /* XXX _POSIX_VERSION */
791 NULL, _POSIX_SPIN_LOCKS, NULL, 0,
792 CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL);
793 sysctl_createv(clog, 0, NULL, NULL,
794 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
795 CTLTYPE_INT, "posix_reader_writer_locks",
796 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
797 "Read-Write Locks option to which the "
798 "system attempts to conform"),
799 /* XXX _POSIX_VERSION */
800 NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0,
801 CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL);
802 sysctl_createv(clog, 0, NULL, NULL,
803 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
804 CTLTYPE_INT, "dump_on_panic",
805 SYSCTL_DESCR("Perform a crash dump on system panic"),
806 NULL, 0, &dumponpanic, 0,
807 CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL);
808 #ifdef DIAGNOSTIC
809 sysctl_createv(clog, 0, NULL, NULL,
810 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
811 CTLTYPE_INT, "panic_now",
812 SYSCTL_DESCR("Trigger a panic"),
813 sysctl_kern_trigger_panic, 0, NULL, 0,
814 CTL_KERN, CTL_CREATE, CTL_EOL);
815 #endif
816 sysctl_createv(clog, 0, NULL, NULL,
817 CTLFLAG_PERMANENT,
818 CTLTYPE_INT, "root_partition",
819 SYSCTL_DESCR("Root partition on the root device"),
820 sysctl_kern_root_partition, 0, NULL, 0,
821 CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL);
822 sysctl_createv(clog, 0, NULL, NULL,
823 CTLFLAG_PERMANENT,
824 CTLTYPE_STRUCT, "drivers",
825 SYSCTL_DESCR("List of all drivers with block and "
826 "character device numbers"),
827 sysctl_kern_drivers, 0, NULL, 0,
828 CTL_KERN, KERN_DRIVERS, CTL_EOL);
829 sysctl_createv(clog, 0, NULL, NULL,
830 CTLFLAG_PERMANENT,
831 CTLTYPE_STRUCT, "file2",
832 SYSCTL_DESCR("System open file table"),
833 sysctl_kern_file2, 0, NULL, 0,
834 CTL_KERN, KERN_FILE2, CTL_EOL);
835 sysctl_createv(clog, 0, NULL, NULL,
836 CTLFLAG_PERMANENT,
837 CTLTYPE_STRUCT, "cp_id",
838 SYSCTL_DESCR("Mapping of CPU number to CPU id"),
839 sysctl_kern_cpid, 0, NULL, 0,
840 CTL_KERN, KERN_CP_ID, CTL_EOL);
841 sysctl_createv(clog, 0, NULL, &rnode,
842 CTLFLAG_PERMANENT,
843 CTLTYPE_NODE, "coredump",
844 SYSCTL_DESCR("Coredump settings."),
845 NULL, 0, NULL, 0,
846 CTL_KERN, CTL_CREATE, CTL_EOL);
847 sysctl_createv(clog, 0, &rnode, &rnode,
848 CTLFLAG_PERMANENT,
849 CTLTYPE_NODE, "setid",
850 SYSCTL_DESCR("Set-id processes' coredump settings."),
851 NULL, 0, NULL, 0,
852 CTL_CREATE, CTL_EOL);
853 sysctl_createv(clog, 0, &rnode, NULL,
854 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
855 CTLTYPE_INT, "dump",
856 SYSCTL_DESCR("Allow set-id processes to dump core."),
857 sysctl_security_setidcore, 0, &security_setidcore_dump,
858 sizeof(security_setidcore_dump),
859 CTL_CREATE, CTL_EOL);
860 sysctl_createv(clog, 0, &rnode, NULL,
861 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
862 CTLTYPE_STRING, "path",
863 SYSCTL_DESCR("Path pattern for set-id coredumps."),
864 sysctl_security_setidcorename, 0,
865 &security_setidcore_path,
866 sizeof(security_setidcore_path),
867 CTL_CREATE, CTL_EOL);
868 sysctl_createv(clog, 0, &rnode, NULL,
869 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
870 CTLTYPE_INT, "owner",
871 SYSCTL_DESCR("Owner id for set-id processes' cores."),
872 sysctl_security_setidcore, 0, &security_setidcore_owner,
873 0,
874 CTL_CREATE, CTL_EOL);
875 sysctl_createv(clog, 0, &rnode, NULL,
876 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
877 CTLTYPE_INT, "group",
878 SYSCTL_DESCR("Group id for set-id processes' cores."),
879 sysctl_security_setidcore, 0, &security_setidcore_group,
880 0,
881 CTL_CREATE, CTL_EOL);
882 sysctl_createv(clog, 0, &rnode, NULL,
883 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
884 CTLTYPE_INT, "mode",
885 SYSCTL_DESCR("Mode for set-id processes' cores."),
886 sysctl_security_setidcore, 0, &security_setidcore_mode,
887 0,
888 CTL_CREATE, CTL_EOL);
889 }
890
891 SYSCTL_SETUP(sysctl_kern_proc_setup,
892 "sysctl kern.proc/proc2/proc_args subtree setup")
893 {
894
895 sysctl_createv(clog, 0, NULL, NULL,
896 CTLFLAG_PERMANENT,
897 CTLTYPE_NODE, "kern", NULL,
898 NULL, 0, NULL, 0,
899 CTL_KERN, CTL_EOL);
900
901 sysctl_createv(clog, 0, NULL, NULL,
902 CTLFLAG_PERMANENT,
903 CTLTYPE_NODE, "proc",
904 SYSCTL_DESCR("System-wide process information"),
905 sysctl_doeproc, 0, NULL, 0,
906 CTL_KERN, KERN_PROC, CTL_EOL);
907 sysctl_createv(clog, 0, NULL, NULL,
908 CTLFLAG_PERMANENT,
909 CTLTYPE_NODE, "proc2",
910 SYSCTL_DESCR("Machine-independent process information"),
911 sysctl_doeproc, 0, NULL, 0,
912 CTL_KERN, KERN_PROC2, CTL_EOL);
913 sysctl_createv(clog, 0, NULL, NULL,
914 CTLFLAG_PERMANENT,
915 CTLTYPE_NODE, "proc_args",
916 SYSCTL_DESCR("Process argument information"),
917 sysctl_kern_proc_args, 0, NULL, 0,
918 CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
919
920 /*
921 "nodes" under these:
922
923 KERN_PROC_ALL
924 KERN_PROC_PID pid
925 KERN_PROC_PGRP pgrp
926 KERN_PROC_SESSION sess
927 KERN_PROC_TTY tty
928 KERN_PROC_UID uid
929 KERN_PROC_RUID uid
930 KERN_PROC_GID gid
931 KERN_PROC_RGID gid
932
933 all in all, probably not worth the effort...
934 */
935 }
936
937 SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
938 {
939 u_int u;
940 u_quad_t q;
941
942 sysctl_createv(clog, 0, NULL, NULL,
943 CTLFLAG_PERMANENT,
944 CTLTYPE_NODE, "hw", NULL,
945 NULL, 0, NULL, 0,
946 CTL_HW, CTL_EOL);
947
948 sysctl_createv(clog, 0, NULL, NULL,
949 CTLFLAG_PERMANENT,
950 CTLTYPE_STRING, "machine",
951 SYSCTL_DESCR("Machine class"),
952 NULL, 0, machine, 0,
953 CTL_HW, HW_MACHINE, CTL_EOL);
954 sysctl_createv(clog, 0, NULL, NULL,
955 CTLFLAG_PERMANENT,
956 CTLTYPE_STRING, "model",
957 SYSCTL_DESCR("Machine model"),
958 NULL, 0, cpu_model, 0,
959 CTL_HW, HW_MODEL, CTL_EOL);
960 sysctl_createv(clog, 0, NULL, NULL,
961 CTLFLAG_PERMANENT,
962 CTLTYPE_INT, "ncpu",
963 SYSCTL_DESCR("Number of active CPUs"),
964 sysctl_hw_ncpu, 0, NULL, 0,
965 CTL_HW, HW_NCPU, CTL_EOL);
966 sysctl_createv(clog, 0, NULL, NULL,
967 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
968 CTLTYPE_INT, "byteorder",
969 SYSCTL_DESCR("System byte order"),
970 NULL, BYTE_ORDER, NULL, 0,
971 CTL_HW, HW_BYTEORDER, CTL_EOL);
972 u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ?
973 UINT_MAX : physmem * PAGE_SIZE;
974 sysctl_createv(clog, 0, NULL, NULL,
975 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
976 CTLTYPE_INT, "physmem",
977 SYSCTL_DESCR("Bytes of physical memory"),
978 NULL, u, NULL, 0,
979 CTL_HW, HW_PHYSMEM, CTL_EOL);
980 sysctl_createv(clog, 0, NULL, NULL,
981 CTLFLAG_PERMANENT,
982 CTLTYPE_INT, "usermem",
983 SYSCTL_DESCR("Bytes of non-kernel memory"),
984 sysctl_hw_usermem, 0, NULL, 0,
985 CTL_HW, HW_USERMEM, CTL_EOL);
986 sysctl_createv(clog, 0, NULL, NULL,
987 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
988 CTLTYPE_INT, "pagesize",
989 SYSCTL_DESCR("Software page size"),
990 NULL, PAGE_SIZE, NULL, 0,
991 CTL_HW, HW_PAGESIZE, CTL_EOL);
992 sysctl_createv(clog, 0, NULL, NULL,
993 CTLFLAG_PERMANENT,
994 CTLTYPE_STRING, "machine_arch",
995 SYSCTL_DESCR("Machine CPU class"),
996 NULL, 0, machine_arch, 0,
997 CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
998 sysctl_createv(clog, 0, NULL, NULL,
999 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1000 CTLTYPE_INT, "alignbytes",
1001 SYSCTL_DESCR("Alignment constraint for all possible "
1002 "data types"),
1003 NULL, ALIGNBYTES, NULL, 0,
1004 CTL_HW, HW_ALIGNBYTES, CTL_EOL);
1005 sysctl_createv(clog, 0, NULL, NULL,
1006 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
1007 CTLTYPE_STRING, "cnmagic",
1008 SYSCTL_DESCR("Console magic key sequence"),
1009 sysctl_hw_cnmagic, 0, NULL, CNS_LEN,
1010 CTL_HW, HW_CNMAGIC, CTL_EOL);
1011 q = (u_quad_t)physmem * PAGE_SIZE;
1012 sysctl_createv(clog, 0, NULL, NULL,
1013 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1014 CTLTYPE_QUAD, "physmem64",
1015 SYSCTL_DESCR("Bytes of physical memory"),
1016 NULL, q, NULL, 0,
1017 CTL_HW, HW_PHYSMEM64, CTL_EOL);
1018 sysctl_createv(clog, 0, NULL, NULL,
1019 CTLFLAG_PERMANENT,
1020 CTLTYPE_QUAD, "usermem64",
1021 SYSCTL_DESCR("Bytes of non-kernel memory"),
1022 sysctl_hw_usermem, 0, NULL, 0,
1023 CTL_HW, HW_USERMEM64, CTL_EOL);
1024 }
1025
1026 #ifdef DEBUG
1027 /*
1028 * Debugging related system variables.
1029 */
1030 struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4;
1031 struct ctldebug debug5, debug6, debug7, debug8, debug9;
1032 struct ctldebug debug10, debug11, debug12, debug13, debug14;
1033 struct ctldebug debug15, debug16, debug17, debug18, debug19;
1034 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
1035 &debug0, &debug1, &debug2, &debug3, &debug4,
1036 &debug5, &debug6, &debug7, &debug8, &debug9,
1037 &debug10, &debug11, &debug12, &debug13, &debug14,
1038 &debug15, &debug16, &debug17, &debug18, &debug19,
1039 };
1040
1041 /*
1042 * this setup routine is a replacement for debug_sysctl()
1043 *
1044 * note that it creates several nodes per defined debug variable
1045 */
1046 SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup")
1047 {
1048 struct ctldebug *cdp;
1049 char nodename[20];
1050 int i;
1051
1052 /*
1053 * two ways here:
1054 *
1055 * the "old" way (debug.name -> value) which was emulated by
1056 * the sysctl(8) binary
1057 *
1058 * the new way, which the sysctl(8) binary was actually using
1059
1060 node debug
1061 node debug.0
1062 string debug.0.name
1063 int debug.0.value
1064 int debug.name
1065
1066 */
1067
1068 sysctl_createv(clog, 0, NULL, NULL,
1069 CTLFLAG_PERMANENT,
1070 CTLTYPE_NODE, "debug", NULL,
1071 NULL, 0, NULL, 0,
1072 CTL_DEBUG, CTL_EOL);
1073
1074 for (i = 0; i < CTL_DEBUG_MAXID; i++) {
1075 cdp = debugvars[i];
1076 if (cdp->debugname == NULL || cdp->debugvar == NULL)
1077 continue;
1078
1079 snprintf(nodename, sizeof(nodename), "debug%d", i);
1080 sysctl_createv(clog, 0, NULL, NULL,
1081 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1082 CTLTYPE_NODE, nodename, NULL,
1083 NULL, 0, NULL, 0,
1084 CTL_DEBUG, i, CTL_EOL);
1085 sysctl_createv(clog, 0, NULL, NULL,
1086 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1087 CTLTYPE_STRING, "name", NULL,
1088 /*XXXUNCONST*/
1089 NULL, 0, __UNCONST(cdp->debugname), 0,
1090 CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL);
1091 sysctl_createv(clog, 0, NULL, NULL,
1092 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN,
1093 CTLTYPE_INT, "value", NULL,
1094 NULL, 0, cdp->debugvar, 0,
1095 CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL);
1096 sysctl_createv(clog, 0, NULL, NULL,
1097 CTLFLAG_PERMANENT,
1098 CTLTYPE_INT, cdp->debugname, NULL,
1099 NULL, 0, cdp->debugvar, 0,
1100 CTL_DEBUG, CTL_CREATE, CTL_EOL);
1101 }
1102 }
1103 #endif /* DEBUG */
1104
1105 /*
1106 * ********************************************************************
1107 * section 2: private node-specific helper routines.
1108 * ********************************************************************
1109 */
1110
1111 #ifdef DIAGNOSTIC
1112 static int
1113 sysctl_kern_trigger_panic(SYSCTLFN_ARGS)
1114 {
1115 int newtrig, error;
1116 struct sysctlnode node;
1117
1118 newtrig = 0;
1119 node = *rnode;
1120 node.sysctl_data = &newtrig;
1121 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1122 if (error || newp == NULL)
1123 return (error);
1124
1125 if (newtrig != 0)
1126 panic("Panic triggered");
1127
1128 return (error);
1129 }
1130 #endif
1131
1132 /*
1133 * sysctl helper routine for kern.maxvnodes. drain vnodes if
1134 * new value is lower than desiredvnodes and then calls reinit
1135 * routines that needs to adjust to the new value.
1136 */
1137 static int
1138 sysctl_kern_maxvnodes(SYSCTLFN_ARGS)
1139 {
1140 int error, new_vnodes, old_vnodes;
1141 struct sysctlnode node;
1142
1143 new_vnodes = desiredvnodes;
1144 node = *rnode;
1145 node.sysctl_data = &new_vnodes;
1146 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1147 if (error || newp == NULL)
1148 return (error);
1149
1150 old_vnodes = desiredvnodes;
1151 desiredvnodes = new_vnodes;
1152 if (new_vnodes < old_vnodes) {
1153 error = vfs_drainvnodes(new_vnodes, l);
1154 if (error) {
1155 desiredvnodes = old_vnodes;
1156 return (error);
1157 }
1158 }
1159 vfs_reinit();
1160 nchreinit();
1161
1162 return (0);
1163 }
1164
1165 /*
1166 * sysctl helper routine for rtc_offset - set time after changes
1167 */
1168 static int
1169 sysctl_kern_rtc_offset(SYSCTLFN_ARGS)
1170 {
1171 struct timespec ts, delta;
1172 int error, new_rtc_offset;
1173 struct sysctlnode node;
1174
1175 new_rtc_offset = rtc_offset;
1176 node = *rnode;
1177 node.sysctl_data = &new_rtc_offset;
1178 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1179 if (error || newp == NULL)
1180 return (error);
1181
1182 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME,
1183 KAUTH_REQ_SYSTEM_TIME_RTCOFFSET,
1184 (void *)(u_long)new_rtc_offset, NULL, NULL))
1185 return (EPERM);
1186 if (rtc_offset == new_rtc_offset)
1187 return (0);
1188
1189 /* if we change the offset, adjust the time */
1190 nanotime(&ts);
1191 delta.tv_sec = 60 * (new_rtc_offset - rtc_offset);
1192 delta.tv_nsec = 0;
1193 timespecadd(&ts, &delta, &ts);
1194 rtc_offset = new_rtc_offset;
1195 settime(l->l_proc, &ts);
1196
1197 return (0);
1198 }
1199
1200 /*
1201 * sysctl helper routine for kern.maxproc. ensures that the new
1202 * values are not too low or too high.
1203 */
1204 static int
1205 sysctl_kern_maxproc(SYSCTLFN_ARGS)
1206 {
1207 int error, nmaxproc;
1208 struct sysctlnode node;
1209
1210 nmaxproc = maxproc;
1211 node = *rnode;
1212 node.sysctl_data = &nmaxproc;
1213 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1214 if (error || newp == NULL)
1215 return (error);
1216
1217 if (nmaxproc < 0 || nmaxproc >= PID_MAX)
1218 return (EINVAL);
1219 #ifdef __HAVE_CPU_MAXPROC
1220 if (nmaxproc > cpu_maxproc())
1221 return (EINVAL);
1222 #endif
1223 maxproc = nmaxproc;
1224
1225 return (0);
1226 }
1227
1228 /*
1229 * sysctl helper function for kern.hostid. the hostid is a long, but
1230 * we export it as an int, so we need to give it a little help.
1231 */
1232 static int
1233 sysctl_kern_hostid(SYSCTLFN_ARGS)
1234 {
1235 int error, inthostid;
1236 struct sysctlnode node;
1237
1238 inthostid = hostid; /* XXX assumes sizeof int <= sizeof long */
1239 node = *rnode;
1240 node.sysctl_data = &inthostid;
1241 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1242 if (error || newp == NULL)
1243 return (error);
1244
1245 hostid = (unsigned)inthostid;
1246
1247 return (0);
1248 }
1249
1250 /*
1251 * sysctl helper function for kern.hostname and kern.domainnname.
1252 * resets the relevant recorded length when the underlying name is
1253 * changed.
1254 */
1255 static int
1256 sysctl_setlen(SYSCTLFN_ARGS)
1257 {
1258 int error;
1259
1260 error = sysctl_lookup(SYSCTLFN_CALL(rnode));
1261 if (error || newp == NULL)
1262 return (error);
1263
1264 switch (rnode->sysctl_num) {
1265 case KERN_HOSTNAME:
1266 hostnamelen = strlen((const char*)rnode->sysctl_data);
1267 break;
1268 case KERN_DOMAINNAME:
1269 domainnamelen = strlen((const char*)rnode->sysctl_data);
1270 break;
1271 }
1272
1273 return (0);
1274 }
1275
1276 /*
1277 * sysctl helper routine for kern.clockrate. assembles a struct on
1278 * the fly to be returned to the caller.
1279 */
1280 static int
1281 sysctl_kern_clockrate(SYSCTLFN_ARGS)
1282 {
1283 struct clockinfo clkinfo;
1284 struct sysctlnode node;
1285
1286 clkinfo.tick = tick;
1287 clkinfo.tickadj = tickadj;
1288 clkinfo.hz = hz;
1289 clkinfo.profhz = profhz;
1290 clkinfo.stathz = stathz ? stathz : hz;
1291
1292 node = *rnode;
1293 node.sysctl_data = &clkinfo;
1294 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1295 }
1296
1297
1298 /*
1299 * sysctl helper routine for kern.file pseudo-subtree.
1300 */
1301 static int
1302 sysctl_kern_file(SYSCTLFN_ARGS)
1303 {
1304 int error;
1305 size_t buflen;
1306 struct file *fp;
1307 char *start, *where;
1308
1309 start = where = oldp;
1310 buflen = *oldlenp;
1311 if (where == NULL) {
1312 /*
1313 * overestimate by 10 files
1314 */
1315 *oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
1316 return (0);
1317 }
1318
1319 /*
1320 * first dcopyout filehead
1321 */
1322 if (buflen < sizeof(filehead)) {
1323 *oldlenp = 0;
1324 return (0);
1325 }
1326 error = dcopyout(l, &filehead, where, sizeof(filehead));
1327 if (error)
1328 return (error);
1329 buflen -= sizeof(filehead);
1330 where += sizeof(filehead);
1331
1332 /*
1333 * followed by an array of file structures
1334 */
1335 LIST_FOREACH(fp, &filehead, f_list) {
1336 if (kauth_authorize_generic(l->l_cred,
1337 KAUTH_GENERIC_CANSEE, fp->f_cred) != 0)
1338 continue;
1339 if (buflen < sizeof(struct file)) {
1340 *oldlenp = where - start;
1341 return (ENOMEM);
1342 }
1343 error = dcopyout(l, fp, where, sizeof(struct file));
1344 if (error)
1345 return (error);
1346 buflen -= sizeof(struct file);
1347 where += sizeof(struct file);
1348 }
1349 *oldlenp = where - start;
1350 return (0);
1351 }
1352
1353 /*
1354 * sysctl helper routine for kern.autonicetime and kern.autoniceval.
1355 * asserts that the assigned value is in the correct range.
1356 */
1357 static int
1358 sysctl_kern_autonice(SYSCTLFN_ARGS)
1359 {
1360 int error, t = 0;
1361 struct sysctlnode node;
1362
1363 node = *rnode;
1364 t = *(int*)node.sysctl_data;
1365 node.sysctl_data = &t;
1366 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1367 if (error || newp == NULL)
1368 return (error);
1369
1370 switch (node.sysctl_num) {
1371 case KERN_AUTONICETIME:
1372 if (t >= 0)
1373 autonicetime = t;
1374 break;
1375 case KERN_AUTONICEVAL:
1376 if (t < PRIO_MIN)
1377 t = PRIO_MIN;
1378 else if (t > PRIO_MAX)
1379 t = PRIO_MAX;
1380 autoniceval = t;
1381 break;
1382 }
1383
1384 return (0);
1385 }
1386
1387 /*
1388 * sysctl helper routine for kern.msgbufsize and kern.msgbuf. for the
1389 * former it merely checks the message buffer is set up. for the latter,
1390 * it also copies out the data if necessary.
1391 */
1392 static int
1393 sysctl_msgbuf(SYSCTLFN_ARGS)
1394 {
1395 char *where = oldp;
1396 size_t len, maxlen;
1397 long beg, end;
1398 int error;
1399
1400 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
1401 msgbufenabled = 0;
1402 return (ENXIO);
1403 }
1404
1405 switch (rnode->sysctl_num) {
1406 case KERN_MSGBUFSIZE: {
1407 struct sysctlnode node = *rnode;
1408 int msg_bufs = (int)msgbufp->msg_bufs;
1409 node.sysctl_data = &msg_bufs;
1410 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1411 }
1412 case KERN_MSGBUF:
1413 break;
1414 default:
1415 return (EOPNOTSUPP);
1416 }
1417
1418 if (newp != NULL)
1419 return (EPERM);
1420
1421 if (oldp == NULL) {
1422 /* always return full buffer size */
1423 *oldlenp = msgbufp->msg_bufs;
1424 return (0);
1425 }
1426
1427 error = 0;
1428 maxlen = MIN(msgbufp->msg_bufs, *oldlenp);
1429
1430 /*
1431 * First, copy from the write pointer to the end of
1432 * message buffer.
1433 */
1434 beg = msgbufp->msg_bufx;
1435 end = msgbufp->msg_bufs;
1436 while (maxlen > 0) {
1437 len = MIN(end - beg, maxlen);
1438 if (len == 0)
1439 break;
1440 error = dcopyout(l, &msgbufp->msg_bufc[beg], where, len);
1441 if (error)
1442 break;
1443 where += len;
1444 maxlen -= len;
1445
1446 /*
1447 * ... then, copy from the beginning of message buffer to
1448 * the write pointer.
1449 */
1450 beg = 0;
1451 end = msgbufp->msg_bufx;
1452 }
1453
1454 return (error);
1455 }
1456
1457 /*
1458 * sysctl helper routine for kern.defcorename. in the case of a new
1459 * string being assigned, check that it's not a zero-length string.
1460 * (XXX the check in -current doesn't work, but do we really care?)
1461 */
1462 static int
1463 sysctl_kern_defcorename(SYSCTLFN_ARGS)
1464 {
1465 int error;
1466 char *newcorename;
1467 struct sysctlnode node;
1468
1469 newcorename = PNBUF_GET();
1470 node = *rnode;
1471 node.sysctl_data = &newcorename[0];
1472 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
1473 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1474 if (error || newp == NULL) {
1475 goto done;
1476 }
1477
1478 /*
1479 * when sysctl_lookup() deals with a string, it's guaranteed
1480 * to come back nul terminated. so there. :)
1481 */
1482 if (strlen(newcorename) == 0) {
1483 error = EINVAL;
1484 } else {
1485 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
1486 error = 0;
1487 }
1488 done:
1489 PNBUF_PUT(newcorename);
1490 return error;
1491 }
1492
1493 /*
1494 * sysctl helper routine for kern.cp_time node. adds up cpu time
1495 * across all cpus.
1496 */
1497 static int
1498 sysctl_kern_cptime(SYSCTLFN_ARGS)
1499 {
1500 struct sysctlnode node = *rnode;
1501
1502 #ifndef MULTIPROCESSOR
1503
1504 if (namelen == 1) {
1505 if (name[0] != 0)
1506 return (ENOENT);
1507 /*
1508 * you're allowed to ask for the zero'th processor
1509 */
1510 name++;
1511 namelen--;
1512 }
1513 node.sysctl_data = curcpu()->ci_schedstate.spc_cp_time;
1514 node.sysctl_size = sizeof(curcpu()->ci_schedstate.spc_cp_time);
1515 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1516
1517 #else /* MULTIPROCESSOR */
1518
1519 uint64_t *cp_time = NULL;
1520 int error, n = sysctl_ncpus(), i;
1521 struct cpu_info *ci;
1522 CPU_INFO_ITERATOR cii;
1523
1524 /*
1525 * if you specifically pass a buffer that is the size of the
1526 * sum, or if you are probing for the size, you get the "sum"
1527 * of cp_time (and the size thereof) across all processors.
1528 *
1529 * alternately, you can pass an additional mib number and get
1530 * cp_time for that particular processor.
1531 */
1532 switch (namelen) {
1533 case 0:
1534 if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) {
1535 node.sysctl_size = sizeof(uint64_t) * CPUSTATES;
1536 n = -1; /* SUM */
1537 }
1538 else {
1539 node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES;
1540 n = -2; /* ALL */
1541 }
1542 break;
1543 case 1:
1544 if (name[0] < 0 || name[0] >= n)
1545 return (ENOENT); /* ENOSUCHPROCESSOR */
1546 node.sysctl_size = sizeof(uint64_t) * CPUSTATES;
1547 n = name[0];
1548 /*
1549 * adjust these so that sysctl_lookup() will be happy
1550 */
1551 name++;
1552 namelen--;
1553 break;
1554 default:
1555 return (EINVAL);
1556 }
1557
1558 cp_time = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
1559 if (cp_time == NULL)
1560 return (ENOMEM);
1561 node.sysctl_data = cp_time;
1562 memset(cp_time, 0, node.sysctl_size);
1563
1564 for (CPU_INFO_FOREACH(cii, ci)) {
1565 if (n <= 0)
1566 for (i = 0; i < CPUSTATES; i++)
1567 cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
1568 /*
1569 * if a specific processor was requested and we just
1570 * did it, we're done here
1571 */
1572 if (n == 0)
1573 break;
1574 /*
1575 * if doing "all", skip to next cp_time set for next processor
1576 */
1577 if (n == -2)
1578 cp_time += CPUSTATES;
1579 /*
1580 * if we're doing a specific processor, we're one
1581 * processor closer
1582 */
1583 if (n > 0)
1584 n--;
1585 }
1586
1587 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1588 free(node.sysctl_data, M_TEMP);
1589 return (error);
1590
1591 #endif /* MULTIPROCESSOR */
1592 }
1593
1594 #if NPTY > 0
1595 /*
1596 * sysctl helper routine for kern.maxptys. ensures that any new value
1597 * is acceptable to the pty subsystem.
1598 */
1599 static int
1600 sysctl_kern_maxptys(SYSCTLFN_ARGS)
1601 {
1602 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */
1603 int error, xmax;
1604 struct sysctlnode node;
1605
1606 /* get current value of maxptys */
1607 xmax = pty_maxptys(0, 0);
1608
1609 node = *rnode;
1610 node.sysctl_data = &xmax;
1611 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1612 if (error || newp == NULL)
1613 return (error);
1614
1615 if (xmax != pty_maxptys(xmax, 1))
1616 return (EINVAL);
1617
1618 return (0);
1619 }
1620 #endif /* NPTY > 0 */
1621
1622 /*
1623 * sysctl helper routine for kern.sbmax. basically just ensures that
1624 * any new value is not too small.
1625 */
1626 static int
1627 sysctl_kern_sbmax(SYSCTLFN_ARGS)
1628 {
1629 int error, new_sbmax;
1630 struct sysctlnode node;
1631
1632 new_sbmax = sb_max;
1633 node = *rnode;
1634 node.sysctl_data = &new_sbmax;
1635 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1636 if (error || newp == NULL)
1637 return (error);
1638
1639 error = sb_max_set(new_sbmax);
1640
1641 return (error);
1642 }
1643
1644 /*
1645 * sysctl helper routine for kern.urandom node. picks a random number
1646 * for you.
1647 */
1648 static int
1649 sysctl_kern_urnd(SYSCTLFN_ARGS)
1650 {
1651 #if NRND > 0
1652 int v;
1653
1654 if (rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY) == sizeof(v)) {
1655 struct sysctlnode node = *rnode;
1656 node.sysctl_data = &v;
1657 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1658 }
1659 else
1660 return (EIO); /*XXX*/
1661 #else
1662 return (EOPNOTSUPP);
1663 #endif
1664 }
1665
1666 /*
1667 * sysctl helper routine for kern.arandom node. picks a random number
1668 * for you.
1669 */
1670 static int
1671 sysctl_kern_arnd(SYSCTLFN_ARGS)
1672 {
1673 #if NRND > 0
1674 int error;
1675 void *v;
1676 struct sysctlnode node = *rnode;
1677
1678 if (*oldlenp == 0)
1679 return 0;
1680 if (*oldlenp > 8192)
1681 return E2BIG;
1682
1683 v = malloc(*oldlenp, M_TEMP, M_WAITOK);
1684
1685 arc4randbytes(v, *oldlenp);
1686 node.sysctl_data = v;
1687 node.sysctl_size = *oldlenp;
1688 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1689 free(v, M_TEMP);
1690 return error;
1691 #else
1692 return (EOPNOTSUPP);
1693 #endif
1694 }
1695 /*
1696 * sysctl helper routine to do kern.lwp.* work.
1697 */
1698 static int
1699 sysctl_kern_lwp(SYSCTLFN_ARGS)
1700 {
1701 struct kinfo_lwp klwp;
1702 struct proc *p;
1703 struct lwp *l2;
1704 char *where, *dp;
1705 int pid, elem_size, elem_count;
1706 int buflen, needed, error;
1707
1708 if (namelen == 1 && name[0] == CTL_QUERY)
1709 return (sysctl_query(SYSCTLFN_CALL(rnode)));
1710
1711 dp = where = oldp;
1712 buflen = where != NULL ? *oldlenp : 0;
1713 error = needed = 0;
1714
1715 if (newp != NULL || namelen != 3)
1716 return (EINVAL);
1717 pid = name[0];
1718 elem_size = name[1];
1719 elem_count = name[2];
1720
1721 p = p_find(pid, PFIND_UNLOCK_FAIL);
1722 if (p == NULL)
1723 return (ESRCH);
1724 mutex_enter(&p->p_smutex);
1725 LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
1726 if (buflen >= elem_size && elem_count > 0) {
1727 lwp_lock(l2);
1728 fill_lwp(l2, &klwp);
1729 lwp_unlock(l2);
1730
1731 /*
1732 * Copy out elem_size, but not larger than
1733 * the size of a struct kinfo_proc2.
1734 *
1735 * XXX We should not be holding p_smutex, but
1736 * for now, the buffer is wired. Fix later.
1737 */
1738 error = dcopyout(l, &klwp, dp,
1739 min(sizeof(klwp), elem_size));
1740 if (error)
1741 goto cleanup;
1742 dp += elem_size;
1743 buflen -= elem_size;
1744 elem_count--;
1745 }
1746 needed += elem_size;
1747 }
1748 mutex_exit(&p->p_smutex);
1749 rw_exit(&proclist_lock);
1750
1751 if (where != NULL) {
1752 *oldlenp = dp - where;
1753 if (needed > *oldlenp)
1754 return (ENOMEM);
1755 } else {
1756 needed += KERN_LWPSLOP;
1757 *oldlenp = needed;
1758 }
1759 return (0);
1760 cleanup:
1761 return (error);
1762 }
1763
1764 /*
1765 * sysctl helper routine for kern.forkfsleep node. ensures that the
1766 * given value is not too large or two small, and is at least one
1767 * timer tick if not zero.
1768 */
1769 static int
1770 sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
1771 {
1772 /* userland sees value in ms, internally is in ticks */
1773 extern int forkfsleep; /* defined in kern/kern_fork.c */
1774 int error, timo, lsleep;
1775 struct sysctlnode node;
1776
1777 lsleep = forkfsleep * 1000 / hz;
1778 node = *rnode;
1779 node.sysctl_data = &lsleep;
1780 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1781 if (error || newp == NULL)
1782 return (error);
1783
1784 /* refuse negative values, and overly 'long time' */
1785 if (lsleep < 0 || lsleep > MAXSLP * 1000)
1786 return (EINVAL);
1787
1788 timo = mstohz(lsleep);
1789
1790 /* if the interval is >0 ms && <1 tick, use 1 tick */
1791 if (lsleep != 0 && timo == 0)
1792 forkfsleep = 1;
1793 else
1794 forkfsleep = timo;
1795
1796 return (0);
1797 }
1798
1799 /*
1800 * sysctl helper routine for kern.root_partition
1801 */
1802 static int
1803 sysctl_kern_root_partition(SYSCTLFN_ARGS)
1804 {
1805 int rootpart = DISKPART(rootdev);
1806 struct sysctlnode node = *rnode;
1807
1808 node.sysctl_data = &rootpart;
1809 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1810 }
1811
1812 /*
1813 * sysctl helper function for kern.drivers
1814 */
1815 static int
1816 sysctl_kern_drivers(SYSCTLFN_ARGS)
1817 {
1818 int error;
1819 size_t buflen;
1820 struct kinfo_drivers kd;
1821 char *start, *where;
1822 const char *dname;
1823 int i;
1824 extern struct devsw_conv *devsw_conv;
1825 extern int max_devsw_convs;
1826
1827 if (newp != NULL || namelen != 0)
1828 return (EINVAL);
1829
1830 start = where = oldp;
1831 buflen = *oldlenp;
1832 if (where == NULL) {
1833 *oldlenp = max_devsw_convs * sizeof kd;
1834 return 0;
1835 }
1836
1837 /*
1838 * An array of kinfo_drivers structures
1839 */
1840 error = 0;
1841 for (i = 0; i < max_devsw_convs; i++) {
1842 dname = devsw_conv[i].d_name;
1843 if (dname == NULL)
1844 continue;
1845 if (buflen < sizeof kd) {
1846 error = ENOMEM;
1847 break;
1848 }
1849 memset(&kd, 0, sizeof(kd));
1850 kd.d_bmajor = devsw_conv[i].d_bmajor;
1851 kd.d_cmajor = devsw_conv[i].d_cmajor;
1852 strlcpy(kd.d_name, dname, sizeof kd.d_name);
1853 error = dcopyout(l, &kd, where, sizeof kd);
1854 if (error != 0)
1855 break;
1856 buflen -= sizeof kd;
1857 where += sizeof kd;
1858 }
1859 *oldlenp = where - start;
1860 return error;
1861 }
1862
1863 /*
1864 * sysctl helper function for kern.file2
1865 */
1866 static int
1867 sysctl_kern_file2(SYSCTLFN_ARGS)
1868 {
1869 struct proc *p;
1870 struct file *fp;
1871 struct filedesc *fd;
1872 struct kinfo_file kf;
1873 char *dp;
1874 u_int i, op;
1875 size_t len, needed, elem_size, out_size;
1876 int error, arg, elem_count;
1877
1878 if (namelen == 1 && name[0] == CTL_QUERY)
1879 return (sysctl_query(SYSCTLFN_CALL(rnode)));
1880
1881 if (namelen != 4)
1882 return (EINVAL);
1883
1884 error = 0;
1885 dp = oldp;
1886 len = (oldp != NULL) ? *oldlenp : 0;
1887 op = name[0];
1888 arg = name[1];
1889 elem_size = name[2];
1890 elem_count = name[3];
1891 out_size = MIN(sizeof(kf), elem_size);
1892 needed = 0;
1893
1894 if (elem_size < 1 || elem_count < 0)
1895 return (EINVAL);
1896
1897 switch (op) {
1898 case KERN_FILE_BYFILE:
1899 /*
1900 * doesn't use arg so it must be zero
1901 */
1902 if (arg != 0)
1903 return (EINVAL);
1904 LIST_FOREACH(fp, &filehead, f_list) {
1905 if (kauth_authorize_generic(l->l_cred,
1906 KAUTH_GENERIC_CANSEE, fp->f_cred) != 0)
1907 continue;
1908 if (len >= elem_size && elem_count > 0) {
1909 fill_file(&kf, fp, NULL, 0);
1910 error = dcopyout(l, &kf, dp, out_size);
1911 if (error)
1912 break;
1913 dp += elem_size;
1914 len -= elem_size;
1915 }
1916 if (elem_count > 0) {
1917 needed += elem_size;
1918 if (elem_count != INT_MAX)
1919 elem_count--;
1920 }
1921 }
1922 break;
1923 case KERN_FILE_BYPID:
1924 if (arg < -1)
1925 /* -1 means all processes */
1926 return (EINVAL);
1927 rw_enter(&proclist_lock, RW_READER);
1928 PROCLIST_FOREACH(p, &allproc) {
1929 if (p->p_stat == SIDL)
1930 /* skip embryonic processes */
1931 continue;
1932 if (kauth_authorize_process(l->l_cred,
1933 KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL) != 0)
1934 continue;
1935 if (arg > 0 && p->p_pid != arg)
1936 /* pick only the one we want */
1937 /* XXX want 0 to mean "kernel files" */
1938 continue;
1939 fd = p->p_fd;
1940 for (i = 0; i < fd->fd_nfiles; i++) {
1941 fp = fd->fd_ofiles[i];
1942 if (fp == NULL || !FILE_IS_USABLE(fp))
1943 continue;
1944 if (len >= elem_size && elem_count > 0) {
1945 fill_file(&kf, fd->fd_ofiles[i],
1946 p, i);
1947 error = dcopyout(l, &kf, dp, out_size);
1948 if (error)
1949 break;
1950 dp += elem_size;
1951 len -= elem_size;
1952 }
1953 if (elem_count > 0) {
1954 needed += elem_size;
1955 if (elem_count != INT_MAX)
1956 elem_count--;
1957 }
1958 }
1959 }
1960 rw_exit(&proclist_lock);
1961 break;
1962 default:
1963 return (EINVAL);
1964 }
1965
1966 if (oldp == NULL)
1967 needed += KERN_FILESLOP * elem_size;
1968 *oldlenp = needed;
1969
1970 return (error);
1971 }
1972
1973 static void
1974 fill_file(struct kinfo_file *kp, const struct file *fp, struct proc *p, int i)
1975 {
1976
1977 memset(kp, 0, sizeof(*kp));
1978
1979 kp->ki_fileaddr = PTRTOUINT64(fp);
1980 kp->ki_flag = fp->f_flag;
1981 kp->ki_iflags = fp->f_iflags;
1982 kp->ki_ftype = fp->f_type;
1983 kp->ki_count = fp->f_count;
1984 kp->ki_msgcount = fp->f_msgcount;
1985 kp->ki_usecount = fp->f_usecount;
1986 kp->ki_fucred = PTRTOUINT64(fp->f_cred);
1987 kp->ki_fuid = kauth_cred_geteuid(fp->f_cred);
1988 kp->ki_fgid = kauth_cred_getegid(fp->f_cred);
1989 kp->ki_fops = PTRTOUINT64(fp->f_ops);
1990 kp->ki_foffset = fp->f_offset;
1991 kp->ki_fdata = PTRTOUINT64(fp->f_data);
1992
1993 /* vnode information to glue this file to something */
1994 if (fp->f_type == DTYPE_VNODE) {
1995 struct vnode *vp = (struct vnode *)fp->f_data;
1996
1997 kp->ki_vun = PTRTOUINT64(vp->v_un.vu_socket);
1998 kp->ki_vsize = vp->v_size;
1999 kp->ki_vtype = vp->v_type;
2000 kp->ki_vtag = vp->v_tag;
2001 kp->ki_vdata = PTRTOUINT64(vp->v_data);
2002 }
2003
2004 /* process information when retrieved via KERN_FILE_BYPID */
2005 if (p) {
2006 kp->ki_pid = p->p_pid;
2007 kp->ki_fd = i;
2008 kp->ki_ofileflags = p->p_fd->fd_ofileflags[i];
2009 }
2010 }
2011
2012 static int
2013 sysctl_doeproc(SYSCTLFN_ARGS)
2014 {
2015 struct eproc *eproc;
2016 struct kinfo_proc2 *kproc2;
2017 struct kinfo_proc *dp;
2018 struct proc *p;
2019 const struct proclist_desc *pd;
2020 char *where, *dp2;
2021 int type, op, arg;
2022 u_int elem_size, elem_count;
2023 size_t buflen, needed;
2024 int error;
2025
2026 if (namelen == 1 && name[0] == CTL_QUERY)
2027 return (sysctl_query(SYSCTLFN_CALL(rnode)));
2028
2029 dp = oldp;
2030 dp2 = where = oldp;
2031 buflen = where != NULL ? *oldlenp : 0;
2032 error = 0;
2033 needed = 0;
2034 type = rnode->sysctl_num;
2035
2036 if (type == KERN_PROC) {
2037 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
2038 return (EINVAL);
2039 op = name[0];
2040 if (op != KERN_PROC_ALL)
2041 arg = name[1];
2042 else
2043 arg = 0; /* Quell compiler warning */
2044 elem_size = elem_count = 0; /* Ditto */
2045 } else {
2046 if (namelen != 4)
2047 return (EINVAL);
2048 op = name[0];
2049 arg = name[1];
2050 elem_size = name[2];
2051 elem_count = name[3];
2052 }
2053
2054 if (type == KERN_PROC) {
2055 eproc = malloc(sizeof(*eproc), M_TEMP, M_WAITOK);
2056 kproc2 = NULL;
2057 } else {
2058 eproc = NULL;
2059 kproc2 = malloc(sizeof(*kproc2), M_TEMP, M_WAITOK);
2060 }
2061 rw_enter(&proclist_lock, RW_READER);
2062
2063 pd = proclists;
2064 again:
2065 PROCLIST_FOREACH(p, pd->pd_list) {
2066 /*
2067 * Skip embryonic processes.
2068 */
2069 if (p->p_stat == SIDL)
2070 continue;
2071
2072 if (kauth_authorize_process(l->l_cred,
2073 KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL) != 0)
2074 continue;
2075
2076 /*
2077 * TODO - make more efficient (see notes below).
2078 * do by session.
2079 */
2080 switch (op) {
2081
2082 case KERN_PROC_PID:
2083 /* could do this with just a lookup */
2084 if (p->p_pid != (pid_t)arg)
2085 continue;
2086 break;
2087
2088 case KERN_PROC_PGRP:
2089 /* could do this by traversing pgrp */
2090 if (p->p_pgrp->pg_id != (pid_t)arg)
2091 continue;
2092 break;
2093
2094 case KERN_PROC_SESSION:
2095 if (p->p_session->s_sid != (pid_t)arg)
2096 continue;
2097 break;
2098
2099 case KERN_PROC_TTY:
2100 if (arg == (int) KERN_PROC_TTY_REVOKE) {
2101 if ((p->p_lflag & PL_CONTROLT) == 0 ||
2102 p->p_session->s_ttyp == NULL ||
2103 p->p_session->s_ttyvp != NULL)
2104 continue;
2105 } else if ((p->p_lflag & PL_CONTROLT) == 0 ||
2106 p->p_session->s_ttyp == NULL) {
2107 if ((dev_t)arg != KERN_PROC_TTY_NODEV)
2108 continue;
2109 } else if (p->p_session->s_ttyp->t_dev != (dev_t)arg)
2110 continue;
2111 break;
2112
2113 case KERN_PROC_UID:
2114 if (kauth_cred_geteuid(p->p_cred) != (uid_t)arg)
2115 continue;
2116 break;
2117
2118 case KERN_PROC_RUID:
2119 if (kauth_cred_getuid(p->p_cred) != (uid_t)arg)
2120 continue;
2121 break;
2122
2123 case KERN_PROC_GID:
2124 if (kauth_cred_getegid(p->p_cred) != (uid_t)arg)
2125 continue;
2126 break;
2127
2128 case KERN_PROC_RGID:
2129 if (kauth_cred_getgid(p->p_cred) != (uid_t)arg)
2130 continue;
2131 break;
2132
2133 case KERN_PROC_ALL:
2134 /* allow everything */
2135 break;
2136
2137 default:
2138 error = EINVAL;
2139 goto cleanup;
2140 }
2141 if (type == KERN_PROC) {
2142 if (buflen >= sizeof(struct kinfo_proc)) {
2143 fill_eproc(p, eproc);
2144 error = dcopyout(l, p, &dp->kp_proc,
2145 sizeof(struct proc));
2146 if (error)
2147 goto cleanup;
2148 error = dcopyout(l, eproc, &dp->kp_eproc,
2149 sizeof(*eproc));
2150 if (error)
2151 goto cleanup;
2152 dp++;
2153 buflen -= sizeof(struct kinfo_proc);
2154 }
2155 needed += sizeof(struct kinfo_proc);
2156 } else { /* KERN_PROC2 */
2157 if (buflen >= elem_size && elem_count > 0) {
2158 fill_kproc2(p, kproc2);
2159 /*
2160 * Copy out elem_size, but not larger than
2161 * the size of a struct kinfo_proc2.
2162 */
2163 error = dcopyout(l, kproc2, dp2,
2164 min(sizeof(*kproc2), elem_size));
2165 if (error)
2166 goto cleanup;
2167 dp2 += elem_size;
2168 buflen -= elem_size;
2169 elem_count--;
2170 }
2171 needed += elem_size;
2172 }
2173 }
2174 pd++;
2175 if (pd->pd_list != NULL)
2176 goto again;
2177 rw_exit(&proclist_lock);
2178
2179 if (where != NULL) {
2180 if (type == KERN_PROC)
2181 *oldlenp = (char *)dp - where;
2182 else
2183 *oldlenp = dp2 - where;
2184 if (needed > *oldlenp) {
2185 error = ENOMEM;
2186 goto out;
2187 }
2188 } else {
2189 needed += KERN_PROCSLOP;
2190 *oldlenp = needed;
2191 }
2192 if (kproc2)
2193 free(kproc2, M_TEMP);
2194 if (eproc)
2195 free(eproc, M_TEMP);
2196 return 0;
2197 cleanup:
2198 rw_exit(&proclist_lock);
2199 out:
2200 if (kproc2)
2201 free(kproc2, M_TEMP);
2202 if (eproc)
2203 free(eproc, M_TEMP);
2204 return error;
2205 }
2206
2207 /*
2208 * sysctl helper routine for kern.proc_args pseudo-subtree.
2209 */
2210 static int
2211 sysctl_kern_proc_args(SYSCTLFN_ARGS)
2212 {
2213 struct ps_strings pss;
2214 struct proc *p;
2215 size_t len, i;
2216 struct uio auio;
2217 struct iovec aiov;
2218 pid_t pid;
2219 int nargv, type, error;
2220 char *arg;
2221 char **argv = NULL;
2222 char *tmp;
2223 struct vmspace *vmspace;
2224 vaddr_t psstr_addr;
2225 vaddr_t offsetn;
2226 vaddr_t offsetv;
2227
2228 if (namelen == 1 && name[0] == CTL_QUERY)
2229 return (sysctl_query(SYSCTLFN_CALL(rnode)));
2230
2231 if (newp != NULL || namelen != 2)
2232 return (EINVAL);
2233 pid = name[0];
2234 type = name[1];
2235
2236 switch (type) {
2237 case KERN_PROC_ARGV:
2238 case KERN_PROC_NARGV:
2239 case KERN_PROC_ENV:
2240 case KERN_PROC_NENV:
2241 /* ok */
2242 break;
2243 default:
2244 return (EINVAL);
2245 }
2246
2247 rw_enter(&proclist_lock, RW_READER);
2248
2249 /* check pid */
2250 if ((p = p_find(pid, PFIND_LOCKED)) == NULL) {
2251 error = EINVAL;
2252 goto out_locked;
2253 }
2254
2255 error = kauth_authorize_process(l->l_cred,
2256 KAUTH_PROCESS_CANSEE, p, NULL, NULL, NULL);
2257 if (error) {
2258 goto out_locked;
2259 }
2260
2261 /* only root or same user change look at the environment */
2262 if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
2263 if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
2264 p, NULL, NULL, NULL)) {
2265 error = EPERM;
2266 goto out_locked;
2267 }
2268 }
2269
2270 if (oldp == NULL) {
2271 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV)
2272 *oldlenp = sizeof (int);
2273 else
2274 *oldlenp = ARG_MAX; /* XXX XXX XXX */
2275 error = 0;
2276 goto out_locked;
2277 }
2278
2279 /*
2280 * Zombies don't have a stack, so we can't read their psstrings.
2281 * System processes also don't have a user stack.
2282 */
2283 if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
2284 error = EINVAL;
2285 goto out_locked;
2286 }
2287
2288 /*
2289 * Lock the process down in memory.
2290 */
2291 /* XXXCDC: how should locking work here? */
2292 if ((l->l_flag & L_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
2293 error = EFAULT;
2294 goto out_locked;
2295 }
2296
2297 psstr_addr = (vaddr_t)p->p_psstr;
2298 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) {
2299 offsetn = p->p_psnargv;
2300 offsetv = p->p_psargv;
2301 } else {
2302 offsetn = p->p_psnenv;
2303 offsetv = p->p_psenv;
2304 }
2305 vmspace = p->p_vmspace;
2306 vmspace->vm_refcnt++; /* XXX */
2307
2308 rw_exit(&proclist_lock);
2309
2310 /*
2311 * Allocate a temporary buffer to hold the arguments.
2312 */
2313 arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
2314
2315 /*
2316 * Read in the ps_strings structure.
2317 */
2318 aiov.iov_base = &pss;
2319 aiov.iov_len = sizeof(pss);
2320 auio.uio_iov = &aiov;
2321 auio.uio_iovcnt = 1;
2322 auio.uio_offset = psstr_addr;
2323 auio.uio_resid = sizeof(pss);
2324 auio.uio_rw = UIO_READ;
2325 UIO_SETUP_SYSSPACE(&auio);
2326 error = uvm_io(&vmspace->vm_map, &auio);
2327 if (error)
2328 goto done;
2329
2330 memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv));
2331 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) {
2332 error = dcopyout(l, &nargv, oldp, sizeof(nargv));
2333 *oldlenp = sizeof(nargv);
2334 goto done;
2335 }
2336 /*
2337 * Now read the address of the argument vector.
2338 */
2339 switch (type) {
2340 case KERN_PROC_ARGV:
2341 /* FALLTHROUGH */
2342 case KERN_PROC_ENV:
2343 memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp));
2344 break;
2345 default:
2346 return (EINVAL);
2347 }
2348
2349 #ifdef COMPAT_NETBSD32
2350 if (p->p_flag & P_32)
2351 len = sizeof(netbsd32_charp) * nargv;
2352 else
2353 #endif
2354 len = sizeof(char *) * nargv;
2355
2356 argv = malloc(len, M_TEMP, M_WAITOK);
2357
2358 aiov.iov_base = argv;
2359 aiov.iov_len = len;
2360 auio.uio_iov = &aiov;
2361 auio.uio_iovcnt = 1;
2362 auio.uio_offset = (off_t)(unsigned long)tmp;
2363 auio.uio_resid = len;
2364 auio.uio_rw = UIO_READ;
2365 UIO_SETUP_SYSSPACE(&auio);
2366 error = uvm_io(&vmspace->vm_map, &auio);
2367 if (error)
2368 goto done;
2369
2370 /*
2371 * Now copy each string.
2372 */
2373 len = 0; /* bytes written to user buffer */
2374 for (i = 0; i < nargv; i++) {
2375 int finished = 0;
2376 vaddr_t base;
2377 size_t xlen;
2378 int j;
2379
2380 #ifdef COMPAT_NETBSD32
2381 if (p->p_flag & P_32) {
2382 netbsd32_charp *argv32;
2383
2384 argv32 = (netbsd32_charp *)argv;
2385
2386 base = (vaddr_t)NETBSD32PTR64(argv32[i]);
2387 } else
2388 #endif
2389 base = (vaddr_t)argv[i];
2390
2391 while (!finished) {
2392 xlen = PAGE_SIZE - (base & PAGE_MASK);
2393
2394 aiov.iov_base = arg;
2395 aiov.iov_len = PAGE_SIZE;
2396 auio.uio_iov = &aiov;
2397 auio.uio_iovcnt = 1;
2398 auio.uio_offset = base;
2399 auio.uio_resid = xlen;
2400 auio.uio_rw = UIO_READ;
2401 UIO_SETUP_SYSSPACE(&auio);
2402 error = uvm_io(&vmspace->vm_map, &auio);
2403 if (error)
2404 goto done;
2405
2406 /* Look for the end of the string */
2407 for (j = 0; j < xlen; j++) {
2408 if (arg[j] == '\0') {
2409 xlen = j + 1;
2410 finished = 1;
2411 break;
2412 }
2413 }
2414
2415 /* Check for user buffer overflow */
2416 if (len + xlen > *oldlenp) {
2417 finished = 1;
2418 if (len > *oldlenp)
2419 xlen = 0;
2420 else
2421 xlen = *oldlenp - len;
2422 }
2423
2424 /* Copyout the page */
2425 error = dcopyout(l, arg, (char *)oldp + len, xlen);
2426 if (error)
2427 goto done;
2428
2429 len += xlen;
2430 base += xlen;
2431 }
2432 }
2433 *oldlenp = len;
2434
2435 done:
2436 if (argv != NULL)
2437 free(argv, M_TEMP);
2438
2439 uvmspace_free(vmspace);
2440
2441 free(arg, M_TEMP);
2442 return error;
2443
2444 out_locked:
2445 rw_exit(&proclist_lock);
2446 return error;
2447 }
2448
2449 static int
2450 sysctl_security_setidcore(SYSCTLFN_ARGS)
2451 {
2452 int newsize, error;
2453 struct sysctlnode node;
2454
2455 node = *rnode;
2456 node.sysctl_data = &newsize;
2457 newsize = *(int *)rnode->sysctl_data;
2458 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2459 if (error || newp == NULL)
2460 return error;
2461
2462 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE,
2463 0, NULL, NULL, NULL))
2464 return (EPERM);
2465
2466 *(int *)rnode->sysctl_data = newsize;
2467
2468 return 0;
2469 }
2470
2471 static int
2472 sysctl_security_setidcorename(SYSCTLFN_ARGS)
2473 {
2474 int error;
2475 char *newsetidcorename;
2476 struct sysctlnode node;
2477
2478 newsetidcorename = PNBUF_GET();
2479 node = *rnode;
2480 node.sysctl_data = newsetidcorename;
2481 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
2482 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2483 if (error || newp == NULL) {
2484 goto out;
2485 }
2486 if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_SETIDCORE,
2487 0, NULL, NULL, NULL)) {
2488 error = EPERM;
2489 goto out;
2490 }
2491 if (strlen(newsetidcorename) == 0) {
2492 error = EINVAL;
2493 goto out;
2494 }
2495 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
2496 out:
2497 PNBUF_PUT(newsetidcorename);
2498 return error;
2499 }
2500
2501 /*
2502 * sysctl helper routine for kern.cp_id node. maps cpus to their
2503 * cpuids.
2504 */
2505 static int
2506 sysctl_kern_cpid(SYSCTLFN_ARGS)
2507 {
2508 struct sysctlnode node = *rnode;
2509
2510 #ifndef MULTIPROCESSOR
2511 uint64_t id;
2512
2513 if (namelen == 1) {
2514 if (name[0] != 0)
2515 return (ENOENT);
2516 /*
2517 * you're allowed to ask for the zero'th processor
2518 */
2519 name++;
2520 namelen--;
2521 }
2522 node.sysctl_data = &id;
2523 node.sysctl_size = sizeof(id);
2524 id = cpu_number();
2525 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2526
2527 #else /* MULTIPROCESSOR */
2528 uint64_t *cp_id = NULL;
2529 int error, n = sysctl_ncpus();
2530 struct cpu_info *ci;
2531 CPU_INFO_ITERATOR cii;
2532
2533 /*
2534 * here you may either retrieve a single cpu id or the whole
2535 * set. the size you get back when probing depends on what
2536 * you ask for.
2537 */
2538 switch (namelen) {
2539 case 0:
2540 node.sysctl_size = n * sizeof(uint64_t);
2541 n = -2; /* ALL */
2542 break;
2543 case 1:
2544 if (name[0] < 0 || name[0] >= n)
2545 return (ENOENT); /* ENOSUCHPROCESSOR */
2546 node.sysctl_size = sizeof(uint64_t);
2547 n = name[0];
2548 /*
2549 * adjust these so that sysctl_lookup() will be happy
2550 */
2551 name++;
2552 namelen--;
2553 break;
2554 default:
2555 return (EINVAL);
2556 }
2557
2558 cp_id = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
2559 if (cp_id == NULL)
2560 return (ENOMEM);
2561 node.sysctl_data = cp_id;
2562 memset(cp_id, 0, node.sysctl_size);
2563
2564 for (CPU_INFO_FOREACH(cii, ci)) {
2565 if (n <= 0)
2566 cp_id[0] = ci->ci_cpuid;
2567 /*
2568 * if a specific processor was requested and we just
2569 * did it, we're done here
2570 */
2571 if (n == 0)
2572 break;
2573 /*
2574 * if doing "all", skip to next cp_id slot for next processor
2575 */
2576 if (n == -2)
2577 cp_id++;
2578 /*
2579 * if we're doing a specific processor, we're one
2580 * processor closer
2581 */
2582 if (n > 0)
2583 n--;
2584 }
2585
2586 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2587 free(node.sysctl_data, M_TEMP);
2588 return (error);
2589
2590 #endif /* MULTIPROCESSOR */
2591 }
2592
2593 /*
2594 * sysctl helper routine for hw.usermem and hw.usermem64. values are
2595 * calculate on the fly taking into account integer overflow and the
2596 * current wired count.
2597 */
2598 static int
2599 sysctl_hw_usermem(SYSCTLFN_ARGS)
2600 {
2601 u_int ui;
2602 u_quad_t uq;
2603 struct sysctlnode node;
2604
2605 node = *rnode;
2606 switch (rnode->sysctl_num) {
2607 case HW_USERMEM:
2608 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE))
2609 ui = UINT_MAX;
2610 else
2611 ui *= PAGE_SIZE;
2612 node.sysctl_data = &ui;
2613 break;
2614 case HW_USERMEM64:
2615 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE;
2616 node.sysctl_data = &uq;
2617 break;
2618 default:
2619 return (EINVAL);
2620 }
2621
2622 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2623 }
2624
2625 /*
2626 * sysctl helper routine for kern.cnmagic node. pulls the old value
2627 * out, encoded, and stuffs the new value in for decoding.
2628 */
2629 static int
2630 sysctl_hw_cnmagic(SYSCTLFN_ARGS)
2631 {
2632 char magic[CNS_LEN];
2633 int error;
2634 struct sysctlnode node;
2635
2636 if (oldp)
2637 cn_get_magic(magic, CNS_LEN);
2638 node = *rnode;
2639 node.sysctl_data = &magic[0];
2640 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2641 if (error || newp == NULL)
2642 return (error);
2643
2644 return (cn_set_magic(magic));
2645 }
2646
2647 static int
2648 sysctl_hw_ncpu(SYSCTLFN_ARGS)
2649 {
2650 int ncpu;
2651 struct sysctlnode node;
2652
2653 ncpu = sysctl_ncpus();
2654 node = *rnode;
2655 node.sysctl_data = &ncpu;
2656
2657 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2658 }
2659
2660
2661 /*
2662 * ********************************************************************
2663 * section 3: public helper routines that are used for more than one
2664 * node
2665 * ********************************************************************
2666 */
2667
2668 /*
2669 * sysctl helper routine for the kern.root_device node and some ports'
2670 * machdep.root_device nodes.
2671 */
2672 int
2673 sysctl_root_device(SYSCTLFN_ARGS)
2674 {
2675 struct sysctlnode node;
2676
2677 node = *rnode;
2678 node.sysctl_data = root_device->dv_xname;
2679 node.sysctl_size = strlen(root_device->dv_xname) + 1;
2680 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2681 }
2682
2683 /*
2684 * sysctl helper routine for kern.consdev, dependent on the current
2685 * state of the console. also used for machdep.console_device on some
2686 * ports.
2687 */
2688 int
2689 sysctl_consdev(SYSCTLFN_ARGS)
2690 {
2691 dev_t consdev;
2692 struct sysctlnode node;
2693
2694 if (cn_tab != NULL)
2695 consdev = cn_tab->cn_dev;
2696 else
2697 consdev = NODEV;
2698 node = *rnode;
2699 node.sysctl_data = &consdev;
2700 node.sysctl_size = sizeof(consdev);
2701 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2702 }
2703
2704 /*
2705 * ********************************************************************
2706 * section 4: support for some helpers
2707 * ********************************************************************
2708 */
2709
2710 /*
2711 * Fill in a kinfo_proc2 structure for the specified process.
2712 */
2713 static void
2714 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
2715 {
2716 struct tty *tp;
2717 struct lwp *l, *l2;
2718 struct timeval ut, st, rt;
2719 sigset_t ss1, ss2;
2720
2721 memset(ki, 0, sizeof(*ki));
2722
2723 ki->p_paddr = PTRTOUINT64(p);
2724 ki->p_fd = PTRTOUINT64(p->p_fd);
2725 ki->p_cwdi = PTRTOUINT64(p->p_cwdi);
2726 ki->p_stats = PTRTOUINT64(p->p_stats);
2727 ki->p_limit = PTRTOUINT64(p->p_limit);
2728 ki->p_vmspace = PTRTOUINT64(p->p_vmspace);
2729 ki->p_sigacts = PTRTOUINT64(p->p_sigacts);
2730 ki->p_sess = PTRTOUINT64(p->p_session);
2731 ki->p_tsess = 0; /* may be changed if controlling tty below */
2732 ki->p_ru = PTRTOUINT64(p->p_ru);
2733
2734 ki->p_eflag = 0;
2735 ki->p_exitsig = p->p_exitsig;
2736
2737 ki->p_flag = sysctl_map_flags(sysctl_flagmap, p->p_flag);
2738 ki->p_flag |= sysctl_map_flags(sysctl_sflagmap, p->p_sflag);
2739 ki->p_flag |= sysctl_map_flags(sysctl_slflagmap, p->p_slflag);
2740 ki->p_flag |= sysctl_map_flags(sysctl_lflagmap, p->p_lflag);
2741 ki->p_flag |= sysctl_map_flags(sysctl_stflagmap, p->p_stflag);
2742
2743 ki->p_pid = p->p_pid;
2744 if (p->p_pptr)
2745 ki->p_ppid = p->p_pptr->p_pid;
2746 else
2747 ki->p_ppid = 0;
2748 ki->p_sid = p->p_session->s_sid;
2749 ki->p__pgid = p->p_pgrp->pg_id;
2750
2751 ki->p_tpgid = NO_PGID; /* may be changed if controlling tty below */
2752
2753 ki->p_uid = kauth_cred_geteuid(p->p_cred);
2754 ki->p_ruid = kauth_cred_getuid(p->p_cred);
2755 ki->p_gid = kauth_cred_getegid(p->p_cred);
2756 ki->p_rgid = kauth_cred_getgid(p->p_cred);
2757 ki->p_svuid = kauth_cred_getsvuid(p->p_cred);
2758 ki->p_svgid = kauth_cred_getsvgid(p->p_cred);
2759
2760 ki->p_ngroups = kauth_cred_ngroups(p->p_cred);
2761 kauth_cred_getgroups(p->p_cred, ki->p_groups,
2762 min(ki->p_ngroups, sizeof(ki->p_groups) / sizeof(ki->p_groups[0])));
2763
2764 ki->p_jobc = p->p_pgrp->pg_jobc;
2765 if ((p->p_lflag & PL_CONTROLT) && (tp = p->p_session->s_ttyp)) {
2766 ki->p_tdev = tp->t_dev;
2767 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
2768 ki->p_tsess = PTRTOUINT64(tp->t_session);
2769 } else {
2770 ki->p_tdev = NODEV;
2771 }
2772
2773 ki->p_estcpu = p->p_estcpu;
2774 ki->p_cpticks = p->p_cpticks;
2775 ki->p_pctcpu = p->p_pctcpu;
2776
2777 ki->p_uticks = p->p_uticks;
2778 ki->p_sticks = p->p_sticks;
2779 ki->p_iticks = p->p_iticks;
2780
2781 ki->p_tracep = PTRTOUINT64(p->p_tracep);
2782 ki->p_traceflag = p->p_traceflag;
2783
2784 mutex_enter(&p->p_smutex);
2785
2786 memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t));
2787 memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t));
2788
2789 ss1 = p->p_sigpend.sp_set;
2790 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
2791 /* This is hardly correct, but... */
2792 sigplusset(&l->l_sigpend.sp_set, &ss1);
2793 sigplusset(l->l_sigmask, &ss2);
2794 }
2795 memcpy(&ki->p_siglist, &ss1, sizeof(ki_sigset_t));
2796 memcpy(&ki->p_sigmask, &ss2, sizeof(ki_sigset_t));
2797
2798 ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */
2799 ki->p_realstat = p->p_stat;
2800 ki->p_nice = p->p_nice;
2801
2802 ki->p_xstat = p->p_xstat;
2803 ki->p_acflag = p->p_acflag;
2804
2805 strncpy(ki->p_comm, p->p_comm,
2806 min(sizeof(ki->p_comm), sizeof(p->p_comm)));
2807
2808 strncpy(ki->p_login, p->p_session->s_login,
2809 min(sizeof ki->p_login - 1, sizeof p->p_session->s_login));
2810
2811 ki->p_nlwps = p->p_nlwps;
2812 ki->p_realflag = ki->p_flag;
2813
2814 if (p->p_stat == SIDL || P_ZOMBIE(p)) {
2815 ki->p_vm_rssize = 0;
2816 ki->p_vm_tsize = 0;
2817 ki->p_vm_dsize = 0;
2818 ki->p_vm_ssize = 0;
2819 ki->p_nrlwps = 0;
2820 l = NULL;
2821 } else {
2822 struct vmspace *vm = p->p_vmspace;
2823 int tmp;
2824
2825 ki->p_vm_rssize = vm_resident_count(vm);
2826 ki->p_vm_tsize = vm->vm_tsize;
2827 ki->p_vm_dsize = vm->vm_dsize;
2828 ki->p_vm_ssize = vm->vm_ssize;
2829
2830 /* Pick a "representative" LWP */
2831 l = proc_representative_lwp(p, &tmp, 1);
2832 lwp_lock(l);
2833 ki->p_nrlwps = tmp;
2834 ki->p_forw = PTRTOUINT64(l->l_forw);
2835 ki->p_back = PTRTOUINT64(l->l_back);
2836 ki->p_addr = PTRTOUINT64(l->l_addr);
2837 ki->p_stat = l->l_stat;
2838 ki->p_flag |= sysctl_map_flags(sysctl_lwpflagmap, l->l_flag);
2839 ki->p_swtime = l->l_swtime;
2840 ki->p_slptime = l->l_slptime;
2841 if (l->l_stat == LSONPROC)
2842 ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags;
2843 else
2844 ki->p_schedflags = 0;
2845 ki->p_holdcnt = l->l_holdcnt;
2846 ki->p_priority = l->l_priority;
2847 ki->p_usrpri = l->l_usrpri;
2848 if (l->l_wmesg)
2849 strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg));
2850 ki->p_wchan = PTRTOUINT64(l->l_wchan);
2851 lwp_unlock(l);
2852 }
2853 if (p->p_session->s_ttyvp)
2854 ki->p_eflag |= EPROC_CTTY;
2855 if (SESS_LEADER(p))
2856 ki->p_eflag |= EPROC_SLEADER;
2857
2858 /* XXX Is this double check necessary? */
2859 if (P_ZOMBIE(p)) {
2860 ki->p_uvalid = 0;
2861 ki->p_rtime_sec = 0;
2862 ki->p_rtime_usec = 0;
2863 } else {
2864 ki->p_uvalid = 1;
2865
2866 ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
2867 ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
2868
2869 calcru(p, &ut, &st, NULL, &rt);
2870 ki->p_rtime_sec = rt.tv_sec;
2871 ki->p_rtime_usec = rt.tv_usec;
2872 ki->p_uutime_sec = ut.tv_sec;
2873 ki->p_uutime_usec = ut.tv_usec;
2874 ki->p_ustime_sec = st.tv_sec;
2875 ki->p_ustime_usec = st.tv_usec;
2876
2877 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
2878 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
2879 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
2880 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
2881 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
2882 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
2883 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
2884 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
2885 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
2886 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
2887 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
2888 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
2889
2890 ki->p_uru_nvcsw = 0;
2891 ki->p_uru_nivcsw = 0;
2892 LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
2893 ki->p_uru_nvcsw += l->l_nvcsw;
2894 ki->p_uru_nivcsw += l->l_nivcsw;
2895 }
2896
2897 timeradd(&p->p_stats->p_cru.ru_utime,
2898 &p->p_stats->p_cru.ru_stime, &ut);
2899 ki->p_uctime_sec = ut.tv_sec;
2900 ki->p_uctime_usec = ut.tv_usec;
2901 }
2902 #ifdef MULTIPROCESSOR
2903 if (l != NULL)
2904 ki->p_cpuid = l->l_cpu->ci_cpuid;
2905 else
2906 #endif
2907 ki->p_cpuid = KI_NOCPU;
2908
2909 mutex_exit(&p->p_smutex);
2910 }
2911
2912 /*
2913 * Fill in a kinfo_lwp structure for the specified lwp.
2914 */
2915 static void
2916 fill_lwp(struct lwp *l, struct kinfo_lwp *kl)
2917 {
2918
2919 kl->l_forw = PTRTOUINT64(l->l_forw);
2920 kl->l_back = PTRTOUINT64(l->l_back);
2921 kl->l_laddr = PTRTOUINT64(l);
2922 kl->l_addr = PTRTOUINT64(l->l_addr);
2923 kl->l_stat = l->l_stat;
2924 kl->l_lid = l->l_lid;
2925 kl->l_flag = l->l_flag;
2926
2927 kl->l_swtime = l->l_swtime;
2928 kl->l_slptime = l->l_slptime;
2929 if (l->l_stat == LSONPROC)
2930 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags;
2931 else
2932 kl->l_schedflags = 0;
2933 kl->l_holdcnt = l->l_holdcnt;
2934 kl->l_priority = l->l_priority;
2935 kl->l_usrpri = l->l_usrpri;
2936 if (l->l_wmesg)
2937 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg));
2938 kl->l_wchan = PTRTOUINT64(l->l_wchan);
2939 #ifdef MULTIPROCESSOR
2940 kl->l_cpuid = l->l_cpu->ci_cpuid;
2941 #else
2942 kl->l_cpuid = KI_NOCPU;
2943 #endif
2944 }
2945
2946 /*
2947 * Fill in an eproc structure for the specified process.
2948 */
2949 void
2950 fill_eproc(struct proc *p, struct eproc *ep)
2951 {
2952 struct tty *tp;
2953 struct lwp *l;
2954
2955 ep->e_paddr = p;
2956 ep->e_sess = p->p_session;
2957 kauth_cred_topcred(p->p_cred, &ep->e_pcred);
2958 kauth_cred_toucred(p->p_cred, &ep->e_ucred);
2959 if (p->p_stat == SIDL || P_ZOMBIE(p)) {
2960 ep->e_vm.vm_rssize = 0;
2961 ep->e_vm.vm_tsize = 0;
2962 ep->e_vm.vm_dsize = 0;
2963 ep->e_vm.vm_ssize = 0;
2964 /* ep->e_vm.vm_pmap = XXX; */
2965 } else {
2966 struct vmspace *vm = p->p_vmspace;
2967
2968 ep->e_vm.vm_rssize = vm_resident_count(vm);
2969 ep->e_vm.vm_tsize = vm->vm_tsize;
2970 ep->e_vm.vm_dsize = vm->vm_dsize;
2971 ep->e_vm.vm_ssize = vm->vm_ssize;
2972
2973 /* Pick a "representative" LWP */
2974 mutex_enter(&p->p_smutex);
2975 l = proc_representative_lwp(p, NULL, 1);
2976 lwp_lock(l);
2977 if (l->l_wmesg)
2978 strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN);
2979 lwp_unlock(l);
2980 mutex_exit(&p->p_smutex);
2981 }
2982 if (p->p_pptr)
2983 ep->e_ppid = p->p_pptr->p_pid;
2984 else
2985 ep->e_ppid = 0;
2986 ep->e_pgid = p->p_pgrp->pg_id;
2987 ep->e_sid = ep->e_sess->s_sid;
2988 ep->e_jobc = p->p_pgrp->pg_jobc;
2989 if ((p->p_lflag & PL_CONTROLT) &&
2990 (tp = ep->e_sess->s_ttyp)) {
2991 ep->e_tdev = tp->t_dev;
2992 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
2993 ep->e_tsess = tp->t_session;
2994 } else
2995 ep->e_tdev = NODEV;
2996
2997 ep->e_xsize = ep->e_xrssize = 0;
2998 ep->e_xccount = ep->e_xswrss = 0;
2999 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
3000 if (SESS_LEADER(p))
3001 ep->e_flag |= EPROC_SLEADER;
3002 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME);
3003 }
3004
3005 u_int
3006 sysctl_map_flags(const u_int *map, u_int word)
3007 {
3008 u_int rv;
3009
3010 for (rv = 0; *map != 0; map += 2)
3011 if ((word & map[0]) != 0)
3012 rv |= map[1];
3013
3014 return rv;
3015 }
3016