1 /* $NetBSD: init_sysctl.c,v 1.170 2009/12/12 17:29:34 dsl Exp $ */
4 * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown, and by Andrew Doran.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.170 2009/12/12 17:29:34 dsl Exp $");
36 #include "opt_compat_netbsd32.h"
37 #include "opt_compat_netbsd.h"
38 #include "opt_modular.h"
40 #include "opt_posix.h"
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/sysctl.h>
48 #include <sys/errno.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/unistd.h>
52 #include <sys/disklabel.h>
54 #include <sys/vnode.h>
55 #include <sys/mount.h>
56 #include <sys/namei.h>
57 #include <sys/msgbuf.h>
59 #include <sys/socketvar.h>
61 #include <sys/filedesc.h>
64 #include <sys/resource.h>
65 #include <sys/resourcevar.h>
68 #include <sys/device.h>
70 #include <sys/kauth.h>
71 #include <sys/ktrace.h>
74 #ifdef COMPAT_NETBSD32
75 #include <compat/netbsd32/netbsd32.h>
78 #include <compat/sys/time.h>
87 #if defined(MODULAR) || defined(P1003_1B_SEMAPHORE)
88 int posix_semaphores
= 200112;
93 int security_setidcore_dump
;
94 char security_setidcore_path
[MAXPATHLEN
] = "/var/crash/%n.core";
95 uid_t security_setidcore_owner
= 0;
96 gid_t security_setidcore_group
= 0;
97 mode_t security_setidcore_mode
= (S_IRUSR
|S_IWUSR
);
99 /* Initialized in sysctl_init() for now... */
100 /* static */ kmutex_t sysctl_file_marker_lock
;
101 static u_int sysctl_file_marker
= 1;
103 static const u_int sysctl_flagmap
[] = {
104 PK_ADVLOCK
, P_ADVLOCK
,
106 PK_NOCLDWAIT
, P_NOCLDWAIT
,
108 PK_CLDSIGIGN
, P_CLDSIGIGN
,
113 static const u_int sysctl_sflagmap
[] = {
114 PS_NOCLDSTOP
, P_NOCLDSTOP
,
116 PS_STOPFORK
, P_STOPFORK
,
117 PS_STOPEXEC
, P_STOPEXEC
,
118 PS_STOPEXIT
, P_STOPEXIT
,
122 static const u_int sysctl_slflagmap
[] = {
123 PSL_TRACED
, P_TRACED
,
124 PSL_FSTRACE
, P_FSTRACE
,
125 PSL_CHTRACED
, P_CHTRACED
,
126 PSL_SYSCALL
, P_SYSCALL
,
130 static const u_int sysctl_lflagmap
[] = {
131 PL_CONTROLT
, P_CONTROLT
,
136 static const u_int sysctl_stflagmap
[] = {
137 PST_PROFIL
, P_PROFIL
,
142 static const u_int sysctl_lwpflagmap
[] = {
145 LW_SA
, P_SA
, /* WRS ??? */
149 static const u_int sysctl_lwpprflagmap
[] = {
150 LPR_DETACHED
, L_DETACHED
,
155 * try over estimating by 5 procs/lwps
157 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
158 #define KERN_LWPSLOP (5 * sizeof(struct kinfo_lwp))
160 static int dcopyout(struct lwp
*, const void *, void *, size_t);
163 dcopyout(struct lwp
*l
, const void *kaddr
, void *uaddr
, size_t len
)
167 error
= copyout(kaddr
, uaddr
, len
);
168 ktrmibio(-1, UIO_READ
, uaddr
, len
, error
);
174 static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO
);
176 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO
);
177 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO
);
178 static int sysctl_kern_maxproc(SYSCTLFN_PROTO
);
179 static int sysctl_kern_hostid(SYSCTLFN_PROTO
);
180 static int sysctl_setlen(SYSCTLFN_PROTO
);
181 static int sysctl_kern_clockrate(SYSCTLFN_PROTO
);
182 static int sysctl_kern_file(SYSCTLFN_PROTO
);
183 static int sysctl_msgbuf(SYSCTLFN_PROTO
);
184 static int sysctl_kern_defcorename(SYSCTLFN_PROTO
);
185 static int sysctl_kern_cptime(SYSCTLFN_PROTO
);
187 static int sysctl_kern_maxptys(SYSCTLFN_PROTO
);
188 #endif /* NPTY > 0 */
189 static int sysctl_kern_sbmax(SYSCTLFN_PROTO
);
190 static int sysctl_kern_urnd(SYSCTLFN_PROTO
);
191 static int sysctl_kern_arnd(SYSCTLFN_PROTO
);
192 static int sysctl_kern_lwp(SYSCTLFN_PROTO
);
193 static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO
);
194 static int sysctl_kern_root_partition(SYSCTLFN_PROTO
);
195 static int sysctl_kern_drivers(SYSCTLFN_PROTO
);
196 static int sysctl_kern_file2(SYSCTLFN_PROTO
);
197 static int sysctl_security_setidcore(SYSCTLFN_PROTO
);
198 static int sysctl_security_setidcorename(SYSCTLFN_PROTO
);
199 static int sysctl_kern_cpid(SYSCTLFN_PROTO
);
200 static int sysctl_doeproc(SYSCTLFN_PROTO
);
201 static int sysctl_kern_proc_args(SYSCTLFN_PROTO
);
202 static int sysctl_hw_usermem(SYSCTLFN_PROTO
);
203 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO
);
205 static u_int
sysctl_map_flags(const u_int
*, u_int
);
206 static void fill_kproc2(struct proc
*, struct kinfo_proc2
*, bool);
207 static void fill_lwp(struct lwp
*l
, struct kinfo_lwp
*kl
);
208 static void fill_file(struct kinfo_file
*, const file_t
*, const fdfile_t
*,
212 * ********************************************************************
213 * section 1: setup routines
214 * ********************************************************************
215 * These functions are stuffed into a link set for sysctl setup
216 * functions. They're never called or referenced from anywhere else.
217 * ********************************************************************
221 * this setup routine is a replacement for kern_sysctl()
223 SYSCTL_SETUP(sysctl_kern_setup
, "sysctl kern subtree setup")
225 extern int kern_logsigexit
; /* defined in kern/kern_sig.c */
226 extern fixpt_t ccpu
; /* defined in kern/kern_synch.c */
227 extern int dumponpanic
; /* defined in kern/subr_prf.c */
228 const struct sysctlnode
*rnode
;
230 sysctl_createv(clog
, 0, NULL
, NULL
,
232 CTLTYPE_NODE
, "kern", NULL
,
236 sysctl_createv(clog
, 0, NULL
, NULL
,
238 CTLTYPE_STRING
, "ostype",
239 SYSCTL_DESCR("Operating system type"),
241 CTL_KERN
, KERN_OSTYPE
, CTL_EOL
);
242 sysctl_createv(clog
, 0, NULL
, NULL
,
244 CTLTYPE_STRING
, "osrelease",
245 SYSCTL_DESCR("Operating system release"),
246 NULL
, 0, &osrelease
, 0,
247 CTL_KERN
, KERN_OSRELEASE
, CTL_EOL
);
248 sysctl_createv(clog
, 0, NULL
, NULL
,
249 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
250 CTLTYPE_INT
, "osrevision",
251 SYSCTL_DESCR("Operating system revision"),
252 NULL
, __NetBSD_Version__
, NULL
, 0,
253 CTL_KERN
, KERN_OSREV
, CTL_EOL
);
254 sysctl_createv(clog
, 0, NULL
, NULL
,
256 CTLTYPE_STRING
, "version",
257 SYSCTL_DESCR("Kernel version"),
258 NULL
, 0, &version
, 0,
259 CTL_KERN
, KERN_VERSION
, CTL_EOL
);
260 sysctl_createv(clog
, 0, NULL
, NULL
,
261 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
262 CTLTYPE_INT
, "maxvnodes",
263 SYSCTL_DESCR("Maximum number of vnodes"),
264 sysctl_kern_maxvnodes
, 0, NULL
, 0,
265 CTL_KERN
, KERN_MAXVNODES
, CTL_EOL
);
266 sysctl_createv(clog
, 0, NULL
, NULL
,
267 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
268 CTLTYPE_INT
, "maxproc",
269 SYSCTL_DESCR("Maximum number of simultaneous processes"),
270 sysctl_kern_maxproc
, 0, NULL
, 0,
271 CTL_KERN
, KERN_MAXPROC
, CTL_EOL
);
272 sysctl_createv(clog
, 0, NULL
, NULL
,
273 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
274 CTLTYPE_INT
, "maxfiles",
275 SYSCTL_DESCR("Maximum number of open files"),
276 NULL
, 0, &maxfiles
, 0,
277 CTL_KERN
, KERN_MAXFILES
, CTL_EOL
);
278 sysctl_createv(clog
, 0, NULL
, NULL
,
279 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
280 CTLTYPE_INT
, "argmax",
281 SYSCTL_DESCR("Maximum number of bytes of arguments to "
283 NULL
, ARG_MAX
, NULL
, 0,
284 CTL_KERN
, KERN_ARGMAX
, CTL_EOL
);
285 sysctl_createv(clog
, 0, NULL
, NULL
,
286 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
287 CTLTYPE_STRING
, "hostname",
288 SYSCTL_DESCR("System hostname"),
289 sysctl_setlen
, 0, &hostname
, MAXHOSTNAMELEN
,
290 CTL_KERN
, KERN_HOSTNAME
, CTL_EOL
);
291 sysctl_createv(clog
, 0, NULL
, NULL
,
292 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
|CTLFLAG_HEX
,
293 CTLTYPE_INT
, "hostid",
294 SYSCTL_DESCR("System host ID number"),
295 sysctl_kern_hostid
, 0, NULL
, 0,
296 CTL_KERN
, KERN_HOSTID
, CTL_EOL
);
297 sysctl_createv(clog
, 0, NULL
, NULL
,
299 CTLTYPE_STRUCT
, "clockrate",
300 SYSCTL_DESCR("Kernel clock rates"),
301 sysctl_kern_clockrate
, 0, NULL
,
302 sizeof(struct clockinfo
),
303 CTL_KERN
, KERN_CLOCKRATE
, CTL_EOL
);
304 sysctl_createv(clog
, 0, NULL
, NULL
,
306 CTLTYPE_INT
, "hardclock_ticks",
307 SYSCTL_DESCR("Number of hardclock ticks"),
308 NULL
, 0, &hardclock_ticks
, sizeof(hardclock_ticks
),
309 CTL_KERN
, KERN_HARDCLOCK_TICKS
, CTL_EOL
);
310 sysctl_createv(clog
, 0, NULL
, NULL
,
312 CTLTYPE_STRUCT
, "vnode",
313 SYSCTL_DESCR("System vnode table"),
314 sysctl_kern_vnode
, 0, NULL
, 0,
315 CTL_KERN
, KERN_VNODE
, CTL_EOL
);
316 sysctl_createv(clog
, 0, NULL
, NULL
,
318 CTLTYPE_STRUCT
, "file",
319 SYSCTL_DESCR("System open file table"),
320 sysctl_kern_file
, 0, NULL
, 0,
321 CTL_KERN
, KERN_FILE
, CTL_EOL
);
323 sysctl_createv(clog
, 0, NULL
, NULL
,
325 CTLTYPE_NODE
, "profiling",
326 SYSCTL_DESCR("Profiling information (not available)"),
327 sysctl_notavail
, 0, NULL
, 0,
328 CTL_KERN
, KERN_PROF
, CTL_EOL
);
330 sysctl_createv(clog
, 0, NULL
, NULL
,
331 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
332 CTLTYPE_INT
, "posix1version",
333 SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) "
334 "with which the operating system attempts "
336 NULL
, _POSIX_VERSION
, NULL
, 0,
337 CTL_KERN
, KERN_POSIX1
, CTL_EOL
);
338 sysctl_createv(clog
, 0, NULL
, NULL
,
339 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
340 CTLTYPE_INT
, "ngroups",
341 SYSCTL_DESCR("Maximum number of supplemental groups"),
342 NULL
, NGROUPS_MAX
, NULL
, 0,
343 CTL_KERN
, KERN_NGROUPS
, CTL_EOL
);
344 sysctl_createv(clog
, 0, NULL
, NULL
,
345 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
346 CTLTYPE_INT
, "job_control",
347 SYSCTL_DESCR("Whether job control is available"),
349 CTL_KERN
, KERN_JOB_CONTROL
, CTL_EOL
);
350 sysctl_createv(clog
, 0, NULL
, NULL
,
351 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
352 CTLTYPE_INT
, "saved_ids",
353 SYSCTL_DESCR("Whether POSIX saved set-group/user ID is "
355 #ifdef _POSIX_SAVED_IDS
357 #else /* _POSIX_SAVED_IDS */
359 #endif /* _POSIX_SAVED_IDS */
360 NULL
, 0, CTL_KERN
, KERN_SAVED_IDS
, CTL_EOL
);
361 sysctl_createv(clog
, 0, NULL
, NULL
,
362 CTLFLAG_PERMANENT
|CTLFLAG_HEX
,
363 CTLTYPE_INT
, "boothowto",
364 SYSCTL_DESCR("Flags from boot loader"),
365 NULL
, 0, &boothowto
, sizeof(boothowto
),
366 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
367 sysctl_createv(clog
, 0, NULL
, NULL
,
369 CTLTYPE_STRUCT
, "boottime",
370 SYSCTL_DESCR("System boot time"),
371 NULL
, 0, &boottime
, sizeof(boottime
),
372 CTL_KERN
, KERN_BOOTTIME
, CTL_EOL
);
375 extern struct timeval50 boottime50
;
376 sysctl_createv(clog
, 0, NULL
, NULL
,
378 CTLTYPE_STRUCT
, "oboottime",
379 SYSCTL_DESCR("System boot time"),
380 NULL
, 0, &boottime50
, sizeof(boottime50
),
381 CTL_KERN
, KERN_OBOOTTIME
, CTL_EOL
);
384 sysctl_createv(clog
, 0, NULL
, NULL
,
385 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
386 CTLTYPE_STRING
, "domainname",
387 SYSCTL_DESCR("YP domain name"),
388 sysctl_setlen
, 0, &domainname
, MAXHOSTNAMELEN
,
389 CTL_KERN
, KERN_DOMAINNAME
, CTL_EOL
);
390 sysctl_createv(clog
, 0, NULL
, NULL
,
391 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
392 CTLTYPE_INT
, "maxpartitions",
393 SYSCTL_DESCR("Maximum number of partitions allowed per "
395 NULL
, MAXPARTITIONS
, NULL
, 0,
396 CTL_KERN
, KERN_MAXPARTITIONS
, CTL_EOL
);
397 sysctl_createv(clog
, 0, NULL
, NULL
,
398 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
399 CTLTYPE_INT
, "rawpartition",
400 SYSCTL_DESCR("Raw partition of a disk"),
401 NULL
, RAW_PART
, NULL
, 0,
402 CTL_KERN
, KERN_RAWPARTITION
, CTL_EOL
);
403 sysctl_createv(clog
, 0, NULL
, NULL
,
405 CTLTYPE_STRUCT
, "timex", NULL
,
406 sysctl_notavail
, 0, NULL
, 0,
407 CTL_KERN
, KERN_TIMEX
, CTL_EOL
);
408 sysctl_createv(clog
, 0, NULL
, NULL
,
409 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
410 CTLTYPE_INT
, "rtc_offset",
411 SYSCTL_DESCR("Offset of real time clock from UTC in "
413 sysctl_kern_rtc_offset
, 0, &rtc_offset
, 0,
414 CTL_KERN
, KERN_RTC_OFFSET
, CTL_EOL
);
415 sysctl_createv(clog
, 0, NULL
, NULL
,
417 CTLTYPE_STRING
, "root_device",
418 SYSCTL_DESCR("Name of the root device"),
419 sysctl_root_device
, 0, NULL
, 0,
420 CTL_KERN
, KERN_ROOT_DEVICE
, CTL_EOL
);
421 sysctl_createv(clog
, 0, NULL
, NULL
,
423 CTLTYPE_INT
, "msgbufsize",
424 SYSCTL_DESCR("Size of the kernel message buffer"),
425 sysctl_msgbuf
, 0, NULL
, 0,
426 CTL_KERN
, KERN_MSGBUFSIZE
, CTL_EOL
);
427 sysctl_createv(clog
, 0, NULL
, NULL
,
428 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
429 CTLTYPE_INT
, "fsync",
430 SYSCTL_DESCR("Whether the POSIX 1003.1b File "
431 "Synchronization Option is available on "
434 CTL_KERN
, KERN_FSYNC
, CTL_EOL
);
435 sysctl_createv(clog
, 0, NULL
, NULL
,
438 SYSCTL_DESCR("SysV IPC options"),
440 CTL_KERN
, KERN_SYSVIPC
, CTL_EOL
);
441 sysctl_createv(clog
, 0, NULL
, NULL
,
442 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
443 CTLTYPE_INT
, "sysvmsg",
444 SYSCTL_DESCR("System V style message support available"),
451 NULL
, 0, CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_MSG
, CTL_EOL
);
452 sysctl_createv(clog
, 0, NULL
, NULL
,
453 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
454 CTLTYPE_INT
, "sysvsem",
455 SYSCTL_DESCR("System V style semaphore support "
462 NULL
, 0, CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_SEM
, CTL_EOL
);
463 sysctl_createv(clog
, 0, NULL
, NULL
,
464 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
465 CTLTYPE_INT
, "sysvshm",
466 SYSCTL_DESCR("System V style shared memory support "
473 NULL
, 0, CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_SHM
, CTL_EOL
);
474 sysctl_createv(clog
, 0, NULL
, NULL
,
475 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
476 CTLTYPE_INT
, "synchronized_io",
477 SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized "
478 "I/O Option is available on this system"),
480 CTL_KERN
, KERN_SYNCHRONIZED_IO
, CTL_EOL
);
481 sysctl_createv(clog
, 0, NULL
, NULL
,
482 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
483 CTLTYPE_INT
, "iov_max",
484 SYSCTL_DESCR("Maximum number of iovec structures per "
486 NULL
, IOV_MAX
, NULL
, 0,
487 CTL_KERN
, KERN_IOV_MAX
, CTL_EOL
);
488 sysctl_createv(clog
, 0, NULL
, NULL
,
489 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
490 CTLTYPE_INT
, "mapped_files",
491 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped "
492 "Files Option is available on this system"),
494 CTL_KERN
, KERN_MAPPED_FILES
, CTL_EOL
);
495 sysctl_createv(clog
, 0, NULL
, NULL
,
496 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
497 CTLTYPE_INT
, "memlock",
498 SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory "
499 "Locking Option is available on this "
502 CTL_KERN
, KERN_MEMLOCK
, CTL_EOL
);
503 sysctl_createv(clog
, 0, NULL
, NULL
,
504 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
505 CTLTYPE_INT
, "memlock_range",
506 SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory "
507 "Locking Option is available on this "
510 CTL_KERN
, KERN_MEMLOCK_RANGE
, CTL_EOL
);
511 sysctl_createv(clog
, 0, NULL
, NULL
,
512 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
513 CTLTYPE_INT
, "memory_protection",
514 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory "
515 "Protection Option is available on this "
518 CTL_KERN
, KERN_MEMORY_PROTECTION
, CTL_EOL
);
519 sysctl_createv(clog
, 0, NULL
, NULL
,
520 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
521 CTLTYPE_INT
, "login_name_max",
522 SYSCTL_DESCR("Maximum login name length"),
523 NULL
, LOGIN_NAME_MAX
, NULL
, 0,
524 CTL_KERN
, KERN_LOGIN_NAME_MAX
, CTL_EOL
);
525 sysctl_createv(clog
, 0, NULL
, NULL
,
526 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
527 CTLTYPE_STRING
, "defcorename",
528 SYSCTL_DESCR("Default core file name"),
529 sysctl_kern_defcorename
, 0, defcorename
, MAXPATHLEN
,
530 CTL_KERN
, KERN_DEFCORENAME
, CTL_EOL
);
531 sysctl_createv(clog
, 0, NULL
, NULL
,
532 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
533 CTLTYPE_INT
, "logsigexit",
534 SYSCTL_DESCR("Log process exit when caused by signals"),
535 NULL
, 0, &kern_logsigexit
, 0,
536 CTL_KERN
, KERN_LOGSIGEXIT
, CTL_EOL
);
537 sysctl_createv(clog
, 0, NULL
, NULL
,
538 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
539 CTLTYPE_INT
, "fscale",
540 SYSCTL_DESCR("Kernel fixed-point scale factor"),
541 NULL
, FSCALE
, NULL
, 0,
542 CTL_KERN
, KERN_FSCALE
, CTL_EOL
);
543 sysctl_createv(clog
, 0, NULL
, NULL
,
546 SYSCTL_DESCR("Scheduler exponential decay value"),
548 CTL_KERN
, KERN_CCPU
, CTL_EOL
);
549 sysctl_createv(clog
, 0, NULL
, NULL
,
551 CTLTYPE_STRUCT
, "cp_time",
552 SYSCTL_DESCR("Clock ticks spent in different CPU states"),
553 sysctl_kern_cptime
, 0, NULL
, 0,
554 CTL_KERN
, KERN_CP_TIME
, CTL_EOL
);
555 sysctl_createv(clog
, 0, NULL
, NULL
,
557 CTLTYPE_INT
, "msgbuf",
558 SYSCTL_DESCR("Kernel message buffer"),
559 sysctl_msgbuf
, 0, NULL
, 0,
560 CTL_KERN
, KERN_MSGBUF
, CTL_EOL
);
561 sysctl_createv(clog
, 0, NULL
, NULL
,
563 CTLTYPE_STRUCT
, "consdev",
564 SYSCTL_DESCR("Console device"),
565 sysctl_consdev
, 0, NULL
, sizeof(dev_t
),
566 CTL_KERN
, KERN_CONSDEV
, CTL_EOL
);
568 sysctl_createv(clog
, 0, NULL
, NULL
,
570 CTLTYPE_INT
, "maxptys",
571 SYSCTL_DESCR("Maximum number of pseudo-ttys"),
572 sysctl_kern_maxptys
, 0, NULL
, 0,
573 CTL_KERN
, KERN_MAXPTYS
, CTL_EOL
);
574 #endif /* NPTY > 0 */
575 sysctl_createv(clog
, 0, NULL
, NULL
,
576 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
577 CTLTYPE_INT
, "maxphys",
578 SYSCTL_DESCR("Maximum raw I/O transfer size"),
579 NULL
, MAXPHYS
, NULL
, 0,
580 CTL_KERN
, KERN_MAXPHYS
, CTL_EOL
);
581 sysctl_createv(clog
, 0, NULL
, NULL
,
582 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
583 CTLTYPE_INT
, "sbmax",
584 SYSCTL_DESCR("Maximum socket buffer size"),
585 sysctl_kern_sbmax
, 0, NULL
, 0,
586 CTL_KERN
, KERN_SBMAX
, CTL_EOL
);
587 sysctl_createv(clog
, 0, NULL
, NULL
,
588 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
589 CTLTYPE_INT
, "monotonic_clock",
590 SYSCTL_DESCR("Implementation version of the POSIX "
591 "1003.1b Monotonic Clock Option"),
592 /* XXX _POSIX_VERSION */
593 NULL
, _POSIX_MONOTONIC_CLOCK
, NULL
, 0,
594 CTL_KERN
, KERN_MONOTONIC_CLOCK
, CTL_EOL
);
595 sysctl_createv(clog
, 0, NULL
, NULL
,
597 CTLTYPE_INT
, "urandom",
598 SYSCTL_DESCR("Random integer value"),
599 sysctl_kern_urnd
, 0, NULL
, 0,
600 CTL_KERN
, KERN_URND
, CTL_EOL
);
601 sysctl_createv(clog
, 0, NULL
, NULL
,
603 CTLTYPE_INT
, "arandom",
604 SYSCTL_DESCR("n bytes of random data"),
605 sysctl_kern_arnd
, 0, NULL
, 0,
606 CTL_KERN
, KERN_ARND
, CTL_EOL
);
607 sysctl_createv(clog
, 0, NULL
, NULL
,
608 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
609 CTLTYPE_INT
, "labelsector",
610 SYSCTL_DESCR("Sector number containing the disklabel"),
611 NULL
, LABELSECTOR
, NULL
, 0,
612 CTL_KERN
, KERN_LABELSECTOR
, CTL_EOL
);
613 sysctl_createv(clog
, 0, NULL
, NULL
,
614 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
615 CTLTYPE_INT
, "labeloffset",
616 SYSCTL_DESCR("Offset of the disklabel within the "
618 NULL
, LABELOFFSET
, NULL
, 0,
619 CTL_KERN
, KERN_LABELOFFSET
, CTL_EOL
);
620 sysctl_createv(clog
, 0, NULL
, NULL
,
623 SYSCTL_DESCR("System-wide LWP information"),
624 sysctl_kern_lwp
, 0, NULL
, 0,
625 CTL_KERN
, KERN_LWP
, CTL_EOL
);
626 sysctl_createv(clog
, 0, NULL
, NULL
,
627 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
628 CTLTYPE_INT
, "forkfsleep",
629 SYSCTL_DESCR("Milliseconds to sleep on fork failure due "
630 "to process limits"),
631 sysctl_kern_forkfsleep
, 0, NULL
, 0,
632 CTL_KERN
, KERN_FORKFSLEEP
, CTL_EOL
);
633 sysctl_createv(clog
, 0, NULL
, NULL
,
634 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
635 CTLTYPE_INT
, "posix_threads",
636 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
637 "Threads option to which the system "
638 "attempts to conform"),
639 /* XXX _POSIX_VERSION */
640 NULL
, _POSIX_THREADS
, NULL
, 0,
641 CTL_KERN
, KERN_POSIX_THREADS
, CTL_EOL
);
642 sysctl_createv(clog
, 0, NULL
, NULL
,
644 CTLTYPE_INT
, "posix_semaphores",
645 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
646 "Semaphores option to which the system "
647 "attempts to conform"), NULL
,
648 0, &posix_semaphores
,
649 0, CTL_KERN
, KERN_POSIX_SEMAPHORES
, CTL_EOL
);
650 sysctl_createv(clog
, 0, NULL
, NULL
,
651 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
652 CTLTYPE_INT
, "posix_barriers",
653 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
654 "Barriers option to which the system "
655 "attempts to conform"),
656 /* XXX _POSIX_VERSION */
657 NULL
, _POSIX_BARRIERS
, NULL
, 0,
658 CTL_KERN
, KERN_POSIX_BARRIERS
, CTL_EOL
);
659 sysctl_createv(clog
, 0, NULL
, NULL
,
660 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
661 CTLTYPE_INT
, "posix_timers",
662 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
663 "Timers option to which the system "
664 "attempts to conform"),
665 /* XXX _POSIX_VERSION */
666 NULL
, _POSIX_TIMERS
, NULL
, 0,
667 CTL_KERN
, KERN_POSIX_TIMERS
, CTL_EOL
);
668 sysctl_createv(clog
, 0, NULL
, NULL
,
669 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
670 CTLTYPE_INT
, "posix_spin_locks",
671 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin "
672 "Locks option to which the system attempts "
674 /* XXX _POSIX_VERSION */
675 NULL
, _POSIX_SPIN_LOCKS
, NULL
, 0,
676 CTL_KERN
, KERN_POSIX_SPIN_LOCKS
, CTL_EOL
);
677 sysctl_createv(clog
, 0, NULL
, NULL
,
678 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
679 CTLTYPE_INT
, "posix_reader_writer_locks",
680 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its "
681 "Read-Write Locks option to which the "
682 "system attempts to conform"),
683 /* XXX _POSIX_VERSION */
684 NULL
, _POSIX_READER_WRITER_LOCKS
, NULL
, 0,
685 CTL_KERN
, KERN_POSIX_READER_WRITER_LOCKS
, CTL_EOL
);
686 sysctl_createv(clog
, 0, NULL
, NULL
,
687 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
688 CTLTYPE_INT
, "dump_on_panic",
689 SYSCTL_DESCR("Perform a crash dump on system panic"),
690 NULL
, 0, &dumponpanic
, 0,
691 CTL_KERN
, KERN_DUMP_ON_PANIC
, CTL_EOL
);
693 sysctl_createv(clog
, 0, NULL
, NULL
,
694 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
695 CTLTYPE_INT
, "panic_now",
696 SYSCTL_DESCR("Trigger a panic"),
697 sysctl_kern_trigger_panic
, 0, NULL
, 0,
698 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
700 sysctl_createv(clog
, 0, NULL
, NULL
,
702 CTLTYPE_INT
, "root_partition",
703 SYSCTL_DESCR("Root partition on the root device"),
704 sysctl_kern_root_partition
, 0, NULL
, 0,
705 CTL_KERN
, KERN_ROOT_PARTITION
, CTL_EOL
);
706 sysctl_createv(clog
, 0, NULL
, NULL
,
708 CTLTYPE_STRUCT
, "drivers",
709 SYSCTL_DESCR("List of all drivers with block and "
710 "character device numbers"),
711 sysctl_kern_drivers
, 0, NULL
, 0,
712 CTL_KERN
, KERN_DRIVERS
, CTL_EOL
);
713 sysctl_createv(clog
, 0, NULL
, NULL
,
715 CTLTYPE_STRUCT
, "file2",
716 SYSCTL_DESCR("System open file table"),
717 sysctl_kern_file2
, 0, NULL
, 0,
718 CTL_KERN
, KERN_FILE2
, CTL_EOL
);
719 sysctl_createv(clog
, 0, NULL
, NULL
,
721 CTLTYPE_STRUCT
, "cp_id",
722 SYSCTL_DESCR("Mapping of CPU number to CPU id"),
723 sysctl_kern_cpid
, 0, NULL
, 0,
724 CTL_KERN
, KERN_CP_ID
, CTL_EOL
);
725 sysctl_createv(clog
, 0, NULL
, &rnode
,
727 CTLTYPE_NODE
, "coredump",
728 SYSCTL_DESCR("Coredump settings."),
730 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
731 sysctl_createv(clog
, 0, &rnode
, &rnode
,
733 CTLTYPE_NODE
, "setid",
734 SYSCTL_DESCR("Set-id processes' coredump settings."),
736 CTL_CREATE
, CTL_EOL
);
737 sysctl_createv(clog
, 0, &rnode
, NULL
,
738 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
740 SYSCTL_DESCR("Allow set-id processes to dump core."),
741 sysctl_security_setidcore
, 0, &security_setidcore_dump
,
742 sizeof(security_setidcore_dump
),
743 CTL_CREATE
, CTL_EOL
);
744 sysctl_createv(clog
, 0, &rnode
, NULL
,
745 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
746 CTLTYPE_STRING
, "path",
747 SYSCTL_DESCR("Path pattern for set-id coredumps."),
748 sysctl_security_setidcorename
, 0,
749 &security_setidcore_path
,
750 sizeof(security_setidcore_path
),
751 CTL_CREATE
, CTL_EOL
);
752 sysctl_createv(clog
, 0, &rnode
, NULL
,
753 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
754 CTLTYPE_INT
, "owner",
755 SYSCTL_DESCR("Owner id for set-id processes' cores."),
756 sysctl_security_setidcore
, 0, &security_setidcore_owner
,
758 CTL_CREATE
, CTL_EOL
);
759 sysctl_createv(clog
, 0, &rnode
, NULL
,
760 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
761 CTLTYPE_INT
, "group",
762 SYSCTL_DESCR("Group id for set-id processes' cores."),
763 sysctl_security_setidcore
, 0, &security_setidcore_group
,
765 CTL_CREATE
, CTL_EOL
);
766 sysctl_createv(clog
, 0, &rnode
, NULL
,
767 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
769 SYSCTL_DESCR("Mode for set-id processes' cores."),
770 sysctl_security_setidcore
, 0, &security_setidcore_mode
,
772 CTL_CREATE
, CTL_EOL
);
774 sysctl_createv(clog
, 0, NULL
, NULL
,
775 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
776 CTLTYPE_INT
, "no_sa_support",
777 SYSCTL_DESCR("0 if the kernel supports SA, otherwise it doesn't"),
778 NULL
, 0, &sa_system_disabled
, 0,
779 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
781 sysctl_createv(clog
, 0, NULL
, NULL
,
782 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
783 CTLTYPE_INT
, "no_sa_support",
784 SYSCTL_DESCR("0 if the kernel supports SA, otherwise it doesn't"),
786 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
790 sysctl_createv(clog
, 0, NULL
, &rnode
,
792 CTLTYPE_NODE
, "posix",
793 SYSCTL_DESCR("POSIX options"),
795 CTL_KERN
, CTL_CREATE
, CTL_EOL
);
796 sysctl_createv(clog
, 0, &rnode
, NULL
,
797 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
,
798 CTLTYPE_INT
, "semmax",
799 SYSCTL_DESCR("Maximal number of semaphores"),
800 NULL
, 0, &ksem_max
, 0,
801 CTL_CREATE
, CTL_EOL
);
804 SYSCTL_SETUP(sysctl_kern_proc_setup
,
805 "sysctl kern.proc/proc2/proc_args subtree setup")
808 sysctl_createv(clog
, 0, NULL
, NULL
,
810 CTLTYPE_NODE
, "kern", NULL
,
814 sysctl_createv(clog
, 0, NULL
, NULL
,
816 CTLTYPE_NODE
, "proc",
817 SYSCTL_DESCR("System-wide process information"),
818 sysctl_doeproc
, 0, NULL
, 0,
819 CTL_KERN
, KERN_PROC
, CTL_EOL
);
820 sysctl_createv(clog
, 0, NULL
, NULL
,
822 CTLTYPE_NODE
, "proc2",
823 SYSCTL_DESCR("Machine-independent process information"),
824 sysctl_doeproc
, 0, NULL
, 0,
825 CTL_KERN
, KERN_PROC2
, CTL_EOL
);
826 sysctl_createv(clog
, 0, NULL
, NULL
,
828 CTLTYPE_NODE
, "proc_args",
829 SYSCTL_DESCR("Process argument information"),
830 sysctl_kern_proc_args
, 0, NULL
, 0,
831 CTL_KERN
, KERN_PROC_ARGS
, CTL_EOL
);
839 KERN_PROC_SESSION sess
846 all in all, probably not worth the effort...
850 SYSCTL_SETUP(sysctl_hw_setup
, "sysctl hw subtree setup")
855 sysctl_createv(clog
, 0, NULL
, NULL
,
857 CTLTYPE_NODE
, "hw", NULL
,
861 sysctl_createv(clog
, 0, NULL
, NULL
,
863 CTLTYPE_STRING
, "machine",
864 SYSCTL_DESCR("Machine class"),
866 CTL_HW
, HW_MACHINE
, CTL_EOL
);
867 sysctl_createv(clog
, 0, NULL
, NULL
,
869 CTLTYPE_STRING
, "model",
870 SYSCTL_DESCR("Machine model"),
871 NULL
, 0, cpu_model
, 0,
872 CTL_HW
, HW_MODEL
, CTL_EOL
);
873 sysctl_createv(clog
, 0, NULL
, NULL
,
876 SYSCTL_DESCR("Number of CPUs configured"),
878 CTL_HW
, HW_NCPU
, CTL_EOL
);
879 sysctl_createv(clog
, 0, NULL
, NULL
,
880 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
881 CTLTYPE_INT
, "byteorder",
882 SYSCTL_DESCR("System byte order"),
883 NULL
, BYTE_ORDER
, NULL
, 0,
884 CTL_HW
, HW_BYTEORDER
, CTL_EOL
);
885 u
= ((u_int
)physmem
> (UINT_MAX
/ PAGE_SIZE
)) ?
886 UINT_MAX
: physmem
* PAGE_SIZE
;
887 sysctl_createv(clog
, 0, NULL
, NULL
,
888 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
889 CTLTYPE_INT
, "physmem",
890 SYSCTL_DESCR("Bytes of physical memory"),
892 CTL_HW
, HW_PHYSMEM
, CTL_EOL
);
893 sysctl_createv(clog
, 0, NULL
, NULL
,
895 CTLTYPE_INT
, "usermem",
896 SYSCTL_DESCR("Bytes of non-kernel memory"),
897 sysctl_hw_usermem
, 0, NULL
, 0,
898 CTL_HW
, HW_USERMEM
, CTL_EOL
);
899 sysctl_createv(clog
, 0, NULL
, NULL
,
900 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
901 CTLTYPE_INT
, "pagesize",
902 SYSCTL_DESCR("Software page size"),
903 NULL
, PAGE_SIZE
, NULL
, 0,
904 CTL_HW
, HW_PAGESIZE
, CTL_EOL
);
905 sysctl_createv(clog
, 0, NULL
, NULL
,
907 CTLTYPE_STRING
, "machine_arch",
908 SYSCTL_DESCR("Machine CPU class"),
909 NULL
, 0, machine_arch
, 0,
910 CTL_HW
, HW_MACHINE_ARCH
, CTL_EOL
);
911 sysctl_createv(clog
, 0, NULL
, NULL
,
912 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
913 CTLTYPE_INT
, "alignbytes",
914 SYSCTL_DESCR("Alignment constraint for all possible "
916 NULL
, ALIGNBYTES
, NULL
, 0,
917 CTL_HW
, HW_ALIGNBYTES
, CTL_EOL
);
918 sysctl_createv(clog
, 0, NULL
, NULL
,
919 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
|CTLFLAG_HEX
,
920 CTLTYPE_STRING
, "cnmagic",
921 SYSCTL_DESCR("Console magic key sequence"),
922 sysctl_hw_cnmagic
, 0, NULL
, CNS_LEN
,
923 CTL_HW
, HW_CNMAGIC
, CTL_EOL
);
924 q
= (u_quad_t
)physmem
* PAGE_SIZE
;
925 sysctl_createv(clog
, 0, NULL
, NULL
,
926 CTLFLAG_PERMANENT
|CTLFLAG_IMMEDIATE
,
927 CTLTYPE_QUAD
, "physmem64",
928 SYSCTL_DESCR("Bytes of physical memory"),
930 CTL_HW
, HW_PHYSMEM64
, CTL_EOL
);
931 sysctl_createv(clog
, 0, NULL
, NULL
,
933 CTLTYPE_QUAD
, "usermem64",
934 SYSCTL_DESCR("Bytes of non-kernel memory"),
935 sysctl_hw_usermem
, 0, NULL
, 0,
936 CTL_HW
, HW_USERMEM64
, CTL_EOL
);
937 sysctl_createv(clog
, 0, NULL
, NULL
,
939 CTLTYPE_INT
, "ncpuonline",
940 SYSCTL_DESCR("Number of CPUs online"),
941 NULL
, 0, &ncpuonline
, 0,
942 CTL_HW
, HW_NCPUONLINE
, CTL_EOL
);
947 * Debugging related system variables.
949 struct ctldebug
/* debug0, */ /* debug1, */ debug2
, debug3
, debug4
;
950 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
951 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
952 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
953 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
954 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
955 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
956 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
957 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
961 * this setup routine is a replacement for debug_sysctl()
963 * note that it creates several nodes per defined debug variable
965 SYSCTL_SETUP(sysctl_debug_setup
, "sysctl debug subtree setup")
967 struct ctldebug
*cdp
;
974 * the "old" way (debug.name -> value) which was emulated by
975 * the sysctl(8) binary
977 * the new way, which the sysctl(8) binary was actually using
987 sysctl_createv(clog
, 0, NULL
, NULL
,
989 CTLTYPE_NODE
, "debug", NULL
,
993 for (i
= 0; i
< CTL_DEBUG_MAXID
; i
++) {
995 if (cdp
->debugname
== NULL
|| cdp
->debugvar
== NULL
)
998 snprintf(nodename
, sizeof(nodename
), "debug%d", i
);
999 sysctl_createv(clog
, 0, NULL
, NULL
,
1000 CTLFLAG_PERMANENT
|CTLFLAG_HIDDEN
,
1001 CTLTYPE_NODE
, nodename
, NULL
,
1003 CTL_DEBUG
, i
, CTL_EOL
);
1004 sysctl_createv(clog
, 0, NULL
, NULL
,
1005 CTLFLAG_PERMANENT
|CTLFLAG_HIDDEN
,
1006 CTLTYPE_STRING
, "name", NULL
,
1008 NULL
, 0, __UNCONST(cdp
->debugname
), 0,
1009 CTL_DEBUG
, i
, CTL_DEBUG_NAME
, CTL_EOL
);
1010 sysctl_createv(clog
, 0, NULL
, NULL
,
1011 CTLFLAG_PERMANENT
|CTLFLAG_HIDDEN
,
1012 CTLTYPE_INT
, "value", NULL
,
1013 NULL
, 0, cdp
->debugvar
, 0,
1014 CTL_DEBUG
, i
, CTL_DEBUG_VALUE
, CTL_EOL
);
1015 sysctl_createv(clog
, 0, NULL
, NULL
,
1017 CTLTYPE_INT
, cdp
->debugname
, NULL
,
1018 NULL
, 0, cdp
->debugvar
, 0,
1019 CTL_DEBUG
, CTL_CREATE
, CTL_EOL
);
1025 * ********************************************************************
1026 * section 2: private node-specific helper routines.
1027 * ********************************************************************
1032 sysctl_kern_trigger_panic(SYSCTLFN_ARGS
)
1035 struct sysctlnode node
;
1039 node
.sysctl_data
= &newtrig
;
1040 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1041 if (error
|| newp
== NULL
)
1045 panic("Panic triggered");
1052 * sysctl helper routine for kern.maxvnodes. Drain vnodes if
1053 * new value is lower than desiredvnodes and then calls reinit
1054 * routines that needs to adjust to the new value.
1057 sysctl_kern_maxvnodes(SYSCTLFN_ARGS
)
1059 int error
, new_vnodes
, old_vnodes
, new_max
;
1060 struct sysctlnode node
;
1062 new_vnodes
= desiredvnodes
;
1064 node
.sysctl_data
= &new_vnodes
;
1065 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1066 if (error
|| newp
== NULL
)
1069 /* Limits: 75% of KVA and physical memory. */
1070 new_max
= calc_cache_size(kernel_map
, 75, 75) / VNODE_COST
;
1071 if (new_vnodes
> new_max
)
1072 new_vnodes
= new_max
;
1074 old_vnodes
= desiredvnodes
;
1075 desiredvnodes
= new_vnodes
;
1076 if (new_vnodes
< old_vnodes
) {
1077 error
= vfs_drainvnodes(new_vnodes
, l
);
1079 desiredvnodes
= old_vnodes
;
1090 * sysctl helper routine for rtc_offset - set time after changes
1093 sysctl_kern_rtc_offset(SYSCTLFN_ARGS
)
1095 struct timespec ts
, delta
;
1096 int error
, new_rtc_offset
;
1097 struct sysctlnode node
;
1099 new_rtc_offset
= rtc_offset
;
1101 node
.sysctl_data
= &new_rtc_offset
;
1102 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1103 if (error
|| newp
== NULL
)
1106 if (kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_TIME
,
1107 KAUTH_REQ_SYSTEM_TIME_RTCOFFSET
,
1108 KAUTH_ARG(new_rtc_offset
), NULL
, NULL
))
1110 if (rtc_offset
== new_rtc_offset
)
1113 /* if we change the offset, adjust the time */
1115 delta
.tv_sec
= 60 * (new_rtc_offset
- rtc_offset
);
1117 timespecadd(&ts
, &delta
, &ts
);
1118 rtc_offset
= new_rtc_offset
;
1119 return (settime(l
->l_proc
, &ts
));
1123 * sysctl helper routine for kern.maxproc. Ensures that the new
1124 * values are not too low or too high.
1127 sysctl_kern_maxproc(SYSCTLFN_ARGS
)
1129 int error
, nmaxproc
;
1130 struct sysctlnode node
;
1134 node
.sysctl_data
= &nmaxproc
;
1135 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1136 if (error
|| newp
== NULL
)
1139 if (nmaxproc
< 0 || nmaxproc
>= PID_MAX
)
1141 #ifdef __HAVE_CPU_MAXPROC
1142 if (nmaxproc
> cpu_maxproc())
1151 * sysctl helper function for kern.hostid. The hostid is a long, but
1152 * we export it as an int, so we need to give it a little help.
1155 sysctl_kern_hostid(SYSCTLFN_ARGS
)
1157 int error
, inthostid
;
1158 struct sysctlnode node
;
1160 inthostid
= hostid
; /* XXX assumes sizeof int <= sizeof long */
1162 node
.sysctl_data
= &inthostid
;
1163 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1164 if (error
|| newp
== NULL
)
1167 hostid
= (unsigned)inthostid
;
1173 * sysctl helper function for kern.hostname and kern.domainnname.
1174 * resets the relevant recorded length when the underlying name is
1178 sysctl_setlen(SYSCTLFN_ARGS
)
1182 error
= sysctl_lookup(SYSCTLFN_CALL(rnode
));
1183 if (error
|| newp
== NULL
)
1186 switch (rnode
->sysctl_num
) {
1188 hostnamelen
= strlen((const char*)rnode
->sysctl_data
);
1190 case KERN_DOMAINNAME
:
1191 domainnamelen
= strlen((const char*)rnode
->sysctl_data
);
1199 * sysctl helper routine for kern.clockrate. Assembles a struct on
1200 * the fly to be returned to the caller.
1203 sysctl_kern_clockrate(SYSCTLFN_ARGS
)
1205 struct clockinfo clkinfo
;
1206 struct sysctlnode node
;
1208 clkinfo
.tick
= tick
;
1209 clkinfo
.tickadj
= tickadj
;
1211 clkinfo
.profhz
= profhz
;
1212 clkinfo
.stathz
= stathz
? stathz
: hz
;
1215 node
.sysctl_data
= &clkinfo
;
1216 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
1220 * Expects to be called with proc_lock and sysctl_file_marker_lock locked.
1223 sysctl_file_marker_reset(void)
1227 PROCLIST_FOREACH(p
, &allproc
) {
1228 struct filedesc
*fd
= p
->p_fd
;
1232 mutex_enter(&fd
->fd_lock
);
1235 for (i
= 0; i
< dt
->dt_nfiles
; i
++) {
1239 if ((ff
= dt
->dt_ff
[i
]) == NULL
) {
1243 if ((fp
= ff
->ff_file
) == NULL
) {
1250 mutex_exit(&fd
->fd_lock
);
1255 * sysctl helper routine for kern.file pseudo-subtree.
1258 sysctl_kern_file(SYSCTLFN_ARGS
)
1262 struct file
*fp
, fbuf
;
1263 char *start
, *where
;
1266 start
= where
= oldp
;
1269 if (where
== NULL
) {
1271 * overestimate by 10 files
1273 *oldlenp
= sizeof(filehead
) + (nfiles
+ 10) *
1274 sizeof(struct file
);
1279 * first dcopyout filehead
1281 if (buflen
< sizeof(filehead
)) {
1286 error
= dcopyout(l
, &filehead
, where
, sizeof(filehead
));
1291 buflen
-= sizeof(filehead
);
1292 where
+= sizeof(filehead
);
1295 * followed by an array of file structures
1297 mutex_enter(&sysctl_file_marker_lock
);
1298 mutex_enter(proc_lock
);
1299 PROCLIST_FOREACH(p
, &allproc
) {
1300 struct filedesc
*fd
;
1304 if (p
->p_stat
== SIDL
) {
1305 /* skip embryonic processes */
1308 mutex_enter(p
->p_lock
);
1309 error
= kauth_authorize_process(l
->l_cred
,
1310 KAUTH_PROCESS_CANSEE
, p
,
1311 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_OPENFILES
),
1313 mutex_exit(p
->p_lock
);
1316 * Don't leak kauth retval if we're silently
1317 * skipping this entry.
1324 * Grab a hold on the process.
1326 if (!rw_tryenter(&p
->p_reflock
, RW_READER
)) {
1329 mutex_exit(proc_lock
);
1332 mutex_enter(&fd
->fd_lock
);
1334 for (i
= 0; i
< dt
->dt_nfiles
; i
++) {
1337 if ((ff
= dt
->dt_ff
[i
]) == NULL
) {
1340 if ((fp
= ff
->ff_file
) == NULL
) {
1344 mutex_enter(&fp
->f_lock
);
1346 if ((fp
->f_count
== 0) ||
1347 (fp
->f_marker
== sysctl_file_marker
)) {
1348 mutex_exit(&fp
->f_lock
);
1352 /* Check that we have enough space. */
1353 if (buflen
< sizeof(struct file
)) {
1354 *oldlenp
= where
- start
;
1355 mutex_exit(&fp
->f_lock
);
1360 memcpy(&fbuf
, fp
, sizeof(fbuf
));
1361 mutex_exit(&fp
->f_lock
);
1362 error
= dcopyout(l
, &fbuf
, where
, sizeof(fbuf
));
1366 buflen
-= sizeof(struct file
);
1367 where
+= sizeof(struct file
);
1369 fp
->f_marker
= sysctl_file_marker
;
1371 mutex_exit(&fd
->fd_lock
);
1374 * Release reference to process.
1376 mutex_enter(proc_lock
);
1377 rw_exit(&p
->p_reflock
);
1383 sysctl_file_marker
++;
1384 /* Reset all markers if wrapped. */
1385 if (sysctl_file_marker
== 0) {
1386 sysctl_file_marker_reset();
1387 sysctl_file_marker
++;
1390 mutex_exit(proc_lock
);
1391 mutex_exit(&sysctl_file_marker_lock
);
1393 *oldlenp
= where
- start
;
1399 * sysctl helper routine for kern.msgbufsize and kern.msgbuf. For the
1400 * former it merely checks the message buffer is set up. For the latter,
1401 * it also copies out the data if necessary.
1404 sysctl_msgbuf(SYSCTLFN_ARGS
)
1409 extern kmutex_t log_lock
;
1412 if (!msgbufenabled
|| msgbufp
->msg_magic
!= MSG_MAGIC
) {
1417 switch (rnode
->sysctl_num
) {
1418 case KERN_MSGBUFSIZE
: {
1419 struct sysctlnode node
= *rnode
;
1420 int msg_bufs
= (int)msgbufp
->msg_bufs
;
1421 node
.sysctl_data
= &msg_bufs
;
1422 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
1427 return (EOPNOTSUPP
);
1434 /* always return full buffer size */
1435 *oldlenp
= msgbufp
->msg_bufs
;
1442 * First, copy from the write pointer to the end of
1446 mutex_spin_enter(&log_lock
);
1447 maxlen
= MIN(msgbufp
->msg_bufs
, *oldlenp
);
1448 beg
= msgbufp
->msg_bufx
;
1449 end
= msgbufp
->msg_bufs
;
1450 mutex_spin_exit(&log_lock
);
1452 while (maxlen
> 0) {
1453 len
= MIN(end
- beg
, maxlen
);
1456 /* XXX unlocked, but hardly matters. */
1457 error
= dcopyout(l
, &msgbufp
->msg_bufc
[beg
], where
, len
);
1464 * ... then, copy from the beginning of message buffer to
1465 * the write pointer.
1468 end
= msgbufp
->msg_bufx
;
1476 * sysctl helper routine for kern.defcorename. In the case of a new
1477 * string being assigned, check that it's not a zero-length string.
1478 * (XXX the check in -current doesn't work, but do we really care?)
1481 sysctl_kern_defcorename(SYSCTLFN_ARGS
)
1485 struct sysctlnode node
;
1487 newcorename
= PNBUF_GET();
1489 node
.sysctl_data
= &newcorename
[0];
1490 memcpy(node
.sysctl_data
, rnode
->sysctl_data
, MAXPATHLEN
);
1491 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1492 if (error
|| newp
== NULL
) {
1497 * when sysctl_lookup() deals with a string, it's guaranteed
1498 * to come back nul terminated. So there. :)
1500 if (strlen(newcorename
) == 0) {
1503 memcpy(rnode
->sysctl_data
, node
.sysctl_data
, MAXPATHLEN
);
1507 PNBUF_PUT(newcorename
);
1512 * sysctl helper routine for kern.cp_time node. Adds up cpu time
1516 sysctl_kern_cptime(SYSCTLFN_ARGS
)
1518 struct sysctlnode node
= *rnode
;
1519 uint64_t *cp_time
= NULL
;
1520 int error
, n
= ncpu
, i
;
1521 struct cpu_info
*ci
;
1522 CPU_INFO_ITERATOR cii
;
1525 * if you specifically pass a buffer that is the size of the
1526 * sum, or if you are probing for the size, you get the "sum"
1527 * of cp_time (and the size thereof) across all processors.
1529 * alternately, you can pass an additional mib number and get
1530 * cp_time for that particular processor.
1534 if (*oldlenp
== sizeof(uint64_t) * CPUSTATES
|| oldp
== NULL
) {
1535 node
.sysctl_size
= sizeof(uint64_t) * CPUSTATES
;
1539 node
.sysctl_size
= n
* sizeof(uint64_t) * CPUSTATES
;
1544 if (name
[0] < 0 || name
[0] >= n
)
1545 return (ENOENT
); /* ENOSUCHPROCESSOR */
1546 node
.sysctl_size
= sizeof(uint64_t) * CPUSTATES
;
1549 * adjust these so that sysctl_lookup() will be happy
1558 cp_time
= kmem_alloc(node
.sysctl_size
, KM_SLEEP
);
1559 if (cp_time
== NULL
)
1561 node
.sysctl_data
= cp_time
;
1562 memset(cp_time
, 0, node
.sysctl_size
);
1564 for (CPU_INFO_FOREACH(cii
, ci
)) {
1566 for (i
= 0; i
< CPUSTATES
; i
++) {
1567 cp_time
[i
] += ci
->ci_schedstate
.spc_cp_time
[i
];
1571 * if a specific processor was requested and we just
1572 * did it, we're done here
1577 * if doing "all", skip to next cp_time set for next processor
1580 cp_time
+= CPUSTATES
;
1582 * if we're doing a specific processor, we're one
1589 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1590 kmem_free(node
.sysctl_data
, node
.sysctl_size
);
1596 * sysctl helper routine for kern.maxptys. Ensures that any new value
1597 * is acceptable to the pty subsystem.
1600 sysctl_kern_maxptys(SYSCTLFN_ARGS
)
1602 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */
1604 struct sysctlnode node
;
1606 /* get current value of maxptys */
1607 xmax
= pty_maxptys(0, 0);
1610 node
.sysctl_data
= &xmax
;
1611 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1612 if (error
|| newp
== NULL
)
1615 if (xmax
!= pty_maxptys(xmax
, 1))
1620 #endif /* NPTY > 0 */
1623 * sysctl helper routine for kern.sbmax. Basically just ensures that
1624 * any new value is not too small.
1627 sysctl_kern_sbmax(SYSCTLFN_ARGS
)
1629 int error
, new_sbmax
;
1630 struct sysctlnode node
;
1634 node
.sysctl_data
= &new_sbmax
;
1635 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1636 if (error
|| newp
== NULL
)
1639 KERNEL_LOCK(1, NULL
);
1640 error
= sb_max_set(new_sbmax
);
1641 KERNEL_UNLOCK_ONE(NULL
);
1647 * sysctl helper routine for kern.urandom node. Picks a random number
1651 sysctl_kern_urnd(SYSCTLFN_ARGS
)
1656 KERNEL_LOCK(1, NULL
);
1657 rv
= rnd_extract_data(&v
, sizeof(v
), RND_EXTRACT_ANY
);
1658 KERNEL_UNLOCK_ONE(NULL
);
1659 if (rv
== sizeof(v
)) {
1660 struct sysctlnode node
= *rnode
;
1661 node
.sysctl_data
= &v
;
1662 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
1665 return (EIO
); /*XXX*/
1667 return (EOPNOTSUPP
);
1672 * sysctl helper routine for kern.arandom node. Picks a random number
1676 sysctl_kern_arnd(SYSCTLFN_ARGS
)
1681 struct sysctlnode node
= *rnode
;
1685 if (*oldlenp
> 8192)
1688 v
= kmem_alloc(*oldlenp
, KM_SLEEP
);
1689 arc4randbytes(v
, *oldlenp
);
1690 node
.sysctl_data
= v
;
1691 node
.sysctl_size
= *oldlenp
;
1692 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1693 kmem_free(v
, *oldlenp
);
1696 return (EOPNOTSUPP
);
1700 * sysctl helper routine to do kern.lwp.* work.
1703 sysctl_kern_lwp(SYSCTLFN_ARGS
)
1705 struct kinfo_lwp klwp
;
1707 struct lwp
*l2
, *l3
;
1709 int pid
, elem_size
, elem_count
;
1710 int buflen
, needed
, error
;
1713 if (namelen
== 1 && name
[0] == CTL_QUERY
)
1714 return (sysctl_query(SYSCTLFN_CALL(rnode
)));
1717 buflen
= where
!= NULL
? *oldlenp
: 0;
1720 if (newp
!= NULL
|| namelen
!= 3)
1723 elem_size
= name
[1];
1724 elem_count
= name
[2];
1728 mutex_enter(proc_lock
);
1729 PROCLIST_FOREACH(p
, &allproc
) {
1730 /* Grab a hold on the process. */
1731 if (!rw_tryenter(&p
->p_reflock
, RW_READER
)) {
1734 mutex_exit(proc_lock
);
1736 mutex_enter(p
->p_lock
);
1737 LIST_FOREACH(l2
, &p
->p_lwps
, l_sibling
) {
1738 if (buflen
>= elem_size
&& elem_count
> 0) {
1740 fill_lwp(l2
, &klwp
);
1742 mutex_exit(p
->p_lock
);
1745 * Copy out elem_size, but not
1746 * larger than the size of a
1747 * struct kinfo_proc2.
1749 error
= dcopyout(l
, &klwp
, dp
,
1750 min(sizeof(klwp
), elem_size
));
1752 rw_exit(&p
->p_reflock
);
1755 mutex_enter(p
->p_lock
);
1756 LIST_FOREACH(l3
, &p
->p_lwps
,
1762 mutex_exit(p
->p_lock
);
1763 rw_exit(&p
->p_reflock
);
1768 buflen
-= elem_size
;
1771 needed
+= elem_size
;
1773 mutex_exit(p
->p_lock
);
1775 /* Drop reference to process. */
1776 mutex_enter(proc_lock
);
1777 rw_exit(&p
->p_reflock
);
1779 mutex_exit(proc_lock
);
1781 mutex_enter(proc_lock
);
1782 p
= p_find(pid
, PFIND_LOCKED
);
1785 mutex_exit(proc_lock
);
1788 /* Grab a hold on the process. */
1789 gotit
= rw_tryenter(&p
->p_reflock
, RW_READER
);
1790 mutex_exit(proc_lock
);
1796 mutex_enter(p
->p_lock
);
1797 LIST_FOREACH(l2
, &p
->p_lwps
, l_sibling
) {
1798 if (buflen
>= elem_size
&& elem_count
> 0) {
1800 fill_lwp(l2
, &klwp
);
1802 mutex_exit(p
->p_lock
);
1804 * Copy out elem_size, but not larger than
1805 * the size of a struct kinfo_proc2.
1807 error
= dcopyout(l
, &klwp
, dp
,
1808 min(sizeof(klwp
), elem_size
));
1810 rw_exit(&p
->p_reflock
);
1813 mutex_enter(p
->p_lock
);
1814 LIST_FOREACH(l3
, &p
->p_lwps
, l_sibling
) {
1819 mutex_exit(p
->p_lock
);
1820 rw_exit(&p
->p_reflock
);
1825 buflen
-= elem_size
;
1828 needed
+= elem_size
;
1830 mutex_exit(p
->p_lock
);
1832 /* Drop reference to process. */
1833 rw_exit(&p
->p_reflock
);
1836 if (where
!= NULL
) {
1837 *oldlenp
= dp
- where
;
1838 if (needed
> *oldlenp
) {
1843 needed
+= KERN_LWPSLOP
;
1853 * sysctl helper routine for kern.forkfsleep node. Ensures that the
1854 * given value is not too large or two small, and is at least one
1855 * timer tick if not zero.
1858 sysctl_kern_forkfsleep(SYSCTLFN_ARGS
)
1860 /* userland sees value in ms, internally is in ticks */
1861 extern int forkfsleep
; /* defined in kern/kern_fork.c */
1862 int error
, timo
, lsleep
;
1863 struct sysctlnode node
;
1865 lsleep
= forkfsleep
* 1000 / hz
;
1867 node
.sysctl_data
= &lsleep
;
1868 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1869 if (error
|| newp
== NULL
)
1872 /* refuse negative values, and overly 'long time' */
1873 if (lsleep
< 0 || lsleep
> MAXSLP
* 1000)
1876 timo
= mstohz(lsleep
);
1878 /* if the interval is >0 ms && <1 tick, use 1 tick */
1879 if (lsleep
!= 0 && timo
== 0)
1888 * sysctl helper routine for kern.root_partition
1891 sysctl_kern_root_partition(SYSCTLFN_ARGS
)
1893 int rootpart
= DISKPART(rootdev
);
1894 struct sysctlnode node
= *rnode
;
1896 node
.sysctl_data
= &rootpart
;
1897 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
1901 * sysctl helper function for kern.drivers
1904 sysctl_kern_drivers(SYSCTLFN_ARGS
)
1908 struct kinfo_drivers kd
;
1909 char *start
, *where
;
1912 extern struct devsw_conv
*devsw_conv
;
1913 extern int max_devsw_convs
;
1915 if (newp
!= NULL
|| namelen
!= 0)
1918 start
= where
= oldp
;
1920 if (where
== NULL
) {
1921 *oldlenp
= max_devsw_convs
* sizeof kd
;
1926 * An array of kinfo_drivers structures
1930 mutex_enter(&device_lock
);
1931 for (i
= 0; i
< max_devsw_convs
; i
++) {
1932 dname
= devsw_conv
[i
].d_name
;
1935 if (buflen
< sizeof kd
) {
1939 memset(&kd
, 0, sizeof(kd
));
1940 kd
.d_bmajor
= devsw_conv
[i
].d_bmajor
;
1941 kd
.d_cmajor
= devsw_conv
[i
].d_cmajor
;
1942 strlcpy(kd
.d_name
, dname
, sizeof kd
.d_name
);
1943 mutex_exit(&device_lock
);
1944 error
= dcopyout(l
, &kd
, where
, sizeof kd
);
1945 mutex_enter(&device_lock
);
1948 buflen
-= sizeof kd
;
1951 mutex_exit(&device_lock
);
1953 *oldlenp
= where
- start
;
1958 * sysctl helper function for kern.file2
1961 sysctl_kern_file2(SYSCTLFN_ARGS
)
1965 struct filedesc
*fd
;
1966 struct kinfo_file kf
;
1969 size_t len
, needed
, elem_size
, out_size
;
1970 int error
, arg
, elem_count
;
1974 if (namelen
== 1 && name
[0] == CTL_QUERY
)
1975 return (sysctl_query(SYSCTLFN_CALL(rnode
)));
1982 len
= (oldp
!= NULL
) ? *oldlenp
: 0;
1985 elem_size
= name
[2];
1986 elem_count
= name
[3];
1987 out_size
= MIN(sizeof(kf
), elem_size
);
1990 if (elem_size
< 1 || elem_count
< 0)
1994 case KERN_FILE_BYFILE
:
1995 case KERN_FILE_BYPID
:
1997 * We're traversing the process list in both cases; the BYFILE
1998 * case does additional work of keeping track of files already
2002 /* doesn't use arg so it must be zero */
2003 if ((op
== KERN_FILE_BYFILE
) && (arg
!= 0))
2006 if ((op
== KERN_FILE_BYPID
) && (arg
< -1))
2007 /* -1 means all processes */
2011 if (op
== KERN_FILE_BYFILE
)
2012 mutex_enter(&sysctl_file_marker_lock
);
2013 mutex_enter(proc_lock
);
2014 PROCLIST_FOREACH(p
, &allproc
) {
2015 if (p
->p_stat
== SIDL
) {
2016 /* skip embryonic processes */
2019 if (arg
> 0 && p
->p_pid
!= arg
) {
2020 /* pick only the one we want */
2021 /* XXX want 0 to mean "kernel files" */
2024 mutex_enter(p
->p_lock
);
2025 error
= kauth_authorize_process(l
->l_cred
,
2026 KAUTH_PROCESS_CANSEE
, p
,
2027 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_OPENFILES
),
2029 mutex_exit(p
->p_lock
);
2032 * Don't leak kauth retval if we're silently
2033 * skipping this entry.
2040 * Grab a hold on the process.
2042 if (!rw_tryenter(&p
->p_reflock
, RW_READER
)) {
2045 mutex_exit(proc_lock
);
2048 mutex_enter(&fd
->fd_lock
);
2050 for (i
= 0; i
< dt
->dt_nfiles
; i
++) {
2051 if ((ff
= dt
->dt_ff
[i
]) == NULL
) {
2054 if ((fp
= ff
->ff_file
) == NULL
) {
2058 if ((op
== KERN_FILE_BYFILE
) &&
2059 (fp
->f_marker
== sysctl_file_marker
)) {
2062 if (len
>= elem_size
&& elem_count
> 0) {
2063 mutex_enter(&fp
->f_lock
);
2064 fill_file(&kf
, fp
, ff
, i
, p
->p_pid
);
2065 mutex_exit(&fp
->f_lock
);
2066 mutex_exit(&fd
->fd_lock
);
2067 error
= dcopyout(l
, &kf
, dp
, out_size
);
2068 mutex_enter(&fd
->fd_lock
);
2074 if (op
== KERN_FILE_BYFILE
)
2075 fp
->f_marker
= sysctl_file_marker
;
2076 needed
+= elem_size
;
2077 if (elem_count
> 0 && elem_count
!= INT_MAX
)
2080 mutex_exit(&fd
->fd_lock
);
2083 * Release reference to process.
2085 mutex_enter(proc_lock
);
2086 rw_exit(&p
->p_reflock
);
2088 if (op
== KERN_FILE_BYFILE
) {
2089 sysctl_file_marker
++;
2091 /* Reset all markers if wrapped. */
2092 if (sysctl_file_marker
== 0) {
2093 sysctl_file_marker_reset();
2094 sysctl_file_marker
++;
2097 mutex_exit(proc_lock
);
2098 if (op
== KERN_FILE_BYFILE
)
2099 mutex_exit(&sysctl_file_marker_lock
);
2107 needed
+= KERN_FILESLOP
* elem_size
;
2114 fill_file(struct kinfo_file
*kp
, const file_t
*fp
, const fdfile_t
*ff
,
2118 memset(kp
, 0, sizeof(*kp
));
2120 kp
->ki_fileaddr
= PTRTOUINT64(fp
);
2121 kp
->ki_flag
= fp
->f_flag
;
2123 kp
->ki_ftype
= fp
->f_type
;
2124 kp
->ki_count
= fp
->f_count
;
2125 kp
->ki_msgcount
= fp
->f_msgcount
;
2126 kp
->ki_fucred
= PTRTOUINT64(fp
->f_cred
);
2127 kp
->ki_fuid
= kauth_cred_geteuid(fp
->f_cred
);
2128 kp
->ki_fgid
= kauth_cred_getegid(fp
->f_cred
);
2129 kp
->ki_fops
= PTRTOUINT64(fp
->f_ops
);
2130 kp
->ki_foffset
= fp
->f_offset
;
2131 kp
->ki_fdata
= PTRTOUINT64(fp
->f_data
);
2133 /* vnode information to glue this file to something */
2134 if (fp
->f_type
== DTYPE_VNODE
) {
2135 struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
2137 kp
->ki_vun
= PTRTOUINT64(vp
->v_un
.vu_socket
);
2138 kp
->ki_vsize
= vp
->v_size
;
2139 kp
->ki_vtype
= vp
->v_type
;
2140 kp
->ki_vtag
= vp
->v_tag
;
2141 kp
->ki_vdata
= PTRTOUINT64(vp
->v_data
);
2144 /* process information when retrieved via KERN_FILE_BYPID */
2148 kp
->ki_ofileflags
= ff
->ff_exclose
;
2149 kp
->ki_usecount
= ff
->ff_refcnt
;
2154 sysctl_doeproc(SYSCTLFN_ARGS
)
2157 struct kinfo_proc kproc
;
2158 struct kinfo_proc2 kproc2
;
2160 struct proc
*p
, *next
, *marker
;
2162 int type
, op
, arg
, error
;
2163 u_int elem_size
, kelem_size
, elem_count
;
2164 size_t buflen
, needed
;
2165 bool match
, zombie
, mmmbrains
;
2167 if (namelen
== 1 && name
[0] == CTL_QUERY
)
2168 return (sysctl_query(SYSCTLFN_CALL(rnode
)));
2171 buflen
= where
!= NULL
? *oldlenp
: 0;
2174 type
= rnode
->sysctl_num
;
2176 if (type
== KERN_PROC
) {
2177 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
2180 if (op
!= KERN_PROC_ALL
)
2183 arg
= 0; /* Quell compiler warning */
2184 elem_count
= 0; /* Ditto */
2185 kelem_size
= elem_size
= sizeof(kbuf
->kproc
);
2191 elem_size
= name
[2];
2192 elem_count
= name
[3];
2193 kelem_size
= sizeof(kbuf
->kproc2
);
2198 kbuf
= kmem_alloc(sizeof(*kbuf
), KM_SLEEP
);
2199 marker
= kmem_alloc(sizeof(*marker
), KM_SLEEP
);
2200 marker
->p_flag
= PK_MARKER
;
2202 mutex_enter(proc_lock
);
2204 for (p
= LIST_FIRST(&allproc
);; p
= next
) {
2207 p
= LIST_FIRST(&zombproc
);
2213 next
= LIST_NEXT(p
, p_list
);
2214 if ((p
->p_flag
& PK_MARKER
) != 0)
2218 * Skip embryonic processes.
2220 if (p
->p_stat
== SIDL
)
2223 mutex_enter(p
->p_lock
);
2224 error
= kauth_authorize_process(l
->l_cred
,
2225 KAUTH_PROCESS_CANSEE
, p
,
2226 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY
), NULL
, NULL
);
2228 mutex_exit(p
->p_lock
);
2233 * TODO - make more efficient (see notes below).
2238 /* could do this with just a lookup */
2239 match
= (p
->p_pid
== (pid_t
)arg
);
2242 case KERN_PROC_PGRP
:
2243 /* could do this by traversing pgrp */
2244 match
= (p
->p_pgrp
->pg_id
== (pid_t
)arg
);
2247 case KERN_PROC_SESSION
:
2248 match
= (p
->p_session
->s_sid
== (pid_t
)arg
);
2253 if (arg
== (int) KERN_PROC_TTY_REVOKE
) {
2254 if ((p
->p_lflag
& PL_CONTROLT
) == 0 ||
2255 p
->p_session
->s_ttyp
== NULL
||
2256 p
->p_session
->s_ttyvp
!= NULL
) {
2259 } else if ((p
->p_lflag
& PL_CONTROLT
) == 0 ||
2260 p
->p_session
->s_ttyp
== NULL
) {
2261 if ((dev_t
)arg
!= KERN_PROC_TTY_NODEV
) {
2264 } else if (p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)arg
) {
2270 match
= (kauth_cred_geteuid(p
->p_cred
) == (uid_t
)arg
);
2273 case KERN_PROC_RUID
:
2274 match
= (kauth_cred_getuid(p
->p_cred
) == (uid_t
)arg
);
2278 match
= (kauth_cred_getegid(p
->p_cred
) == (uid_t
)arg
);
2281 case KERN_PROC_RGID
:
2282 match
= (kauth_cred_getgid(p
->p_cred
) == (uid_t
)arg
);
2287 /* allow everything */
2292 mutex_exit(p
->p_lock
);
2296 mutex_exit(p
->p_lock
);
2301 * Grab a hold on the process.
2306 zombie
= !rw_tryenter(&p
->p_reflock
, RW_READER
);
2309 LIST_INSERT_AFTER(p
, marker
, p_list
);
2312 if (buflen
>= elem_size
&&
2313 (type
== KERN_PROC
|| elem_count
> 0)) {
2314 if (type
== KERN_PROC
) {
2315 kbuf
->kproc
.kp_proc
= *p
;
2316 fill_eproc(p
, &kbuf
->kproc
.kp_eproc
, zombie
);
2318 fill_kproc2(p
, &kbuf
->kproc2
, zombie
);
2321 mutex_exit(p
->p_lock
);
2322 mutex_exit(proc_lock
);
2324 * Copy out elem_size, but not larger than kelem_size
2326 error
= dcopyout(l
, kbuf
, dp
,
2327 min(kelem_size
, elem_size
));
2328 mutex_enter(proc_lock
);
2333 buflen
-= elem_size
;
2335 mutex_exit(p
->p_lock
);
2337 needed
+= elem_size
;
2340 * Release reference to process.
2343 next
= LIST_NEXT(marker
, p_list
);
2344 LIST_REMOVE(marker
, p_list
);
2346 rw_exit(&p
->p_reflock
);
2349 mutex_exit(proc_lock
);
2351 if (where
!= NULL
) {
2352 *oldlenp
= dp
- where
;
2353 if (needed
> *oldlenp
) {
2358 needed
+= KERN_PROCSLOP
;
2362 kmem_free(kbuf
, sizeof(*kbuf
));
2364 kmem_free(marker
, sizeof(*marker
));
2369 LIST_REMOVE(marker
, p_list
);
2371 rw_exit(&p
->p_reflock
);
2373 mutex_exit(proc_lock
);
2376 kmem_free(kbuf
, sizeof(*kbuf
));
2378 kmem_free(marker
, sizeof(*marker
));
2384 * sysctl helper routine for kern.proc_args pseudo-subtree.
2387 sysctl_kern_proc_args(SYSCTLFN_ARGS
)
2389 struct ps_strings pss
;
2395 int nargv
, type
, error
, argvlen
;
2399 struct vmspace
*vmspace
;
2404 if (namelen
== 1 && name
[0] == CTL_QUERY
)
2405 return (sysctl_query(SYSCTLFN_CALL(rnode
)));
2407 if (newp
!= NULL
|| namelen
!= 2)
2415 case KERN_PROC_ARGV
:
2416 case KERN_PROC_NARGV
:
2418 case KERN_PROC_NENV
:
2428 mutex_enter(proc_lock
);
2429 if ((p
= p_find(pid
, PFIND_LOCKED
)) == NULL
) {
2433 mutex_enter(p
->p_lock
);
2435 /* Check permission. */
2436 if (type
== KERN_PROC_ARGV
|| type
== KERN_PROC_NARGV
)
2437 error
= kauth_authorize_process(l
->l_cred
, KAUTH_PROCESS_CANSEE
,
2438 p
, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ARGS
), NULL
, NULL
);
2439 else if (type
== KERN_PROC_ENV
|| type
== KERN_PROC_NENV
)
2440 error
= kauth_authorize_process(l
->l_cred
, KAUTH_PROCESS_CANSEE
,
2441 p
, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENV
), NULL
, NULL
);
2443 error
= EINVAL
; /* XXXGCC */
2445 mutex_exit(p
->p_lock
);
2450 if (type
== KERN_PROC_NARGV
|| type
== KERN_PROC_NENV
)
2451 *oldlenp
= sizeof (int);
2453 *oldlenp
= ARG_MAX
; /* XXX XXX XXX */
2455 mutex_exit(p
->p_lock
);
2460 * Zombies don't have a stack, so we can't read their psstrings.
2461 * System processes also don't have a user stack.
2463 if (P_ZOMBIE(p
) || (p
->p_flag
& PK_SYSTEM
) != 0) {
2465 mutex_exit(p
->p_lock
);
2470 * Lock the process down in memory.
2472 psstr_addr
= (vaddr_t
)p
->p_psstr
;
2473 if (type
== KERN_PROC_ARGV
|| type
== KERN_PROC_NARGV
) {
2474 offsetn
= p
->p_psnargv
;
2475 offsetv
= p
->p_psargv
;
2477 offsetn
= p
->p_psnenv
;
2478 offsetv
= p
->p_psenv
;
2480 vmspace
= p
->p_vmspace
;
2481 uvmspace_addref(vmspace
);
2482 mutex_exit(p
->p_lock
);
2483 mutex_exit(proc_lock
);
2486 * Allocate a temporary buffer to hold the arguments.
2488 arg
= kmem_alloc(PAGE_SIZE
, KM_SLEEP
);
2491 * Read in the ps_strings structure.
2493 aiov
.iov_base
= &pss
;
2494 aiov
.iov_len
= sizeof(pss
);
2495 auio
.uio_iov
= &aiov
;
2496 auio
.uio_iovcnt
= 1;
2497 auio
.uio_offset
= psstr_addr
;
2498 auio
.uio_resid
= sizeof(pss
);
2499 auio
.uio_rw
= UIO_READ
;
2500 UIO_SETUP_SYSSPACE(&auio
);
2501 error
= uvm_io(&vmspace
->vm_map
, &auio
);
2505 memcpy(&nargv
, (char *)&pss
+ offsetn
, sizeof(nargv
));
2506 if (type
== KERN_PROC_NARGV
|| type
== KERN_PROC_NENV
) {
2507 error
= dcopyout(l
, &nargv
, oldp
, sizeof(nargv
));
2508 *oldlenp
= sizeof(nargv
);
2512 * Now read the address of the argument vector.
2515 case KERN_PROC_ARGV
:
2518 memcpy(&tmp
, (char *)&pss
+ offsetv
, sizeof(tmp
));
2525 #ifdef COMPAT_NETBSD32
2526 if (p
->p_flag
& PK_32
)
2527 len
= sizeof(netbsd32_charp
) * nargv
;
2530 len
= sizeof(char *) * nargv
;
2532 if ((argvlen
= len
) != 0)
2533 argv
= kmem_alloc(len
, KM_SLEEP
);
2535 aiov
.iov_base
= argv
;
2537 auio
.uio_iov
= &aiov
;
2538 auio
.uio_iovcnt
= 1;
2539 auio
.uio_offset
= (off_t
)(unsigned long)tmp
;
2540 auio
.uio_resid
= len
;
2541 auio
.uio_rw
= UIO_READ
;
2542 UIO_SETUP_SYSSPACE(&auio
);
2543 error
= uvm_io(&vmspace
->vm_map
, &auio
);
2548 * Now copy each string.
2550 len
= 0; /* bytes written to user buffer */
2551 for (i
= 0; i
< nargv
; i
++) {
2557 #ifdef COMPAT_NETBSD32
2558 if (p
->p_flag
& PK_32
) {
2559 netbsd32_charp
*argv32
;
2561 argv32
= (netbsd32_charp
*)argv
;
2562 base
= (vaddr_t
)NETBSD32PTR64(argv32
[i
]);
2565 base
= (vaddr_t
)argv
[i
];
2568 * The program has messed around with its arguments,
2569 * possibly deleting some, and replacing them with
2570 * NULL's. Treat this as the last argument and not
2577 xlen
= PAGE_SIZE
- (base
& PAGE_MASK
);
2579 aiov
.iov_base
= arg
;
2580 aiov
.iov_len
= PAGE_SIZE
;
2581 auio
.uio_iov
= &aiov
;
2582 auio
.uio_iovcnt
= 1;
2583 auio
.uio_offset
= base
;
2584 auio
.uio_resid
= xlen
;
2585 auio
.uio_rw
= UIO_READ
;
2586 UIO_SETUP_SYSSPACE(&auio
);
2587 error
= uvm_io(&vmspace
->vm_map
, &auio
);
2591 /* Look for the end of the string */
2592 for (j
= 0; j
< xlen
; j
++) {
2593 if (arg
[j
] == '\0') {
2600 /* Check for user buffer overflow */
2601 if (len
+ xlen
> *oldlenp
) {
2606 xlen
= *oldlenp
- len
;
2609 /* Copyout the page */
2610 error
= dcopyout(l
, arg
, (char *)oldp
+ len
, xlen
);
2622 kmem_free(argv
, argvlen
);
2623 uvmspace_free(vmspace
);
2624 kmem_free(arg
, PAGE_SIZE
);
2629 mutex_exit(proc_lock
);
2635 sysctl_security_setidcore(SYSCTLFN_ARGS
)
2638 struct sysctlnode node
;
2641 node
.sysctl_data
= &newsize
;
2642 newsize
= *(int *)rnode
->sysctl_data
;
2643 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
2644 if (error
|| newp
== NULL
)
2647 if (kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_SETIDCORE
,
2648 0, NULL
, NULL
, NULL
))
2651 *(int *)rnode
->sysctl_data
= newsize
;
2657 sysctl_security_setidcorename(SYSCTLFN_ARGS
)
2660 char *newsetidcorename
;
2661 struct sysctlnode node
;
2663 newsetidcorename
= PNBUF_GET();
2665 node
.sysctl_data
= newsetidcorename
;
2666 memcpy(node
.sysctl_data
, rnode
->sysctl_data
, MAXPATHLEN
);
2667 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
2668 if (error
|| newp
== NULL
) {
2671 if (kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_SETIDCORE
,
2672 0, NULL
, NULL
, NULL
)) {
2676 if (strlen(newsetidcorename
) == 0) {
2680 memcpy(rnode
->sysctl_data
, node
.sysctl_data
, MAXPATHLEN
);
2682 PNBUF_PUT(newsetidcorename
);
2687 * sysctl helper routine for kern.cp_id node. Maps cpus to their
2691 sysctl_kern_cpid(SYSCTLFN_ARGS
)
2693 struct sysctlnode node
= *rnode
;
2694 uint64_t *cp_id
= NULL
;
2695 int error
, n
= ncpu
;
2696 struct cpu_info
*ci
;
2697 CPU_INFO_ITERATOR cii
;
2700 * Here you may either retrieve a single cpu id or the whole
2701 * set. The size you get back when probing depends on what
2706 node
.sysctl_size
= n
* sizeof(uint64_t);
2710 if (name
[0] < 0 || name
[0] >= n
)
2711 return (ENOENT
); /* ENOSUCHPROCESSOR */
2712 node
.sysctl_size
= sizeof(uint64_t);
2715 * adjust these so that sysctl_lookup() will be happy
2724 cp_id
= kmem_alloc(node
.sysctl_size
, KM_SLEEP
);
2727 node
.sysctl_data
= cp_id
;
2728 memset(cp_id
, 0, node
.sysctl_size
);
2730 for (CPU_INFO_FOREACH(cii
, ci
)) {
2732 cp_id
[0] = cpu_index(ci
);
2734 * if a specific processor was requested and we just
2735 * did it, we're done here
2740 * if doing "all", skip to next cp_id slot for next processor
2745 * if we're doing a specific processor, we're one
2752 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
2753 kmem_free(node
.sysctl_data
, node
.sysctl_size
);
2758 * sysctl helper routine for hw.usermem and hw.usermem64. Values are
2759 * calculate on the fly taking into account integer overflow and the
2760 * current wired count.
2763 sysctl_hw_usermem(SYSCTLFN_ARGS
)
2767 struct sysctlnode node
;
2770 switch (rnode
->sysctl_num
) {
2772 if ((ui
= physmem
- uvmexp
.wired
) > (UINT_MAX
/ PAGE_SIZE
))
2776 node
.sysctl_data
= &ui
;
2779 uq
= (u_quad_t
)(physmem
- uvmexp
.wired
) * PAGE_SIZE
;
2780 node
.sysctl_data
= &uq
;
2786 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
2790 * sysctl helper routine for kern.cnmagic node. Pulls the old value
2791 * out, encoded, and stuffs the new value in for decoding.
2794 sysctl_hw_cnmagic(SYSCTLFN_ARGS
)
2796 char magic
[CNS_LEN
];
2798 struct sysctlnode node
;
2801 cn_get_magic(magic
, CNS_LEN
);
2803 node
.sysctl_data
= &magic
[0];
2804 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
2805 if (error
|| newp
== NULL
)
2808 return (cn_set_magic(magic
));
2812 * ********************************************************************
2813 * section 3: public helper routines that are used for more than one
2815 * ********************************************************************
2819 * sysctl helper routine for the kern.root_device node and some ports'
2820 * machdep.root_device nodes.
2823 sysctl_root_device(SYSCTLFN_ARGS
)
2825 struct sysctlnode node
;
2828 node
.sysctl_data
= root_device
->dv_xname
;
2829 node
.sysctl_size
= strlen(device_xname(root_device
)) + 1;
2830 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
2834 * sysctl helper routine for kern.consdev, dependent on the current
2835 * state of the console. Also used for machdep.console_device on some
2839 sysctl_consdev(SYSCTLFN_ARGS
)
2843 struct sysctlnode node
;
2846 consdev
= cn_tab
->cn_dev
;
2851 case sizeof(consdev
):
2852 node
.sysctl_data
= &consdev
;
2853 node
.sysctl_size
= sizeof(consdev
);
2855 case sizeof(oconsdev
):
2856 oconsdev
= (uint32_t)consdev
;
2857 node
.sysctl_data
= &oconsdev
;
2858 node
.sysctl_size
= sizeof(oconsdev
);
2863 return (sysctl_lookup(SYSCTLFN_CALL(&node
)));
2867 * ********************************************************************
2868 * section 4: support for some helpers
2869 * ********************************************************************
2872 * Find the most ``active'' lwp of a process and return it for ps display
2876 proc_active_lwp(struct proc
*p
)
2878 static const int ostat
[] = {
2890 struct lwp
*l
, *lp
= NULL
;
2891 LIST_FOREACH(l
, &p
->p_lwps
, l_sibling
) {
2892 KASSERT(l
->l_stat
>= 0 && l
->l_stat
< __arraycount(ostat
));
2894 ostat
[l
->l_stat
] > ostat
[lp
->l_stat
] ||
2895 (ostat
[l
->l_stat
] == ostat
[lp
->l_stat
] &&
2896 l
->l_cpticks
> lp
->l_cpticks
)) {
2906 * Fill in a kinfo_proc2 structure for the specified process.
2909 fill_kproc2(struct proc
*p
, struct kinfo_proc2
*ki
, bool zombie
)
2913 struct timeval ut
, st
, rt
;
2918 KASSERT(mutex_owned(proc_lock
));
2919 KASSERT(mutex_owned(p
->p_lock
));
2923 memset(ki
, 0, sizeof(*ki
));
2925 ki
->p_paddr
= PTRTOUINT64(p
);
2926 ki
->p_fd
= PTRTOUINT64(p
->p_fd
);
2927 ki
->p_cwdi
= PTRTOUINT64(p
->p_cwdi
);
2928 ki
->p_stats
= PTRTOUINT64(p
->p_stats
);
2929 ki
->p_limit
= PTRTOUINT64(p
->p_limit
);
2930 ki
->p_vmspace
= PTRTOUINT64(p
->p_vmspace
);
2931 ki
->p_sigacts
= PTRTOUINT64(p
->p_sigacts
);
2932 ki
->p_sess
= PTRTOUINT64(p
->p_session
);
2933 ki
->p_tsess
= 0; /* may be changed if controlling tty below */
2934 ki
->p_ru
= PTRTOUINT64(&p
->p_stats
->p_ru
);
2936 ki
->p_exitsig
= p
->p_exitsig
;
2937 ki
->p_flag
= L_INMEM
; /* Process never swapped out */
2938 ki
->p_flag
|= sysctl_map_flags(sysctl_flagmap
, p
->p_flag
);
2939 ki
->p_flag
|= sysctl_map_flags(sysctl_sflagmap
, p
->p_sflag
);
2940 ki
->p_flag
|= sysctl_map_flags(sysctl_slflagmap
, p
->p_slflag
);
2941 ki
->p_flag
|= sysctl_map_flags(sysctl_lflagmap
, p
->p_lflag
);
2942 ki
->p_flag
|= sysctl_map_flags(sysctl_stflagmap
, p
->p_stflag
);
2943 ki
->p_pid
= p
->p_pid
;
2945 ki
->p_ppid
= p
->p_pptr
->p_pid
;
2948 ki
->p_uid
= kauth_cred_geteuid(p
->p_cred
);
2949 ki
->p_ruid
= kauth_cred_getuid(p
->p_cred
);
2950 ki
->p_gid
= kauth_cred_getegid(p
->p_cred
);
2951 ki
->p_rgid
= kauth_cred_getgid(p
->p_cred
);
2952 ki
->p_svuid
= kauth_cred_getsvuid(p
->p_cred
);
2953 ki
->p_svgid
= kauth_cred_getsvgid(p
->p_cred
);
2954 ki
->p_ngroups
= kauth_cred_ngroups(p
->p_cred
);
2955 kauth_cred_getgroups(p
->p_cred
, ki
->p_groups
,
2956 min(ki
->p_ngroups
, sizeof(ki
->p_groups
) / sizeof(ki
->p_groups
[0])),
2959 ki
->p_uticks
= p
->p_uticks
;
2960 ki
->p_sticks
= p
->p_sticks
;
2961 ki
->p_iticks
= p
->p_iticks
;
2962 ki
->p_tpgid
= NO_PGID
; /* may be changed if controlling tty below */
2963 ki
->p_tracep
= PTRTOUINT64(p
->p_tracep
);
2964 ki
->p_traceflag
= p
->p_traceflag
;
2966 memcpy(&ki
->p_sigignore
, &p
->p_sigctx
.ps_sigignore
,sizeof(ki_sigset_t
));
2967 memcpy(&ki
->p_sigcatch
, &p
->p_sigctx
.ps_sigcatch
, sizeof(ki_sigset_t
));
2970 ki
->p_pctcpu
= p
->p_pctcpu
;
2972 ki
->p_stat
= p
->p_stat
; /* Will likely be overridden by LWP status */
2973 ki
->p_realstat
= p
->p_stat
;
2974 ki
->p_nice
= p
->p_nice
;
2975 ki
->p_xstat
= p
->p_xstat
;
2976 ki
->p_acflag
= p
->p_acflag
;
2978 strncpy(ki
->p_comm
, p
->p_comm
,
2979 min(sizeof(ki
->p_comm
), sizeof(p
->p_comm
)));
2980 strncpy(ki
->p_ename
, p
->p_emul
->e_name
, sizeof(ki
->p_ename
));
2982 ki
->p_nlwps
= p
->p_nlwps
;
2983 ki
->p_realflag
= ki
->p_flag
;
2985 if (p
->p_stat
!= SIDL
&& !P_ZOMBIE(p
) && !zombie
) {
2987 ki
->p_vm_rssize
= vm_resident_count(vm
);
2988 ki
->p_vm_tsize
= vm
->vm_tsize
;
2989 ki
->p_vm_dsize
= vm
->vm_dsize
;
2990 ki
->p_vm_ssize
= vm
->vm_ssize
;
2991 ki
->p_vm_vsize
= vm
->vm_map
.size
;
2993 * Since the stack is initially mapped mostly with
2994 * PROT_NONE and grown as needed, adjust the "mapped size"
2995 * to skip the unused stack portion.
2998 atop(vm
->vm_map
.size
) - vm
->vm_issize
+ vm
->vm_ssize
;
3000 /* Pick the primary (first) LWP */
3001 l
= proc_active_lwp(p
);
3004 ki
->p_nrlwps
= p
->p_nrlwps
;
3007 ki
->p_addr
= PTRTOUINT64(l
->l_addr
);
3008 ki
->p_stat
= l
->l_stat
;
3009 ki
->p_flag
|= sysctl_map_flags(sysctl_lwpflagmap
, l
->l_flag
);
3010 ki
->p_swtime
= l
->l_swtime
;
3011 ki
->p_slptime
= l
->l_slptime
;
3012 if (l
->l_stat
== LSONPROC
)
3013 ki
->p_schedflags
= l
->l_cpu
->ci_schedstate
.spc_flags
;
3015 ki
->p_schedflags
= 0;
3016 ki
->p_priority
= lwp_eprio(l
);
3017 ki
->p_usrpri
= l
->l_priority
;
3019 strncpy(ki
->p_wmesg
, l
->l_wmesg
, sizeof(ki
->p_wmesg
));
3020 ki
->p_wchan
= PTRTOUINT64(l
->l_wchan
);
3021 ki
->p_cpuid
= cpu_index(l
->l_cpu
);
3023 LIST_FOREACH(l
, &p
->p_lwps
, l_sibling
) {
3024 /* This is hardly correct, but... */
3025 sigplusset(&l
->l_sigpend
.sp_set
, &ss1
);
3026 sigplusset(&l
->l_sigmask
, &ss2
);
3027 ki
->p_cpticks
+= l
->l_cpticks
;
3028 ki
->p_pctcpu
+= l
->l_pctcpu
;
3029 ki
->p_estcpu
+= l
->l_estcpu
;
3032 sigplusset(&p
->p_sigpend
.sp_set
, &ss2
);
3033 memcpy(&ki
->p_siglist
, &ss1
, sizeof(ki_sigset_t
));
3034 memcpy(&ki
->p_sigmask
, &ss2
, sizeof(ki_sigset_t
));
3036 if (p
->p_session
!= NULL
) {
3037 ki
->p_sid
= p
->p_session
->s_sid
;
3038 ki
->p__pgid
= p
->p_pgrp
->pg_id
;
3039 if (p
->p_session
->s_ttyvp
)
3040 ki
->p_eflag
|= EPROC_CTTY
;
3042 ki
->p_eflag
|= EPROC_SLEADER
;
3043 strncpy(ki
->p_login
, p
->p_session
->s_login
,
3044 min(sizeof ki
->p_login
- 1, sizeof p
->p_session
->s_login
));
3045 ki
->p_jobc
= p
->p_pgrp
->pg_jobc
;
3046 if ((p
->p_lflag
& PL_CONTROLT
) && (tp
= p
->p_session
->s_ttyp
)) {
3047 ki
->p_tdev
= tp
->t_dev
;
3048 ki
->p_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PGID
;
3049 ki
->p_tsess
= PTRTOUINT64(tp
->t_session
);
3051 ki
->p_tdev
= (int32_t)NODEV
;
3055 if (!P_ZOMBIE(p
) && !zombie
) {
3057 ki
->p_ustart_sec
= p
->p_stats
->p_start
.tv_sec
;
3058 ki
->p_ustart_usec
= p
->p_stats
->p_start
.tv_usec
;
3060 calcru(p
, &ut
, &st
, NULL
, &rt
);
3061 ki
->p_rtime_sec
= rt
.tv_sec
;
3062 ki
->p_rtime_usec
= rt
.tv_usec
;
3063 ki
->p_uutime_sec
= ut
.tv_sec
;
3064 ki
->p_uutime_usec
= ut
.tv_usec
;
3065 ki
->p_ustime_sec
= st
.tv_sec
;
3066 ki
->p_ustime_usec
= st
.tv_usec
;
3068 memcpy(&ru
, &p
->p_stats
->p_ru
, sizeof(ru
));
3069 ki
->p_uru_nvcsw
= 0;
3070 ki
->p_uru_nivcsw
= 0;
3071 LIST_FOREACH(l2
, &p
->p_lwps
, l_sibling
) {
3072 ki
->p_uru_nvcsw
+= (l2
->l_ncsw
- l2
->l_nivcsw
);
3073 ki
->p_uru_nivcsw
+= l2
->l_nivcsw
;
3074 ruadd(&ru
, &l2
->l_ru
);
3076 ki
->p_uru_maxrss
= ru
.ru_maxrss
;
3077 ki
->p_uru_ixrss
= ru
.ru_ixrss
;
3078 ki
->p_uru_idrss
= ru
.ru_idrss
;
3079 ki
->p_uru_isrss
= ru
.ru_isrss
;
3080 ki
->p_uru_minflt
= ru
.ru_minflt
;
3081 ki
->p_uru_majflt
= ru
.ru_majflt
;
3082 ki
->p_uru_nswap
= ru
.ru_nswap
;
3083 ki
->p_uru_inblock
= ru
.ru_inblock
;
3084 ki
->p_uru_oublock
= ru
.ru_oublock
;
3085 ki
->p_uru_msgsnd
= ru
.ru_msgsnd
;
3086 ki
->p_uru_msgrcv
= ru
.ru_msgrcv
;
3087 ki
->p_uru_nsignals
= ru
.ru_nsignals
;
3089 timeradd(&p
->p_stats
->p_cru
.ru_utime
,
3090 &p
->p_stats
->p_cru
.ru_stime
, &ut
);
3091 ki
->p_uctime_sec
= ut
.tv_sec
;
3092 ki
->p_uctime_usec
= ut
.tv_usec
;
3097 * Fill in a kinfo_lwp structure for the specified lwp.
3100 fill_lwp(struct lwp
*l
, struct kinfo_lwp
*kl
)
3102 struct proc
*p
= l
->l_proc
;
3105 KASSERT(lwp_locked(l
, NULL
));
3109 kl
->l_laddr
= PTRTOUINT64(l
);
3110 kl
->l_addr
= PTRTOUINT64(l
->l_addr
);
3111 kl
->l_stat
= l
->l_stat
;
3112 kl
->l_lid
= l
->l_lid
;
3113 kl
->l_flag
= L_INMEM
;
3114 kl
->l_flag
|= sysctl_map_flags(sysctl_lwpprflagmap
, l
->l_prflag
);
3115 kl
->l_flag
|= sysctl_map_flags(sysctl_lwpflagmap
, l
->l_flag
);
3117 kl
->l_swtime
= l
->l_swtime
;
3118 kl
->l_slptime
= l
->l_slptime
;
3119 if (l
->l_stat
== LSONPROC
)
3120 kl
->l_schedflags
= l
->l_cpu
->ci_schedstate
.spc_flags
;
3122 kl
->l_schedflags
= 0;
3123 kl
->l_priority
= lwp_eprio(l
);
3124 kl
->l_usrpri
= l
->l_priority
;
3126 strncpy(kl
->l_wmesg
, l
->l_wmesg
, sizeof(kl
->l_wmesg
));
3127 kl
->l_wchan
= PTRTOUINT64(l
->l_wchan
);
3128 kl
->l_cpuid
= cpu_index(l
->l_cpu
);
3129 bintime2timeval(&l
->l_rtime
, &tv
);
3130 kl
->l_rtime_sec
= tv
.tv_sec
;
3131 kl
->l_rtime_usec
= tv
.tv_usec
;
3132 kl
->l_cpticks
= l
->l_cpticks
;
3133 kl
->l_pctcpu
= l
->l_pctcpu
;
3134 kl
->l_pid
= p
->p_pid
;
3135 if (l
->l_name
== NULL
)
3136 kl
->l_name
[0] = '\0';
3138 strlcpy(kl
->l_name
, l
->l_name
, sizeof(kl
->l_name
));
3142 * Fill in an eproc structure for the specified process.
3145 fill_eproc(struct proc
*p
, struct eproc
*ep
, bool zombie
)
3150 KASSERT(mutex_owned(proc_lock
));
3151 KASSERT(mutex_owned(p
->p_lock
));
3153 memset(ep
, 0, sizeof(*ep
));
3156 ep
->e_sess
= p
->p_session
;
3158 kauth_cred_topcred(p
->p_cred
, &ep
->e_pcred
);
3159 kauth_cred_toucred(p
->p_cred
, &ep
->e_ucred
);
3161 if (p
->p_stat
!= SIDL
&& !P_ZOMBIE(p
) && !zombie
) {
3162 struct vmspace
*vm
= p
->p_vmspace
;
3164 ep
->e_vm
.vm_rssize
= vm_resident_count(vm
);
3165 ep
->e_vm
.vm_tsize
= vm
->vm_tsize
;
3166 ep
->e_vm
.vm_dsize
= vm
->vm_dsize
;
3167 ep
->e_vm
.vm_ssize
= vm
->vm_ssize
;
3168 ep
->e_vm
.vm_map
.size
= vm
->vm_map
.size
;
3170 /* Pick the primary (first) LWP */
3171 l
= proc_active_lwp(p
);
3175 strncpy(ep
->e_wmesg
, l
->l_wmesg
, WMESGLEN
);
3179 ep
->e_ppid
= p
->p_pptr
->p_pid
;
3180 if (p
->p_pgrp
&& p
->p_session
) {
3181 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
3182 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
3183 ep
->e_sid
= p
->p_session
->s_sid
;
3184 if ((p
->p_lflag
& PL_CONTROLT
) &&
3185 (tp
= ep
->e_sess
->s_ttyp
)) {
3186 ep
->e_tdev
= tp
->t_dev
;
3187 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PGID
;
3188 ep
->e_tsess
= tp
->t_session
;
3190 ep
->e_tdev
= (uint32_t)NODEV
;
3191 ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
3193 ep
->e_flag
|= EPROC_SLEADER
;
3194 strncpy(ep
->e_login
, ep
->e_sess
->s_login
, MAXLOGNAME
);
3196 ep
->e_xsize
= ep
->e_xrssize
= 0;
3197 ep
->e_xccount
= ep
->e_xswrss
= 0;
3201 sysctl_map_flags(const u_int
*map
, u_int word
)
3205 for (rv
= 0; *map
!= 0; map
+= 2)
3206 if ((word
& map
[0]) != 0)