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