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