xref: /openbsd-src/sys/kern/kern_sysctl.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: kern_sysctl.c,v 1.169 2009/04/19 17:53:38 deraadt 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/proc.h>
47 #include <sys/resourcevar.h>
48 #include <sys/file.h>
49 #include <sys/vnode.h>
50 #include <sys/unistd.h>
51 #include <sys/buf.h>
52 #include <sys/ioctl.h>
53 #include <sys/tty.h>
54 #include <sys/disklabel.h>
55 #include <sys/disk.h>
56 #include <uvm/uvm_extern.h>
57 #include <sys/sysctl.h>
58 #include <sys/msgbuf.h>
59 #include <sys/dkstat.h>
60 #include <sys/vmmeter.h>
61 #include <sys/namei.h>
62 #include <sys/exec.h>
63 #include <sys/mbuf.h>
64 #include <sys/sensors.h>
65 #ifdef __HAVE_TIMECOUNTER
66 #include <sys/timetc.h>
67 #endif
68 #include <sys/evcount.h>
69 
70 #include <sys/mount.h>
71 #include <sys/syscallargs.h>
72 #include <dev/rndvar.h>
73 
74 #ifdef DDB
75 #include <ddb/db_var.h>
76 #endif
77 
78 #ifdef SYSVMSG
79 #include <sys/msg.h>
80 #endif
81 #ifdef SYSVSEM
82 #include <sys/sem.h>
83 #endif
84 #ifdef SYSVSHM
85 #include <sys/shm.h>
86 #endif
87 
88 #define	PTRTOINT64(_x)	((u_int64_t)(u_long)(_x))
89 
90 extern struct forkstat forkstat;
91 extern struct nchstats nchstats;
92 extern int nselcoll, fscale;
93 extern struct disklist_head disklist;
94 extern fixpt_t ccpu;
95 extern  long numvnodes;
96 
97 extern void nmbclust_update(void);
98 
99 int sysctl_diskinit(int, struct proc *);
100 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
101 int sysctl_intrcnt(int *, u_int, void *, size_t *);
102 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
103 int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
104 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
105 
106 int (*cpu_cpuspeed)(int *);
107 void (*cpu_setperf)(int);
108 int perflevel = 100;
109 
110 /*
111  * Lock to avoid too many processes vslocking a large amount of memory
112  * at the same time.
113  */
114 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk");
115 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk");
116 
117 int
118 sys___sysctl(struct proc *p, void *v, register_t *retval)
119 {
120 	struct sys___sysctl_args /* {
121 		syscallarg(int *) name;
122 		syscallarg(u_int) namelen;
123 		syscallarg(void *) old;
124 		syscallarg(size_t *) oldlenp;
125 		syscallarg(void *) new;
126 		syscallarg(size_t) newlen;
127 	} */ *uap = v;
128 	int error, dolock = 1;
129 	size_t savelen = 0, oldlen = 0;
130 	sysctlfn *fn;
131 	int name[CTL_MAXNAME];
132 
133 	if (SCARG(uap, new) != NULL &&
134 	    (error = suser(p, 0)))
135 		return (error);
136 	/*
137 	 * all top-level sysctl names are non-terminal
138 	 */
139 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
140 		return (EINVAL);
141 	error = copyin(SCARG(uap, name), name,
142 		       SCARG(uap, namelen) * sizeof(int));
143 	if (error)
144 		return (error);
145 
146 	switch (name[0]) {
147 	case CTL_KERN:
148 		fn = kern_sysctl;
149 		if (name[1] == KERN_VNODE)	/* XXX */
150 			dolock = 0;
151 		break;
152 	case CTL_HW:
153 		fn = hw_sysctl;
154 		break;
155 	case CTL_VM:
156 		fn = uvm_sysctl;
157 		break;
158 	case CTL_NET:
159 		fn = net_sysctl;
160 		break;
161 	case CTL_FS:
162 		fn = fs_sysctl;
163 		break;
164 	case CTL_VFS:
165 		fn = vfs_sysctl;
166 		break;
167 	case CTL_MACHDEP:
168 		fn = cpu_sysctl;
169 		break;
170 #ifdef DEBUG
171 	case CTL_DEBUG:
172 		fn = debug_sysctl;
173 		break;
174 #endif
175 #ifdef DDB
176 	case CTL_DDB:
177 		fn = ddb_sysctl;
178 		break;
179 #endif
180 	default:
181 		return (EOPNOTSUPP);
182 	}
183 
184 	if (SCARG(uap, oldlenp) &&
185 	    (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
186 		return (error);
187 	if (SCARG(uap, old) != NULL) {
188 		if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0)
189 			return (error);
190 		if (dolock) {
191 			if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) {
192 				rw_exit_write(&sysctl_lock);
193 				return (ENOMEM);
194 			}
195 			error = uvm_vslock(p, SCARG(uap, old), oldlen,
196 			    VM_PROT_READ|VM_PROT_WRITE);
197 			if (error) {
198 				rw_exit_write(&sysctl_lock);
199 				return (error);
200 			}
201 		}
202 		savelen = oldlen;
203 	}
204 	error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old),
205 	    &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
206 	if (SCARG(uap, old) != NULL) {
207 		if (dolock)
208 			uvm_vsunlock(p, SCARG(uap, old), savelen);
209 		rw_exit_write(&sysctl_lock);
210 	}
211 	if (error)
212 		return (error);
213 	if (SCARG(uap, oldlenp))
214 		error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
215 	return (error);
216 }
217 
218 /*
219  * Attributes stored in the kernel.
220  */
221 char hostname[MAXHOSTNAMELEN];
222 int hostnamelen;
223 char domainname[MAXHOSTNAMELEN];
224 int domainnamelen;
225 long hostid;
226 char *disknames = NULL;
227 struct diskstats *diskstats = NULL;
228 #ifdef INSECURE
229 int securelevel = -1;
230 #else
231 int securelevel;
232 #endif
233 
234 /*
235  * kernel related system variables.
236  */
237 int
238 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
239     size_t newlen, struct proc *p)
240 {
241 	int error, level, inthostid, stackgap;
242 	extern int somaxconn, sominconn;
243 	extern int usermount, nosuidcoredump;
244 	extern long cp_time[CPUSTATES];
245 	extern int stackgap_random;
246 #ifdef CRYPTO
247 	extern int usercrypto;
248 	extern int userasymcrypto;
249 	extern int cryptodevallowsoft;
250 #endif
251 	extern int maxlocksperuid;
252 
253 	/* all sysctl names at this level are terminal except a ton of them */
254 	if (namelen != 1) {
255 		switch (name[0]) {
256 		case KERN_PROC:
257 		case KERN_PROC2:
258 		case KERN_PROF:
259 		case KERN_MALLOCSTATS:
260 		case KERN_TTY:
261 		case KERN_POOL:
262 		case KERN_PROC_ARGS:
263 		case KERN_SYSVIPC_INFO:
264 		case KERN_SEMINFO:
265 		case KERN_SHMINFO:
266 		case KERN_INTRCNT:
267 		case KERN_WATCHDOG:
268 		case KERN_EMUL:
269 		case KERN_EVCOUNT:
270 #ifdef __HAVE_TIMECOUNTER
271 		case KERN_TIMECOUNTER:
272 #endif
273 		case KERN_CPTIME2:
274 			break;
275 		default:
276 			return (ENOTDIR);	/* overloaded */
277 		}
278 	}
279 
280 	switch (name[0]) {
281 	case KERN_OSTYPE:
282 		return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
283 	case KERN_OSRELEASE:
284 		return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
285 	case KERN_OSREV:
286 		return (sysctl_rdint(oldp, oldlenp, newp, OpenBSD));
287 	case KERN_OSVERSION:
288 		return (sysctl_rdstring(oldp, oldlenp, newp, osversion));
289 	case KERN_VERSION:
290 		return (sysctl_rdstring(oldp, oldlenp, newp, version));
291 	case KERN_MAXVNODES:
292 		return(sysctl_int(oldp, oldlenp, newp, newlen, &maxvnodes));
293 	case KERN_MAXPROC:
294 		return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc));
295 	case KERN_MAXFILES:
296 		return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles));
297 	case KERN_NFILES:
298 		return (sysctl_rdint(oldp, oldlenp, newp, nfiles));
299 	case KERN_TTYCOUNT:
300 		return (sysctl_rdint(oldp, oldlenp, newp, tty_count));
301 	case KERN_NUMVNODES:
302 		return (sysctl_rdint(oldp, oldlenp, newp, numvnodes));
303 	case KERN_ARGMAX:
304 		return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX));
305 	case KERN_NSELCOLL:
306 		return (sysctl_rdint(oldp, oldlenp, newp, nselcoll));
307 	case KERN_SECURELVL:
308 		level = securelevel;
309 		if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
310 		    newp == NULL)
311 			return (error);
312 		if ((securelevel > 0 || level < -1) &&
313 		    level < securelevel && p->p_pid != 1)
314 			return (EPERM);
315 		securelevel = level;
316 		return (0);
317 	case KERN_HOSTNAME:
318 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
319 		    hostname, sizeof(hostname));
320 		if (newp && !error)
321 			hostnamelen = newlen;
322 		return (error);
323 	case KERN_DOMAINNAME:
324 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
325 		    domainname, sizeof(domainname));
326 		if (newp && !error)
327 			domainnamelen = newlen;
328 		return (error);
329 	case KERN_HOSTID:
330 		inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */
331 		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
332 		hostid = inthostid;
333 		return (error);
334 	case KERN_CLOCKRATE:
335 		return (sysctl_clockrate(oldp, oldlenp, newp));
336 	case KERN_BOOTTIME:
337 		return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime,
338 		    sizeof(struct timeval)));
339 	case KERN_VNODE:
340 		return (sysctl_vnode(oldp, oldlenp, p));
341 #ifndef SMALL_KERNEL
342 	case KERN_PROC:
343 	case KERN_PROC2:
344 		return (sysctl_doproc(name, namelen, oldp, oldlenp));
345 	case KERN_PROC_ARGS:
346 		return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
347 		     p));
348 #endif
349 	case KERN_FILE:
350 		return (sysctl_file(oldp, oldlenp, p));
351 	case KERN_MBSTAT:
352 		return (sysctl_rdstruct(oldp, oldlenp, newp, &mbstat,
353 		    sizeof(mbstat)));
354 #ifdef GPROF
355 	case KERN_PROF:
356 		return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
357 		    newp, newlen));
358 #endif
359 	case KERN_POSIX1:
360 		return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION));
361 	case KERN_NGROUPS:
362 		return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX));
363 	case KERN_JOB_CONTROL:
364 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
365 	case KERN_SAVED_IDS:
366 #ifdef _POSIX_SAVED_IDS
367 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
368 #else
369 		return (sysctl_rdint(oldp, oldlenp, newp, 0));
370 #endif
371 	case KERN_MAXPARTITIONS:
372 		return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS));
373 	case KERN_RAWPARTITION:
374 		return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART));
375 	case KERN_SOMAXCONN:
376 		return (sysctl_int(oldp, oldlenp, newp, newlen, &somaxconn));
377 	case KERN_SOMINCONN:
378 		return (sysctl_int(oldp, oldlenp, newp, newlen, &sominconn));
379 	case KERN_USERMOUNT:
380 		return (sysctl_int(oldp, oldlenp, newp, newlen, &usermount));
381 	case KERN_RND:
382 		return (sysctl_rdstruct(oldp, oldlenp, newp, &rndstats,
383 		    sizeof(rndstats)));
384 	case KERN_ARND: {
385 		char buf[256];
386 
387 		if (*oldlenp > sizeof(buf))
388 			*oldlenp = sizeof(buf);
389 		if (oldp) {
390 			arc4random_buf(buf, *oldlenp);
391 			if ((error = copyout(buf, oldp, *oldlenp)))
392 				return (error);
393 		}
394 		return (0);
395 	}
396 	case KERN_NOSUIDCOREDUMP:
397 		return (sysctl_int(oldp, oldlenp, newp, newlen, &nosuidcoredump));
398 	case KERN_FSYNC:
399 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
400 	case KERN_SYSVMSG:
401 #ifdef SYSVMSG
402 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
403 #else
404 		return (sysctl_rdint(oldp, oldlenp, newp, 0));
405 #endif
406 	case KERN_SYSVSEM:
407 #ifdef SYSVSEM
408 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
409 #else
410 		return (sysctl_rdint(oldp, oldlenp, newp, 0));
411 #endif
412 	case KERN_SYSVSHM:
413 #ifdef SYSVSHM
414 		return (sysctl_rdint(oldp, oldlenp, newp, 1));
415 #else
416 		return (sysctl_rdint(oldp, oldlenp, newp, 0));
417 #endif
418 	case KERN_MSGBUFSIZE:
419 		/*
420 		 * deal with cases where the message buffer has
421 		 * become corrupted.
422 		 */
423 		if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
424 			return (ENXIO);
425 		return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs));
426 	case KERN_MSGBUF:
427 		/* see note above */
428 		if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
429 			return (ENXIO);
430 		return (sysctl_rdstruct(oldp, oldlenp, newp, msgbufp,
431 		    msgbufp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
432 	case KERN_MALLOCSTATS:
433 		return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp,
434 		    newp, newlen, p));
435 	case KERN_CPTIME:
436 	{
437 		CPU_INFO_ITERATOR cii;
438 		struct cpu_info *ci;
439 		int i;
440 
441 		bzero(cp_time, sizeof(cp_time));
442 
443 		CPU_INFO_FOREACH(cii, ci) {
444 			for (i = 0; i < CPUSTATES; i++)
445 				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
446 		}
447 
448 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time,
449 		    sizeof(cp_time)));
450 	}
451 	case KERN_NCHSTATS:
452 		return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats,
453 		    sizeof(struct nchstats)));
454 	case KERN_FORKSTAT:
455 		return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat,
456 		    sizeof(struct forkstat)));
457 	case KERN_TTY:
458 		return (sysctl_tty(name + 1, namelen - 1, oldp, oldlenp,
459 		    newp, newlen));
460 	case KERN_FSCALE:
461 		return (sysctl_rdint(oldp, oldlenp, newp, fscale));
462 	case KERN_CCPU:
463 		return (sysctl_rdint(oldp, oldlenp, newp, ccpu));
464 	case KERN_NPROCS:
465 		return (sysctl_rdint(oldp, oldlenp, newp, nprocs));
466 	case KERN_POOL:
467 		return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp));
468 	case KERN_STACKGAPRANDOM:
469 		stackgap = stackgap_random;
470 		error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap);
471 		if (error)
472 			return (error);
473 		/*
474 		 * Safety harness.
475 		 */
476 		if ((stackgap < ALIGNBYTES && stackgap != 0) ||
477 		    !powerof2(stackgap) || stackgap >= MAXSSIZ)
478 			return (EINVAL);
479 		stackgap_random = stackgap;
480 		return (0);
481 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
482 	case KERN_SYSVIPC_INFO:
483 		return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp));
484 #endif
485 #ifdef CRYPTO
486 	case KERN_USERCRYPTO:
487 		return (sysctl_int(oldp, oldlenp, newp, newlen, &usercrypto));
488 	case KERN_USERASYMCRYPTO:
489 		return (sysctl_int(oldp, oldlenp, newp, newlen,
490 			    &userasymcrypto));
491 	case KERN_CRYPTODEVALLOWSOFT:
492 		return (sysctl_int(oldp, oldlenp, newp, newlen,
493 			    &cryptodevallowsoft));
494 #endif
495 	case KERN_SPLASSERT:
496 		return (sysctl_int(oldp, oldlenp, newp, newlen,
497 		    &splassert_ctl));
498 #ifdef SYSVSEM
499 	case KERN_SEMINFO:
500 		return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp,
501 		    newp, newlen));
502 #endif
503 #ifdef SYSVSHM
504 	case KERN_SHMINFO:
505 		return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp,
506 		    newp, newlen));
507 #endif
508 #ifndef SMALL_KERNEL
509 	case KERN_INTRCNT:
510 		return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp));
511 	case KERN_WATCHDOG:
512 		return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp,
513 		    newp, newlen));
514 	case KERN_EMUL:
515 		return (sysctl_emul(name + 1, namelen - 1, oldp, oldlenp,
516 		    newp, newlen));
517 #endif
518 	case KERN_MAXCLUSTERS:
519 		error = sysctl_int(oldp, oldlenp, newp, newlen, &nmbclust);
520 		if (!error)
521 			nmbclust_update();
522 		return (error);
523 #ifndef SMALL_KERNEL
524 	case KERN_EVCOUNT:
525 		return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp,
526 		    newp, newlen));
527 #endif
528 #ifdef __HAVE_TIMECOUNTER
529 	case KERN_TIMECOUNTER:
530 		return (sysctl_tc(name + 1, namelen - 1, oldp, oldlenp,
531 		    newp, newlen));
532 #endif
533 	case KERN_MAXLOCKSPERUID:
534 		return (sysctl_int(oldp, oldlenp, newp, newlen, &maxlocksperuid));
535 	case KERN_CPTIME2:
536 		return (sysctl_cptime2(name + 1, namelen -1, oldp, oldlenp,
537 		    newp, newlen));
538 	default:
539 		return (EOPNOTSUPP);
540 	}
541 	/* NOTREACHED */
542 }
543 
544 /*
545  * hardware related system variables.
546  */
547 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
548 
549 int
550 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
551     size_t newlen, struct proc *p)
552 {
553 	extern char machine[], cpu_model[];
554 	int err, cpuspeed;
555 
556 	/* all sysctl names at this level except sensors are terminal */
557 	if (name[0] != HW_SENSORS && namelen != 1)
558 		return (ENOTDIR);		/* overloaded */
559 
560 	switch (name[0]) {
561 	case HW_MACHINE:
562 		return (sysctl_rdstring(oldp, oldlenp, newp, machine));
563 	case HW_MODEL:
564 		return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
565 	case HW_NCPU:
566 		return (sysctl_rdint(oldp, oldlenp, newp, ncpus));
567 	case HW_NCPUFOUND:
568 		return (sysctl_rdint(oldp, oldlenp, newp, ncpusfound));
569 	case HW_BYTEORDER:
570 		return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER));
571 	case HW_PHYSMEM:
572 		return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem)));
573 	case HW_USERMEM:
574 		return (sysctl_rdint(oldp, oldlenp, newp,
575 		    ptoa(physmem - uvmexp.wired)));
576 	case HW_PAGESIZE:
577 		return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE));
578 	case HW_DISKNAMES:
579 		err = sysctl_diskinit(0, p);
580 		if (err)
581 			return err;
582 		if (disknames)
583 			return (sysctl_rdstring(oldp, oldlenp, newp,
584 			    disknames));
585 		else
586 			return (sysctl_rdstring(oldp, oldlenp, newp, ""));
587 	case HW_DISKSTATS:
588 		err = sysctl_diskinit(1, p);
589 		if (err)
590 			return err;
591 		return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats,
592 		    disk_count * sizeof(struct diskstats)));
593 	case HW_DISKCOUNT:
594 		return (sysctl_rdint(oldp, oldlenp, newp, disk_count));
595 #ifndef	SMALL_KERNEL
596 	case HW_SENSORS:
597 		return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
598 		    newp, newlen));
599 #endif
600 	case HW_CPUSPEED:
601 		if (!cpu_cpuspeed)
602 			return (EOPNOTSUPP);
603 		err = cpu_cpuspeed(&cpuspeed);
604 		if (err)
605 			return err;
606 		return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
607 	case HW_SETPERF:
608 		if (!cpu_setperf)
609 			return (EOPNOTSUPP);
610 		err = sysctl_int(oldp, oldlenp, newp, newlen, &perflevel);
611 		if (err)
612 			return err;
613 		if (perflevel > 100)
614 			perflevel = 100;
615 		if (perflevel < 0)
616 			perflevel = 0;
617 		if (newp)
618 			cpu_setperf(perflevel);
619 		return (0);
620 	case HW_VENDOR:
621 		if (hw_vendor)
622 			return (sysctl_rdstring(oldp, oldlenp, newp,
623 			    hw_vendor));
624 		else
625 			return (EOPNOTSUPP);
626 	case HW_PRODUCT:
627 		if (hw_prod)
628 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod));
629 		else
630 			return (EOPNOTSUPP);
631 	case HW_VERSION:
632 		if (hw_ver)
633 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver));
634 		else
635 			return (EOPNOTSUPP);
636 	case HW_SERIALNO:
637 		if (hw_serial)
638 			return (sysctl_rdstring(oldp, oldlenp, newp,
639 			    hw_serial));
640 		else
641 			return (EOPNOTSUPP);
642 	case HW_UUID:
643 		if (hw_uuid)
644 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid));
645 		else
646 			return (EOPNOTSUPP);
647 	case HW_PHYSMEM64:
648 		return (sysctl_rdquad(oldp, oldlenp, newp,
649 		    ptoa((psize_t)physmem)));
650 	case HW_USERMEM64:
651 		return (sysctl_rdquad(oldp, oldlenp, newp,
652 		    ptoa((psize_t)physmem - uvmexp.wired)));
653 	default:
654 		return (EOPNOTSUPP);
655 	}
656 	/* NOTREACHED */
657 }
658 
659 #ifdef DEBUG
660 /*
661  * Debugging related system variables.
662  */
663 extern struct ctldebug debug0, debug1;
664 struct ctldebug debug2, debug3, debug4;
665 struct ctldebug debug5, debug6, debug7, debug8, debug9;
666 struct ctldebug debug10, debug11, debug12, debug13, debug14;
667 struct ctldebug debug15, debug16, debug17, debug18, debug19;
668 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
669 	&debug0, &debug1, &debug2, &debug3, &debug4,
670 	&debug5, &debug6, &debug7, &debug8, &debug9,
671 	&debug10, &debug11, &debug12, &debug13, &debug14,
672 	&debug15, &debug16, &debug17, &debug18, &debug19,
673 };
674 int
675 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
676     size_t newlen, struct proc *p)
677 {
678 	struct ctldebug *cdp;
679 
680 	/* all sysctl names at this level are name and field */
681 	if (namelen != 2)
682 		return (ENOTDIR);		/* overloaded */
683 	cdp = debugvars[name[0]];
684 	if (cdp->debugname == 0)
685 		return (EOPNOTSUPP);
686 	switch (name[1]) {
687 	case CTL_DEBUG_NAME:
688 		return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
689 	case CTL_DEBUG_VALUE:
690 		return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
691 	default:
692 		return (EOPNOTSUPP);
693 	}
694 	/* NOTREACHED */
695 }
696 #endif /* DEBUG */
697 
698 /*
699  * Reads, or writes that lower the value
700  */
701 int
702 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
703 {
704 	unsigned int oval = *valp, val = *valp;
705 	int error;
706 
707 	if (newp == NULL)
708 		return (sysctl_rdint(oldp, oldlenp, newp, *valp));
709 
710 	if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
711 		return (error);
712 	if (val > oval)
713 		return (EPERM);		/* do not allow raising */
714 	*(unsigned int *)valp = val;
715 	return (0);
716 }
717 
718 /*
719  * Validate parameters and get old / set new parameters
720  * for an integer-valued sysctl function.
721  */
722 int
723 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
724 {
725 	int error = 0;
726 
727 	if (oldp && *oldlenp < sizeof(int))
728 		return (ENOMEM);
729 	if (newp && newlen != sizeof(int))
730 		return (EINVAL);
731 	*oldlenp = sizeof(int);
732 	if (oldp)
733 		error = copyout(valp, oldp, sizeof(int));
734 	if (error == 0 && newp)
735 		error = copyin(newp, valp, sizeof(int));
736 	return (error);
737 }
738 
739 /*
740  * As above, but read-only.
741  */
742 int
743 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val)
744 {
745 	int error = 0;
746 
747 	if (oldp && *oldlenp < sizeof(int))
748 		return (ENOMEM);
749 	if (newp)
750 		return (EPERM);
751 	*oldlenp = sizeof(int);
752 	if (oldp)
753 		error = copyout((caddr_t)&val, oldp, sizeof(int));
754 	return (error);
755 }
756 
757 /*
758  * Array of integer values.
759  */
760 int
761 sysctl_int_arr(int **valpp, int *name, u_int namelen, void *oldp,
762     size_t *oldlenp, void *newp, size_t newlen)
763 {
764 	if (namelen > 1)
765 		return (ENOTDIR);
766 	if (name[0] < 0 || valpp[name[0]] == NULL)
767 		return (EOPNOTSUPP);
768 	return (sysctl_int(oldp, oldlenp, newp, newlen, valpp[name[0]]));
769 }
770 
771 /*
772  * Validate parameters and get old / set new parameters
773  * for an integer-valued sysctl function.
774  */
775 int
776 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
777     int64_t *valp)
778 {
779 	int error = 0;
780 
781 	if (oldp && *oldlenp < sizeof(int64_t))
782 		return (ENOMEM);
783 	if (newp && newlen != sizeof(int64_t))
784 		return (EINVAL);
785 	*oldlenp = sizeof(int64_t);
786 	if (oldp)
787 		error = copyout(valp, oldp, sizeof(int64_t));
788 	if (error == 0 && newp)
789 		error = copyin(newp, valp, sizeof(int64_t));
790 	return (error);
791 }
792 
793 /*
794  * As above, but read-only.
795  */
796 int
797 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val)
798 {
799 	int error = 0;
800 
801 	if (oldp && *oldlenp < sizeof(int64_t))
802 		return (ENOMEM);
803 	if (newp)
804 		return (EPERM);
805 	*oldlenp = sizeof(int64_t);
806 	if (oldp)
807 		error = copyout((caddr_t)&val, oldp, sizeof(int64_t));
808 	return (error);
809 }
810 
811 /*
812  * Validate parameters and get old / set new parameters
813  * for a string-valued sysctl function.
814  */
815 int
816 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str,
817     int maxlen)
818 {
819 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
820 }
821 
822 int
823 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
824     char *str, int maxlen)
825 {
826 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
827 }
828 
829 int
830 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
831     char *str, int maxlen, int trunc)
832 {
833 	int len, error = 0;
834 	char c;
835 
836 	len = strlen(str) + 1;
837 	if (oldp && *oldlenp < len) {
838 		if (trunc == 0 || *oldlenp == 0)
839 			return (ENOMEM);
840 	}
841 	if (newp && newlen >= maxlen)
842 		return (EINVAL);
843 	if (oldp) {
844 		if (trunc && *oldlenp < len) {
845 			/* save & zap NUL terminator while copying */
846 			c = str[*oldlenp-1];
847 			str[*oldlenp-1] = '\0';
848 			error = copyout(str, oldp, *oldlenp);
849 			str[*oldlenp-1] = c;
850 		} else {
851 			*oldlenp = len;
852 			error = copyout(str, oldp, len);
853 		}
854 	}
855 	if (error == 0 && newp) {
856 		error = copyin(newp, str, newlen);
857 		str[newlen] = 0;
858 	}
859 	return (error);
860 }
861 
862 /*
863  * As above, but read-only.
864  */
865 int
866 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str)
867 {
868 	int len, error = 0;
869 
870 	len = strlen(str) + 1;
871 	if (oldp && *oldlenp < len)
872 		return (ENOMEM);
873 	if (newp)
874 		return (EPERM);
875 	*oldlenp = len;
876 	if (oldp)
877 		error = copyout(str, oldp, len);
878 	return (error);
879 }
880 
881 /*
882  * Validate parameters and get old / set new parameters
883  * for a structure oriented sysctl function.
884  */
885 int
886 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp,
887     int len)
888 {
889 	int error = 0;
890 
891 	if (oldp && *oldlenp < len)
892 		return (ENOMEM);
893 	if (newp && newlen > len)
894 		return (EINVAL);
895 	if (oldp) {
896 		*oldlenp = len;
897 		error = copyout(sp, oldp, len);
898 	}
899 	if (error == 0 && newp)
900 		error = copyin(newp, sp, len);
901 	return (error);
902 }
903 
904 /*
905  * Validate parameters and get old parameters
906  * for a structure oriented sysctl function.
907  */
908 int
909 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
910     int len)
911 {
912 	int error = 0;
913 
914 	if (oldp && *oldlenp < len)
915 		return (ENOMEM);
916 	if (newp)
917 		return (EPERM);
918 	*oldlenp = len;
919 	if (oldp)
920 		error = copyout(sp, oldp, len);
921 	return (error);
922 }
923 
924 /*
925  * Get file structures.
926  */
927 int
928 sysctl_file(char *where, size_t *sizep, struct proc *p)
929 {
930 	int buflen, error;
931 	struct file *fp, cfile;
932 	char *start = where;
933 	struct ucred *cred = p->p_ucred;
934 
935 	buflen = *sizep;
936 	if (where == NULL) {
937 		/*
938 		 * overestimate by 10 files
939 		 */
940 		*sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
941 		return (0);
942 	}
943 
944 	/*
945 	 * first copyout filehead
946 	 */
947 	if (buflen < sizeof(filehead)) {
948 		*sizep = 0;
949 		return (0);
950 	}
951 	error = copyout((caddr_t)&filehead, where, sizeof(filehead));
952 	if (error)
953 		return (error);
954 	buflen -= sizeof(filehead);
955 	where += sizeof(filehead);
956 
957 	/*
958 	 * followed by an array of file structures
959 	 */
960 	LIST_FOREACH(fp, &filehead, f_list) {
961 		if (buflen < sizeof(struct file)) {
962 			*sizep = where - start;
963 			return (ENOMEM);
964 		}
965 
966 		/* Only let the superuser or the owner see some information */
967 		bcopy(fp, &cfile, sizeof (struct file));
968 		if (suser(p, 0) != 0 && cred->cr_uid != fp->f_cred->cr_uid) {
969 			cfile.f_offset = (off_t)-1;
970 			cfile.f_rxfer = 0;
971 			cfile.f_wxfer = 0;
972 			cfile.f_rbytes = 0;
973 			cfile.f_wbytes = 0;
974 		}
975 		error = copyout(&cfile, where, sizeof (struct file));
976 		if (error)
977 			return (error);
978 		buflen -= sizeof(struct file);
979 		where += sizeof(struct file);
980 	}
981 	*sizep = where - start;
982 	return (0);
983 }
984 
985 #ifndef SMALL_KERNEL
986 
987 /*
988  * try over estimating by 5 procs
989  */
990 #define KERN_PROCSLOP	(5 * sizeof (struct kinfo_proc))
991 
992 int
993 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
994 {
995 	struct kinfo_proc2 *kproc2 = NULL;
996 	struct eproc *eproc = NULL;
997 	struct proc *p;
998 	char *dp;
999 	int arg, buflen, doingzomb, elem_size, elem_count;
1000 	int error, needed, type, op;
1001 
1002 	dp = where;
1003 	buflen = where != NULL ? *sizep : 0;
1004 	needed = error = 0;
1005 	type = name[0];
1006 
1007 	if (type == KERN_PROC) {
1008 		if (namelen != 3 && !(namelen == 2 &&
1009 		    (name[1] == KERN_PROC_ALL || name[1] == KERN_PROC_KTHREAD)))
1010 			return (EINVAL);
1011 		op = name[1];
1012 		arg = op == KERN_PROC_ALL ? 0 : name[2];
1013 		elem_size = elem_count = 0;
1014 		eproc = malloc(sizeof(struct eproc), M_TEMP, M_WAITOK);
1015 	} else /* if (type == KERN_PROC2) */ {
1016 		if (namelen != 5 || name[3] < 0 || name[4] < 0)
1017 			return (EINVAL);
1018 		op = name[1];
1019 		arg = name[2];
1020 		elem_size = name[3];
1021 		elem_count = name[4];
1022 		kproc2 = malloc(sizeof(struct kinfo_proc2), M_TEMP, M_WAITOK);
1023 	}
1024 	p = LIST_FIRST(&allproc);
1025 	doingzomb = 0;
1026 again:
1027 	for (; p != 0; p = LIST_NEXT(p, p_list)) {
1028 		/*
1029 		 * Skip embryonic processes.
1030 		 */
1031 		if (p->p_stat == SIDL)
1032 			continue;
1033 		/*
1034 		 * TODO - make more efficient (see notes below).
1035 		 */
1036 		switch (op) {
1037 
1038 		case KERN_PROC_PID:
1039 			/* could do this with just a lookup */
1040 			if (p->p_pid != (pid_t)arg)
1041 				continue;
1042 			break;
1043 
1044 		case KERN_PROC_PGRP:
1045 			/* could do this by traversing pgrp */
1046 			if (p->p_pgrp->pg_id != (pid_t)arg)
1047 				continue;
1048 			break;
1049 
1050 		case KERN_PROC_SESSION:
1051 			if (p->p_session->s_leader == NULL ||
1052 			    p->p_session->s_leader->p_pid != (pid_t)arg)
1053 				continue;
1054 			break;
1055 
1056 		case KERN_PROC_TTY:
1057 			if ((p->p_flag & P_CONTROLT) == 0 ||
1058 			    p->p_session->s_ttyp == NULL ||
1059 			    p->p_session->s_ttyp->t_dev != (dev_t)arg)
1060 				continue;
1061 			break;
1062 
1063 		case KERN_PROC_UID:
1064 			if (p->p_ucred->cr_uid != (uid_t)arg)
1065 				continue;
1066 			break;
1067 
1068 		case KERN_PROC_RUID:
1069 			if (p->p_cred->p_ruid != (uid_t)arg)
1070 				continue;
1071 			break;
1072 
1073 		case KERN_PROC_ALL:
1074 			if (p->p_flag & P_SYSTEM)
1075 				continue;
1076 			break;
1077 		case KERN_PROC_KTHREAD:
1078 			/* no filtering */
1079 			break;
1080 		default:
1081 			error = EINVAL;
1082 			goto err;
1083 		}
1084 		if (type == KERN_PROC) {
1085 			if (buflen >= sizeof(struct kinfo_proc)) {
1086 				fill_eproc(p, eproc);
1087 				error = copyout((caddr_t)p,
1088 				    &((struct kinfo_proc *)dp)->kp_proc,
1089 				    sizeof(struct proc));
1090 				if (error)
1091 					goto err;
1092 				error = copyout((caddr_t)eproc,
1093 				    &((struct kinfo_proc *)dp)->kp_eproc,
1094 				    sizeof(*eproc));
1095 				if (error)
1096 					goto err;
1097 				dp += sizeof(struct kinfo_proc);
1098 				buflen -= sizeof(struct kinfo_proc);
1099 			}
1100 			needed += sizeof(struct kinfo_proc);
1101 		} else /* if (type == KERN_PROC2) */ {
1102 			if (buflen >= elem_size && elem_count > 0) {
1103 				fill_kproc2(p, kproc2);
1104 				/*
1105 				 * Copy out elem_size, but not larger than
1106 				 * the size of a struct kinfo_proc2.
1107 				 */
1108 				error = copyout(kproc2, dp,
1109 				    min(sizeof(*kproc2), elem_size));
1110 				if (error)
1111 					goto err;
1112 				dp += elem_size;
1113 				buflen -= elem_size;
1114 				elem_count--;
1115 			}
1116 			needed += elem_size;
1117 		}
1118 	}
1119 	if (doingzomb == 0) {
1120 		p = LIST_FIRST(&zombproc);
1121 		doingzomb++;
1122 		goto again;
1123 	}
1124 	if (where != NULL) {
1125 		*sizep = dp - where;
1126 		if (needed > *sizep) {
1127 			error = ENOMEM;
1128 			goto err;
1129 		}
1130 	} else {
1131 		needed += KERN_PROCSLOP;
1132 		*sizep = needed;
1133 	}
1134 err:
1135 	if (eproc)
1136 		free(eproc, M_TEMP);
1137 	if (kproc2)
1138 		free(kproc2, M_TEMP);
1139 	return (error);
1140 }
1141 
1142 #endif	/* SMALL_KERNEL */
1143 
1144 /*
1145  * Fill in an eproc structure for the specified process.
1146  */
1147 void
1148 fill_eproc(struct proc *p, struct eproc *ep)
1149 {
1150 	struct tty *tp;
1151 
1152 	ep->e_paddr = p;
1153 	ep->e_sess = p->p_pgrp->pg_session;
1154 	ep->e_pcred = *p->p_cred;
1155 	ep->e_ucred = *p->p_ucred;
1156 	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
1157 		ep->e_vm.vm_rssize = 0;
1158 		ep->e_vm.vm_tsize = 0;
1159 		ep->e_vm.vm_dsize = 0;
1160 		ep->e_vm.vm_ssize = 0;
1161 		bzero(&ep->e_pstats, sizeof(ep->e_pstats));
1162 		ep->e_pstats_valid = 0;
1163 	} else {
1164 		struct vmspace *vm = p->p_vmspace;
1165 
1166 		ep->e_vm.vm_rssize = vm_resident_count(vm);
1167 		ep->e_vm.vm_tsize = vm->vm_tsize;
1168 		ep->e_vm.vm_dsize = vm->vm_dused;
1169 		ep->e_vm.vm_ssize = vm->vm_ssize;
1170 		ep->e_pstats = *p->p_stats;
1171 		ep->e_pstats_valid = 1;
1172 	}
1173 	if (p->p_pptr)
1174 		ep->e_ppid = p->p_pptr->p_pid;
1175 	else
1176 		ep->e_ppid = 0;
1177 	ep->e_pgid = p->p_pgrp->pg_id;
1178 	ep->e_jobc = p->p_pgrp->pg_jobc;
1179 	if ((p->p_flag & P_CONTROLT) &&
1180 	     (tp = ep->e_sess->s_ttyp)) {
1181 		ep->e_tdev = tp->t_dev;
1182 		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1183 		ep->e_tsess = tp->t_session;
1184 	} else
1185 		ep->e_tdev = NODEV;
1186 	ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
1187 	if (SESS_LEADER(p))
1188 		ep->e_flag |= EPROC_SLEADER;
1189 	strncpy(ep->e_wmesg, p->p_wmesg ? p->p_wmesg : "", WMESGLEN);
1190 	ep->e_wmesg[WMESGLEN] = '\0';
1191 	ep->e_xsize = ep->e_xrssize = 0;
1192 	ep->e_xccount = ep->e_xswrss = 0;
1193 	strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME-1);
1194 	ep->e_login[MAXLOGNAME-1] = '\0';
1195 	strncpy(ep->e_emul, p->p_emul->e_name, EMULNAMELEN);
1196 	ep->e_emul[EMULNAMELEN] = '\0';
1197 	ep->e_maxrss = p->p_rlimit ? p->p_rlimit[RLIMIT_RSS].rlim_cur : 0;
1198 	ep->e_limit = p->p_p->ps_limit;
1199 }
1200 
1201 #ifndef	SMALL_KERNEL
1202 
1203 /*
1204  * Fill in a kproc2 structure for the specified process.
1205  */
1206 void
1207 fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
1208 {
1209 	struct tty *tp;
1210 	struct timeval ut, st;
1211 
1212 	bzero(ki, sizeof(*ki));
1213 
1214 	ki->p_paddr = PTRTOINT64(p);
1215 	ki->p_fd = PTRTOINT64(p->p_fd);
1216 	ki->p_stats = PTRTOINT64(p->p_stats);
1217 	ki->p_limit = PTRTOINT64(p->p_p->ps_limit);
1218 	ki->p_vmspace = PTRTOINT64(p->p_vmspace);
1219 	ki->p_sigacts = PTRTOINT64(p->p_sigacts);
1220 	ki->p_sess = PTRTOINT64(p->p_session);
1221 	ki->p_tsess = 0;	/* may be changed if controlling tty below */
1222 	ki->p_ru = PTRTOINT64(p->p_ru);
1223 
1224 	ki->p_eflag = 0;
1225 	ki->p_exitsig = p->p_exitsig;
1226 	ki->p_flag = p->p_flag | P_INMEM;
1227 
1228 	ki->p_pid = p->p_pid;
1229 	if (p->p_pptr)
1230 		ki->p_ppid = p->p_pptr->p_pid;
1231 	else
1232 		ki->p_ppid = 0;
1233 	if (p->p_session->s_leader)
1234 		ki->p_sid = p->p_session->s_leader->p_pid;
1235 	else
1236 		ki->p_sid = 0;
1237 	ki->p__pgid = p->p_pgrp->pg_id;
1238 
1239 	ki->p_tpgid = -1;	/* may be changed if controlling tty below */
1240 
1241 	ki->p_uid = p->p_ucred->cr_uid;
1242 	ki->p_ruid = p->p_cred->p_ruid;
1243 	ki->p_gid = p->p_ucred->cr_gid;
1244 	ki->p_rgid = p->p_cred->p_rgid;
1245 	ki->p_svuid = p->p_cred->p_svuid;
1246 	ki->p_svgid = p->p_cred->p_svgid;
1247 
1248 	memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups,
1249 	    min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups)));
1250 	ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups;
1251 
1252 	ki->p_jobc = p->p_pgrp->pg_jobc;
1253 	if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) {
1254 		ki->p_tdev = tp->t_dev;
1255 		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1;
1256 		ki->p_tsess = PTRTOINT64(tp->t_session);
1257 	} else {
1258 		ki->p_tdev = NODEV;
1259 	}
1260 
1261 	ki->p_estcpu = p->p_estcpu;
1262 	ki->p_rtime_sec = p->p_rtime.tv_sec;
1263 	ki->p_rtime_usec = p->p_rtime.tv_usec;
1264 	ki->p_cpticks = p->p_cpticks;
1265 	ki->p_pctcpu = p->p_pctcpu;
1266 
1267 	ki->p_uticks = p->p_uticks;
1268 	ki->p_sticks = p->p_sticks;
1269 	ki->p_iticks = p->p_iticks;
1270 
1271 	ki->p_tracep = PTRTOINT64(p->p_tracep);
1272 	ki->p_traceflag = p->p_traceflag;
1273 
1274 	ki->p_siglist = p->p_siglist;
1275 	ki->p_sigmask = p->p_sigmask;
1276 	ki->p_sigignore = p->p_sigignore;
1277 	ki->p_sigcatch = p->p_sigcatch;
1278 
1279 	ki->p_stat = p->p_stat;
1280 	ki->p_nice = p->p_nice;
1281 
1282 	ki->p_xstat = p->p_xstat;
1283 	ki->p_acflag = p->p_acflag;
1284 
1285 	strlcpy(ki->p_emul, p->p_emul->e_name, sizeof(ki->p_emul));
1286 	strlcpy(ki->p_comm, p->p_comm, sizeof(ki->p_comm));
1287 	strncpy(ki->p_login, p->p_session->s_login,
1288 	    min(sizeof(ki->p_login) - 1, sizeof(p->p_session->s_login)));
1289 
1290 	if (p->p_stat == SIDL || P_ZOMBIE(p)) {
1291 		ki->p_vm_rssize = 0;
1292 		ki->p_vm_tsize = 0;
1293 		ki->p_vm_dsize = 0;
1294 		ki->p_vm_ssize = 0;
1295 	} else {
1296 		struct vmspace *vm = p->p_vmspace;
1297 
1298 		ki->p_vm_rssize = vm_resident_count(vm);
1299 		ki->p_vm_tsize = vm->vm_tsize;
1300 		ki->p_vm_dsize = vm->vm_dused;
1301 		ki->p_vm_ssize = vm->vm_ssize;
1302 		ki->p_forw = ki->p_back = 0;
1303 		ki->p_addr = PTRTOINT64(p->p_addr);
1304 		ki->p_stat = p->p_stat;
1305 		ki->p_swtime = p->p_swtime;
1306 		ki->p_slptime = p->p_slptime;
1307 		ki->p_schedflags = 0;
1308 		ki->p_holdcnt = 1;
1309 		ki->p_priority = p->p_priority;
1310 		ki->p_usrpri = p->p_usrpri;
1311 		if (p->p_wmesg)
1312 			strlcpy(ki->p_wmesg, p->p_wmesg, sizeof(ki->p_wmesg));
1313 		ki->p_wchan = PTRTOINT64(p->p_wchan);
1314 
1315 	}
1316 
1317 	if (p->p_session->s_ttyvp)
1318 		ki->p_eflag |= EPROC_CTTY;
1319 	if (SESS_LEADER(p))
1320 		ki->p_eflag |= EPROC_SLEADER;
1321 	if (p->p_rlimit)
1322 		ki->p_rlim_rss_cur = p->p_rlimit[RLIMIT_RSS].rlim_cur;
1323 
1324 	/* XXX Is this double check necessary? */
1325 	if (P_ZOMBIE(p)) {
1326 		ki->p_uvalid = 0;
1327 	} else {
1328 		ki->p_uvalid = 1;
1329 
1330 		ki->p_ustart_sec = p->p_stats->p_start.tv_sec;
1331 		ki->p_ustart_usec = p->p_stats->p_start.tv_usec;
1332 
1333 		calcru(p, &ut, &st, NULL);
1334 		ki->p_uutime_sec = ut.tv_sec;
1335 		ki->p_uutime_usec = ut.tv_usec;
1336 		ki->p_ustime_sec = st.tv_sec;
1337 		ki->p_ustime_usec = st.tv_usec;
1338 
1339 		ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss;
1340 		ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss;
1341 		ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss;
1342 		ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss;
1343 		ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt;
1344 		ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt;
1345 		ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap;
1346 		ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock;
1347 		ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock;
1348 		ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd;
1349 		ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv;
1350 		ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals;
1351 		ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw;
1352 		ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw;
1353 
1354 		timeradd(&p->p_stats->p_cru.ru_utime,
1355 			 &p->p_stats->p_cru.ru_stime, &ut);
1356 		ki->p_uctime_sec = ut.tv_sec;
1357 		ki->p_uctime_usec = ut.tv_usec;
1358 		ki->p_cpuid = KI_NOCPU;
1359 #ifdef MULTIPROCESSOR
1360 		if (p->p_cpu != NULL)
1361 			ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu);
1362 #endif
1363 	}
1364 }
1365 
1366 int
1367 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1368     struct proc *cp)
1369 {
1370 	struct proc *vp;
1371 	pid_t pid;
1372 	struct ps_strings pss;
1373 	struct iovec iov;
1374 	struct uio uio;
1375 	int error, cnt, op;
1376 	size_t limit;
1377 	char **rargv, **vargv;		/* reader vs. victim */
1378 	char *rarg, *varg, *buf;
1379 	struct vmspace *vm;
1380 
1381 	if (namelen > 2)
1382 		return (ENOTDIR);
1383 	if (namelen < 2)
1384 		return (EINVAL);
1385 
1386 	pid = name[0];
1387 	op = name[1];
1388 
1389 	switch (op) {
1390 	case KERN_PROC_ARGV:
1391 	case KERN_PROC_NARGV:
1392 	case KERN_PROC_ENV:
1393 	case KERN_PROC_NENV:
1394 		break;
1395 	default:
1396 		return (EOPNOTSUPP);
1397 	}
1398 
1399 	if ((vp = pfind(pid)) == NULL)
1400 		return (ESRCH);
1401 
1402 	if (oldp == NULL) {
1403 		if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV)
1404 			*oldlenp = sizeof(int);
1405 		else
1406 			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
1407 		return (0);
1408 	}
1409 
1410 	if (P_ZOMBIE(vp) || (vp->p_flag & P_SYSTEM))
1411 		return (EINVAL);
1412 
1413 	/* Exiting - don't bother, it will be gone soon anyway */
1414 	if ((vp->p_flag & P_WEXIT))
1415 		return (ESRCH);
1416 
1417 	/* Execing - danger. */
1418 	if ((vp->p_flag & P_INEXEC))
1419 		return (EBUSY);
1420 
1421 	vm = vp->p_vmspace;
1422 	vm->vm_refcnt++;
1423 	vp = NULL;
1424 
1425 	buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
1426 
1427 	iov.iov_base = &pss;
1428 	iov.iov_len = sizeof(pss);
1429 	uio.uio_iov = &iov;
1430 	uio.uio_iovcnt = 1;
1431 	uio.uio_offset = (off_t)PS_STRINGS;
1432 	uio.uio_resid = sizeof(pss);
1433 	uio.uio_segflg = UIO_SYSSPACE;
1434 	uio.uio_rw = UIO_READ;
1435 	uio.uio_procp = cp;
1436 
1437 	if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1438 		goto out;
1439 
1440 	if (op == KERN_PROC_NARGV) {
1441 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr);
1442 		goto out;
1443 	}
1444 	if (op == KERN_PROC_NENV) {
1445 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr);
1446 		goto out;
1447 	}
1448 
1449 	if (op == KERN_PROC_ARGV) {
1450 		cnt = pss.ps_nargvstr;
1451 		vargv = pss.ps_argvstr;
1452 	} else {
1453 		cnt = pss.ps_nenvstr;
1454 		vargv = pss.ps_envstr;
1455 	}
1456 
1457 	/* -1 to have space for a terminating NUL */
1458 	limit = *oldlenp - 1;
1459 	*oldlenp = 0;
1460 
1461 	rargv = oldp;
1462 
1463 	/*
1464 	 * *oldlenp - number of bytes copied out into readers buffer.
1465 	 * limit - maximal number of bytes allowed into readers buffer.
1466 	 * rarg - pointer into readers buffer where next arg will be stored.
1467 	 * rargv - pointer into readers buffer where the next rarg pointer
1468 	 *  will be stored.
1469 	 * vargv - pointer into victim address space where the next argument
1470 	 *  will be read.
1471 	 */
1472 
1473 	/* space for cnt pointers and a NULL */
1474 	rarg = (char *)(rargv + cnt + 1);
1475 	*oldlenp += (cnt + 1) * sizeof(char **);
1476 
1477 	while (cnt > 0 && *oldlenp < limit) {
1478 		size_t len, vstrlen;
1479 
1480 		/* Write to readers argv */
1481 		if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0)
1482 			goto out;
1483 
1484 		/* read the victim argv */
1485 		iov.iov_base = &varg;
1486 		iov.iov_len = sizeof(varg);
1487 		uio.uio_iov = &iov;
1488 		uio.uio_iovcnt = 1;
1489 		uio.uio_offset = (off_t)(vaddr_t)vargv;
1490 		uio.uio_resid = sizeof(varg);
1491 		uio.uio_segflg = UIO_SYSSPACE;
1492 		uio.uio_rw = UIO_READ;
1493 		uio.uio_procp = cp;
1494 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1495 			goto out;
1496 
1497 		if (varg == NULL)
1498 			break;
1499 
1500 		/*
1501 		 * read the victim arg. We must jump through hoops to avoid
1502 		 * crossing a page boundary too much and returning an error.
1503 		 */
1504 more:
1505 		len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK);
1506 		/* leave space for the terminating NUL */
1507 		iov.iov_base = buf;
1508 		iov.iov_len = len;
1509 		uio.uio_iov = &iov;
1510 		uio.uio_iovcnt = 1;
1511 		uio.uio_offset = (off_t)(vaddr_t)varg;
1512 		uio.uio_resid = len;
1513 		uio.uio_segflg = UIO_SYSSPACE;
1514 		uio.uio_rw = UIO_READ;
1515 		uio.uio_procp = cp;
1516 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1517 			goto out;
1518 
1519 		for (vstrlen = 0; vstrlen < len; vstrlen++) {
1520 			if (buf[vstrlen] == '\0')
1521 				break;
1522 		}
1523 
1524 		/* Don't overflow readers buffer. */
1525 		if (*oldlenp + vstrlen + 1 >= limit) {
1526 			error = ENOMEM;
1527 			goto out;
1528 		}
1529 
1530 		if ((error = copyout(buf, rarg, vstrlen)) != 0)
1531 			goto out;
1532 
1533 		*oldlenp += vstrlen;
1534 		rarg += vstrlen;
1535 
1536 		/* The string didn't end in this page? */
1537 		if (vstrlen == len) {
1538 			varg += vstrlen;
1539 			goto more;
1540 		}
1541 
1542 		/* End of string. Terminate it with a NUL */
1543 		buf[0] = '\0';
1544 		if ((error = copyout(buf, rarg, 1)) != 0)
1545 			goto out;
1546 		*oldlenp += 1;
1547 		rarg += 1;
1548 
1549 		vargv++;
1550 		rargv++;
1551 		cnt--;
1552 	}
1553 
1554 	if (*oldlenp >= limit) {
1555 		error = ENOMEM;
1556 		goto out;
1557 	}
1558 
1559 	/* Write the terminating null */
1560 	rarg = NULL;
1561 	error = copyout(&rarg, rargv, sizeof(rarg));
1562 
1563 out:
1564 	uvmspace_free(vm);
1565 	free(buf, M_TEMP);
1566 	return (error);
1567 }
1568 
1569 #endif
1570 
1571 /*
1572  * Initialize disknames/diskstats for export by sysctl. If update is set,
1573  * then we simply update the disk statistics information.
1574  */
1575 int
1576 sysctl_diskinit(int update, struct proc *p)
1577 {
1578 	struct diskstats *sdk;
1579 	struct disk *dk;
1580 	int i, tlen, l;
1581 
1582 	if ((i = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0)
1583 		return i;
1584 
1585 	if (disk_change) {
1586 		for (dk = TAILQ_FIRST(&disklist), tlen = 0; dk;
1587 		    dk = TAILQ_NEXT(dk, dk_link))
1588 			tlen += strlen(dk->dk_name) + 1;
1589 		tlen++;
1590 
1591 		if (disknames)
1592 			free(disknames, M_SYSCTL);
1593 		if (diskstats)
1594 			free(diskstats, M_SYSCTL);
1595 		diskstats = NULL;
1596 		disknames = NULL;
1597 		diskstats = malloc(disk_count * sizeof(struct diskstats),
1598 		    M_SYSCTL, M_WAITOK);
1599 		disknames = malloc(tlen, M_SYSCTL, M_WAITOK);
1600 		disknames[0] = '\0';
1601 
1602 		for (dk = TAILQ_FIRST(&disklist), i = 0, l = 0; dk;
1603 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
1604 			snprintf(disknames + l, tlen - l, "%s,",
1605 			    dk->dk_name ? dk->dk_name : "");
1606 			l += strlen(disknames + l);
1607 			sdk = diskstats + i;
1608 			strlcpy(sdk->ds_name, dk->dk_name,
1609 			    sizeof(sdk->ds_name));
1610 			mtx_enter(&dk->dk_mtx);
1611 			sdk->ds_busy = dk->dk_busy;
1612 			sdk->ds_rxfer = dk->dk_rxfer;
1613 			sdk->ds_wxfer = dk->dk_wxfer;
1614 			sdk->ds_seek = dk->dk_seek;
1615 			sdk->ds_rbytes = dk->dk_rbytes;
1616 			sdk->ds_wbytes = dk->dk_wbytes;
1617 			sdk->ds_attachtime = dk->dk_attachtime;
1618 			sdk->ds_timestamp = dk->dk_timestamp;
1619 			sdk->ds_time = dk->dk_time;
1620 			mtx_leave(&dk->dk_mtx);
1621 		}
1622 
1623 		/* Eliminate trailing comma */
1624 		if (l != 0)
1625 			disknames[l - 1] = '\0';
1626 		disk_change = 0;
1627 	} else if (update) {
1628 		/* Just update, number of drives hasn't changed */
1629 		for (dk = TAILQ_FIRST(&disklist), i = 0; dk;
1630 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
1631 			sdk = diskstats + i;
1632 			strlcpy(sdk->ds_name, dk->dk_name,
1633 			    sizeof(sdk->ds_name));
1634 			mtx_enter(&dk->dk_mtx);
1635 			sdk->ds_busy = dk->dk_busy;
1636 			sdk->ds_rxfer = dk->dk_rxfer;
1637 			sdk->ds_wxfer = dk->dk_wxfer;
1638 			sdk->ds_seek = dk->dk_seek;
1639 			sdk->ds_rbytes = dk->dk_rbytes;
1640 			sdk->ds_wbytes = dk->dk_wbytes;
1641 			sdk->ds_attachtime = dk->dk_attachtime;
1642 			sdk->ds_timestamp = dk->dk_timestamp;
1643 			sdk->ds_time = dk->dk_time;
1644 			mtx_leave(&dk->dk_mtx);
1645 		}
1646 	}
1647 	rw_exit_write(&sysctl_disklock);
1648 	return 0;
1649 }
1650 
1651 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
1652 int
1653 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep)
1654 {
1655 #ifdef SYSVMSG
1656 	struct msg_sysctl_info *msgsi;
1657 #endif
1658 #ifdef SYSVSEM
1659 	struct sem_sysctl_info *semsi;
1660 #endif
1661 #ifdef SYSVSHM
1662 	struct shm_sysctl_info *shmsi;
1663 #endif
1664 	size_t infosize, dssize, tsize, buflen;
1665 	int i, nds, error, ret;
1666 	void *buf;
1667 
1668 	if (namelen != 1)
1669 		return (EINVAL);
1670 
1671 	buflen = *sizep;
1672 
1673 	switch (*name) {
1674 	case KERN_SYSVIPC_MSG_INFO:
1675 #ifdef SYSVMSG
1676 		infosize = sizeof(msgsi->msginfo);
1677 		nds = msginfo.msgmni;
1678 		dssize = sizeof(msgsi->msgids[0]);
1679 		break;
1680 #else
1681 		return (EOPNOTSUPP);
1682 #endif
1683 	case KERN_SYSVIPC_SEM_INFO:
1684 #ifdef SYSVSEM
1685 		infosize = sizeof(semsi->seminfo);
1686 		nds = seminfo.semmni;
1687 		dssize = sizeof(semsi->semids[0]);
1688 		break;
1689 #else
1690 		return (EOPNOTSUPP);
1691 #endif
1692 	case KERN_SYSVIPC_SHM_INFO:
1693 #ifdef SYSVSHM
1694 		infosize = sizeof(shmsi->shminfo);
1695 		nds = shminfo.shmmni;
1696 		dssize = sizeof(shmsi->shmids[0]);
1697 		break;
1698 #else
1699 		return (EOPNOTSUPP);
1700 #endif
1701 	default:
1702 		return (EINVAL);
1703 	}
1704 	tsize = infosize + (nds * dssize);
1705 
1706 	/* Return just the total size required. */
1707 	if (where == NULL) {
1708 		*sizep = tsize;
1709 		return (0);
1710 	}
1711 
1712 	/* Not enough room for even the info struct. */
1713 	if (buflen < infosize) {
1714 		*sizep = 0;
1715 		return (ENOMEM);
1716 	}
1717 	buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK|M_ZERO);
1718 
1719 	switch (*name) {
1720 #ifdef SYSVMSG
1721 	case KERN_SYSVIPC_MSG_INFO:
1722 		msgsi = (struct msg_sysctl_info *)buf;
1723 		msgsi->msginfo = msginfo;
1724 		break;
1725 #endif
1726 #ifdef SYSVSEM
1727 	case KERN_SYSVIPC_SEM_INFO:
1728 		semsi = (struct sem_sysctl_info *)buf;
1729 		semsi->seminfo = seminfo;
1730 		break;
1731 #endif
1732 #ifdef SYSVSHM
1733 	case KERN_SYSVIPC_SHM_INFO:
1734 		shmsi = (struct shm_sysctl_info *)buf;
1735 		shmsi->shminfo = shminfo;
1736 		break;
1737 #endif
1738 	}
1739 	buflen -= infosize;
1740 
1741 	ret = 0;
1742 	if (buflen > 0) {
1743 		/* Fill in the IPC data structures.  */
1744 		for (i = 0; i < nds; i++) {
1745 			if (buflen < dssize) {
1746 				ret = ENOMEM;
1747 				break;
1748 			}
1749 			switch (*name) {
1750 #ifdef SYSVMSG
1751 			case KERN_SYSVIPC_MSG_INFO:
1752 				bcopy(&msqids[i], &msgsi->msgids[i], dssize);
1753 				break;
1754 #endif
1755 #ifdef SYSVSEM
1756 			case KERN_SYSVIPC_SEM_INFO:
1757 				if (sema[i] != NULL)
1758 					bcopy(sema[i], &semsi->semids[i],
1759 					    dssize);
1760 				else
1761 					bzero(&semsi->semids[i], dssize);
1762 				break;
1763 #endif
1764 #ifdef SYSVSHM
1765 			case KERN_SYSVIPC_SHM_INFO:
1766 				if (shmsegs[i] != NULL)
1767 					bcopy(shmsegs[i], &shmsi->shmids[i],
1768 					    dssize);
1769 				else
1770 					bzero(&shmsi->shmids[i], dssize);
1771 				break;
1772 #endif
1773 			}
1774 			buflen -= dssize;
1775 		}
1776 	}
1777 	*sizep -= buflen;
1778 	error = copyout(buf, where, *sizep);
1779 	free(buf, M_TEMP);
1780 	/* If copyout succeeded, use return code set earlier. */
1781 	return (error ? error : ret);
1782 }
1783 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
1784 
1785 #ifndef	SMALL_KERNEL
1786 
1787 int
1788 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp)
1789 {
1790 	return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0));
1791 }
1792 
1793 
1794 int
1795 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1796     void *newp, size_t newlen)
1797 {
1798 	struct ksensor *ks;
1799 	struct sensor *us;
1800 	struct ksensordev *ksd;
1801 	struct sensordev *usd;
1802 	int dev, numt, ret;
1803 	enum sensor_type type;
1804 
1805 	if (namelen != 1 && namelen != 3)
1806 		return (ENOTDIR);
1807 
1808 	dev = name[0];
1809 	if (namelen == 1) {
1810 		ksd = sensordev_get(dev);
1811 		if (ksd == NULL)
1812 			return (ENOENT);
1813 
1814 		/* Grab a copy, to clear the kernel pointers */
1815 		usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO);
1816 		usd->num = ksd->num;
1817 		strlcpy(usd->xname, ksd->xname, sizeof(usd->xname));
1818 		memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt));
1819 		usd->sensors_count = ksd->sensors_count;
1820 
1821 		ret = sysctl_rdstruct(oldp, oldlenp, newp, usd,
1822 		    sizeof(struct sensordev));
1823 
1824 		free(usd, M_TEMP);
1825 		return (ret);
1826 	}
1827 
1828 	type = name[1];
1829 	numt = name[2];
1830 
1831 	ks = sensor_find(dev, type, numt);
1832 	if (ks == NULL)
1833 		return (ENOENT);
1834 
1835 	/* Grab a copy, to clear the kernel pointers */
1836 	us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO);
1837 	memcpy(us->desc, ks->desc, sizeof(us->desc));
1838 	us->tv = ks->tv;
1839 	us->value = ks->value;
1840 	us->type = ks->type;
1841 	us->status = ks->status;
1842 	us->numt = ks->numt;
1843 	us->flags = ks->flags;
1844 
1845 	ret = sysctl_rdstruct(oldp, oldlenp, newp, us,
1846 	    sizeof(struct sensor));
1847 	free(us, M_TEMP);
1848 	return (ret);
1849 }
1850 
1851 int
1852 sysctl_emul(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1853     void *newp, size_t newlen)
1854 {
1855 	int enabled, error;
1856 	struct emul *e;
1857 
1858 	if (name[0] == KERN_EMUL_NUM) {
1859 		if (namelen != 1)
1860 			return (ENOTDIR);
1861 		return (sysctl_rdint(oldp, oldlenp, newp, nexecs));
1862 	}
1863 
1864 	if (namelen != 2)
1865 		return (ENOTDIR);
1866 	if (name[0] > nexecs || name[0] < 0)
1867 		return (EINVAL);
1868 	e = execsw[name[0] - 1].es_emul;
1869 	if (e == NULL)
1870 		return (EINVAL);
1871 
1872 	switch (name[1]) {
1873 	case KERN_EMUL_NAME:
1874 		return (sysctl_rdstring(oldp, oldlenp, newp, e->e_name));
1875 	case KERN_EMUL_ENABLED:
1876 		enabled = (e->e_flags & EMUL_ENABLED);
1877 		error = sysctl_int(oldp, oldlenp, newp, newlen,
1878 		    &enabled);
1879 		e->e_flags = (enabled & EMUL_ENABLED);
1880 		return (error);
1881 	default:
1882 		return (EINVAL);
1883 	}
1884 }
1885 
1886 #endif	/* SMALL_KERNEL */
1887 
1888 int
1889 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1890     void *newp, size_t newlen)
1891 {
1892 	CPU_INFO_ITERATOR cii;
1893 	struct cpu_info *ci;
1894 	int i;
1895 
1896 	if (namelen != 1)
1897 		return (ENOTDIR);
1898 
1899 	i = name[0];
1900 
1901 	CPU_INFO_FOREACH(cii, ci) {
1902 		if (i-- == 0)
1903 			break;
1904 	}
1905 	if (i > 0)
1906 		return (ENOENT);
1907 
1908 	return (sysctl_rdstruct(oldp, oldlenp, newp,
1909 	    &ci->ci_schedstate.spc_cp_time,
1910 	    sizeof(ci->ci_schedstate.spc_cp_time)));
1911 }
1912