xref: /openbsd-src/sys/kern/kern_sysctl.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /*	$OpenBSD: kern_sysctl.c,v 1.415 2023/05/21 12:47:54 claudio Exp $	*/
2 /*	$NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $	*/
3 
4 /*-
5  * Copyright (c) 1982, 1986, 1989, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Mike Karels at Berkeley Software Design, Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)kern_sysctl.c	8.4 (Berkeley) 4/14/94
36  */
37 
38 /*
39  * sysctl system call.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #include <sys/pool.h>
47 #include <sys/proc.h>
48 #include <sys/resourcevar.h>
49 #include <sys/signalvar.h>
50 #include <sys/fcntl.h>
51 #include <sys/file.h>
52 #include <sys/filedesc.h>
53 #include <sys/vnode.h>
54 #include <sys/unistd.h>
55 #include <sys/buf.h>
56 #include <sys/clockintr.h>
57 #include <sys/tty.h>
58 #include <sys/disklabel.h>
59 #include <sys/disk.h>
60 #include <sys/sysctl.h>
61 #include <sys/msgbuf.h>
62 #include <sys/vmmeter.h>
63 #include <sys/namei.h>
64 #include <sys/exec.h>
65 #include <sys/mbuf.h>
66 #include <sys/percpu.h>
67 #include <sys/sensors.h>
68 #include <sys/pipe.h>
69 #include <sys/eventvar.h>
70 #include <sys/socketvar.h>
71 #include <sys/socket.h>
72 #include <sys/domain.h>
73 #include <sys/protosw.h>
74 #include <sys/pledge.h>
75 #include <sys/timetc.h>
76 #include <sys/evcount.h>
77 #include <sys/un.h>
78 #include <sys/unpcb.h>
79 #include <sys/sched.h>
80 #include <sys/mount.h>
81 #include <sys/syscallargs.h>
82 #include <sys/wait.h>
83 #include <sys/witness.h>
84 
85 #include <uvm/uvm_extern.h>
86 
87 #include <dev/cons.h>
88 
89 #include <net/route.h>
90 #include <netinet/in.h>
91 #include <netinet/ip.h>
92 #include <netinet/ip_var.h>
93 #include <netinet/in_pcb.h>
94 #include <netinet/ip6.h>
95 #include <netinet/tcp.h>
96 #include <netinet/tcp_timer.h>
97 #include <netinet/tcp_var.h>
98 #include <netinet/udp.h>
99 #include <netinet/udp_var.h>
100 #include <netinet6/ip6_var.h>
101 
102 #ifdef DDB
103 #include <ddb/db_var.h>
104 #endif
105 
106 #ifdef SYSVMSG
107 #include <sys/msg.h>
108 #endif
109 #ifdef SYSVSEM
110 #include <sys/sem.h>
111 #endif
112 #ifdef SYSVSHM
113 #include <sys/shm.h>
114 #endif
115 
116 #include "audio.h"
117 #include "dt.h"
118 #include "pf.h"
119 #include "video.h"
120 
121 extern struct forkstat forkstat;
122 extern struct nchstats nchstats;
123 extern int fscale;
124 extern fixpt_t ccpu;
125 extern long numvnodes;
126 extern int allowdt;
127 extern int audio_record_enable;
128 extern int video_record_enable;
129 extern int autoconf_serial;
130 
131 int allowkmem;
132 
133 int sysctl_diskinit(int, struct proc *);
134 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
135 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *);
136 int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *,
137 	struct proc *);
138 int sysctl_proc_vmmap(int *, u_int, void *, size_t *, struct proc *);
139 int sysctl_intrcnt(int *, u_int, void *, size_t *);
140 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
141 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
142 int sysctl_audio(int *, u_int, void *, size_t *, void *, size_t);
143 int sysctl_video(int *, u_int, void *, size_t *, void *, size_t);
144 int sysctl_cpustats(int *, u_int, void *, size_t *, void *, size_t);
145 int sysctl_utc_offset(void *, size_t *, void *, size_t);
146 int sysctl_hwbattery(int *, u_int, void *, size_t *, void *, size_t);
147 
148 void fill_file(struct kinfo_file *, struct file *, struct filedesc *, int,
149     struct vnode *, struct process *, struct proc *, struct socket *, int);
150 void fill_kproc(struct process *, struct kinfo_proc *, struct proc *, int);
151 
152 int (*cpu_cpuspeed)(int *);
153 
154 /*
155  * Lock to avoid too many processes vslocking a large amount of memory
156  * at the same time.
157  */
158 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk");
159 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk");
160 
161 int
162 sys_sysctl(struct proc *p, void *v, register_t *retval)
163 {
164 	struct sys_sysctl_args /* {
165 		syscallarg(const int *) name;
166 		syscallarg(u_int) namelen;
167 		syscallarg(void *) old;
168 		syscallarg(size_t *) oldlenp;
169 		syscallarg(void *) new;
170 		syscallarg(size_t) newlen;
171 	} */ *uap = v;
172 	int error, dolock = 1;
173 	size_t savelen = 0, oldlen = 0;
174 	sysctlfn *fn;
175 	int name[CTL_MAXNAME];
176 
177 	if (SCARG(uap, new) != NULL &&
178 	    (error = suser(p)))
179 		return (error);
180 	/*
181 	 * all top-level sysctl names are non-terminal
182 	 */
183 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
184 		return (EINVAL);
185 	error = copyin(SCARG(uap, name), name,
186 		       SCARG(uap, namelen) * sizeof(int));
187 	if (error)
188 		return (error);
189 
190 	error = pledge_sysctl(p, SCARG(uap, namelen),
191 	    name, SCARG(uap, new));
192 	if (error)
193 		return (error);
194 
195 	switch (name[0]) {
196 	case CTL_KERN:
197 		fn = kern_sysctl;
198 		break;
199 	case CTL_HW:
200 		fn = hw_sysctl;
201 		break;
202 	case CTL_VM:
203 		fn = uvm_sysctl;
204 		break;
205 	case CTL_NET:
206 		fn = net_sysctl;
207 		break;
208 	case CTL_FS:
209 		fn = fs_sysctl;
210 		break;
211 	case CTL_VFS:
212 		fn = vfs_sysctl;
213 		break;
214 	case CTL_MACHDEP:
215 		fn = cpu_sysctl;
216 		break;
217 #ifdef DEBUG_SYSCTL
218 	case CTL_DEBUG:
219 		fn = debug_sysctl;
220 		break;
221 #endif
222 #ifdef DDB
223 	case CTL_DDB:
224 		fn = ddb_sysctl;
225 		break;
226 #endif
227 	default:
228 		return (EOPNOTSUPP);
229 	}
230 
231 	if (SCARG(uap, oldlenp) &&
232 	    (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
233 		return (error);
234 	if (SCARG(uap, old) != NULL) {
235 		if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0)
236 			return (error);
237 		if (dolock) {
238 			if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) {
239 				rw_exit_write(&sysctl_lock);
240 				return (ENOMEM);
241 			}
242 			error = uvm_vslock(p, SCARG(uap, old), oldlen,
243 			    PROT_READ | PROT_WRITE);
244 			if (error) {
245 				rw_exit_write(&sysctl_lock);
246 				return (error);
247 			}
248 		}
249 		savelen = oldlen;
250 	}
251 	error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old),
252 	    &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
253 	if (SCARG(uap, old) != NULL) {
254 		if (dolock)
255 			uvm_vsunlock(p, SCARG(uap, old), savelen);
256 		rw_exit_write(&sysctl_lock);
257 	}
258 	if (error)
259 		return (error);
260 	if (SCARG(uap, oldlenp))
261 		error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
262 	return (error);
263 }
264 
265 /*
266  * Attributes stored in the kernel.
267  */
268 char hostname[MAXHOSTNAMELEN];
269 int hostnamelen;
270 char domainname[MAXHOSTNAMELEN];
271 int domainnamelen;
272 long hostid;
273 char *disknames = NULL;
274 size_t disknameslen;
275 struct diskstats *diskstats = NULL;
276 size_t diskstatslen;
277 int securelevel;
278 
279 /* morally const values reported by sysctl_bounded_arr */
280 static int arg_max = ARG_MAX;
281 static int openbsd = OpenBSD;
282 static int posix_version = _POSIX_VERSION;
283 static int ngroups_max = NGROUPS_MAX;
284 static int int_zero = 0;
285 static int int_one = 1;
286 static int maxpartitions = MAXPARTITIONS;
287 static int raw_part = RAW_PART;
288 
289 extern int somaxconn, sominconn;
290 extern int nosuidcoredump;
291 extern int maxlocksperuid;
292 extern int uvm_wxabort;
293 extern int global_ptrace;
294 
295 const struct sysctl_bounded_args kern_vars[] = {
296 	{KERN_OSREV, &openbsd, SYSCTL_INT_READONLY},
297 	{KERN_MAXVNODES, &maxvnodes, 0, INT_MAX},
298 	{KERN_MAXPROC, &maxprocess, 0, INT_MAX},
299 	{KERN_MAXFILES, &maxfiles, 0, INT_MAX},
300 	{KERN_NFILES, &numfiles, SYSCTL_INT_READONLY},
301 	{KERN_TTYCOUNT, &tty_count, SYSCTL_INT_READONLY},
302 	{KERN_ARGMAX, &arg_max, SYSCTL_INT_READONLY},
303 	{KERN_POSIX1, &posix_version, SYSCTL_INT_READONLY},
304 	{KERN_NGROUPS, &ngroups_max, SYSCTL_INT_READONLY},
305 	{KERN_JOB_CONTROL, &int_one, SYSCTL_INT_READONLY},
306 	{KERN_SAVED_IDS, &int_one, SYSCTL_INT_READONLY},
307 	{KERN_MAXPARTITIONS, &maxpartitions, SYSCTL_INT_READONLY},
308 	{KERN_RAWPARTITION, &raw_part, SYSCTL_INT_READONLY},
309 	{KERN_MAXTHREAD, &maxthread, 0, INT_MAX},
310 	{KERN_NTHREADS, &nthreads, SYSCTL_INT_READONLY},
311 	{KERN_SOMAXCONN, &somaxconn, 0, SHRT_MAX},
312 	{KERN_SOMINCONN, &sominconn, 0, SHRT_MAX},
313 	{KERN_NOSUIDCOREDUMP, &nosuidcoredump, 0, 3},
314 	{KERN_FSYNC, &int_one, SYSCTL_INT_READONLY},
315 	{KERN_SYSVMSG,
316 #ifdef SYSVMSG
317 	 &int_one,
318 #else
319 	 &int_zero,
320 #endif
321 	 SYSCTL_INT_READONLY},
322 	{KERN_SYSVSEM,
323 #ifdef SYSVSEM
324 	 &int_one,
325 #else
326 	 &int_zero,
327 #endif
328 	 SYSCTL_INT_READONLY},
329 	{KERN_SYSVSHM,
330 #ifdef SYSVSHM
331 	 &int_one,
332 #else
333 	 &int_zero,
334 #endif
335 	 SYSCTL_INT_READONLY},
336 	{KERN_FSCALE, &fscale, SYSCTL_INT_READONLY},
337 	{KERN_CCPU, &ccpu, SYSCTL_INT_READONLY},
338 	{KERN_NPROCS, &nprocesses, SYSCTL_INT_READONLY},
339 	{KERN_SPLASSERT, &splassert_ctl, 0, 3},
340 	{KERN_MAXLOCKSPERUID, &maxlocksperuid, 0, INT_MAX},
341 	{KERN_WXABORT, &uvm_wxabort, 0, 1},
342 	{KERN_NETLIVELOCKS, &int_zero, SYSCTL_INT_READONLY},
343 #ifdef PTRACE
344 	{KERN_GLOBAL_PTRACE, &global_ptrace, 0, 1},
345 #endif
346 	{KERN_AUTOCONF_SERIAL, &autoconf_serial, SYSCTL_INT_READONLY},
347 };
348 
349 int
350 kern_sysctl_dirs(int top_name, int *name, u_int namelen,
351     void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p)
352 {
353 	switch (top_name) {
354 #ifndef SMALL_KERNEL
355 	case KERN_PROC:
356 		return (sysctl_doproc(name, namelen, oldp, oldlenp));
357 	case KERN_PROC_ARGS:
358 		return (sysctl_proc_args(name, namelen, oldp, oldlenp, p));
359 	case KERN_PROC_CWD:
360 		return (sysctl_proc_cwd(name, namelen, oldp, oldlenp, p));
361 	case KERN_PROC_NOBROADCASTKILL:
362 		return (sysctl_proc_nobroadcastkill(name, namelen,
363 		     newp, newlen, oldp, oldlenp, p));
364 	case KERN_PROC_VMMAP:
365 		return (sysctl_proc_vmmap(name, namelen, oldp, oldlenp, p));
366 	case KERN_FILE:
367 		return (sysctl_file(name, namelen, oldp, oldlenp, p));
368 #endif
369 #if defined(GPROF) || defined(DDBPROF)
370 	case KERN_PROF:
371 		return (sysctl_doprof(name, namelen, oldp, oldlenp,
372 		    newp, newlen));
373 #endif
374 	case KERN_MALLOCSTATS:
375 		return (sysctl_malloc(name, namelen, oldp, oldlenp,
376 		    newp, newlen, p));
377 	case KERN_TTY:
378 		return (sysctl_tty(name, namelen, oldp, oldlenp,
379 		    newp, newlen));
380 	case KERN_POOL:
381 		return (sysctl_dopool(name, namelen, oldp, oldlenp));
382 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
383 	case KERN_SYSVIPC_INFO:
384 		return (sysctl_sysvipc(name, namelen, oldp, oldlenp));
385 #endif
386 #ifdef SYSVSEM
387 	case KERN_SEMINFO:
388 		return (sysctl_sysvsem(name, namelen, oldp, oldlenp,
389 		    newp, newlen));
390 #endif
391 #ifdef SYSVSHM
392 	case KERN_SHMINFO:
393 		return (sysctl_sysvshm(name, namelen, oldp, oldlenp,
394 		    newp, newlen));
395 #endif
396 #ifndef SMALL_KERNEL
397 	case KERN_INTRCNT:
398 		return (sysctl_intrcnt(name, namelen, oldp, oldlenp));
399 	case KERN_WATCHDOG:
400 		return (sysctl_wdog(name, namelen, oldp, oldlenp,
401 		    newp, newlen));
402 #endif
403 #ifndef SMALL_KERNEL
404 	case KERN_EVCOUNT:
405 		return (evcount_sysctl(name, namelen, oldp, oldlenp,
406 		    newp, newlen));
407 #endif
408 	case KERN_TIMECOUNTER:
409 		return (sysctl_tc(name, namelen, oldp, oldlenp, newp, newlen));
410 	case KERN_CPTIME2:
411 		return (sysctl_cptime2(name, namelen, oldp, oldlenp,
412 		    newp, newlen));
413 #ifdef WITNESS
414 	case KERN_WITNESSWATCH:
415 		return witness_sysctl_watch(oldp, oldlenp, newp, newlen);
416 	case KERN_WITNESS:
417 		return witness_sysctl(name, namelen, oldp, oldlenp,
418 		    newp, newlen);
419 #endif
420 #if NAUDIO > 0
421 	case KERN_AUDIO:
422 		return (sysctl_audio(name, namelen, oldp, oldlenp,
423 		    newp, newlen));
424 #endif
425 #if NVIDEO > 0
426 	case KERN_VIDEO:
427 		return (sysctl_video(name, namelen, oldp, oldlenp,
428 		    newp, newlen));
429 #endif
430 	case KERN_CPUSTATS:
431 		return (sysctl_cpustats(name, namelen, oldp, oldlenp,
432 		    newp, newlen));
433 #ifdef __HAVE_CLOCKINTR
434 	case KERN_CLOCKINTR:
435 		return sysctl_clockintr(name, namelen, oldp, oldlenp, newp,
436 		    newlen);
437 #endif
438 	default:
439 		return (ENOTDIR);	/* overloaded */
440 	}
441 }
442 
443 /*
444  * kernel related system variables.
445  */
446 int
447 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
448     size_t newlen, struct proc *p)
449 {
450 	int error, level, inthostid, stackgap;
451 	dev_t dev;
452 	extern int pool_debug;
453 
454 	/* dispatch the non-terminal nodes first */
455 	if (namelen != 1) {
456 		return kern_sysctl_dirs(name[0], name + 1, namelen - 1,
457 		    oldp, oldlenp, newp, newlen, p);
458 	}
459 
460 	switch (name[0]) {
461 	case KERN_OSTYPE:
462 		return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
463 	case KERN_OSRELEASE:
464 		return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
465 	case KERN_OSVERSION:
466 		return (sysctl_rdstring(oldp, oldlenp, newp, osversion));
467 	case KERN_VERSION:
468 		return (sysctl_rdstring(oldp, oldlenp, newp, version));
469 	case KERN_NUMVNODES:  /* XXX numvnodes is a long */
470 		return (sysctl_rdint(oldp, oldlenp, newp, numvnodes));
471 	case KERN_SECURELVL:
472 		level = securelevel;
473 		if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
474 		    newp == NULL)
475 			return (error);
476 		if ((securelevel > 0 || level < -1) &&
477 		    level < securelevel && p->p_p->ps_pid != 1)
478 			return (EPERM);
479 		securelevel = level;
480 		return (0);
481 #if NDT > 0
482 	case KERN_ALLOWDT:
483 		return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen,
484 		    &allowdt));
485 #endif
486 	case KERN_ALLOWKMEM:
487 		return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen,
488 		    &allowkmem));
489 	case KERN_HOSTNAME:
490 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
491 		    hostname, sizeof(hostname));
492 		if (newp && !error)
493 			hostnamelen = newlen;
494 		return (error);
495 	case KERN_DOMAINNAME:
496 		if (securelevel >= 1 && domainnamelen && newp)
497 			error = EPERM;
498 		else
499 			error = sysctl_tstring(oldp, oldlenp, newp, newlen,
500 			    domainname, sizeof(domainname));
501 		if (newp && !error)
502 			domainnamelen = newlen;
503 		return (error);
504 	case KERN_HOSTID:
505 		inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */
506 		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
507 		hostid = inthostid;
508 		return (error);
509 	case KERN_CLOCKRATE:
510 		return (sysctl_clockrate(oldp, oldlenp, newp));
511 	case KERN_BOOTTIME: {
512 		struct timeval bt;
513 		memset(&bt, 0, sizeof bt);
514 		microboottime(&bt);
515 		return (sysctl_rdstruct(oldp, oldlenp, newp, &bt, sizeof bt));
516 	  }
517 	case KERN_MBSTAT: {
518 		extern struct cpumem *mbstat;
519 		uint64_t counters[MBSTAT_COUNT];
520 		struct mbstat mbs;
521 		unsigned int i;
522 
523 		memset(&mbs, 0, sizeof(mbs));
524 		counters_read(mbstat, counters, MBSTAT_COUNT);
525 		for (i = 0; i < MBSTAT_TYPES; i++)
526 			mbs.m_mtypes[i] = counters[i];
527 
528 		mbs.m_drops = counters[MBSTAT_DROPS];
529 		mbs.m_wait = counters[MBSTAT_WAIT];
530 		mbs.m_drain = counters[MBSTAT_DRAIN];
531 
532 		return (sysctl_rdstruct(oldp, oldlenp, newp,
533 		    &mbs, sizeof(mbs)));
534 	}
535 	case KERN_MSGBUFSIZE:
536 	case KERN_CONSBUFSIZE: {
537 		struct msgbuf *mp;
538 		mp = (name[0] == KERN_MSGBUFSIZE) ? msgbufp : consbufp;
539 		/*
540 		 * deal with cases where the message buffer has
541 		 * become corrupted.
542 		 */
543 		if (!mp || mp->msg_magic != MSG_MAGIC)
544 			return (ENXIO);
545 		return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
546 	}
547 	case KERN_CONSBUF:
548 		if ((error = suser(p)))
549 			return (error);
550 		/* FALLTHROUGH */
551 	case KERN_MSGBUF: {
552 		struct msgbuf *mp;
553 		mp = (name[0] == KERN_MSGBUF) ? msgbufp : consbufp;
554 		/* see note above */
555 		if (!mp || mp->msg_magic != MSG_MAGIC)
556 			return (ENXIO);
557 		return (sysctl_rdstruct(oldp, oldlenp, newp, mp,
558 		    mp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
559 	}
560 	case KERN_CPTIME:
561 	{
562 		CPU_INFO_ITERATOR cii;
563 		struct cpu_info *ci;
564 		long cp_time[CPUSTATES];
565 		int i, n = 0;
566 
567 		memset(cp_time, 0, sizeof(cp_time));
568 
569 		CPU_INFO_FOREACH(cii, ci) {
570 			if (!cpu_is_online(ci))
571 				continue;
572 			n++;
573 			for (i = 0; i < CPUSTATES; i++)
574 				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
575 		}
576 
577 		for (i = 0; i < CPUSTATES; i++)
578 			cp_time[i] /= n;
579 
580 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time,
581 		    sizeof(cp_time)));
582 	}
583 	case KERN_NCHSTATS:
584 		return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats,
585 		    sizeof(struct nchstats)));
586 	case KERN_FORKSTAT:
587 		return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat,
588 		    sizeof(struct forkstat)));
589 	case KERN_STACKGAPRANDOM:
590 		stackgap = stackgap_random;
591 		error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap);
592 		if (error)
593 			return (error);
594 		/*
595 		 * Safety harness.
596 		 */
597 		if ((stackgap < ALIGNBYTES && stackgap != 0) ||
598 		    !powerof2(stackgap) || stackgap >= MAXSSIZ)
599 			return (EINVAL);
600 		stackgap_random = stackgap;
601 		return (0);
602 	case KERN_MAXCLUSTERS: {
603 		int val = nmbclust;
604 		error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
605 		if (error == 0 && val != nmbclust)
606 			error = nmbclust_update(val);
607 		return (error);
608 	}
609 	case KERN_CACHEPCT: {
610 		u_int64_t dmapages;
611 		int opct, pgs;
612 		opct = bufcachepercent;
613 		error = sysctl_int(oldp, oldlenp, newp, newlen,
614 		    &bufcachepercent);
615 		if (error)
616 			return(error);
617 		if (bufcachepercent > 90 || bufcachepercent < 5) {
618 			bufcachepercent = opct;
619 			return (EINVAL);
620 		}
621 		dmapages = uvm_pagecount(&dma_constraint);
622 		if (bufcachepercent != opct) {
623 			pgs = bufcachepercent * dmapages / 100;
624 			bufadjust(pgs); /* adjust bufpages */
625 			bufhighpages = bufpages; /* set high water mark */
626 		}
627 		return(0);
628 	}
629 	case KERN_CONSDEV:
630 		if (cn_tab != NULL)
631 			dev = cn_tab->cn_dev;
632 		else
633 			dev = NODEV;
634 		return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
635 	case KERN_POOL_DEBUG: {
636 		int old_pool_debug = pool_debug;
637 
638 		error = sysctl_int(oldp, oldlenp, newp, newlen,
639 		    &pool_debug);
640 		if (error == 0 && pool_debug != old_pool_debug)
641 			pool_reclaim_all();
642 		return (error);
643 	}
644 #if NPF > 0
645 	case KERN_PFSTATUS:
646 		return (pf_sysctl(oldp, oldlenp, newp, newlen));
647 #endif
648 	case KERN_TIMEOUT_STATS:
649 		return (timeout_sysctl(oldp, oldlenp, newp, newlen));
650 	case KERN_UTC_OFFSET:
651 		return (sysctl_utc_offset(oldp, oldlenp, newp, newlen));
652 	default:
653 		return (sysctl_bounded_arr(kern_vars, nitems(kern_vars), name,
654 		    namelen, oldp, oldlenp, newp, newlen));
655 	}
656 	/* NOTREACHED */
657 }
658 
659 /*
660  * hardware related system variables.
661  */
662 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
663 int allowpowerdown = 1;
664 int hw_power = 1;
665 
666 /* morally const values reported by sysctl_bounded_arr */
667 static int byte_order = BYTE_ORDER;
668 static int page_size = PAGE_SIZE;
669 
670 const struct sysctl_bounded_args hw_vars[] = {
671 	{HW_NCPU, &ncpus, SYSCTL_INT_READONLY},
672 	{HW_NCPUFOUND, &ncpusfound, SYSCTL_INT_READONLY},
673 	{HW_BYTEORDER, &byte_order, SYSCTL_INT_READONLY},
674 	{HW_PAGESIZE, &page_size, SYSCTL_INT_READONLY},
675 	{HW_DISKCOUNT, &disk_count, SYSCTL_INT_READONLY},
676 	{HW_POWER, &hw_power, SYSCTL_INT_READONLY},
677 };
678 
679 int
680 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
681     size_t newlen, struct proc *p)
682 {
683 	extern char machine[], cpu_model[];
684 	int err, cpuspeed;
685 
686 	/*
687 	 * all sysctl names at this level except sensors and battery
688 	 * are terminal
689 	 */
690 	if (name[0] != HW_SENSORS && name[0] != HW_BATTERY && namelen != 1)
691 		return (ENOTDIR);		/* overloaded */
692 
693 	switch (name[0]) {
694 	case HW_MACHINE:
695 		return (sysctl_rdstring(oldp, oldlenp, newp, machine));
696 	case HW_MODEL:
697 		return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
698 	case HW_NCPUONLINE:
699 		return (sysctl_rdint(oldp, oldlenp, newp,
700 		    sysctl_hwncpuonline()));
701 	case HW_PHYSMEM:
702 		return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem)));
703 	case HW_USERMEM:
704 		return (sysctl_rdint(oldp, oldlenp, newp,
705 		    ptoa(physmem - uvmexp.wired)));
706 	case HW_DISKNAMES:
707 		err = sysctl_diskinit(0, p);
708 		if (err)
709 			return err;
710 		if (disknames)
711 			return (sysctl_rdstring(oldp, oldlenp, newp,
712 			    disknames));
713 		else
714 			return (sysctl_rdstring(oldp, oldlenp, newp, ""));
715 	case HW_DISKSTATS:
716 		err = sysctl_diskinit(1, p);
717 		if (err)
718 			return err;
719 		return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats,
720 		    disk_count * sizeof(struct diskstats)));
721 	case HW_CPUSPEED:
722 		if (!cpu_cpuspeed)
723 			return (EOPNOTSUPP);
724 		err = cpu_cpuspeed(&cpuspeed);
725 		if (err)
726 			return err;
727 		return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
728 #ifndef	SMALL_KERNEL
729 	case HW_SENSORS:
730 		return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
731 		    newp, newlen));
732 	case HW_SETPERF:
733 		return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen));
734 	case HW_PERFPOLICY:
735 		return (sysctl_hwperfpolicy(oldp, oldlenp, newp, newlen));
736 #endif /* !SMALL_KERNEL */
737 	case HW_VENDOR:
738 		if (hw_vendor)
739 			return (sysctl_rdstring(oldp, oldlenp, newp,
740 			    hw_vendor));
741 		else
742 			return (EOPNOTSUPP);
743 	case HW_PRODUCT:
744 		if (hw_prod)
745 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod));
746 		else
747 			return (EOPNOTSUPP);
748 	case HW_VERSION:
749 		if (hw_ver)
750 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver));
751 		else
752 			return (EOPNOTSUPP);
753 	case HW_SERIALNO:
754 		if (hw_serial)
755 			return (sysctl_rdstring(oldp, oldlenp, newp,
756 			    hw_serial));
757 		else
758 			return (EOPNOTSUPP);
759 	case HW_UUID:
760 		if (hw_uuid)
761 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid));
762 		else
763 			return (EOPNOTSUPP);
764 	case HW_PHYSMEM64:
765 		return (sysctl_rdquad(oldp, oldlenp, newp,
766 		    ptoa((psize_t)physmem)));
767 	case HW_USERMEM64:
768 		return (sysctl_rdquad(oldp, oldlenp, newp,
769 		    ptoa((psize_t)physmem - uvmexp.wired)));
770 	case HW_ALLOWPOWERDOWN:
771 		return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen,
772 		    &allowpowerdown));
773 #ifdef __HAVE_CPU_TOPOLOGY
774 	case HW_SMT:
775 		return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
776 #endif
777 #ifndef SMALL_KERNEL
778 	case HW_BATTERY:
779 		return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp,
780 		    newp, newlen));
781 #endif
782 	default:
783 		return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name,
784 		    namelen, oldp, oldlenp, newp, newlen);
785 	}
786 	/* NOTREACHED */
787 }
788 
789 #ifndef SMALL_KERNEL
790 
791 int hw_battery_chargemode;
792 int hw_battery_chargestart;
793 int hw_battery_chargestop;
794 int (*hw_battery_setchargemode)(int);
795 int (*hw_battery_setchargestart)(int);
796 int (*hw_battery_setchargestop)(int);
797 
798 int
799 sysctl_hwchargemode(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
800 {
801 	int mode = hw_battery_chargemode;
802 	int error;
803 
804 	if (!hw_battery_setchargemode)
805 		return EOPNOTSUPP;
806 
807 	error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
808 	    &mode, -1, 1);
809 	if (error)
810 		return error;
811 
812 	if (newp != NULL)
813 		error = hw_battery_setchargemode(mode);
814 
815 	return error;
816 }
817 
818 int
819 sysctl_hwchargestart(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
820 {
821 	int start = hw_battery_chargestart;
822 	int error;
823 
824 	if (!hw_battery_setchargestart)
825 		return EOPNOTSUPP;
826 
827 	error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
828 	    &start, 0, 100);
829 	if (error)
830 		return error;
831 
832 	if (newp != NULL)
833 		error = hw_battery_setchargestart(start);
834 
835 	return error;
836 }
837 
838 int
839 sysctl_hwchargestop(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
840 {
841 	int stop = hw_battery_chargestop;
842 	int error;
843 
844 	if (!hw_battery_setchargestop)
845 		return EOPNOTSUPP;
846 
847 	error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
848 	    &stop, 0, 100);
849 	if (error)
850 		return error;
851 
852 	if (newp != NULL)
853 		error = hw_battery_setchargestop(stop);
854 
855 	return error;
856 }
857 
858 int
859 sysctl_hwbattery(int *name, u_int namelen, void *oldp, size_t *oldlenp,
860     void *newp, size_t newlen)
861 {
862 	if (namelen != 1)
863 		return (ENOTDIR);
864 
865 	switch (name[0]) {
866 	case HW_BATTERY_CHARGEMODE:
867 		return (sysctl_hwchargemode(oldp, oldlenp, newp, newlen));
868 	case HW_BATTERY_CHARGESTART:
869 		return (sysctl_hwchargestart(oldp, oldlenp, newp, newlen));
870 	case HW_BATTERY_CHARGESTOP:
871 		return (sysctl_hwchargestop(oldp, oldlenp, newp, newlen));
872 	default:
873 		return (EOPNOTSUPP);
874 	}
875 	/* NOTREACHED */
876 }
877 
878 #endif
879 
880 #ifdef DEBUG_SYSCTL
881 /*
882  * Debugging related system variables.
883  */
884 extern struct ctldebug debug_vfs_busyprt;
885 struct ctldebug debug1, debug2, debug3, debug4;
886 struct ctldebug debug5, debug6, debug7, debug8, debug9;
887 struct ctldebug debug10, debug11, debug12, debug13, debug14;
888 struct ctldebug debug15, debug16, debug17, debug18, debug19;
889 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
890 	&debug_vfs_busyprt,
891 	&debug1, &debug2, &debug3, &debug4,
892 	&debug5, &debug6, &debug7, &debug8, &debug9,
893 	&debug10, &debug11, &debug12, &debug13, &debug14,
894 	&debug15, &debug16, &debug17, &debug18, &debug19,
895 };
896 int
897 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
898     size_t newlen, struct proc *p)
899 {
900 	struct ctldebug *cdp;
901 
902 	/* all sysctl names at this level are name and field */
903 	if (namelen != 2)
904 		return (ENOTDIR);		/* overloaded */
905 	if (name[0] < 0 || name[0] >= nitems(debugvars))
906 		return (EOPNOTSUPP);
907 	cdp = debugvars[name[0]];
908 	if (cdp->debugname == 0)
909 		return (EOPNOTSUPP);
910 	switch (name[1]) {
911 	case CTL_DEBUG_NAME:
912 		return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
913 	case CTL_DEBUG_VALUE:
914 		return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
915 	default:
916 		return (EOPNOTSUPP);
917 	}
918 	/* NOTREACHED */
919 }
920 #endif /* DEBUG_SYSCTL */
921 
922 /*
923  * Reads, or writes that lower the value
924  */
925 int
926 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
927     int *valp)
928 {
929 	unsigned int oval = *valp, val = *valp;
930 	int error;
931 
932 	if (newp == NULL)
933 		return (sysctl_rdint(oldp, oldlenp, newp, val));
934 
935 	if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
936 		return (error);
937 	if (val > oval)
938 		return (EPERM);		/* do not allow raising */
939 	*(unsigned int *)valp = val;
940 	return (0);
941 }
942 
943 /*
944  * Validate parameters and get old / set new parameters
945  * for an integer-valued sysctl function.
946  */
947 int
948 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
949 {
950 	int error = 0;
951 
952 	if (oldp && *oldlenp < sizeof(int))
953 		return (ENOMEM);
954 	if (newp && newlen != sizeof(int))
955 		return (EINVAL);
956 	*oldlenp = sizeof(int);
957 	if (oldp)
958 		error = copyout(valp, oldp, sizeof(int));
959 	if (error == 0 && newp)
960 		error = copyin(newp, valp, sizeof(int));
961 	return (error);
962 }
963 
964 /*
965  * As above, but read-only.
966  */
967 int
968 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val)
969 {
970 	int error = 0;
971 
972 	if (oldp && *oldlenp < sizeof(int))
973 		return (ENOMEM);
974 	if (newp)
975 		return (EPERM);
976 	*oldlenp = sizeof(int);
977 	if (oldp)
978 		error = copyout((caddr_t)&val, oldp, sizeof(int));
979 	return (error);
980 }
981 
982 /*
983  * Selects between sysctl_rdint and sysctl_int according to securelevel.
984  */
985 int
986 sysctl_securelevel_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
987     int *valp)
988 {
989 	if (securelevel > 0)
990 		return (sysctl_rdint(oldp, oldlenp, newp, *valp));
991 	return (sysctl_int(oldp, oldlenp, newp, newlen, valp));
992 }
993 
994 /*
995  * Read-only or bounded integer values.
996  */
997 int
998 sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
999     int *valp, int minimum, int maximum)
1000 {
1001 	int val = *valp;
1002 	int error;
1003 
1004 	/* read only */
1005 	if (newp == NULL || minimum > maximum)
1006 		return (sysctl_rdint(oldp, oldlenp, newp, val));
1007 
1008 	if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
1009 		return (error);
1010 	/* outside limits */
1011 	if (val < minimum || maximum < val)
1012 		return (EINVAL);
1013 	*valp = val;
1014 	return (0);
1015 }
1016 
1017 /*
1018  * Array of read-only or bounded integer values.
1019  */
1020 int
1021 sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen,
1022     int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1023     size_t newlen)
1024 {
1025 	u_int i;
1026 	if (namelen != 1)
1027 		return (ENOTDIR);
1028 	for (i = 0; i < valplen; ++i) {
1029 		if (valpp[i].mib == name[0]) {
1030 			return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
1031 			    valpp[i].var, valpp[i].minimum, valpp[i].maximum));
1032 		}
1033 	}
1034 	return (EOPNOTSUPP);
1035 }
1036 
1037 /*
1038  * Validate parameters and get old / set new parameters
1039  * for an integer-valued sysctl function.
1040  */
1041 int
1042 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
1043     int64_t *valp)
1044 {
1045 	int error = 0;
1046 
1047 	if (oldp && *oldlenp < sizeof(int64_t))
1048 		return (ENOMEM);
1049 	if (newp && newlen != sizeof(int64_t))
1050 		return (EINVAL);
1051 	*oldlenp = sizeof(int64_t);
1052 	if (oldp)
1053 		error = copyout(valp, oldp, sizeof(int64_t));
1054 	if (error == 0 && newp)
1055 		error = copyin(newp, valp, sizeof(int64_t));
1056 	return (error);
1057 }
1058 
1059 /*
1060  * As above, but read-only.
1061  */
1062 int
1063 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val)
1064 {
1065 	int error = 0;
1066 
1067 	if (oldp && *oldlenp < sizeof(int64_t))
1068 		return (ENOMEM);
1069 	if (newp)
1070 		return (EPERM);
1071 	*oldlenp = sizeof(int64_t);
1072 	if (oldp)
1073 		error = copyout((caddr_t)&val, oldp, sizeof(int64_t));
1074 	return (error);
1075 }
1076 
1077 /*
1078  * Validate parameters and get old / set new parameters
1079  * for a string-valued sysctl function.
1080  */
1081 int
1082 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str,
1083     size_t maxlen)
1084 {
1085 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
1086 }
1087 
1088 int
1089 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
1090     char *str, size_t maxlen)
1091 {
1092 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
1093 }
1094 
1095 int
1096 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
1097     char *str, size_t maxlen, int trunc)
1098 {
1099 	size_t len;
1100 	int error = 0;
1101 
1102 	len = strlen(str) + 1;
1103 	if (oldp && *oldlenp < len) {
1104 		if (trunc == 0 || *oldlenp == 0)
1105 			return (ENOMEM);
1106 	}
1107 	if (newp && newlen >= maxlen)
1108 		return (EINVAL);
1109 	if (oldp) {
1110 		if (trunc && *oldlenp < len) {
1111 			len = *oldlenp;
1112 			error = copyout(str, oldp, len - 1);
1113 			if (error == 0)
1114 				error = copyout("", (char *)oldp + len - 1, 1);
1115 		} else {
1116 			error = copyout(str, oldp, len);
1117 		}
1118 	}
1119 	*oldlenp = len;
1120 	if (error == 0 && newp) {
1121 		error = copyin(newp, str, newlen);
1122 		str[newlen] = 0;
1123 	}
1124 	return (error);
1125 }
1126 
1127 /*
1128  * As above, but read-only.
1129  */
1130 int
1131 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str)
1132 {
1133 	size_t len;
1134 	int error = 0;
1135 
1136 	len = strlen(str) + 1;
1137 	if (oldp && *oldlenp < len)
1138 		return (ENOMEM);
1139 	if (newp)
1140 		return (EPERM);
1141 	*oldlenp = len;
1142 	if (oldp)
1143 		error = copyout(str, oldp, len);
1144 	return (error);
1145 }
1146 
1147 /*
1148  * Validate parameters and get old / set new parameters
1149  * for a structure oriented sysctl function.
1150  */
1151 int
1152 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp,
1153     size_t len)
1154 {
1155 	int error = 0;
1156 
1157 	if (oldp && *oldlenp < len)
1158 		return (ENOMEM);
1159 	if (newp && newlen > len)
1160 		return (EINVAL);
1161 	if (oldp) {
1162 		*oldlenp = len;
1163 		error = copyout(sp, oldp, len);
1164 	}
1165 	if (error == 0 && newp)
1166 		error = copyin(newp, sp, len);
1167 	return (error);
1168 }
1169 
1170 /*
1171  * Validate parameters and get old parameters
1172  * for a structure oriented sysctl function.
1173  */
1174 int
1175 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
1176     size_t len)
1177 {
1178 	int error = 0;
1179 
1180 	if (oldp && *oldlenp < len)
1181 		return (ENOMEM);
1182 	if (newp)
1183 		return (EPERM);
1184 	*oldlenp = len;
1185 	if (oldp)
1186 		error = copyout(sp, oldp, len);
1187 	return (error);
1188 }
1189 
1190 #ifndef SMALL_KERNEL
1191 void
1192 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp,
1193 	  int fd, struct vnode *vp, struct process *pr, struct proc *p,
1194 	  struct socket *so, int show_pointers)
1195 {
1196 	struct vattr va;
1197 
1198 	memset(kf, 0, sizeof(*kf));
1199 
1200 	kf->fd_fd = fd;		/* might not really be an fd */
1201 
1202 	if (fp != NULL) {
1203 		if (show_pointers)
1204 			kf->f_fileaddr = PTRTOINT64(fp);
1205 		kf->f_flag = fp->f_flag;
1206 		kf->f_iflags = fp->f_iflags;
1207 		kf->f_type = fp->f_type;
1208 		kf->f_count = fp->f_count;
1209 		if (show_pointers)
1210 			kf->f_ucred = PTRTOINT64(fp->f_cred);
1211 		kf->f_uid = fp->f_cred->cr_uid;
1212 		kf->f_gid = fp->f_cred->cr_gid;
1213 		if (show_pointers)
1214 			kf->f_ops = PTRTOINT64(fp->f_ops);
1215 		if (show_pointers)
1216 			kf->f_data = PTRTOINT64(fp->f_data);
1217 		kf->f_usecount = 0;
1218 
1219 		if (suser(p) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) {
1220 			mtx_enter(&fp->f_mtx);
1221 			kf->f_offset = fp->f_offset;
1222 			kf->f_rxfer = fp->f_rxfer;
1223 			kf->f_rwfer = fp->f_wxfer;
1224 			kf->f_seek = fp->f_seek;
1225 			kf->f_rbytes = fp->f_rbytes;
1226 			kf->f_wbytes = fp->f_wbytes;
1227 			mtx_leave(&fp->f_mtx);
1228 		} else
1229 			kf->f_offset = -1;
1230 	} else if (vp != NULL) {
1231 		/* fake it */
1232 		kf->f_type = DTYPE_VNODE;
1233 		kf->f_flag = FREAD;
1234 		if (fd == KERN_FILE_TRACE)
1235 			kf->f_flag |= FWRITE;
1236 	} else if (so != NULL) {
1237 		/* fake it */
1238 		kf->f_type = DTYPE_SOCKET;
1239 	}
1240 
1241 	/* information about the object associated with this file */
1242 	switch (kf->f_type) {
1243 	case DTYPE_VNODE:
1244 		if (fp != NULL)
1245 			vp = (struct vnode *)fp->f_data;
1246 
1247 		if (show_pointers)
1248 			kf->v_un = PTRTOINT64(vp->v_un.vu_socket);
1249 		kf->v_type = vp->v_type;
1250 		kf->v_tag = vp->v_tag;
1251 		kf->v_flag = vp->v_flag;
1252 		if (show_pointers)
1253 			kf->v_data = PTRTOINT64(vp->v_data);
1254 		if (show_pointers)
1255 			kf->v_mount = PTRTOINT64(vp->v_mount);
1256 		if (vp->v_mount)
1257 			strlcpy(kf->f_mntonname,
1258 			    vp->v_mount->mnt_stat.f_mntonname,
1259 			    sizeof(kf->f_mntonname));
1260 
1261 		if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) {
1262 			kf->va_fileid = va.va_fileid;
1263 			kf->va_mode = MAKEIMODE(va.va_type, va.va_mode);
1264 			kf->va_size = va.va_size;
1265 			kf->va_rdev = va.va_rdev;
1266 			kf->va_fsid = va.va_fsid & 0xffffffff;
1267 			kf->va_nlink = va.va_nlink;
1268 		}
1269 		break;
1270 
1271 	case DTYPE_SOCKET: {
1272 		int locked = 0;
1273 
1274 		if (so == NULL) {
1275 			so = (struct socket *)fp->f_data;
1276 			/* if so is passed as parameter it is already locked */
1277 			switch (so->so_proto->pr_domain->dom_family) {
1278 			case AF_INET:
1279 			case AF_INET6:
1280 				NET_LOCK();
1281 				locked = 1;
1282 				break;
1283 			}
1284 		}
1285 
1286 		kf->so_type = so->so_type;
1287 		kf->so_state = so->so_state | so->so_snd.sb_state |
1288 		    so->so_rcv.sb_state;
1289 		if (show_pointers)
1290 			kf->so_pcb = PTRTOINT64(so->so_pcb);
1291 		else
1292 			kf->so_pcb = -1;
1293 		kf->so_protocol = so->so_proto->pr_protocol;
1294 		kf->so_family = so->so_proto->pr_domain->dom_family;
1295 		kf->so_rcv_cc = so->so_rcv.sb_cc;
1296 		kf->so_snd_cc = so->so_snd.sb_cc;
1297 		if (isspliced(so)) {
1298 			if (show_pointers)
1299 				kf->so_splice =
1300 				    PTRTOINT64(so->so_sp->ssp_socket);
1301 			kf->so_splicelen = so->so_sp->ssp_len;
1302 		} else if (issplicedback(so))
1303 			kf->so_splicelen = -1;
1304 		if (so->so_pcb == NULL) {
1305 			if (locked)
1306 				NET_UNLOCK();
1307 			break;
1308 		}
1309 		switch (kf->so_family) {
1310 		case AF_INET: {
1311 			struct inpcb *inpcb = so->so_pcb;
1312 
1313 			NET_ASSERT_LOCKED();
1314 			if (show_pointers)
1315 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1316 			kf->inp_lport = inpcb->inp_lport;
1317 			kf->inp_laddru[0] = inpcb->inp_laddr.s_addr;
1318 			kf->inp_fport = inpcb->inp_fport;
1319 			kf->inp_faddru[0] = inpcb->inp_faddr.s_addr;
1320 			kf->inp_rtableid = inpcb->inp_rtableid;
1321 			if (so->so_type == SOCK_RAW)
1322 				kf->inp_proto = inpcb->inp_ip.ip_p;
1323 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1324 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1325 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1326 				kf->t_snd_wnd = tcpcb->snd_wnd;
1327 				kf->t_snd_cwnd = tcpcb->snd_cwnd;
1328 				kf->t_state = tcpcb->t_state;
1329 			}
1330 			break;
1331 		    }
1332 		case AF_INET6: {
1333 			struct inpcb *inpcb = so->so_pcb;
1334 
1335 			NET_ASSERT_LOCKED();
1336 			if (show_pointers)
1337 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1338 			kf->inp_lport = inpcb->inp_lport;
1339 			kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0];
1340 			kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1];
1341 			kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2];
1342 			kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3];
1343 			kf->inp_fport = inpcb->inp_fport;
1344 			kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0];
1345 			kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1];
1346 			kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2];
1347 			kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3];
1348 			kf->inp_rtableid = inpcb->inp_rtableid;
1349 			if (so->so_type == SOCK_RAW)
1350 				kf->inp_proto = inpcb->inp_ipv6.ip6_nxt;
1351 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1352 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1353 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1354 				kf->t_snd_wnd = tcpcb->snd_wnd;
1355 				kf->t_state = tcpcb->t_state;
1356 			}
1357 			break;
1358 		    }
1359 		case AF_UNIX: {
1360 			struct unpcb *unpcb = so->so_pcb;
1361 
1362 			kf->f_msgcount = unpcb->unp_msgcount;
1363 			if (show_pointers) {
1364 				kf->unp_conn	= PTRTOINT64(unpcb->unp_conn);
1365 				kf->unp_refs	= PTRTOINT64(
1366 				    SLIST_FIRST(&unpcb->unp_refs));
1367 				kf->unp_nextref	= PTRTOINT64(
1368 				    SLIST_NEXT(unpcb, unp_nextref));
1369 				kf->v_un	= PTRTOINT64(unpcb->unp_vnode);
1370 				kf->unp_addr	= PTRTOINT64(unpcb->unp_addr);
1371 			}
1372 			if (unpcb->unp_addr != NULL) {
1373 				struct sockaddr_un *un = mtod(unpcb->unp_addr,
1374 				    struct sockaddr_un *);
1375 				memcpy(kf->unp_path, un->sun_path, un->sun_len
1376 				    - offsetof(struct sockaddr_un,sun_path));
1377 			}
1378 			break;
1379 		    }
1380 		}
1381 		if (locked)
1382 			NET_UNLOCK();
1383 		break;
1384 	    }
1385 
1386 	case DTYPE_PIPE: {
1387 		struct pipe *pipe = (struct pipe *)fp->f_data;
1388 
1389 		if (show_pointers)
1390 			kf->pipe_peer = PTRTOINT64(pipe->pipe_peer);
1391 		kf->pipe_state = pipe->pipe_state;
1392 		break;
1393 	    }
1394 
1395 	case DTYPE_KQUEUE: {
1396 		struct kqueue *kqi = (struct kqueue *)fp->f_data;
1397 
1398 		kf->kq_count = kqi->kq_count;
1399 		kf->kq_state = kqi->kq_state;
1400 		break;
1401 	    }
1402 	}
1403 
1404 	/* per-process information for KERN_FILE_BY[PU]ID */
1405 	if (pr != NULL) {
1406 		kf->p_pid = pr->ps_pid;
1407 		kf->p_uid = pr->ps_ucred->cr_uid;
1408 		kf->p_gid = pr->ps_ucred->cr_gid;
1409 		kf->p_tid = -1;
1410 		strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm));
1411 	}
1412 	if (fdp != NULL) {
1413 		fdplock(fdp);
1414 		kf->fd_ofileflags = fdp->fd_ofileflags[fd];
1415 		fdpunlock(fdp);
1416 	}
1417 }
1418 
1419 /*
1420  * Get file structures.
1421  */
1422 int
1423 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
1424     struct proc *p)
1425 {
1426 	struct kinfo_file *kf;
1427 	struct filedesc *fdp;
1428 	struct file *fp;
1429 	struct process *pr;
1430 	size_t buflen, elem_size, elem_count, outsize;
1431 	char *dp = where;
1432 	int arg, i, error = 0, needed = 0, matched;
1433 	u_int op;
1434 	int show_pointers;
1435 
1436 	if (namelen > 4)
1437 		return (ENOTDIR);
1438 	if (namelen < 4 || name[2] > sizeof(*kf))
1439 		return (EINVAL);
1440 
1441 	buflen = where != NULL ? *sizep : 0;
1442 	op = name[0];
1443 	arg = name[1];
1444 	elem_size = name[2];
1445 	elem_count = name[3];
1446 	outsize = MIN(sizeof(*kf), elem_size);
1447 
1448 	if (elem_size < 1)
1449 		return (EINVAL);
1450 
1451 	show_pointers = suser(curproc) == 0;
1452 
1453 	kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK);
1454 
1455 #define FILLIT2(fp, fdp, i, vp, pr, so) do {				\
1456 	if (buflen >= elem_size && elem_count > 0) {			\
1457 		fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\
1458 		error = copyout(kf, dp, outsize);			\
1459 		if (error)						\
1460 			break;						\
1461 		dp += elem_size;					\
1462 		buflen -= elem_size;					\
1463 		elem_count--;						\
1464 	}								\
1465 	needed += elem_size;						\
1466 } while (0)
1467 #define FILLIT(fp, fdp, i, vp, pr) \
1468 	FILLIT2(fp, fdp, i, vp, pr, NULL)
1469 #define FILLSO(so) \
1470 	FILLIT2(NULL, NULL, 0, NULL, NULL, so)
1471 
1472 	switch (op) {
1473 	case KERN_FILE_BYFILE:
1474 		/* use the inp-tables to pick up closed connections, too */
1475 		if (arg == DTYPE_SOCKET) {
1476 			struct inpcb *inp;
1477 
1478 			NET_LOCK();
1479 			mtx_enter(&tcbtable.inpt_mtx);
1480 			TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue)
1481 				FILLSO(inp->inp_socket);
1482 			mtx_leave(&tcbtable.inpt_mtx);
1483 			mtx_enter(&udbtable.inpt_mtx);
1484 			TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue)
1485 				FILLSO(inp->inp_socket);
1486 			mtx_leave(&udbtable.inpt_mtx);
1487 			mtx_enter(&rawcbtable.inpt_mtx);
1488 			TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue)
1489 				FILLSO(inp->inp_socket);
1490 			mtx_leave(&rawcbtable.inpt_mtx);
1491 #ifdef INET6
1492 			mtx_enter(&rawin6pcbtable.inpt_mtx);
1493 			TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue,
1494 			    inp_queue)
1495 				FILLSO(inp->inp_socket);
1496 			mtx_leave(&rawin6pcbtable.inpt_mtx);
1497 #endif
1498 			NET_UNLOCK();
1499 		}
1500 		fp = NULL;
1501 		while ((fp = fd_iterfile(fp, p)) != NULL) {
1502 			if ((arg == 0 || fp->f_type == arg)) {
1503 				int af, skip = 0;
1504 				if (arg == DTYPE_SOCKET && fp->f_type == arg) {
1505 					af = ((struct socket *)fp->f_data)->
1506 					    so_proto->pr_domain->dom_family;
1507 					if (af == AF_INET || af == AF_INET6)
1508 						skip = 1;
1509 				}
1510 				if (!skip)
1511 					FILLIT(fp, NULL, 0, NULL, NULL);
1512 			}
1513 		}
1514 		break;
1515 	case KERN_FILE_BYPID:
1516 		/* A arg of -1 indicates all processes */
1517 		if (arg < -1) {
1518 			error = EINVAL;
1519 			break;
1520 		}
1521 		matched = 0;
1522 		LIST_FOREACH(pr, &allprocess, ps_list) {
1523 			/*
1524 			 * skip system, exiting, embryonic and undead
1525 			 * processes
1526 			 */
1527 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1528 				continue;
1529 			if (arg > 0 && pr->ps_pid != (pid_t)arg) {
1530 				/* not the pid we are looking for */
1531 				continue;
1532 			}
1533 			matched = 1;
1534 			fdp = pr->ps_fd;
1535 			if (pr->ps_textvp)
1536 				FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr);
1537 			if (fdp->fd_cdir)
1538 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1539 			if (fdp->fd_rdir)
1540 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1541 			if (pr->ps_tracevp)
1542 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1543 			for (i = 0; i < fdp->fd_nfiles; i++) {
1544 				if ((fp = fd_getfile(fdp, i)) == NULL)
1545 					continue;
1546 				FILLIT(fp, fdp, i, NULL, pr);
1547 				FRELE(fp, p);
1548 			}
1549 		}
1550 		if (!matched)
1551 			error = ESRCH;
1552 		break;
1553 	case KERN_FILE_BYUID:
1554 		LIST_FOREACH(pr, &allprocess, ps_list) {
1555 			/*
1556 			 * skip system, exiting, embryonic and undead
1557 			 * processes
1558 			 */
1559 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1560 				continue;
1561 			if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) {
1562 				/* not the uid we are looking for */
1563 				continue;
1564 			}
1565 			fdp = pr->ps_fd;
1566 			if (fdp->fd_cdir)
1567 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1568 			if (fdp->fd_rdir)
1569 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1570 			if (pr->ps_tracevp)
1571 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1572 			for (i = 0; i < fdp->fd_nfiles; i++) {
1573 				if ((fp = fd_getfile(fdp, i)) == NULL)
1574 					continue;
1575 				FILLIT(fp, fdp, i, NULL, pr);
1576 				FRELE(fp, p);
1577 			}
1578 		}
1579 		break;
1580 	default:
1581 		error = EINVAL;
1582 		break;
1583 	}
1584 	free(kf, M_TEMP, sizeof(*kf));
1585 
1586 	if (!error) {
1587 		if (where == NULL)
1588 			needed += KERN_FILESLOP * elem_size;
1589 		else if (*sizep < needed)
1590 			error = ENOMEM;
1591 		*sizep = needed;
1592 	}
1593 
1594 	return (error);
1595 }
1596 
1597 /*
1598  * try over estimating by 5 procs
1599  */
1600 #define KERN_PROCSLOP	5
1601 
1602 int
1603 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
1604 {
1605 	struct kinfo_proc *kproc = NULL;
1606 	struct proc *p;
1607 	struct process *pr;
1608 	char *dp;
1609 	int arg, buflen, doingzomb, elem_size, elem_count;
1610 	int error, needed, op;
1611 	int dothreads = 0;
1612 	int show_pointers;
1613 
1614 	dp = where;
1615 	buflen = where != NULL ? *sizep : 0;
1616 	needed = error = 0;
1617 
1618 	if (namelen != 4 || name[2] <= 0 || name[3] < 0 ||
1619 	    name[2] > sizeof(*kproc))
1620 		return (EINVAL);
1621 	op = name[0];
1622 	arg = name[1];
1623 	elem_size = name[2];
1624 	elem_count = name[3];
1625 
1626 	dothreads = op & KERN_PROC_SHOW_THREADS;
1627 	op &= ~KERN_PROC_SHOW_THREADS;
1628 
1629 	show_pointers = suser(curproc) == 0;
1630 
1631 	if (where != NULL)
1632 		kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK);
1633 
1634 	pr = LIST_FIRST(&allprocess);
1635 	doingzomb = 0;
1636 again:
1637 	for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) {
1638 		/* XXX skip processes in the middle of being zapped */
1639 		if (pr->ps_pgrp == NULL)
1640 			continue;
1641 
1642 		/*
1643 		 * Skip embryonic processes.
1644 		 */
1645 		if (pr->ps_flags & PS_EMBRYO)
1646 			continue;
1647 
1648 		/*
1649 		 * TODO - make more efficient (see notes below).
1650 		 */
1651 		switch (op) {
1652 
1653 		case KERN_PROC_PID:
1654 			/* could do this with just a lookup */
1655 			if (pr->ps_pid != (pid_t)arg)
1656 				continue;
1657 			break;
1658 
1659 		case KERN_PROC_PGRP:
1660 			/* could do this by traversing pgrp */
1661 			if (pr->ps_pgrp->pg_id != (pid_t)arg)
1662 				continue;
1663 			break;
1664 
1665 		case KERN_PROC_SESSION:
1666 			if (pr->ps_session->s_leader == NULL ||
1667 			    pr->ps_session->s_leader->ps_pid != (pid_t)arg)
1668 				continue;
1669 			break;
1670 
1671 		case KERN_PROC_TTY:
1672 			if ((pr->ps_flags & PS_CONTROLT) == 0 ||
1673 			    pr->ps_session->s_ttyp == NULL ||
1674 			    pr->ps_session->s_ttyp->t_dev != (dev_t)arg)
1675 				continue;
1676 			break;
1677 
1678 		case KERN_PROC_UID:
1679 			if (pr->ps_ucred->cr_uid != (uid_t)arg)
1680 				continue;
1681 			break;
1682 
1683 		case KERN_PROC_RUID:
1684 			if (pr->ps_ucred->cr_ruid != (uid_t)arg)
1685 				continue;
1686 			break;
1687 
1688 		case KERN_PROC_ALL:
1689 			if (pr->ps_flags & PS_SYSTEM)
1690 				continue;
1691 			break;
1692 
1693 		case KERN_PROC_KTHREAD:
1694 			/* no filtering */
1695 			break;
1696 
1697 		default:
1698 			error = EINVAL;
1699 			goto err;
1700 		}
1701 
1702 		if (buflen >= elem_size && elem_count > 0) {
1703 			fill_kproc(pr, kproc, NULL, show_pointers);
1704 			error = copyout(kproc, dp, elem_size);
1705 			if (error)
1706 				goto err;
1707 			dp += elem_size;
1708 			buflen -= elem_size;
1709 			elem_count--;
1710 		}
1711 		needed += elem_size;
1712 
1713 		/* Skip per-thread entries if not required by op */
1714 		if (!dothreads)
1715 			continue;
1716 
1717 		TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
1718 			if (buflen >= elem_size && elem_count > 0) {
1719 				fill_kproc(pr, kproc, p, show_pointers);
1720 				error = copyout(kproc, dp, elem_size);
1721 				if (error)
1722 					goto err;
1723 				dp += elem_size;
1724 				buflen -= elem_size;
1725 				elem_count--;
1726 			}
1727 			needed += elem_size;
1728 		}
1729 	}
1730 	if (doingzomb == 0) {
1731 		pr = LIST_FIRST(&zombprocess);
1732 		doingzomb++;
1733 		goto again;
1734 	}
1735 	if (where != NULL) {
1736 		*sizep = dp - where;
1737 		if (needed > *sizep) {
1738 			error = ENOMEM;
1739 			goto err;
1740 		}
1741 	} else {
1742 		needed += KERN_PROCSLOP * elem_size;
1743 		*sizep = needed;
1744 	}
1745 err:
1746 	if (kproc)
1747 		free(kproc, M_TEMP, sizeof(*kproc));
1748 	return (error);
1749 }
1750 
1751 /*
1752  * Fill in a kproc structure for the specified process.
1753  */
1754 void
1755 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p,
1756     int show_pointers)
1757 {
1758 	struct session *s = pr->ps_session;
1759 	struct tty *tp;
1760 	struct vmspace *vm = pr->ps_vmspace;
1761 	struct timespec booted, st, ut, utc;
1762 	int isthread;
1763 
1764 	isthread = p != NULL;
1765 	if (!isthread)
1766 		p = pr->ps_mainproc;		/* XXX */
1767 
1768 	FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp,
1769 	    p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread,
1770 	    show_pointers);
1771 
1772 	/* stuff that's too painful to generalize into the macros */
1773 	if (pr->ps_pptr)
1774 		ki->p_ppid = pr->ps_ppid;
1775 	if (s->s_leader)
1776 		ki->p_sid = s->s_leader->ps_pid;
1777 
1778 	if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) {
1779 		ki->p_tdev = tp->t_dev;
1780 		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1;
1781 		if (show_pointers)
1782 			ki->p_tsess = PTRTOINT64(tp->t_session);
1783 	} else {
1784 		ki->p_tdev = NODEV;
1785 		ki->p_tpgid = -1;
1786 	}
1787 
1788 	/* fixups that can only be done in the kernel */
1789 	if ((pr->ps_flags & PS_ZOMBIE) == 0) {
1790 		if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL)
1791 			ki->p_vm_rssize = vm_resident_count(vm);
1792 		calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL);
1793 		ki->p_uutime_sec = ut.tv_sec;
1794 		ki->p_uutime_usec = ut.tv_nsec/1000;
1795 		ki->p_ustime_sec = st.tv_sec;
1796 		ki->p_ustime_usec = st.tv_nsec/1000;
1797 
1798 		/* Convert starting uptime to a starting UTC time. */
1799 		nanoboottime(&booted);
1800 		timespecadd(&booted, &pr->ps_start, &utc);
1801 		ki->p_ustart_sec = utc.tv_sec;
1802 		ki->p_ustart_usec = utc.tv_nsec / 1000;
1803 
1804 #ifdef MULTIPROCESSOR
1805 		if (p->p_cpu != NULL)
1806 			ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu);
1807 #endif
1808 	}
1809 
1810 	/* get %cpu and schedule state: just one thread or sum of all? */
1811 	if (isthread) {
1812 		ki->p_pctcpu = p->p_pctcpu;
1813 		ki->p_stat   = p->p_stat;
1814 	} else {
1815 		ki->p_pctcpu = 0;
1816 		ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL;
1817 		TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
1818 			ki->p_pctcpu += p->p_pctcpu;
1819 			/* find best state: ONPROC > RUN > STOP > SLEEP > .. */
1820 			if (p->p_stat == SONPROC || ki->p_stat == SONPROC)
1821 				ki->p_stat = SONPROC;
1822 			else if (p->p_stat == SRUN || ki->p_stat == SRUN)
1823 				ki->p_stat = SRUN;
1824 			else if (p->p_stat == SSTOP || ki->p_stat == SSTOP)
1825 				ki->p_stat = SSTOP;
1826 			else if (p->p_stat == SSLEEP)
1827 				ki->p_stat = SSLEEP;
1828 		}
1829 	}
1830 }
1831 
1832 int
1833 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1834     struct proc *cp)
1835 {
1836 	struct process *vpr;
1837 	pid_t pid;
1838 	struct ps_strings pss;
1839 	struct iovec iov;
1840 	struct uio uio;
1841 	int error, cnt, op;
1842 	size_t limit;
1843 	char **rargv, **vargv;		/* reader vs. victim */
1844 	char *rarg, *varg, *buf;
1845 	struct vmspace *vm;
1846 	vaddr_t ps_strings;
1847 
1848 	if (namelen > 2)
1849 		return (ENOTDIR);
1850 	if (namelen < 2)
1851 		return (EINVAL);
1852 
1853 	pid = name[0];
1854 	op = name[1];
1855 
1856 	switch (op) {
1857 	case KERN_PROC_ARGV:
1858 	case KERN_PROC_NARGV:
1859 	case KERN_PROC_ENV:
1860 	case KERN_PROC_NENV:
1861 		break;
1862 	default:
1863 		return (EOPNOTSUPP);
1864 	}
1865 
1866 	if ((vpr = prfind(pid)) == NULL)
1867 		return (ESRCH);
1868 
1869 	if (oldp == NULL) {
1870 		if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV)
1871 			*oldlenp = sizeof(int);
1872 		else
1873 			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
1874 		return (0);
1875 	}
1876 
1877 	/* Either system process or exiting/zombie */
1878 	if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING))
1879 		return (EINVAL);
1880 
1881 	/* Execing - danger. */
1882 	if ((vpr->ps_flags & PS_INEXEC))
1883 		return (EBUSY);
1884 
1885 	/* Only owner or root can get env */
1886 	if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) &&
1887 	    (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
1888 	    (error = suser(cp)) != 0))
1889 		return (error);
1890 
1891 	ps_strings = vpr->ps_strings;
1892 	vm = vpr->ps_vmspace;
1893 	uvmspace_addref(vm);
1894 	vpr = NULL;
1895 
1896 	buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
1897 
1898 	iov.iov_base = &pss;
1899 	iov.iov_len = sizeof(pss);
1900 	uio.uio_iov = &iov;
1901 	uio.uio_iovcnt = 1;
1902 	uio.uio_offset = (off_t)ps_strings;
1903 	uio.uio_resid = sizeof(pss);
1904 	uio.uio_segflg = UIO_SYSSPACE;
1905 	uio.uio_rw = UIO_READ;
1906 	uio.uio_procp = cp;
1907 
1908 	if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1909 		goto out;
1910 
1911 	if (op == KERN_PROC_NARGV) {
1912 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr);
1913 		goto out;
1914 	}
1915 	if (op == KERN_PROC_NENV) {
1916 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr);
1917 		goto out;
1918 	}
1919 
1920 	if (op == KERN_PROC_ARGV) {
1921 		cnt = pss.ps_nargvstr;
1922 		vargv = pss.ps_argvstr;
1923 	} else {
1924 		cnt = pss.ps_nenvstr;
1925 		vargv = pss.ps_envstr;
1926 	}
1927 
1928 	/* -1 to have space for a terminating NUL */
1929 	limit = *oldlenp - 1;
1930 	*oldlenp = 0;
1931 
1932 	rargv = oldp;
1933 
1934 	/*
1935 	 * *oldlenp - number of bytes copied out into readers buffer.
1936 	 * limit - maximal number of bytes allowed into readers buffer.
1937 	 * rarg - pointer into readers buffer where next arg will be stored.
1938 	 * rargv - pointer into readers buffer where the next rarg pointer
1939 	 *  will be stored.
1940 	 * vargv - pointer into victim address space where the next argument
1941 	 *  will be read.
1942 	 */
1943 
1944 	/* space for cnt pointers and a NULL */
1945 	rarg = (char *)(rargv + cnt + 1);
1946 	*oldlenp += (cnt + 1) * sizeof(char **);
1947 
1948 	while (cnt > 0 && *oldlenp < limit) {
1949 		size_t len, vstrlen;
1950 
1951 		/* Write to readers argv */
1952 		if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0)
1953 			goto out;
1954 
1955 		/* read the victim argv */
1956 		iov.iov_base = &varg;
1957 		iov.iov_len = sizeof(varg);
1958 		uio.uio_iov = &iov;
1959 		uio.uio_iovcnt = 1;
1960 		uio.uio_offset = (off_t)(vaddr_t)vargv;
1961 		uio.uio_resid = sizeof(varg);
1962 		uio.uio_segflg = UIO_SYSSPACE;
1963 		uio.uio_rw = UIO_READ;
1964 		uio.uio_procp = cp;
1965 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1966 			goto out;
1967 
1968 		if (varg == NULL)
1969 			break;
1970 
1971 		/*
1972 		 * read the victim arg. We must jump through hoops to avoid
1973 		 * crossing a page boundary too much and returning an error.
1974 		 */
1975 more:
1976 		len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK);
1977 		/* leave space for the terminating NUL */
1978 		iov.iov_base = buf;
1979 		iov.iov_len = len;
1980 		uio.uio_iov = &iov;
1981 		uio.uio_iovcnt = 1;
1982 		uio.uio_offset = (off_t)(vaddr_t)varg;
1983 		uio.uio_resid = len;
1984 		uio.uio_segflg = UIO_SYSSPACE;
1985 		uio.uio_rw = UIO_READ;
1986 		uio.uio_procp = cp;
1987 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1988 			goto out;
1989 
1990 		for (vstrlen = 0; vstrlen < len; vstrlen++) {
1991 			if (buf[vstrlen] == '\0')
1992 				break;
1993 		}
1994 
1995 		/* Don't overflow readers buffer. */
1996 		if (*oldlenp + vstrlen + 1 >= limit) {
1997 			error = ENOMEM;
1998 			goto out;
1999 		}
2000 
2001 		if ((error = copyout(buf, rarg, vstrlen)) != 0)
2002 			goto out;
2003 
2004 		*oldlenp += vstrlen;
2005 		rarg += vstrlen;
2006 
2007 		/* The string didn't end in this page? */
2008 		if (vstrlen == len) {
2009 			varg += vstrlen;
2010 			goto more;
2011 		}
2012 
2013 		/* End of string. Terminate it with a NUL */
2014 		buf[0] = '\0';
2015 		if ((error = copyout(buf, rarg, 1)) != 0)
2016 			goto out;
2017 		*oldlenp += 1;
2018 		rarg += 1;
2019 
2020 		vargv++;
2021 		rargv++;
2022 		cnt--;
2023 	}
2024 
2025 	if (*oldlenp >= limit) {
2026 		error = ENOMEM;
2027 		goto out;
2028 	}
2029 
2030 	/* Write the terminating null */
2031 	rarg = NULL;
2032 	error = copyout(&rarg, rargv, sizeof(rarg));
2033 
2034 out:
2035 	uvmspace_free(vm);
2036 	free(buf, M_TEMP, PAGE_SIZE);
2037 	return (error);
2038 }
2039 
2040 int
2041 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2042     struct proc *cp)
2043 {
2044 	struct process *findpr;
2045 	struct vnode *vp;
2046 	pid_t pid;
2047 	int error;
2048 	size_t lenused, len;
2049 	char *path, *bp, *bend;
2050 
2051 	if (namelen > 1)
2052 		return (ENOTDIR);
2053 	if (namelen < 1)
2054 		return (EINVAL);
2055 
2056 	pid = name[0];
2057 	if ((findpr = prfind(pid)) == NULL)
2058 		return (ESRCH);
2059 
2060 	if (oldp == NULL) {
2061 		*oldlenp = MAXPATHLEN * 4;
2062 		return (0);
2063 	}
2064 
2065 	/* Either system process or exiting/zombie */
2066 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2067 		return (EINVAL);
2068 
2069 	/* Only owner or root can get cwd */
2070 	if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
2071 	    (error = suser(cp)) != 0)
2072 		return (error);
2073 
2074 	len = *oldlenp;
2075 	if (len > MAXPATHLEN * 4)
2076 		len = MAXPATHLEN * 4;
2077 	else if (len < 2)
2078 		return (ERANGE);
2079 	*oldlenp = 0;
2080 
2081 	/* snag a reference to the vnode before we can sleep */
2082 	vp = findpr->ps_fd->fd_cdir;
2083 	vref(vp);
2084 
2085 	path = malloc(len, M_TEMP, M_WAITOK);
2086 
2087 	bp = &path[len];
2088 	bend = bp;
2089 	*(--bp) = '\0';
2090 
2091 	/* Same as sys__getcwd */
2092 	error = vfs_getcwd_common(vp, NULL,
2093 	    &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp);
2094 	if (error == 0) {
2095 		*oldlenp = lenused = bend - bp;
2096 		error = copyout(bp, oldp, lenused);
2097 	}
2098 
2099 	vrele(vp);
2100 	free(path, M_TEMP, len);
2101 
2102 	return (error);
2103 }
2104 
2105 int
2106 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen,
2107     void *oldp, size_t *oldlenp, struct proc *cp)
2108 {
2109 	struct process *findpr;
2110 	pid_t pid;
2111 	int error, flag;
2112 
2113 	if (namelen > 1)
2114 		return (ENOTDIR);
2115 	if (namelen < 1)
2116 		return (EINVAL);
2117 
2118 	pid = name[0];
2119 	if ((findpr = prfind(pid)) == NULL)
2120 		return (ESRCH);
2121 
2122 	/* Either system process or exiting/zombie */
2123 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2124 		return (EINVAL);
2125 
2126 	/* Only root can change PS_NOBROADCASTKILL */
2127 	if (newp != NULL && (error = suser(cp)) != 0)
2128 		return (error);
2129 
2130 	/* get the PS_NOBROADCASTKILL flag */
2131 	flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0;
2132 
2133 	error = sysctl_int(oldp, oldlenp, newp, newlen, &flag);
2134 	if (error == 0 && newp) {
2135 		if (flag)
2136 			atomic_setbits_int(&findpr->ps_flags,
2137 			    PS_NOBROADCASTKILL);
2138 		else
2139 			atomic_clearbits_int(&findpr->ps_flags,
2140 			    PS_NOBROADCASTKILL);
2141 	}
2142 
2143 	return (error);
2144 }
2145 
2146 /* Arbitrary but reasonable limit for one iteration. */
2147 #define	VMMAP_MAXLEN	MAXPHYS
2148 
2149 int
2150 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2151     struct proc *cp)
2152 {
2153 	struct process *findpr;
2154 	pid_t pid;
2155 	int error;
2156 	size_t oldlen, len;
2157 	struct kinfo_vmentry *kve, *ukve;
2158 	u_long *ustart, start;
2159 
2160 	if (namelen > 1)
2161 		return (ENOTDIR);
2162 	if (namelen < 1)
2163 		return (EINVAL);
2164 
2165 	/* Provide max buffer length as hint. */
2166 	if (oldp == NULL) {
2167 		if (oldlenp == NULL)
2168 			return (EINVAL);
2169 		else {
2170 			*oldlenp = VMMAP_MAXLEN;
2171 			return (0);
2172 		}
2173 	}
2174 
2175 	pid = name[0];
2176 	if (pid == cp->p_p->ps_pid) {
2177 		/* Self process mapping. */
2178 		findpr = cp->p_p;
2179 	} else if (pid > 0) {
2180 		if ((findpr = prfind(pid)) == NULL)
2181 			return (ESRCH);
2182 
2183 		/* Either system process or exiting/zombie */
2184 		if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2185 			return (EINVAL);
2186 
2187 #if 1
2188 		/* XXX Allow only root for now */
2189 		if ((error = suser(cp)) != 0)
2190 			return (error);
2191 #else
2192 		/* Only owner or root can get vmmap */
2193 		if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
2194 		    (error = suser(cp)) != 0)
2195 			return (error);
2196 #endif
2197 	} else {
2198 		/* Only root can get kernel_map */
2199 		if ((error = suser(cp)) != 0)
2200 			return (error);
2201 		findpr = NULL;
2202 	}
2203 
2204 	/* Check the given size. */
2205 	oldlen = *oldlenp;
2206 	if (oldlen == 0 || oldlen % sizeof(*kve) != 0)
2207 		return (EINVAL);
2208 
2209 	/* Deny huge allocation. */
2210 	if (oldlen > VMMAP_MAXLEN)
2211 		return (EINVAL);
2212 
2213 	/*
2214 	 * Iterate from the given address passed as the first element's
2215 	 * kve_start via oldp.
2216 	 */
2217 	ukve = (struct kinfo_vmentry *)oldp;
2218 	ustart = &ukve->kve_start;
2219 	error = copyin(ustart, &start, sizeof(start));
2220 	if (error != 0)
2221 		return (error);
2222 
2223 	/* Allocate wired memory to not block. */
2224 	kve = malloc(oldlen, M_TEMP, M_WAITOK);
2225 
2226 	/* Set the base address and read entries. */
2227 	kve[0].kve_start = start;
2228 	len = oldlen;
2229 	error = fill_vmmap(findpr, kve, &len);
2230 	if (error != 0 && error != ENOMEM)
2231 		goto done;
2232 	if (len == 0)
2233 		goto done;
2234 
2235 	KASSERT(len <= oldlen);
2236 	KASSERT((len % sizeof(struct kinfo_vmentry)) == 0);
2237 
2238 	error = copyout(kve, oldp, len);
2239 
2240 done:
2241 	*oldlenp = len;
2242 
2243 	free(kve, M_TEMP, oldlen);
2244 
2245 	return (error);
2246 }
2247 #endif
2248 
2249 /*
2250  * Initialize disknames/diskstats for export by sysctl. If update is set,
2251  * then we simply update the disk statistics information.
2252  */
2253 int
2254 sysctl_diskinit(int update, struct proc *p)
2255 {
2256 	struct diskstats *sdk;
2257 	struct disk *dk;
2258 	const char *duid;
2259 	int error, changed = 0;
2260 
2261 	KERNEL_ASSERT_LOCKED();
2262 
2263 	if ((error = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0)
2264 		return error;
2265 
2266 	/* Run in a loop, disks may change while malloc sleeps. */
2267 	while (disk_change) {
2268 		int tlen;
2269 
2270 		disk_change = 0;
2271 
2272 		tlen = 0;
2273 		TAILQ_FOREACH(dk, &disklist, dk_link) {
2274 			if (dk->dk_name)
2275 				tlen += strlen(dk->dk_name);
2276 			tlen += 18;	/* label uid + separators */
2277 		}
2278 		tlen++;
2279 
2280 		/*
2281 		 * The sysctl_disklock ensures that no other process can
2282 		 * allocate disknames and diskstats while our malloc sleeps.
2283 		 */
2284 		free(disknames, M_SYSCTL, disknameslen);
2285 		free(diskstats, M_SYSCTL, diskstatslen);
2286 		diskstats = NULL;
2287 		disknames = NULL;
2288 		diskstats = mallocarray(disk_count, sizeof(struct diskstats),
2289 		    M_SYSCTL, M_WAITOK|M_ZERO);
2290 		diskstatslen = disk_count * sizeof(struct diskstats);
2291 		disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO);
2292 		disknameslen = tlen;
2293 		disknames[0] = '\0';
2294 		changed = 1;
2295 	}
2296 
2297 	if (changed) {
2298 		int l;
2299 
2300 		l = 0;
2301 		sdk = diskstats;
2302 		TAILQ_FOREACH(dk, &disklist, dk_link) {
2303 			duid = NULL;
2304 			if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid))
2305 				duid = duid_format(dk->dk_label->d_uid);
2306 			snprintf(disknames + l, disknameslen - l, "%s:%s,",
2307 			    dk->dk_name ? dk->dk_name : "",
2308 			    duid ? duid : "");
2309 			l += strlen(disknames + l);
2310 			strlcpy(sdk->ds_name, dk->dk_name,
2311 			    sizeof(sdk->ds_name));
2312 			mtx_enter(&dk->dk_mtx);
2313 			sdk->ds_busy = dk->dk_busy;
2314 			sdk->ds_rxfer = dk->dk_rxfer;
2315 			sdk->ds_wxfer = dk->dk_wxfer;
2316 			sdk->ds_seek = dk->dk_seek;
2317 			sdk->ds_rbytes = dk->dk_rbytes;
2318 			sdk->ds_wbytes = dk->dk_wbytes;
2319 			sdk->ds_attachtime = dk->dk_attachtime;
2320 			sdk->ds_timestamp = dk->dk_timestamp;
2321 			sdk->ds_time = dk->dk_time;
2322 			mtx_leave(&dk->dk_mtx);
2323 			sdk++;
2324 		}
2325 
2326 		/* Eliminate trailing comma */
2327 		if (l != 0)
2328 			disknames[l - 1] = '\0';
2329 	} else if (update) {
2330 		/* Just update, number of drives hasn't changed */
2331 		sdk = diskstats;
2332 		TAILQ_FOREACH(dk, &disklist, dk_link) {
2333 			strlcpy(sdk->ds_name, dk->dk_name,
2334 			    sizeof(sdk->ds_name));
2335 			mtx_enter(&dk->dk_mtx);
2336 			sdk->ds_busy = dk->dk_busy;
2337 			sdk->ds_rxfer = dk->dk_rxfer;
2338 			sdk->ds_wxfer = dk->dk_wxfer;
2339 			sdk->ds_seek = dk->dk_seek;
2340 			sdk->ds_rbytes = dk->dk_rbytes;
2341 			sdk->ds_wbytes = dk->dk_wbytes;
2342 			sdk->ds_attachtime = dk->dk_attachtime;
2343 			sdk->ds_timestamp = dk->dk_timestamp;
2344 			sdk->ds_time = dk->dk_time;
2345 			mtx_leave(&dk->dk_mtx);
2346 			sdk++;
2347 		}
2348 	}
2349 	rw_exit_write(&sysctl_disklock);
2350 	return 0;
2351 }
2352 
2353 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
2354 int
2355 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep)
2356 {
2357 #ifdef SYSVSEM
2358 	struct sem_sysctl_info *semsi;
2359 #endif
2360 #ifdef SYSVSHM
2361 	struct shm_sysctl_info *shmsi;
2362 #endif
2363 	size_t infosize, dssize, tsize, buflen, bufsiz;
2364 	int i, nds, error, ret;
2365 	void *buf;
2366 
2367 	if (namelen != 1)
2368 		return (EINVAL);
2369 
2370 	buflen = *sizep;
2371 
2372 	switch (*name) {
2373 	case KERN_SYSVIPC_MSG_INFO:
2374 #ifdef SYSVMSG
2375 		return (sysctl_sysvmsg(name, namelen, where, sizep));
2376 #else
2377 		return (EOPNOTSUPP);
2378 #endif
2379 	case KERN_SYSVIPC_SEM_INFO:
2380 #ifdef SYSVSEM
2381 		infosize = sizeof(semsi->seminfo);
2382 		nds = seminfo.semmni;
2383 		dssize = sizeof(semsi->semids[0]);
2384 		break;
2385 #else
2386 		return (EOPNOTSUPP);
2387 #endif
2388 	case KERN_SYSVIPC_SHM_INFO:
2389 #ifdef SYSVSHM
2390 		infosize = sizeof(shmsi->shminfo);
2391 		nds = shminfo.shmmni;
2392 		dssize = sizeof(shmsi->shmids[0]);
2393 		break;
2394 #else
2395 		return (EOPNOTSUPP);
2396 #endif
2397 	default:
2398 		return (EINVAL);
2399 	}
2400 	tsize = infosize + (nds * dssize);
2401 
2402 	/* Return just the total size required. */
2403 	if (where == NULL) {
2404 		*sizep = tsize;
2405 		return (0);
2406 	}
2407 
2408 	/* Not enough room for even the info struct. */
2409 	if (buflen < infosize) {
2410 		*sizep = 0;
2411 		return (ENOMEM);
2412 	}
2413 	bufsiz = min(tsize, buflen);
2414 	buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO);
2415 
2416 	switch (*name) {
2417 #ifdef SYSVSEM
2418 	case KERN_SYSVIPC_SEM_INFO:
2419 		semsi = (struct sem_sysctl_info *)buf;
2420 		semsi->seminfo = seminfo;
2421 		break;
2422 #endif
2423 #ifdef SYSVSHM
2424 	case KERN_SYSVIPC_SHM_INFO:
2425 		shmsi = (struct shm_sysctl_info *)buf;
2426 		shmsi->shminfo = shminfo;
2427 		break;
2428 #endif
2429 	}
2430 	buflen -= infosize;
2431 
2432 	ret = 0;
2433 	if (buflen > 0) {
2434 		/* Fill in the IPC data structures.  */
2435 		for (i = 0; i < nds; i++) {
2436 			if (buflen < dssize) {
2437 				ret = ENOMEM;
2438 				break;
2439 			}
2440 			switch (*name) {
2441 #ifdef SYSVSEM
2442 			case KERN_SYSVIPC_SEM_INFO:
2443 				if (sema[i] != NULL)
2444 					memcpy(&semsi->semids[i], sema[i],
2445 					    dssize);
2446 				else
2447 					memset(&semsi->semids[i], 0, dssize);
2448 				break;
2449 #endif
2450 #ifdef SYSVSHM
2451 			case KERN_SYSVIPC_SHM_INFO:
2452 				if (shmsegs[i] != NULL)
2453 					memcpy(&shmsi->shmids[i], shmsegs[i],
2454 					    dssize);
2455 				else
2456 					memset(&shmsi->shmids[i], 0, dssize);
2457 				break;
2458 #endif
2459 			}
2460 			buflen -= dssize;
2461 		}
2462 	}
2463 	*sizep -= buflen;
2464 	error = copyout(buf, where, *sizep);
2465 	free(buf, M_TEMP, bufsiz);
2466 	/* If copyout succeeded, use return code set earlier. */
2467 	return (error ? error : ret);
2468 }
2469 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
2470 
2471 #ifndef	SMALL_KERNEL
2472 
2473 int
2474 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp)
2475 {
2476 	return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0));
2477 }
2478 
2479 
2480 int
2481 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2482     void *newp, size_t newlen)
2483 {
2484 	struct ksensor *ks;
2485 	struct sensor *us;
2486 	struct ksensordev *ksd;
2487 	struct sensordev *usd;
2488 	int dev, numt, ret;
2489 	enum sensor_type type;
2490 
2491 	if (namelen != 1 && namelen != 3)
2492 		return (ENOTDIR);
2493 
2494 	dev = name[0];
2495 	if (namelen == 1) {
2496 		ret = sensordev_get(dev, &ksd);
2497 		if (ret)
2498 			return (ret);
2499 
2500 		/* Grab a copy, to clear the kernel pointers */
2501 		usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO);
2502 		usd->num = ksd->num;
2503 		strlcpy(usd->xname, ksd->xname, sizeof(usd->xname));
2504 		memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt));
2505 		usd->sensors_count = ksd->sensors_count;
2506 
2507 		ret = sysctl_rdstruct(oldp, oldlenp, newp, usd,
2508 		    sizeof(struct sensordev));
2509 
2510 		free(usd, M_TEMP, sizeof(*usd));
2511 		return (ret);
2512 	}
2513 
2514 	type = name[1];
2515 	numt = name[2];
2516 
2517 	ret = sensor_find(dev, type, numt, &ks);
2518 	if (ret)
2519 		return (ret);
2520 
2521 	/* Grab a copy, to clear the kernel pointers */
2522 	us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO);
2523 	memcpy(us->desc, ks->desc, sizeof(us->desc));
2524 	us->tv = ks->tv;
2525 	us->value = ks->value;
2526 	us->type = ks->type;
2527 	us->status = ks->status;
2528 	us->numt = ks->numt;
2529 	us->flags = ks->flags;
2530 
2531 	ret = sysctl_rdstruct(oldp, oldlenp, newp, us,
2532 	    sizeof(struct sensor));
2533 	free(us, M_TEMP, sizeof(*us));
2534 	return (ret);
2535 }
2536 #endif	/* SMALL_KERNEL */
2537 
2538 int
2539 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2540     void *newp, size_t newlen)
2541 {
2542 	CPU_INFO_ITERATOR cii;
2543 	struct cpu_info *ci;
2544 	int found = 0;
2545 
2546 	if (namelen != 1)
2547 		return (ENOTDIR);
2548 
2549 	CPU_INFO_FOREACH(cii, ci) {
2550 		if (name[0] == CPU_INFO_UNIT(ci)) {
2551 			found = 1;
2552 			break;
2553 		}
2554 	}
2555 	if (!found)
2556 		return (ENOENT);
2557 
2558 	return (sysctl_rdstruct(oldp, oldlenp, newp,
2559 	    &ci->ci_schedstate.spc_cp_time,
2560 	    sizeof(ci->ci_schedstate.spc_cp_time)));
2561 }
2562 
2563 #if NAUDIO > 0
2564 int
2565 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2566     void *newp, size_t newlen)
2567 {
2568 	if (namelen != 1)
2569 		return (ENOTDIR);
2570 
2571 	if (name[0] != KERN_AUDIO_RECORD)
2572 		return (ENOENT);
2573 
2574 	return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable));
2575 }
2576 #endif
2577 
2578 #if NVIDEO > 0
2579 int
2580 sysctl_video(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2581     void *newp, size_t newlen)
2582 {
2583 	if (namelen != 1)
2584 		return (ENOTDIR);
2585 
2586 	if (name[0] != KERN_VIDEO_RECORD)
2587 		return (ENOENT);
2588 
2589 	return (sysctl_int(oldp, oldlenp, newp, newlen, &video_record_enable));
2590 }
2591 #endif
2592 
2593 int
2594 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2595     void *newp, size_t newlen)
2596 {
2597 	CPU_INFO_ITERATOR cii;
2598 	struct cpustats cs;
2599 	struct cpu_info *ci;
2600 	int found = 0;
2601 
2602 	if (namelen != 1)
2603 		return (ENOTDIR);
2604 
2605 	CPU_INFO_FOREACH(cii, ci) {
2606 		if (name[0] == CPU_INFO_UNIT(ci)) {
2607 			found = 1;
2608 			break;
2609 		}
2610 	}
2611 	if (!found)
2612 		return (ENOENT);
2613 
2614 	memset(&cs, 0, sizeof cs);
2615 	memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time));
2616 	cs.cs_flags = 0;
2617 	if (cpu_is_online(ci))
2618 		cs.cs_flags |= CPUSTATS_ONLINE;
2619 
2620 	return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs)));
2621 }
2622 
2623 int
2624 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
2625 {
2626 	struct timespec adjusted, now;
2627 	int adjustment_seconds, error, new_offset_minutes, old_offset_minutes;
2628 
2629 	old_offset_minutes = utc_offset / 60;	/* seconds -> minutes */
2630 	new_offset_minutes = old_offset_minutes;
2631 	error = sysctl_securelevel_int(oldp, oldlenp, newp, newlen,
2632 	     &new_offset_minutes);
2633 	if (error)
2634 		return error;
2635 	if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60)
2636 		return EINVAL;
2637 	if (new_offset_minutes == old_offset_minutes)
2638 		return 0;
2639 
2640 	utc_offset = new_offset_minutes * 60;	/* minutes -> seconds */
2641 	adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60;
2642 
2643 	nanotime(&now);
2644 	adjusted = now;
2645 	adjusted.tv_sec -= adjustment_seconds;
2646 	tc_setrealtimeclock(&adjusted);
2647 	resettodr();
2648 
2649 	return 0;
2650 }
2651