init_sysctl.c revision 1.20
1/*	$NetBSD: init_sysctl.c,v 1.20 2004/01/17 03:33:24 atatat 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.20 2004/01/17 03:33:24 atatat Exp $");
41
42#include "opt_sysv.h"
43#include "opt_multiprocessor.h"
44#include "opt_posix.h"
45#include "pty.h"
46#include "rnd.h"
47
48#include <sys/types.h>
49#include <sys/param.h>
50#include <sys/sysctl.h>
51#include <sys/errno.h>
52#include <sys/systm.h>
53#include <sys/kernel.h>
54#include <sys/unistd.h>
55#include <sys/disklabel.h>
56#include <sys/rnd.h>
57#include <sys/vnode.h>
58#include <sys/mount.h>
59#include <sys/namei.h>
60#include <sys/msgbuf.h>
61#include <dev/cons.h>
62#include <sys/socketvar.h>
63#include <sys/file.h>
64#include <sys/tty.h>
65#include <sys/malloc.h>
66#include <sys/resource.h>
67#include <sys/resourcevar.h>
68#include <sys/exec.h>
69#include <sys/conf.h>
70#include <sys/device.h>
71
72#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
73#include <sys/ipc.h>
74#endif
75#ifdef SYSVMSG
76#include <sys/msg.h>
77#endif
78#ifdef SYSVSEM
79#include <sys/sem.h>
80#endif
81#ifdef SYSVSHM
82#include <sys/shm.h>
83#endif
84
85#include <machine/cpu.h>
86
87/*
88 * try over estimating by 5 procs/lwps
89 */
90#define KERN_PROCSLOP	(5 * sizeof(struct kinfo_proc))
91#define KERN_LWPSLOP	(5 * sizeof(struct kinfo_lwp))
92
93/*
94 * convert pointer to 64 int for struct kinfo_proc2
95 */
96#define PTRTOINT64(foo)	((u_int64_t)(uintptr_t)(foo))
97
98#ifndef MULTIPROCESSOR
99#define	sysctl_ncpus()	(1)
100#else /* MULTIPROCESSOR */
101#ifndef CPU_INFO_FOREACH
102#define CPU_INFO_ITERATOR int
103#define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL
104#endif
105static int
106sysctl_ncpus(void)
107{
108	struct cpu_info *ci;
109	CPU_INFO_ITERATOR cii;
110
111	int ncpus = 0;
112	for (CPU_INFO_FOREACH(cii, ci))
113		ncpus++;
114	return (ncpus);
115}
116#endif /* MULTIPROCESSOR */
117
118static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
119static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
120static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
121static int sysctl_kern_securelevel(SYSCTLFN_PROTO);
122static int sysctl_kern_hostid(SYSCTLFN_PROTO);
123static int sysctl_setlen(SYSCTLFN_PROTO);
124static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
125static int sysctl_kern_file(SYSCTLFN_PROTO);
126static int sysctl_kern_autonice(SYSCTLFN_PROTO);
127static int sysctl_msgbuf(SYSCTLFN_PROTO);
128static int sysctl_kern_defcorename(SYSCTLFN_PROTO);
129static int sysctl_kern_cptime(SYSCTLFN_PROTO);
130#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
131static int sysctl_kern_sysvipc(SYSCTLFN_PROTO);
132#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
133#if NPTY > 0
134static int sysctl_kern_maxptys(SYSCTLFN_PROTO);
135#endif /* NPTY > 0 */
136static int sysctl_kern_sbmax(SYSCTLFN_PROTO);
137static int sysctl_kern_urnd(SYSCTLFN_PROTO);
138static int sysctl_kern_lwp(SYSCTLFN_PROTO);
139static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
140static int sysctl_kern_somaxkva(SYSCTLFN_PROTO);
141static int sysctl_kern_root_partition(SYSCTLFN_PROTO);
142static int sysctl_kern_drivers(SYSCTLFN_PROTO);
143static int sysctl_doeproc(SYSCTLFN_PROTO);
144static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
145static int sysctl_hw_usermem(SYSCTLFN_PROTO);
146static int sysctl_hw_cnmagic(SYSCTLFN_PROTO);
147static int sysctl_hw_ncpu(SYSCTLFN_PROTO);
148
149static void fill_kproc2(struct proc *, struct kinfo_proc2 *);
150static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl);
151
152/*
153 * ********************************************************************
154 * section 1: setup routines
155 * ********************************************************************
156 * these functions are stuffed into a link set for sysctl setup
157 * functions.  they're never called or referenced from anywhere else.
158 * ********************************************************************
159 */
160
161/*
162 * sets up the base nodes...
163 */
164SYSCTL_SETUP(sysctl_root_setup, "sysctl base setup")
165{
166
167	sysctl_createv(SYSCTL_PERMANENT,
168		       CTLTYPE_NODE, "kern", NULL,
169		       NULL, 0, NULL, 0,
170		       CTL_KERN, CTL_EOL);
171	sysctl_createv(SYSCTL_PERMANENT,
172		       CTLTYPE_NODE, "vm", NULL,
173		       NULL, 0, NULL, 0,
174		       CTL_VM, CTL_EOL);
175	sysctl_createv(SYSCTL_PERMANENT,
176		       CTLTYPE_NODE, "vfs", NULL,
177		       NULL, 0, NULL, 0,
178		       CTL_VFS, CTL_EOL);
179	sysctl_createv(SYSCTL_PERMANENT,
180		       CTLTYPE_NODE, "net", NULL,
181		       NULL, 0, NULL, 0,
182		       CTL_NET, CTL_EOL);
183	sysctl_createv(SYSCTL_PERMANENT,
184		       CTLTYPE_NODE, "debug", NULL,
185		       NULL, 0, NULL, 0,
186		       CTL_DEBUG, CTL_EOL);
187	sysctl_createv(SYSCTL_PERMANENT,
188		       CTLTYPE_NODE, "hw", NULL,
189		       NULL, 0, NULL, 0,
190		       CTL_HW, CTL_EOL);
191	sysctl_createv(SYSCTL_PERMANENT,
192		       CTLTYPE_NODE, "machdep", NULL,
193		       NULL, 0, NULL, 0,
194		       CTL_MACHDEP, CTL_EOL);
195	/*
196	 * this node is inserted so that the sysctl nodes in libc can
197	 * operate.
198	 */
199	sysctl_createv(SYSCTL_PERMANENT,
200		       CTLTYPE_NODE, "user", NULL,
201		       NULL, 0, NULL, 0,
202		       CTL_USER, CTL_EOL);
203	sysctl_createv(SYSCTL_PERMANENT,
204		       CTLTYPE_NODE, "ddb", NULL,
205		       NULL, 0, NULL, 0,
206		       CTL_DDB, CTL_EOL);
207	sysctl_createv(SYSCTL_PERMANENT,
208		       CTLTYPE_NODE, "proc", NULL,
209		       NULL, 0, NULL, 0,
210		       CTL_PROC, CTL_EOL);
211	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
212		       CTLTYPE_NODE, "vendor", NULL,
213		       NULL, 0, NULL, 0,
214		       CTL_VENDOR, CTL_EOL);
215	sysctl_createv(SYSCTL_PERMANENT,
216		       CTLTYPE_NODE, "emul", NULL,
217		       NULL, 0, NULL, 0,
218		       CTL_EMUL, CTL_EOL);
219}
220
221/*
222 * this setup routine is a replacement for kern_sysctl()
223 */
224SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup")
225{
226	extern int kern_logsigexit;	/* defined in kern/kern_sig.c */
227	extern fixpt_t ccpu;		/* defined in kern/kern_synch.c */
228	extern int dumponpanic;		/* defined in kern/subr_prf.c */
229
230	sysctl_createv(SYSCTL_PERMANENT,
231		       CTLTYPE_NODE, "kern", NULL,
232		       NULL, 0, NULL, 0,
233		       CTL_KERN, CTL_EOL);
234
235	sysctl_createv(SYSCTL_PERMANENT,
236		       CTLTYPE_STRING, "ostype", NULL,
237		       NULL, 0, &ostype, 0,
238		       CTL_KERN, KERN_OSTYPE, CTL_EOL);
239	sysctl_createv(SYSCTL_PERMANENT,
240		       CTLTYPE_STRING, "osrelease", NULL,
241		       NULL, 0, &osrelease, 0,
242		       CTL_KERN, KERN_OSRELEASE, CTL_EOL);
243	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
244		       CTLTYPE_INT, "osrevision", NULL,
245		       NULL, __NetBSD_Version__, NULL, 0,
246		       CTL_KERN, KERN_OSREV, CTL_EOL);
247	sysctl_createv(SYSCTL_PERMANENT,
248		       CTLTYPE_STRING, "version", NULL,
249		       NULL, 0, &version, 0,
250		       CTL_KERN, KERN_VERSION, CTL_EOL);
251	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
252		       CTLTYPE_INT, "maxvnodes", NULL,
253		       sysctl_kern_maxvnodes, 0, NULL, 0,
254		       CTL_KERN, KERN_MAXVNODES, CTL_EOL);
255	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
256		       CTLTYPE_INT, "maxproc", NULL,
257		       sysctl_kern_maxproc, 0, NULL, 0,
258		       CTL_KERN, KERN_MAXPROC, CTL_EOL);
259	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
260		       CTLTYPE_INT, "maxfiles", NULL,
261		       NULL, 0, &maxfiles, 0,
262		       CTL_KERN, KERN_MAXFILES, CTL_EOL);
263	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
264		       CTLTYPE_INT, "argmax", NULL,
265		       NULL, ARG_MAX, NULL, 0,
266		       CTL_KERN, KERN_ARGMAX, CTL_EOL);
267	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
268		       CTLTYPE_INT, "securelevel", NULL,
269		       sysctl_kern_securelevel, 0, &securelevel, 0,
270		       CTL_KERN, KERN_SECURELVL, CTL_EOL);
271	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
272		       CTLTYPE_STRING, "hostname", NULL,
273		       sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN,
274		       CTL_KERN, KERN_HOSTNAME, CTL_EOL);
275	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
276		       CTLTYPE_INT, "hostid", NULL,
277		       sysctl_kern_hostid, 0, NULL, 0,
278		       CTL_KERN, KERN_HOSTID, CTL_EOL);
279	sysctl_createv(SYSCTL_PERMANENT,
280		       CTLTYPE_STRUCT, "clockrate", NULL,
281		       sysctl_kern_clockrate, 0, NULL,
282		       sizeof(struct clockinfo),
283		       CTL_KERN, KERN_CLOCKRATE, CTL_EOL);
284	sysctl_createv(SYSCTL_PERMANENT,
285		       CTLTYPE_STRUCT, "vnode", NULL,
286		       sysctl_kern_vnode, 0, NULL, 0,
287		       CTL_KERN, KERN_VNODE, CTL_EOL);
288	sysctl_createv(SYSCTL_PERMANENT,
289		       CTLTYPE_STRUCT, "file", NULL,
290		       sysctl_kern_file, 0, NULL, 0,
291		       CTL_KERN, KERN_FILE, CTL_EOL);
292#ifndef GPROF
293	sysctl_createv(SYSCTL_PERMANENT,
294		       CTLTYPE_NODE, "profiling", NULL,
295		       sysctl_notavail, 0, NULL, 0,
296		       CTL_KERN, KERN_PROF, CTL_EOL);
297#endif
298	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
299		       CTLTYPE_INT, "posix1version", NULL,
300		       NULL, _POSIX_VERSION, NULL, 0,
301		       CTL_KERN, KERN_POSIX1, CTL_EOL);
302	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
303		       CTLTYPE_INT, "ngroups", NULL,
304		       NULL, NGROUPS_MAX, NULL, 0,
305		       CTL_KERN, KERN_NGROUPS, CTL_EOL);
306	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
307		       CTLTYPE_INT, "job_control", NULL,
308		       NULL, 1, NULL, 0,
309		       CTL_KERN, KERN_JOB_CONTROL, CTL_EOL);
310	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
311		       CTLTYPE_INT, "saved_ids", NULL, NULL,
312#ifdef _POSIX_SAVED_IDS
313		       1,
314#else /* _POSIX_SAVED_IDS */
315		       0,
316#endif /* _POSIX_SAVED_IDS */
317		       NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL);
318	sysctl_createv(SYSCTL_PERMANENT,
319		       CTLTYPE_STRUCT, "boottime", NULL,
320		       NULL, 0, &boottime, sizeof(boottime),
321		       CTL_KERN, KERN_BOOTTIME, CTL_EOL);
322	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
323		       CTLTYPE_STRING, "domainname", NULL,
324		       sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN,
325		       CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
326	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
327		       CTLTYPE_INT, "maxpartitions", NULL,
328		       NULL, MAXPARTITIONS, NULL, 0,
329		       CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL);
330	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
331		       CTLTYPE_INT, "rawpartition", NULL,
332		       NULL, RAW_PART, NULL, 0,
333		       CTL_KERN, KERN_RAWPARTITION, CTL_EOL);
334	sysctl_createv(SYSCTL_PERMANENT,
335		       CTLTYPE_STRUCT, "timex", NULL,
336		       sysctl_notavail, 0, NULL, 0,
337		       CTL_KERN, KERN_TIMEX, CTL_EOL);
338	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
339		       CTLTYPE_INT, "autonicetime", NULL,
340		       sysctl_kern_autonice, 0, &autonicetime, 0,
341		       CTL_KERN, KERN_AUTONICETIME, CTL_EOL);
342	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
343		       CTLTYPE_INT, "autoniceval", NULL,
344		       sysctl_kern_autonice, 0, &autoniceval, 0,
345		       CTL_KERN, KERN_AUTONICEVAL, CTL_EOL);
346	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
347		       CTLTYPE_INT, "rtc_offset", NULL,
348		       sysctl_kern_rtc_offset, 0, &rtc_offset, 0,
349		       CTL_KERN, KERN_RTC_OFFSET, CTL_EOL);
350	sysctl_createv(SYSCTL_PERMANENT,
351		       CTLTYPE_STRING, "root_device", NULL,
352		       sysctl_root_device, 0, NULL, 0,
353		       CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL);
354	sysctl_createv(SYSCTL_PERMANENT,
355		       CTLTYPE_INT, "msgbufsize", NULL,
356		       sysctl_msgbuf, 0, &msgbufp->msg_bufs, 0,
357		       CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL);
358	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
359		       CTLTYPE_INT, "fsync", NULL,
360		       NULL, 1, NULL, 0,
361		       CTL_KERN, KERN_FSYNC, CTL_EOL);
362	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
363		       CTLTYPE_INT, "sysvmsg", NULL, NULL,
364#ifdef SYSVMSG
365		       1,
366#else /* SYSVMSG */
367		       0,
368#endif /* SYSVMSG */
369		       NULL, 0, CTL_KERN, KERN_SYSVMSG, CTL_EOL);
370	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
371		       CTLTYPE_INT, "sysvsem", NULL, NULL,
372#ifdef SYSVSEM
373		       1,
374#else /* SYSVSEM */
375		       0,
376#endif /* SYSVSEM */
377		       NULL, 0, CTL_KERN, KERN_SYSVSEM, CTL_EOL);
378	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
379		       CTLTYPE_INT, "sysvshm", NULL, NULL,
380#ifdef SYSVSHM
381		       1,
382#else /* SYSVSHM */
383		       0,
384#endif /* SYSVSHM */
385		       NULL, 0, CTL_KERN, KERN_SYSVSHM, CTL_EOL);
386	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
387		       CTLTYPE_INT, "synchronized_io", NULL,
388		       NULL, 1, NULL, 0,
389		       CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL);
390	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
391		       CTLTYPE_INT, "iov_max", NULL,
392		       NULL, IOV_MAX, NULL, 0,
393		       CTL_KERN, KERN_IOV_MAX, CTL_EOL);
394	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
395		       CTLTYPE_INT, "mapped_files", NULL,
396		       NULL, 1, NULL, 0,
397		       CTL_KERN, KERN_MAPPED_FILES, CTL_EOL);
398	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
399		       CTLTYPE_INT, "memlock", NULL,
400		       NULL, 1, NULL, 0,
401		       CTL_KERN, KERN_MEMLOCK, CTL_EOL);
402	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
403		       CTLTYPE_INT, "memlock_range", NULL,
404		       NULL, 1, NULL, 0,
405		       CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL);
406	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
407		       CTLTYPE_INT, "memory_protection", NULL,
408		       NULL, 1, NULL, 0,
409		       CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL);
410	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
411		       CTLTYPE_INT, "login_name_max", NULL,
412		       NULL, LOGIN_NAME_MAX, NULL, 0,
413		       CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL);
414	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
415		       CTLTYPE_STRING, "defcorename", NULL,
416		       sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN,
417		       CTL_KERN, KERN_DEFCORENAME, CTL_EOL);
418	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
419		       CTLTYPE_INT, "logsigexit", NULL,
420		       NULL, 0, &kern_logsigexit, 0,
421		       CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL);
422	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
423		       CTLTYPE_INT, "fscale", NULL,
424		       NULL, FSCALE, NULL, 0,
425		       CTL_KERN, KERN_FSCALE, CTL_EOL);
426	sysctl_createv(SYSCTL_PERMANENT,
427		       CTLTYPE_INT, "ccpu", NULL,
428		       NULL, 0, &ccpu, 0,
429		       CTL_KERN, KERN_CCPU, CTL_EOL);
430	sysctl_createv(SYSCTL_PERMANENT,
431		       CTLTYPE_STRUCT, "cp_time", NULL,
432		       sysctl_kern_cptime, 0, NULL, 0,
433		       CTL_KERN, KERN_CP_TIME, CTL_EOL);
434#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
435	sysctl_createv(SYSCTL_PERMANENT,
436		       CTLTYPE_STRUCT, "sysvipc_info", NULL,
437		       sysctl_kern_sysvipc, 0, NULL, 0,
438		       CTL_KERN, KERN_SYSVIPC_INFO, CTL_EOL);
439#endif /* SYSVMSG || SYSVSEM || SYSVSHM */
440	sysctl_createv(SYSCTL_PERMANENT,
441		       CTLTYPE_INT, "msgbuf", NULL,
442		       sysctl_msgbuf, 0, NULL, 0,
443		       CTL_KERN, KERN_MSGBUF, CTL_EOL);
444	sysctl_createv(SYSCTL_PERMANENT,
445		       CTLTYPE_STRUCT, "consdev", NULL,
446		       sysctl_consdev, 0, NULL, sizeof(dev_t),
447		       CTL_KERN, KERN_CONSDEV, CTL_EOL);
448#if NPTY > 0
449	sysctl_createv(SYSCTL_PERMANENT,
450		       CTLTYPE_INT, "maxptys", NULL,
451		       sysctl_kern_maxptys, 0, NULL, 0,
452		       CTL_KERN, KERN_MAXPTYS, CTL_EOL);
453#endif /* NPTY > 0 */
454	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
455		       CTLTYPE_INT, "maxphys", NULL,
456		       NULL, MAXPHYS, NULL, 0,
457		       CTL_KERN, KERN_MAXPHYS, CTL_EOL);
458	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
459		       CTLTYPE_INT, "sbmax", NULL,
460		       sysctl_kern_sbmax, 0, NULL, 0,
461		       CTL_KERN, KERN_SBMAX, CTL_EOL);
462	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
463		       CTLTYPE_INT, "monotonic_clock", NULL,
464		       /* XXX _POSIX_VERSION */
465		       NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0,
466		       CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL);
467	sysctl_createv(SYSCTL_PERMANENT,
468		       CTLTYPE_INT, "urandom", NULL,
469		       sysctl_kern_urnd, 0, NULL, 0,
470		       CTL_KERN, KERN_URND, CTL_EOL);
471	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
472		       CTLTYPE_INT, "labelsector", NULL,
473		       NULL, LABELSECTOR, NULL, 0,
474		       CTL_KERN, KERN_LABELSECTOR, CTL_EOL);
475	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
476		       CTLTYPE_INT, "labeloffset", NULL,
477		       NULL, LABELOFFSET, NULL, 0,
478		       CTL_KERN, KERN_LABELOFFSET, CTL_EOL);
479	sysctl_createv(SYSCTL_PERMANENT,
480		       CTLTYPE_NODE, "lwp", NULL,
481		       sysctl_kern_lwp, 0, NULL, 0,
482		       CTL_KERN, KERN_LWP, CTL_EOL);
483	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
484		       CTLTYPE_INT, "forkfsleep", NULL,
485		       sysctl_kern_forkfsleep, 0, NULL, 0,
486		       CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
487	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
488		       CTLTYPE_INT, "posix_threads", NULL,
489		       /* XXX _POSIX_VERSION */
490		       NULL, _POSIX_THREADS, NULL, 0,
491		       CTL_KERN, KERN_POSIX_THREADS, CTL_EOL);
492	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
493		       CTLTYPE_INT, "posix_semaphores", NULL, NULL,
494#ifdef P1003_1B_SEMAPHORE
495		       200112,
496#else /* P1003_1B_SEMAPHORE */
497		       0,
498#endif /* P1003_1B_SEMAPHORE */
499		       NULL, 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL);
500	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
501		       CTLTYPE_INT, "posix_barriers", NULL,
502		       /* XXX _POSIX_VERSION */
503		       NULL, _POSIX_BARRIERS, NULL, 0,
504		       CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL);
505	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
506		       CTLTYPE_INT, "posix_timers", NULL,
507		       /* XXX _POSIX_VERSION */
508		       NULL, _POSIX_TIMERS, NULL, 0,
509		       CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL);
510	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
511		       CTLTYPE_INT, "posix_spin_locks", NULL,
512		       /* XXX _POSIX_VERSION */
513		       NULL, _POSIX_SPIN_LOCKS, NULL, 0,
514		       CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL);
515	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
516		       CTLTYPE_INT, "posix_reader_writer_locks", NULL,
517		       /* XXX _POSIX_VERSION */
518		       NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0,
519		       CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL);
520	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
521		       CTLTYPE_INT, "dump_on_panic", NULL,
522		       NULL, 0, &dumponpanic, 0,
523		       CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL);
524	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
525		       CTLTYPE_INT, "somaxkva", NULL,
526		       sysctl_kern_somaxkva, 0, NULL, 0,
527		       CTL_KERN, KERN_SOMAXKVA, CTL_EOL);
528	sysctl_createv(SYSCTL_PERMANENT,
529		       CTLTYPE_INT, "root_partition", NULL,
530		       sysctl_kern_root_partition, 0, NULL, 0,
531		       CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL);
532	sysctl_createv(SYSCTL_PERMANENT,
533		       CTLTYPE_STRUCT, "drivers", NULL,
534		       sysctl_kern_drivers, 0, NULL, 0,
535		       CTL_KERN, KERN_DRIVERS, CTL_EOL);
536}
537
538SYSCTL_SETUP(sysctl_kern_proc_setup,
539	     "sysctl kern.proc/proc2/proc_args subtree setup")
540{
541
542	sysctl_createv(SYSCTL_PERMANENT,
543		       CTLTYPE_NODE, "kern", NULL,
544		       NULL, 0, NULL, 0,
545		       CTL_KERN, CTL_EOL);
546
547	sysctl_createv(SYSCTL_PERMANENT,
548		       CTLTYPE_NODE, "proc", NULL,
549		       sysctl_doeproc, 0, NULL, 0,
550		       CTL_KERN, KERN_PROC, CTL_EOL);
551	sysctl_createv(SYSCTL_PERMANENT,
552		       CTLTYPE_NODE, "proc2", NULL,
553		       sysctl_doeproc, 0, NULL, 0,
554		       CTL_KERN, KERN_PROC2, CTL_EOL);
555	sysctl_createv(SYSCTL_PERMANENT,
556		       CTLTYPE_NODE, "proc_args", NULL,
557		       sysctl_kern_proc_args, 0, NULL, 0,
558		       CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
559
560	/*
561	  "nodes" under these:
562
563	  KERN_PROC_ALL
564	  KERN_PROC_PID pid
565	  KERN_PROC_PGRP pgrp
566	  KERN_PROC_SESSION sess
567	  KERN_PROC_TTY tty
568	  KERN_PROC_UID uid
569	  KERN_PROC_RUID uid
570	  KERN_PROC_GID gid
571	  KERN_PROC_RGID gid
572
573	  all in all, probably not worth the effort...
574	*/
575}
576
577SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
578{
579	u_int u;
580	u_quad_t q;
581
582	sysctl_createv(SYSCTL_PERMANENT,
583		       CTLTYPE_NODE, "hw", NULL,
584		       NULL, 0, NULL, 0,
585		       CTL_HW, CTL_EOL);
586
587	sysctl_createv(SYSCTL_PERMANENT,
588		       CTLTYPE_STRING, "machine", NULL,
589		       NULL, 0, machine, 0,
590		       CTL_HW, HW_MACHINE, CTL_EOL);
591	sysctl_createv(SYSCTL_PERMANENT,
592		       CTLTYPE_STRING, "model", NULL,
593		       NULL, 0, cpu_model, 0,
594		       CTL_HW, HW_MODEL, CTL_EOL);
595	sysctl_createv(SYSCTL_PERMANENT,
596		       CTLTYPE_INT, "ncpu", NULL,
597		       sysctl_hw_ncpu, 0, NULL, 0,
598		       CTL_HW, HW_NCPU, CTL_EOL);
599	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
600		       CTLTYPE_INT, "byteorder", NULL,
601		       NULL, BYTE_ORDER, NULL, 0,
602		       CTL_HW, HW_BYTEORDER, CTL_EOL);
603	u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ?
604		UINT_MAX : physmem * PAGE_SIZE;
605	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
606		       CTLTYPE_INT, "physmem", NULL,
607		       NULL, u, NULL, 0,
608		       CTL_HW, HW_PHYSMEM, CTL_EOL);
609	sysctl_createv(SYSCTL_PERMANENT,
610		       CTLTYPE_INT, "usermem", NULL,
611		       sysctl_hw_usermem, 0, NULL, 0,
612		       CTL_HW, HW_USERMEM, CTL_EOL);
613	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
614		       CTLTYPE_INT, "pagesize", NULL,
615		       NULL, PAGE_SIZE, NULL, 0,
616		       CTL_HW, HW_PAGESIZE, CTL_EOL);
617	sysctl_createv(SYSCTL_PERMANENT,
618		       CTLTYPE_STRING, "disknames", NULL,
619		       sysctl_hw_disknames, 0, NULL, 0,
620		       CTL_HW, HW_DISKNAMES, CTL_EOL);
621	sysctl_createv(SYSCTL_PERMANENT,
622		       CTLTYPE_STRUCT, "diskstats", NULL,
623		       sysctl_hw_diskstats, 0, NULL, 0,
624		       CTL_HW, HW_DISKSTATS, CTL_EOL);
625	sysctl_createv(SYSCTL_PERMANENT,
626		       CTLTYPE_STRING, "machine_arch", NULL,
627		       NULL, 0, machine_arch, 0,
628		       CTL_HW, HW_MACHINE_ARCH, CTL_EOL);
629	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
630		       CTLTYPE_INT, "alignbytes", NULL,
631		       NULL, ALIGNBYTES, NULL, 0,
632		       CTL_HW, HW_ALIGNBYTES, CTL_EOL);
633	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE|SYSCTL_HEX,
634		       CTLTYPE_STRING, "cnmagic", NULL,
635		       sysctl_hw_cnmagic, 0, NULL, CNS_LEN,
636		       CTL_HW, HW_CNMAGIC, CTL_EOL);
637	q = (u_quad_t)physmem * PAGE_SIZE;
638	sysctl_createv(SYSCTL_PERMANENT|SYSCTL_IMMEDIATE,
639		       CTLTYPE_QUAD, "physmem64", NULL,
640		       NULL, q, NULL, 0,
641		       CTL_HW, HW_PHYSMEM64, CTL_EOL);
642	sysctl_createv(SYSCTL_PERMANENT,
643		       CTLTYPE_QUAD, "usermem64", NULL,
644		       sysctl_hw_usermem, 0, NULL, 0,
645		       CTL_HW, HW_USERMEM64, CTL_EOL);
646}
647
648#ifdef DEBUG
649/*
650 * Debugging related system variables.
651 */
652struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4;
653struct ctldebug debug5, debug6, debug7, debug8, debug9;
654struct ctldebug debug10, debug11, debug12, debug13, debug14;
655struct ctldebug debug15, debug16, debug17, debug18, debug19;
656static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
657	&debug0, &debug1, &debug2, &debug3, &debug4,
658	&debug5, &debug6, &debug7, &debug8, &debug9,
659	&debug10, &debug11, &debug12, &debug13, &debug14,
660	&debug15, &debug16, &debug17, &debug18, &debug19,
661};
662
663/*
664 * this setup routine is a replacement for debug_sysctl()
665 *
666 * note that it creates several nodes per defined debug variable
667 */
668SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup")
669{
670	struct ctldebug *cdp;
671	char nodename[20];
672	int i;
673
674	/*
675	 * two ways here:
676	 *
677	 * the "old" way (debug.name -> value) which was emulated by
678	 * the sysctl(8) binary
679	 *
680	 * the new way, which the sysctl(8) binary was actually using
681
682	 node	debug
683	 node	debug.0
684	 string	debug.0.name
685	 int	debug.0.value
686	 int	debug.name
687
688	 */
689
690	sysctl_createv(SYSCTL_PERMANENT,
691		       CTLTYPE_NODE, "debug", NULL,
692		       NULL, 0, NULL, 0,
693		       CTL_DEBUG, CTL_EOL);
694
695	for (i = 0; i < CTL_DEBUG_MAXID; i++) {
696		cdp = debugvars[i];
697		if (cdp->debugname == NULL || cdp->debugvar == NULL)
698			continue;
699
700		snprintf(nodename, sizeof(nodename), "debug%d", i);
701		sysctl_createv(SYSCTL_PERMANENT|SYSCTL_HIDDEN,
702			       CTLTYPE_NODE, nodename, NULL,
703			       NULL, 0, NULL, 0,
704			       CTL_DEBUG, i, CTL_EOL);
705		sysctl_createv(SYSCTL_PERMANENT|SYSCTL_HIDDEN,
706			       CTLTYPE_STRING, "name", NULL,
707			       NULL, 0, cdp->debugname, 0,
708			       CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL);
709		sysctl_createv(SYSCTL_PERMANENT|SYSCTL_HIDDEN,
710			       CTLTYPE_INT, "value", NULL,
711			       NULL, 0, cdp->debugvar, 0,
712			       CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL);
713		sysctl_createv(SYSCTL_PERMANENT,
714			       CTLTYPE_INT, cdp->debugname, NULL,
715			       NULL, 0, cdp->debugvar, 0,
716			       CTL_DEBUG, CTL_CREATE, CTL_EOL);
717	}
718}
719#endif /* DEBUG */
720
721/*
722 * ********************************************************************
723 * section 2: private node-specific helper routines.
724 * ********************************************************************
725 */
726
727/*
728 * sysctl helper routine for kern.maxvnodes.  drain vnodes if
729 * new value is lower than desiredvnodes and then calls reinit
730 * routines that needs to adjust to the new value.
731 */
732static int
733sysctl_kern_maxvnodes(SYSCTLFN_ARGS)
734{
735	int error, new_vnodes, old_vnodes;
736	struct sysctlnode node;
737
738	new_vnodes = desiredvnodes;
739	node = *rnode;
740	node.sysctl_data = &new_vnodes;
741	error = sysctl_lookup(SYSCTLFN_CALL(&node));
742	if (error || newp == NULL)
743		return (error);
744
745	old_vnodes = desiredvnodes;
746	desiredvnodes = new_vnodes;
747	if (new_vnodes < old_vnodes) {
748		error = vfs_drainvnodes(new_vnodes, l->l_proc);
749		if (error) {
750			desiredvnodes = old_vnodes;
751			return (error);
752		}
753	}
754	vfs_reinit();
755	nchreinit();
756
757	return (0);
758}
759
760/*
761 * sysctl helper routine for rtc_offset - set time after changes
762 */
763static int
764sysctl_kern_rtc_offset(SYSCTLFN_ARGS)
765{
766	struct timeval tv, delta;
767	int s, error, new_rtc_offset;
768	struct sysctlnode node;
769
770	new_rtc_offset = rtc_offset;
771	node = *rnode;
772	node.sysctl_data = &new_rtc_offset;
773	error = sysctl_lookup(SYSCTLFN_CALL(&node));
774	if (error || newp == NULL)
775		return (error);
776
777	if (securelevel > 0)
778		return (EPERM);
779	if (rtc_offset == new_rtc_offset)
780		return (0);
781
782	/* if we change the offset, adjust the time */
783	s = splclock();
784	tv = time;
785	splx(s);
786	delta.tv_sec = 60*(new_rtc_offset - rtc_offset);
787	delta.tv_usec = 0;
788	timeradd(&tv, &delta, &tv);
789	rtc_offset = new_rtc_offset;
790	settime(&tv);
791
792	return (0);
793}
794
795/*
796 * sysctl helper routine for kern.maxvnodes.  ensures that the new
797 * values are not too low or too high.
798 */
799static int
800sysctl_kern_maxproc(SYSCTLFN_ARGS)
801{
802	int error, nmaxproc;
803	struct sysctlnode node;
804
805	nmaxproc = maxproc;
806	node = *rnode;
807	node.sysctl_data = &nmaxproc;
808	error = sysctl_lookup(SYSCTLFN_CALL(&node));
809	if (error || newp == NULL)
810		return (error);
811
812	if (nmaxproc < 0 || nmaxproc >= PID_MAX)
813		return (EINVAL);
814#ifdef __HAVE_CPU_MAXPROC
815	if (nmaxproc > cpu_maxproc())
816		return (EINVAL);
817#endif
818	maxproc = nmaxproc;
819
820	return (0);
821}
822
823/*
824 * sysctl helper routine for kern.securelevel.  ensures that the value
825 * only rises unless the caller has pid 1 (assumed to be init).
826 */
827static int
828sysctl_kern_securelevel(SYSCTLFN_ARGS)
829{
830	int newsecurelevel, error;
831	struct sysctlnode node;
832
833	newsecurelevel = securelevel;
834	node = *rnode;
835	node.sysctl_data = &newsecurelevel;
836	error = sysctl_lookup(SYSCTLFN_CALL(&node));
837	if (error || newp == NULL)
838		return (error);
839
840	if (newsecurelevel < securelevel && l && l->l_proc->p_pid != 1)
841		return (EPERM);
842	securelevel = newsecurelevel;
843
844	return (error);
845}
846
847/*
848 * sysctl helper function for kern.hostid.  the hostid is a long, but
849 * we export it as an int, so we need to give it a little help.
850 */
851static int
852sysctl_kern_hostid(SYSCTLFN_ARGS)
853{
854	int error, inthostid;
855	struct sysctlnode node;
856
857	inthostid = hostid;  /* XXX assumes sizeof int >= sizeof long */
858	node = *rnode;
859	node.sysctl_data = &inthostid;
860	error = sysctl_lookup(SYSCTLFN_CALL(&node));
861	if (error || newp == NULL)
862		return (error);
863
864	hostid = inthostid;
865
866	return (0);
867}
868
869/*
870 * sysctl helper function for kern.hostname and kern.domainnname.
871 * resets the relevant recorded length when the underlying name is
872 * changed.
873 */
874static int
875sysctl_setlen(SYSCTLFN_ARGS)
876{
877	int error;
878
879	error = sysctl_lookup(SYSCTLFN_CALL(rnode));
880	if (error || newp == NULL)
881		return (error);
882
883	switch (rnode->sysctl_num) {
884	case KERN_HOSTNAME:
885		hostnamelen = strlen((const char*)rnode->sysctl_data);
886		break;
887	case KERN_DOMAINNAME:
888		domainnamelen = strlen((const char*)rnode->sysctl_data);
889		break;
890	}
891
892	return (0);
893}
894
895/*
896 * sysctl helper routine for kern.clockrate.  assembles a struct on
897 * the fly to be returned to the caller.
898 */
899static int
900sysctl_kern_clockrate(SYSCTLFN_ARGS)
901{
902	struct clockinfo clkinfo;
903	struct sysctlnode node;
904
905	clkinfo.tick = tick;
906	clkinfo.tickadj = tickadj;
907	clkinfo.hz = hz;
908	clkinfo.profhz = profhz;
909	clkinfo.stathz = stathz ? stathz : hz;
910
911	node = *rnode;
912	node.sysctl_data = &clkinfo;
913	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
914}
915
916
917/*
918 * sysctl helper routine for kern.file pseudo-subtree.
919 */
920static int
921sysctl_kern_file(SYSCTLFN_ARGS)
922{
923	int error;
924	size_t buflen;
925	struct file *fp;
926	char *start, *where;
927
928	start = where = oldp;
929	buflen = *oldlenp;
930	if (where == NULL) {
931		/*
932		 * overestimate by 10 files
933		 */
934		*oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
935		return (0);
936	}
937
938	/*
939	 * first copyout filehead
940	 */
941	if (buflen < sizeof(filehead)) {
942		*oldlenp = 0;
943		return (0);
944	}
945	error = copyout(&filehead, where, sizeof(filehead));
946	if (error)
947		return (error);
948	buflen -= sizeof(filehead);
949	where += sizeof(filehead);
950
951	/*
952	 * followed by an array of file structures
953	 */
954	LIST_FOREACH(fp, &filehead, f_list) {
955		if (buflen < sizeof(struct file)) {
956			*oldlenp = where - start;
957			return (ENOMEM);
958		}
959		error = copyout(fp, where, sizeof(struct file));
960		if (error)
961			return (error);
962		buflen -= sizeof(struct file);
963		where += sizeof(struct file);
964	}
965	*oldlenp = where - start;
966	return (0);
967}
968
969/*
970 * sysctl helper routine for kern.autonicetime and kern.autoniceval.
971 * asserts that the assigned value is in the correct range.
972 */
973static int
974sysctl_kern_autonice(SYSCTLFN_ARGS)
975{
976	int error, t = 0;
977	struct sysctlnode node;
978
979	node = *rnode;
980	t = *(int*)node.sysctl_data;
981	node.sysctl_data = &t;
982	error = sysctl_lookup(SYSCTLFN_CALL(&node));
983	if (error || newp == NULL)
984		return (error);
985
986	switch (node.sysctl_num) {
987	case KERN_AUTONICETIME:
988		if (t >= 0)
989			autonicetime = t;
990		break;
991	case KERN_AUTONICEVAL:
992		if (t < PRIO_MIN)
993			t = PRIO_MIN;
994		else if (t > PRIO_MAX)
995			t = PRIO_MAX;
996		autoniceval = t;
997		break;
998	}
999
1000	return (0);
1001}
1002
1003/*
1004 * sysctl helper routine for kern.msgbufsize and kern.msgbuf.  for the
1005 * former it merely checks the the message buffer is set up.  for the
1006 * latter, it also copies out the data if necessary.
1007 */
1008static int
1009sysctl_msgbuf(SYSCTLFN_ARGS)
1010{
1011	char *where = oldp;
1012	size_t len, maxlen;
1013	long beg, end;
1014	int error;
1015
1016	if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
1017		msgbufenabled = 0;
1018		return (ENXIO);
1019	}
1020
1021	switch (rnode->sysctl_num) {
1022	case KERN_MSGBUFSIZE:
1023		return (sysctl_lookup(SYSCTLFN_CALL(rnode)));
1024	case KERN_MSGBUF:
1025		break;
1026	default:
1027		return (EOPNOTSUPP);
1028	}
1029
1030	if (newp != NULL)
1031		return (EPERM);
1032
1033        if (oldp == NULL) {
1034		/* always return full buffer size */
1035		*oldlenp = msgbufp->msg_bufs;
1036		return (0);
1037        }
1038
1039	error = 0;
1040	maxlen = MIN(msgbufp->msg_bufs, *oldlenp);
1041
1042	/*
1043	 * First, copy from the write pointer to the end of
1044	 * message buffer.
1045	 */
1046	beg = msgbufp->msg_bufx;
1047	end = msgbufp->msg_bufs;
1048	while (maxlen > 0) {
1049		len = MIN(end - beg, maxlen);
1050		if (len == 0)
1051			break;
1052		error = copyout(&msgbufp->msg_bufc[beg], where, len);
1053		if (error)
1054			break;
1055		where += len;
1056		maxlen -= len;
1057
1058		/*
1059		 * ... then, copy from the beginning of message buffer to
1060		 * the write pointer.
1061		 */
1062		beg = 0;
1063		end = msgbufp->msg_bufx;
1064	}
1065
1066	return (error);
1067}
1068
1069/*
1070 * sysctl helper routine for kern.defcorename.  in the case of a new
1071 * string being assigned, check that it's not a zero-length string.
1072 * (XXX the check in -current doesn't work, but do we really care?)
1073 */
1074static int
1075sysctl_kern_defcorename(SYSCTLFN_ARGS)
1076{
1077	int error;
1078	char newcorename[MAXPATHLEN];
1079	struct sysctlnode node;
1080
1081	node = *rnode;
1082	node.sysctl_data = &newcorename[0];
1083	memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN);
1084	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1085	if (error || newp == NULL)
1086		return (error);
1087
1088	/*
1089	 * when sysctl_lookup() deals with a string, it's guaranteed
1090	 * to come back nul terminated.  so there.  :)
1091	 */
1092	if (strlen(newcorename) == 0)
1093		return (EINVAL);
1094
1095	memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN);
1096
1097	return (0);
1098}
1099
1100/*
1101 * sysctl helper routine for kern.cp_time node.  adds up cpu time
1102 * across all cpus.
1103 */
1104static int
1105sysctl_kern_cptime(SYSCTLFN_ARGS)
1106{
1107	struct sysctlnode node = *rnode;
1108
1109#ifndef MULTIPROCESSOR
1110
1111	if (namelen == 1) {
1112		if (name[0] != 0)
1113			return (ENOENT);
1114		/*
1115		 * you're allowed to ask for the zero'th processor
1116		 */
1117		name++;
1118		namelen--;
1119	}
1120	node.sysctl_data = curcpu()->ci_schedstate.spc_cp_time;
1121	node.sysctl_size = sizeof(curcpu()->ci_schedstate.spc_cp_time);
1122	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1123
1124#else /* MULTIPROCESSOR */
1125
1126	u_int64_t *cp_time = NULL;
1127	int error, n = sysctl_ncpus(), i;
1128	struct cpu_info *ci;
1129	CPU_INFO_ITERATOR cii;
1130
1131	/*
1132	 * if you specifically pass a buffer that is the size of the
1133	 * sum, or if you are probing for the size, you get the "sum"
1134	 * of cp_time (and the size thereof) across all processors.
1135	 *
1136	 * alternately, you can pass an additional mib number and get
1137	 * cp_time for that particular processor.
1138	 */
1139	switch (namelen) {
1140	case 0:
1141	    	if (*oldlenp == sizeof(u_int64_t) * CPUSTATES || oldp == NULL) {
1142			node.sysctl_size = sizeof(u_int64_t) * CPUSTATES;
1143			n = -1; /* SUM */
1144		}
1145		else {
1146			node.sysctl_size = n * sizeof(u_int64_t) * CPUSTATES;
1147			n = -2; /* ALL */
1148		}
1149		break;
1150	case 1:
1151		if (name[0] < 0 || name[0] >= n)
1152			return (ENOENT); /* ENOSUCHPROCESSOR */
1153		node.sysctl_size = sizeof(u_int64_t) * CPUSTATES;
1154		n = name[0];
1155		/*
1156		 * adjust these so that sysctl_lookup() will be happy
1157		 */
1158		name++;
1159		namelen--;
1160		break;
1161	default:
1162		return (EINVAL);
1163	}
1164
1165	cp_time = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL);
1166	if (cp_time == NULL)
1167		return (ENOMEM);
1168	node.sysctl_data = cp_time;
1169	memset(cp_time, 0, node.sysctl_size);
1170
1171	for (CPU_INFO_FOREACH(cii, ci)) {
1172		if (n <= 0)
1173			for (i = 0; i < CPUSTATES; i++)
1174				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
1175		/*
1176		 * if a specific processor was requested and we just
1177		 * did it, we're done here
1178		 */
1179		if (n == 0)
1180			break;
1181		/*
1182		 * if doing "all", skip to next cp_time set for next processor
1183		 */
1184		if (n == -2)
1185			cp_time += CPUSTATES;
1186		/*
1187		 * if we're doing a specific processor, we're one
1188		 * processor closer
1189		 */
1190		if (n > 0)
1191			n--;
1192	}
1193
1194	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1195	free(node.sysctl_data, M_TEMP);
1196	return (error);
1197
1198#endif /* MULTIPROCESSOR */
1199}
1200
1201#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
1202/*
1203 * sysctl helper routine for kern.sysvipc_info subtree.
1204 */
1205
1206#define	FILL_PERM(src, dst) do { \
1207	(dst)._key = (src)._key; \
1208	(dst).uid = (src).uid; \
1209	(dst).gid = (src).gid; \
1210	(dst).cuid = (src).cuid; \
1211	(dst).cgid = (src).cgid; \
1212	(dst).mode = (src).mode; \
1213	(dst)._seq = (src)._seq; \
1214} while (/*CONSTCOND*/ 0);
1215#define	FILL_MSG(src, dst) do { \
1216	FILL_PERM((src).msg_perm, (dst).msg_perm); \
1217	(dst).msg_qnum = (src).msg_qnum; \
1218	(dst).msg_qbytes = (src).msg_qbytes; \
1219	(dst)._msg_cbytes = (src)._msg_cbytes; \
1220	(dst).msg_lspid = (src).msg_lspid; \
1221	(dst).msg_lrpid = (src).msg_lrpid; \
1222	(dst).msg_stime = (src).msg_stime; \
1223	(dst).msg_rtime = (src).msg_rtime; \
1224	(dst).msg_ctime = (src).msg_ctime; \
1225} while (/*CONSTCOND*/ 0)
1226#define	FILL_SEM(src, dst) do { \
1227	FILL_PERM((src).sem_perm, (dst).sem_perm); \
1228	(dst).sem_nsems = (src).sem_nsems; \
1229	(dst).sem_otime = (src).sem_otime; \
1230	(dst).sem_ctime = (src).sem_ctime; \
1231} while (/*CONSTCOND*/ 0)
1232#define	FILL_SHM(src, dst) do { \
1233	FILL_PERM((src).shm_perm, (dst).shm_perm); \
1234	(dst).shm_segsz = (src).shm_segsz; \
1235	(dst).shm_lpid = (src).shm_lpid; \
1236	(dst).shm_cpid = (src).shm_cpid; \
1237	(dst).shm_atime = (src).shm_atime; \
1238	(dst).shm_dtime = (src).shm_dtime; \
1239	(dst).shm_ctime = (src).shm_ctime; \
1240	(dst).shm_nattch = (src).shm_nattch; \
1241} while (/*CONSTCOND*/ 0)
1242
1243static int
1244sysctl_kern_sysvipc(SYSCTLFN_ARGS)
1245{
1246	void *where = oldp;
1247	size_t *sizep = oldlenp;
1248#ifdef SYSVMSG
1249	struct msg_sysctl_info *msgsi = NULL;
1250#endif
1251#ifdef SYSVSEM
1252	struct sem_sysctl_info *semsi = NULL;
1253#endif
1254#ifdef SYSVSHM
1255	struct shm_sysctl_info *shmsi = NULL;
1256#endif
1257	size_t infosize, dssize, tsize, buflen;
1258	void *buf = NULL;
1259	char *start;
1260	int32_t nds;
1261	int i, error, ret;
1262
1263	if (namelen != 1)
1264		return (EINVAL);
1265
1266	start = where;
1267	buflen = *sizep;
1268
1269	switch (*name) {
1270	case KERN_SYSVIPC_MSG_INFO:
1271#ifdef SYSVMSG
1272		infosize = sizeof(msgsi->msginfo);
1273		nds = msginfo.msgmni;
1274		dssize = sizeof(msgsi->msgids[0]);
1275		break;
1276#else
1277		return (EINVAL);
1278#endif
1279	case KERN_SYSVIPC_SEM_INFO:
1280#ifdef SYSVSEM
1281		infosize = sizeof(semsi->seminfo);
1282		nds = seminfo.semmni;
1283		dssize = sizeof(semsi->semids[0]);
1284		break;
1285#else
1286		return (EINVAL);
1287#endif
1288	case KERN_SYSVIPC_SHM_INFO:
1289#ifdef SYSVSHM
1290		infosize = sizeof(shmsi->shminfo);
1291		nds = shminfo.shmmni;
1292		dssize = sizeof(shmsi->shmids[0]);
1293		break;
1294#else
1295		return (EINVAL);
1296#endif
1297	default:
1298		return (EINVAL);
1299	}
1300	/*
1301	 * Round infosize to 64 bit boundary if requesting more than just
1302	 * the info structure or getting the total data size.
1303	 */
1304	if (where == NULL || *sizep > infosize)
1305		infosize = ((infosize + 7) / 8) * 8;
1306	tsize = infosize + nds * dssize;
1307
1308	/* Return just the total size required. */
1309	if (where == NULL) {
1310		*sizep = tsize;
1311		return (0);
1312	}
1313
1314	/* Not enough room for even the info struct. */
1315	if (buflen < infosize) {
1316		*sizep = 0;
1317		return (ENOMEM);
1318	}
1319	buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK);
1320	memset(buf, 0, min(tsize, buflen));
1321
1322	switch (*name) {
1323#ifdef SYSVMSG
1324	case KERN_SYSVIPC_MSG_INFO:
1325		msgsi = (struct msg_sysctl_info *)buf;
1326		msgsi->msginfo = msginfo;
1327		break;
1328#endif
1329#ifdef SYSVSEM
1330	case KERN_SYSVIPC_SEM_INFO:
1331		semsi = (struct sem_sysctl_info *)buf;
1332		semsi->seminfo = seminfo;
1333		break;
1334#endif
1335#ifdef SYSVSHM
1336	case KERN_SYSVIPC_SHM_INFO:
1337		shmsi = (struct shm_sysctl_info *)buf;
1338		shmsi->shminfo = shminfo;
1339		break;
1340#endif
1341	}
1342	buflen -= infosize;
1343
1344	ret = 0;
1345	if (buflen > 0) {
1346		/* Fill in the IPC data structures.  */
1347		for (i = 0; i < nds; i++) {
1348			if (buflen < dssize) {
1349				ret = ENOMEM;
1350				break;
1351			}
1352			switch (*name) {
1353#ifdef SYSVMSG
1354			case KERN_SYSVIPC_MSG_INFO:
1355				FILL_MSG(msqids[i], msgsi->msgids[i]);
1356				break;
1357#endif
1358#ifdef SYSVSEM
1359			case KERN_SYSVIPC_SEM_INFO:
1360				FILL_SEM(sema[i], semsi->semids[i]);
1361				break;
1362#endif
1363#ifdef SYSVSHM
1364			case KERN_SYSVIPC_SHM_INFO:
1365				FILL_SHM(shmsegs[i], shmsi->shmids[i]);
1366				break;
1367#endif
1368			}
1369			buflen -= dssize;
1370		}
1371	}
1372	*sizep -= buflen;
1373	error = copyout(buf, start, *sizep);
1374	/* If copyout succeeded, use return code set earlier. */
1375	if (error == 0)
1376		error = ret;
1377	if (buf)
1378		free(buf, M_TEMP);
1379	return (error);
1380}
1381
1382#undef FILL_PERM
1383#undef FILL_MSG
1384#undef FILL_SEM
1385#undef FILL_SHM
1386
1387#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */
1388
1389#if NPTY > 0
1390/*
1391 * sysctl helper routine for kern.maxptys.  ensures that any new value
1392 * is acceptable to the pty subsystem.
1393 */
1394static int
1395sysctl_kern_maxptys(SYSCTLFN_ARGS)
1396{
1397	int pty_maxptys(int, int);		/* defined in kern/tty_pty.c */
1398	int error, max;
1399	struct sysctlnode node;
1400
1401	/* get current value of maxptys */
1402	max = pty_maxptys(0, 0);
1403
1404	node = *rnode;
1405	node.sysctl_data = &max;
1406	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1407	if (error || newp == NULL)
1408		return (error);
1409
1410	if (max != pty_maxptys(max, 1))
1411		return (EINVAL);
1412
1413	return (0);
1414}
1415#endif /* NPTY > 0 */
1416
1417/*
1418 * sysctl helper routine for kern.sbmax.  basically just ensures that
1419 * any new value is not too small.
1420 */
1421static int
1422sysctl_kern_sbmax(SYSCTLFN_ARGS)
1423{
1424	int error, new_sbmax;
1425	struct sysctlnode node;
1426
1427	new_sbmax = sb_max;
1428	node = *rnode;
1429	node.sysctl_data = &new_sbmax;
1430	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1431	if (error || newp == NULL)
1432		return (error);
1433
1434	error = sb_max_set(new_sbmax);
1435
1436	return (error);
1437}
1438
1439/*
1440 * sysctl helper routine for kern.urandom node.  picks a random number
1441 * for you.
1442 */
1443static int
1444sysctl_kern_urnd(SYSCTLFN_ARGS)
1445{
1446#if NRND > 0
1447	int v;
1448
1449	if (rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY) == sizeof(v)) {
1450		struct sysctlnode node = *rnode;
1451		node.sysctl_data = &v;
1452		return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1453	}
1454	else
1455		return (EIO);	/*XXX*/
1456#else
1457	return (EOPNOTSUPP);
1458#endif
1459}
1460
1461/*
1462 * sysctl helper routine to do kern.lwp.* work.
1463 */
1464static int
1465sysctl_kern_lwp(SYSCTLFN_ARGS)
1466{
1467	struct kinfo_lwp klwp;
1468	struct proc *p;
1469	struct lwp *l2;
1470	char *where, *dp;
1471	int pid, elem_size, elem_count;
1472	int buflen, needed, error;
1473
1474	if (namelen == 1 && name[0] == CTL_QUERY)
1475		return (sysctl_query(SYSCTLFN_CALL(rnode)));
1476
1477	dp = where = oldp;
1478	buflen = where != NULL ? *oldlenp : 0;
1479	error = needed = 0;
1480
1481	if (newp != NULL || namelen != 3)
1482		return (EINVAL);
1483	pid = name[0];
1484	elem_size = name[1];
1485	elem_count = name[2];
1486
1487	p = pfind(pid);
1488	if (p == NULL)
1489		return (ESRCH);
1490	LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
1491		if (buflen >= elem_size && elem_count > 0) {
1492			fill_lwp(l2, &klwp);
1493			/*
1494			 * Copy out elem_size, but not larger than
1495			 * the size of a struct kinfo_proc2.
1496			 */
1497			error = copyout(&klwp, dp,
1498			    min(sizeof(klwp), elem_size));
1499			if (error)
1500				goto cleanup;
1501			dp += elem_size;
1502			buflen -= elem_size;
1503			elem_count--;
1504		}
1505		needed += elem_size;
1506	}
1507
1508	if (where != NULL) {
1509		*oldlenp = dp - where;
1510		if (needed > *oldlenp)
1511			return (ENOMEM);
1512	} else {
1513		needed += KERN_PROCSLOP;
1514		*oldlenp = needed;
1515	}
1516	return (0);
1517 cleanup:
1518	return (error);
1519}
1520
1521/*
1522 * sysctl helper routine for kern.forkfsleep node.  ensures that the
1523 * given value is not too large or two small, and is at least one
1524 * timer tick if not zero.
1525 */
1526static int
1527sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
1528{
1529	/* userland sees value in ms, internally is in ticks */
1530	extern int forkfsleep;		/* defined in kern/kern_fork.c */
1531	int error, timo, lsleep;
1532	struct sysctlnode node;
1533
1534	lsleep = forkfsleep * 1000 / hz;
1535	node = *rnode;
1536	node.sysctl_data = &lsleep;
1537	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1538	if (error || newp == NULL)
1539		return (error);
1540
1541	/* refuse negative values, and overly 'long time' */
1542	if (lsleep < 0 || lsleep > MAXSLP * 1000)
1543		return (EINVAL);
1544
1545	timo = mstohz(lsleep);
1546
1547	/* if the interval is >0 ms && <1 tick, use 1 tick */
1548	if (lsleep != 0 && timo == 0)
1549		forkfsleep = 1;
1550	else
1551		forkfsleep = timo;
1552
1553	return (0);
1554}
1555
1556/*
1557 * sysctl helper routine for kern.somaxkva.  ensures that the given
1558 * value is not too small.
1559 * (XXX should we maybe make sure it's not too large as well?)
1560 */
1561static int
1562sysctl_kern_somaxkva(SYSCTLFN_ARGS)
1563{
1564	int error, new_somaxkva;
1565	struct sysctlnode node;
1566
1567	new_somaxkva = somaxkva;
1568	node = *rnode;
1569	node.sysctl_data = &new_somaxkva;
1570	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1571	if (error || newp == NULL)
1572		return (error);
1573
1574	if (new_somaxkva < (16 * 1024 * 1024)) /* sanity */
1575		return (EINVAL);
1576	somaxkva = new_somaxkva;
1577
1578	return (error);
1579}
1580
1581/*
1582 * sysctl helper routine for kern.root_partition
1583 */
1584static int
1585sysctl_kern_root_partition(SYSCTLFN_ARGS)
1586{
1587	int rootpart = DISKPART(rootdev);
1588	struct sysctlnode node = *rnode;
1589
1590	node.sysctl_data = &rootpart;
1591	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1592}
1593
1594/*
1595 * sysctl helper function for kern.drivers
1596 */
1597static int
1598sysctl_kern_drivers(SYSCTLFN_ARGS)
1599{
1600	int error;
1601	size_t buflen;
1602	struct kinfo_drivers kd;
1603	char *start, *where;
1604	const char *dname;
1605	int i;
1606	extern struct devsw_conv *devsw_conv;
1607	extern int max_devsw_convs;
1608
1609	if (newp != NULL || namelen != 0)
1610		return (EINVAL);
1611
1612	start = where = oldp;
1613	buflen = *oldlenp;
1614	if (where == NULL) {
1615		*oldlenp = max_devsw_convs * sizeof kd;
1616		return 0;
1617	}
1618
1619	/*
1620	 * An array of kinfo_drivers structures
1621	 */
1622	error = 0;
1623	for (i = 0; i < max_devsw_convs; i++) {
1624		dname = devsw_conv[i].d_name;
1625		if (dname == NULL)
1626			continue;
1627		if (buflen < sizeof kd) {
1628			error = ENOMEM;
1629			break;
1630		}
1631		kd.d_bmajor = devsw_conv[i].d_bmajor;
1632		kd.d_cmajor = devsw_conv[i].d_cmajor;
1633		strlcpy(kd.d_name, dname, sizeof kd.d_name);
1634		error = copyout(&kd, where, sizeof kd);
1635		if (error != 0)
1636			break;
1637		buflen -= sizeof kd;
1638		where += sizeof kd;
1639	}
1640	*oldlenp = where - start;
1641	return error;
1642}
1643
1644static int
1645sysctl_doeproc(SYSCTLFN_ARGS)
1646{
1647	struct eproc eproc;
1648	struct kinfo_proc2 kproc2;
1649	struct kinfo_proc *dp;
1650	struct proc *p;
1651	const struct proclist_desc *pd;
1652	char *where, *dp2;
1653	int type, op, arg;
1654	u_int elem_size, elem_count;
1655	size_t buflen, needed;
1656	int error;
1657
1658	if (namelen == 1 && name[0] == CTL_QUERY)
1659		return (sysctl_query(SYSCTLFN_CALL(rnode)));
1660
1661	dp = oldp;
1662	dp2 = where = oldp;
1663	buflen = where != NULL ? *oldlenp : 0;
1664	error = 0;
1665	needed = 0;
1666	type = rnode->sysctl_num;
1667
1668	if (type == KERN_PROC) {
1669		if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
1670			return (EINVAL);
1671		op = name[0];
1672		if (op != KERN_PROC_ALL)
1673			arg = name[1];
1674		else
1675			arg = 0;		/* Quell compiler warning */
1676		elem_size = elem_count = 0;	/* Ditto */
1677	} else {
1678		if (namelen != 4)
1679			return (EINVAL);
1680		op = name[0];
1681		arg = name[1];
1682		elem_size = name[2];
1683		elem_count = name[3];
1684	}
1685
1686	proclist_lock_read();
1687
1688	pd = proclists;
1689again:
1690	for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) {
1691		/*
1692		 * Skip embryonic processes.
1693		 */
1694		if (p->p_stat == SIDL)
1695			continue;
1696		/*
1697		 * TODO - make more efficient (see notes below).
1698		 * do by session.
1699		 */
1700		switch (op) {
1701
1702		case KERN_PROC_PID:
1703			/* could do this with just a lookup */
1704			if (p->p_pid != (pid_t)arg)
1705				continue;
1706			break;
1707
1708		case KERN_PROC_PGRP:
1709			/* could do this by traversing pgrp */
1710			if (p->p_pgrp->pg_id != (pid_t)arg)
1711				continue;
1712			break;
1713
1714		case KERN_PROC_SESSION:
1715			if (p->p_session->s_sid != (pid_t)arg)
1716				continue;
1717			break;
1718
1719		case KERN_PROC_TTY:
1720			if (arg == (int) KERN_PROC_TTY_REVOKE) {
1721				if ((p->p_flag & P_CONTROLT) == 0 ||
1722				    p->p_session->s_ttyp == NULL ||
1723				    p->p_session->s_ttyvp != NULL)
1724					continue;
1725			} else if ((p->p_flag & P_CONTROLT) == 0 ||
1726			    p->p_session->s_ttyp == NULL) {
1727				if ((dev_t)arg != KERN_PROC_TTY_NODEV)
1728					continue;
1729			} else if (p->p_session->s_ttyp->t_dev != (dev_t)arg)
1730				continue;
1731			break;
1732
1733		case KERN_PROC_UID:
1734			if (p->p_ucred->cr_uid != (uid_t)arg)
1735				continue;
1736			break;
1737
1738		case KERN_PROC_RUID:
1739			if (p->p_cred->p_ruid != (uid_t)arg)
1740				continue;
1741			break;
1742
1743		case KERN_PROC_GID:
1744			if (p->p_ucred->cr_gid != (uid_t)arg)
1745				continue;
1746			break;
1747
1748		case KERN_PROC_RGID:
1749			if (p->p_cred->p_rgid != (uid_t)arg)
1750				continue;
1751			break;
1752
1753		case KERN_PROC_ALL:
1754			/* allow everything */
1755			break;
1756
1757		default:
1758			error = EINVAL;
1759			goto cleanup;
1760		}
1761		if (type == KERN_PROC) {
1762			if (buflen >= sizeof(struct kinfo_proc)) {
1763				fill_eproc(p, &eproc);
1764				error = copyout(p, &dp->kp_proc,
1765				    sizeof(struct proc));
1766				if (error)
1767					goto cleanup;
1768				error = copyout(&eproc, &dp->kp_eproc,
1769				    sizeof(eproc));
1770				if (error)
1771					goto cleanup;
1772				dp++;
1773				buflen -= sizeof(struct kinfo_proc);
1774			}
1775			needed += sizeof(struct kinfo_proc);
1776		} else { /* KERN_PROC2 */
1777			if (buflen >= elem_size && elem_count > 0) {
1778				fill_kproc2(p, &kproc2);
1779				/*
1780				 * Copy out elem_size, but not larger than
1781				 * the size of a struct kinfo_proc2.
1782				 */
1783				error = copyout(&kproc2, dp2,
1784				    min(sizeof(kproc2), elem_size));
1785				if (error)
1786					goto cleanup;
1787				dp2 += elem_size;
1788				buflen -= elem_size;
1789				elem_count--;
1790			}
1791			needed += elem_size;
1792		}
1793	}
1794	pd++;
1795	if (pd->pd_list != NULL)
1796		goto again;
1797	proclist_unlock_read();
1798
1799	if (where != NULL) {
1800		if (type == KERN_PROC)
1801			*oldlenp = (char *)dp - where;
1802		else
1803			*oldlenp = dp2 - where;
1804		if (needed > *oldlenp)
1805			return (ENOMEM);
1806	} else {
1807		needed += KERN_LWPSLOP;
1808		*oldlenp = needed;
1809	}
1810	return (0);
1811 cleanup:
1812	proclist_unlock_read();
1813	return (error);
1814}
1815
1816/*
1817 * sysctl helper routine for kern.proc_args pseudo-subtree.
1818 */
1819static int
1820sysctl_kern_proc_args(SYSCTLFN_ARGS)
1821{
1822	struct ps_strings pss;
1823	struct proc *p, *up = l->l_proc;
1824	size_t len, upper_bound, xlen, i;
1825	struct uio auio;
1826	struct iovec aiov;
1827	vaddr_t argv;
1828	pid_t pid;
1829	int nargv, type, error;
1830	char *arg;
1831	char *tmp;
1832
1833	if (namelen == 1 && name[0] == CTL_QUERY)
1834		return (sysctl_query(SYSCTLFN_CALL(rnode)));
1835
1836	if (newp != NULL || namelen != 2)
1837		return (EINVAL);
1838	pid = name[0];
1839	type = name[1];
1840
1841	switch (type) {
1842	case KERN_PROC_ARGV:
1843	case KERN_PROC_NARGV:
1844	case KERN_PROC_ENV:
1845	case KERN_PROC_NENV:
1846		/* ok */
1847		break;
1848	default:
1849		return (EINVAL);
1850	}
1851
1852	/* check pid */
1853	if ((p = pfind(pid)) == NULL)
1854		return (EINVAL);
1855
1856	/* only root or same user change look at the environment */
1857	if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
1858		if (up->p_ucred->cr_uid != 0) {
1859			if (up->p_cred->p_ruid != p->p_cred->p_ruid ||
1860			    up->p_cred->p_ruid != p->p_cred->p_svuid)
1861				return (EPERM);
1862		}
1863	}
1864
1865	if (oldp == NULL) {
1866		if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV)
1867			*oldlenp = sizeof (int);
1868		else
1869			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
1870		return (0);
1871	}
1872
1873	/*
1874	 * Zombies don't have a stack, so we can't read their psstrings.
1875	 * System processes also don't have a user stack.
1876	 */
1877	if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0)
1878		return (EINVAL);
1879
1880	/*
1881	 * Lock the process down in memory.
1882	 */
1883	/* XXXCDC: how should locking work here? */
1884	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
1885		return (EFAULT);
1886
1887	p->p_vmspace->vm_refcnt++;	/* XXX */
1888
1889	/*
1890	 * Allocate a temporary buffer to hold the arguments.
1891	 */
1892	arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
1893
1894	/*
1895	 * Read in the ps_strings structure.
1896	 */
1897	aiov.iov_base = &pss;
1898	aiov.iov_len = sizeof(pss);
1899	auio.uio_iov = &aiov;
1900	auio.uio_iovcnt = 1;
1901	auio.uio_offset = (vaddr_t)p->p_psstr;
1902	auio.uio_resid = sizeof(pss);
1903	auio.uio_segflg = UIO_SYSSPACE;
1904	auio.uio_rw = UIO_READ;
1905	auio.uio_procp = NULL;
1906	error = uvm_io(&p->p_vmspace->vm_map, &auio);
1907	if (error)
1908		goto done;
1909
1910	if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV)
1911		memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv));
1912	else
1913		memcpy(&nargv, (char *)&pss + p->p_psnenv, sizeof(nargv));
1914	if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) {
1915		error = copyout(&nargv, oldp, sizeof(nargv));
1916		*oldlenp = sizeof(nargv);
1917		goto done;
1918	}
1919	/*
1920	 * Now read the address of the argument vector.
1921	 */
1922	switch (type) {
1923	case KERN_PROC_ARGV:
1924		/* XXX compat32 stuff here */
1925		memcpy(&tmp, (char *)&pss + p->p_psargv, sizeof(tmp));
1926		break;
1927	case KERN_PROC_ENV:
1928		memcpy(&tmp, (char *)&pss + p->p_psenv, sizeof(tmp));
1929		break;
1930	default:
1931		return (EINVAL);
1932	}
1933	auio.uio_offset = (off_t)(long)tmp;
1934	aiov.iov_base = &argv;
1935	aiov.iov_len = sizeof(argv);
1936	auio.uio_iov = &aiov;
1937	auio.uio_iovcnt = 1;
1938	auio.uio_resid = sizeof(argv);
1939	auio.uio_segflg = UIO_SYSSPACE;
1940	auio.uio_rw = UIO_READ;
1941	auio.uio_procp = NULL;
1942	error = uvm_io(&p->p_vmspace->vm_map, &auio);
1943	if (error)
1944		goto done;
1945
1946	/*
1947	 * Now copy in the actual argument vector, one page at a time,
1948	 * since we don't know how long the vector is (though, we do
1949	 * know how many NUL-terminated strings are in the vector).
1950	 */
1951	len = 0;
1952	upper_bound = *oldlenp;
1953	for (; nargv != 0 && len < upper_bound; len += xlen) {
1954		aiov.iov_base = arg;
1955		aiov.iov_len = PAGE_SIZE;
1956		auio.uio_iov = &aiov;
1957		auio.uio_iovcnt = 1;
1958		auio.uio_offset = argv + len;
1959		xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
1960		auio.uio_resid = xlen;
1961		auio.uio_segflg = UIO_SYSSPACE;
1962		auio.uio_rw = UIO_READ;
1963		auio.uio_procp = NULL;
1964		error = uvm_io(&p->p_vmspace->vm_map, &auio);
1965		if (error)
1966			goto done;
1967
1968		for (i = 0; i < xlen && nargv != 0; i++) {
1969			if (arg[i] == '\0')
1970				nargv--;	/* one full string */
1971		}
1972
1973		/*
1974		 * Make sure we don't copyout past the end of the user's
1975		 * buffer.
1976		 */
1977		if (len + i > upper_bound)
1978			i = upper_bound - len;
1979
1980		error = copyout(arg, (char *)oldp + len, i);
1981		if (error)
1982			break;
1983
1984		if (nargv == 0) {
1985			len += i;
1986			break;
1987		}
1988	}
1989	*oldlenp = len;
1990
1991done:
1992	uvmspace_free(p->p_vmspace);
1993
1994	free(arg, M_TEMP);
1995	return (error);
1996}
1997
1998/*
1999 * sysctl helper routine for hw.usermem and hw.usermem64.  values are
2000 * calculate on the fly taking into account integer overflow and the
2001 * current wired count.
2002 */
2003static int
2004sysctl_hw_usermem(SYSCTLFN_ARGS)
2005{
2006	u_int ui;
2007	u_quad_t uq;
2008	struct sysctlnode node;
2009
2010	node = *rnode;
2011	switch (rnode->sysctl_num) {
2012	    case HW_USERMEM:
2013		if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE))
2014			ui = UINT_MAX;
2015		else
2016			ui *= PAGE_SIZE;
2017		node.sysctl_data = &ui;
2018		break;
2019	case HW_USERMEM64:
2020		uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE;
2021		node.sysctl_data = &uq;
2022		break;
2023	default:
2024		return (EINVAL);
2025	}
2026
2027	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2028}
2029
2030/*
2031 * sysctl helper routine for kern.cnmagic node.  pulls the old value
2032 * out, encoded, and stuffs the new value in for decoding.
2033 */
2034static int
2035sysctl_hw_cnmagic(SYSCTLFN_ARGS)
2036{
2037	char magic[CNS_LEN];
2038	int error;
2039	struct sysctlnode node;
2040
2041	if (oldp)
2042		cn_get_magic(magic, CNS_LEN);
2043	node = *rnode;
2044	node.sysctl_data = &magic[0];
2045	error = sysctl_lookup(SYSCTLFN_CALL(&node));
2046	if (error || newp == NULL)
2047		return (error);
2048
2049	return (cn_set_magic(magic));
2050}
2051
2052static int
2053sysctl_hw_ncpu(SYSCTLFN_ARGS)
2054{
2055	int ncpu;
2056	struct sysctlnode node;
2057
2058	ncpu = sysctl_ncpus();
2059	node = *rnode;
2060	node.sysctl_data = &ncpu;
2061
2062	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2063}
2064
2065
2066/*
2067 * ********************************************************************
2068 * section 3: public helper routines that are used for more than one
2069 * node
2070 * ********************************************************************
2071 */
2072
2073/*
2074 * sysctl helper routine for the kern.root_device node and some ports'
2075 * machdep.root_device nodes.
2076 */
2077int
2078sysctl_root_device(SYSCTLFN_ARGS)
2079{
2080	struct sysctlnode node;
2081
2082	node = *rnode;
2083	node.sysctl_data = root_device->dv_xname;
2084	node.sysctl_size = strlen(root_device->dv_xname) + 1;
2085	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2086}
2087
2088/*
2089 * sysctl helper routine for kern.consdev, dependent on the current
2090 * state of the console.  also used for machdep.console_device on some
2091 * ports.
2092 */
2093int
2094sysctl_consdev(SYSCTLFN_ARGS)
2095{
2096	dev_t consdev;
2097	struct sysctlnode node;
2098
2099	if (cn_tab != NULL)
2100		consdev = cn_tab->cn_dev;
2101	else
2102		consdev = NODEV;
2103	node = *rnode;
2104	node.sysctl_data = &consdev;
2105	node.sysctl_size = sizeof(consdev);
2106	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
2107}
2108
2109/*
2110 * ********************************************************************
2111 * section 4: support for some helpers
2112 * ********************************************************************
2113 */
2114
2115/*
2116 * Fill in a kinfo_proc2 structure for the specified process.
2117 */
2118static void
2119fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
2120{
2121	struct tty *tp;
2122	struct lwp *l;
2123	struct timeval ut, st;
2124
2125	memset(ki, 0, sizeof(*ki));
2126
2127	ki->p_paddr = PTRTOINT64(p);
2128	ki->p_fd = PTRTOINT64(p->p_fd);
2129	ki->p_cwdi = PTRTOINT64(p->p_cwdi);
2130	ki->p_stats = PTRTOINT64(p->p_stats);
2131	ki->p_limit = PTRTOINT64(p->p_limit);
2132	ki->p_vmspace = PTRTOINT64(p->p_vmspace);
2133	ki->p_sigacts = PTRTOINT64(p->p_sigacts);
2134	ki->p_sess = PTRTOINT64(p->p_session);
2135	ki->p_tsess = 0;	/* may be changed if controlling tty below */
2136	ki->p_ru = PTRTOINT64(p->p_ru);
2137
2138	ki->p_eflag = 0;
2139	ki->p_exitsig = p->p_exitsig;
2140	ki->p_flag = p->p_flag;
2141
2142	ki->p_pid = p->p_pid;
2143	if (p->p_pptr)
2144		ki->p_ppid = p->p_pptr->p_pid;
2145	else
2146		ki->p_ppid = 0;
2147	ki->p_sid = p->p_session->s_sid;
2148	ki->p__pgid = p->p_pgrp->pg_id;
2149
2150	ki->p_tpgid = NO_PGID;	/* may be changed if controlling tty below */
2151
2152	ki->p_uid = p->p_ucred->cr_uid;
2153	ki->p_ruid = p->p_cred->p_ruid;
2154	ki->p_gid = p->p_ucred->cr_gid;
2155	ki->p_rgid = p->p_cred->p_rgid;
2156	ki->p_svuid = p->p_cred->p_svuid;
2157	ki->p_svgid = p->p_cred->p_svgid;
2158
2159	memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups,
2160	    min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups)));
2161	ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups;
2162
2163	ki->p_jobc = p->p_pgrp->pg_jobc;
2164	if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) {
2165		ki->p_tdev = tp->t_dev;
2166		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
2167		ki->p_tsess = PTRTOINT64(tp->t_session);
2168	} else {
2169		ki->p_tdev = NODEV;
2170	}
2171
2172	ki->p_estcpu = p->p_estcpu;
2173	ki->p_rtime_sec = p->p_rtime.tv_sec;
2174	ki->p_rtime_usec = p->p_rtime.tv_usec;
2175	ki->p_cpticks = p->p_cpticks;
2176	ki->p_pctcpu = p->p_pctcpu;
2177
2178	ki->p_uticks = p->p_uticks;
2179	ki->p_sticks = p->p_sticks;
2180	ki->p_iticks = p->p_iticks;
2181
2182	ki->p_tracep = PTRTOINT64(p->p_tracep);
2183	ki->p_traceflag = p->p_traceflag;
2184
2185
2186	memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t));
2187	memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t));
2188	memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t));
2189	memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t));
2190
2191	ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */
2192	ki->p_realstat = p->p_stat;
2193	ki->p_nice = p->p_nice;
2194
2195	ki->p_xstat = p->p_xstat;
2196	ki->p_acflag = p->p_acflag;
2197
2198	strncpy(ki->p_comm, p->p_comm,
2199	    min(sizeof(ki->p_comm), sizeof(p->p_comm)));
2200
2201	strncpy(ki->p_login, p->p_session->s_login,
2202	    min(sizeof ki->p_login - 1, sizeof p->p_session->s_login));
2203
2204	ki->p_nlwps = p->p_nlwps;
2205	ki->p_nrlwps = p->p_nrlwps;
2206	ki->p_realflag = p->p_flag;
2207
2208	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
2209		ki->p_vm_rssize = 0;
2210		ki->p_vm_tsize = 0;
2211		ki->p_vm_dsize = 0;
2212		ki->p_vm_ssize = 0;
2213		l = NULL;
2214	} else {
2215		struct vmspace *vm = p->p_vmspace;
2216
2217		ki->p_vm_rssize = vm_resident_count(vm);
2218		ki->p_vm_tsize = vm->vm_tsize;
2219		ki->p_vm_dsize = vm->vm_dsize;
2220		ki->p_vm_ssize = vm->vm_ssize;
2221
2222		/* Pick a "representative" LWP */
2223		l = proc_representative_lwp(p);
2224		ki->p_forw = PTRTOINT64(l->l_forw);
2225		ki->p_back = PTRTOINT64(l->l_back);
2226		ki->p_addr = PTRTOINT64(l->l_addr);
2227		ki->p_stat = l->l_stat;
2228		ki->p_flag |= l->l_flag;
2229		ki->p_swtime = l->l_swtime;
2230		ki->p_slptime = l->l_slptime;
2231		if (l->l_stat == LSONPROC) {
2232			KDASSERT(l->l_cpu != NULL);
2233			ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags;
2234		} else
2235			ki->p_schedflags = 0;
2236		ki->p_holdcnt = l->l_holdcnt;
2237		ki->p_priority = l->l_priority;
2238		ki->p_usrpri = l->l_usrpri;
2239		if (l->l_wmesg)
2240			strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg));
2241		ki->p_wchan = PTRTOINT64(l->l_wchan);
2242
2243	}
2244
2245	if (p->p_session->s_ttyvp)
2246		ki->p_eflag |= EPROC_CTTY;
2247	if (SESS_LEADER(p))
2248		ki->p_eflag |= EPROC_SLEADER;
2249
2250	/* XXX Is this double check necessary? */
2251	if (P_ZOMBIE(p)) {
2252		ki->p_uvalid = 0;
2253	} else {
2254		ki->p_uvalid = 1;
2255
2256		ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
2257		ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
2258
2259		calcru(p, &ut, &st, 0);
2260		ki->p_uutime_sec = ut.tv_sec;
2261		ki->p_uutime_usec = ut.tv_usec;
2262		ki->p_ustime_sec = st.tv_sec;
2263		ki->p_ustime_usec = st.tv_usec;
2264
2265		ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
2266		ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
2267		ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
2268		ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
2269		ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
2270		ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
2271		ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
2272		ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
2273		ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
2274		ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
2275		ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
2276		ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
2277		ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw;
2278		ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw;
2279
2280		timeradd(&p->p_stats->p_cru.ru_utime,
2281			 &p->p_stats->p_cru.ru_stime, &ut);
2282		ki->p_uctime_sec = ut.tv_sec;
2283		ki->p_uctime_usec = ut.tv_usec;
2284	}
2285#ifdef MULTIPROCESSOR
2286	if (l && l->l_cpu != NULL)
2287		ki->p_cpuid = l->l_cpu->ci_cpuid;
2288	else
2289#endif
2290		ki->p_cpuid = KI_NOCPU;
2291}
2292
2293/*
2294 * Fill in a kinfo_lwp structure for the specified lwp.
2295 */
2296static void
2297fill_lwp(struct lwp *l, struct kinfo_lwp *kl)
2298{
2299
2300	kl->l_forw = PTRTOINT64(l->l_forw);
2301	kl->l_back = PTRTOINT64(l->l_back);
2302	kl->l_laddr = PTRTOINT64(l);
2303	kl->l_addr = PTRTOINT64(l->l_addr);
2304	kl->l_stat = l->l_stat;
2305	kl->l_lid = l->l_lid;
2306	kl->l_flag = l->l_flag;
2307
2308	kl->l_swtime = l->l_swtime;
2309	kl->l_slptime = l->l_slptime;
2310	if (l->l_stat == LSONPROC) {
2311		KDASSERT(l->l_cpu != NULL);
2312		kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags;
2313	} else
2314		kl->l_schedflags = 0;
2315	kl->l_holdcnt = l->l_holdcnt;
2316	kl->l_priority = l->l_priority;
2317	kl->l_usrpri = l->l_usrpri;
2318	if (l->l_wmesg)
2319		strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg));
2320	kl->l_wchan = PTRTOINT64(l->l_wchan);
2321#ifdef MULTIPROCESSOR
2322	if (l->l_cpu != NULL)
2323		kl->l_cpuid = l->l_cpu->ci_cpuid;
2324	else
2325#endif
2326		kl->l_cpuid = KI_NOCPU;
2327}
2328
2329/*
2330 * Fill in an eproc structure for the specified process.
2331 */
2332void
2333fill_eproc(struct proc *p, struct eproc *ep)
2334{
2335	struct tty *tp;
2336	struct lwp *l;
2337
2338	ep->e_paddr = p;
2339	ep->e_sess = p->p_session;
2340	ep->e_pcred = *p->p_cred;
2341	ep->e_ucred = *p->p_ucred;
2342	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
2343		ep->e_vm.vm_rssize = 0;
2344		ep->e_vm.vm_tsize = 0;
2345		ep->e_vm.vm_dsize = 0;
2346		ep->e_vm.vm_ssize = 0;
2347		/* ep->e_vm.vm_pmap = XXX; */
2348	} else {
2349		struct vmspace *vm = p->p_vmspace;
2350
2351		ep->e_vm.vm_rssize = vm_resident_count(vm);
2352		ep->e_vm.vm_tsize = vm->vm_tsize;
2353		ep->e_vm.vm_dsize = vm->vm_dsize;
2354		ep->e_vm.vm_ssize = vm->vm_ssize;
2355
2356		/* Pick a "representative" LWP */
2357		l = proc_representative_lwp(p);
2358
2359		if (l->l_wmesg)
2360			strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN);
2361	}
2362	if (p->p_pptr)
2363		ep->e_ppid = p->p_pptr->p_pid;
2364	else
2365		ep->e_ppid = 0;
2366	ep->e_pgid = p->p_pgrp->pg_id;
2367	ep->e_sid = ep->e_sess->s_sid;
2368	ep->e_jobc = p->p_pgrp->pg_jobc;
2369	if ((p->p_flag & P_CONTROLT) &&
2370	    (tp = ep->e_sess->s_ttyp)) {
2371		ep->e_tdev = tp->t_dev;
2372		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
2373		ep->e_tsess = tp->t_session;
2374	} else
2375		ep->e_tdev = NODEV;
2376
2377	ep->e_xsize = ep->e_xrssize = 0;
2378	ep->e_xccount = ep->e_xswrss = 0;
2379	ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
2380	if (SESS_LEADER(p))
2381		ep->e_flag |= EPROC_SLEADER;
2382	strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME);
2383}
2384