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