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