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