init_sysctl.c revision 1.66
1/* $NetBSD: init_sysctl.c,v 1.66 2006/04/14 13:09:06 blymn Exp $ */ 2 3/*- 4 * Copyright (c) 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Brown. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39#include <sys/cdefs.h> 40__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.66 2006/04/14 13:09:06 blymn Exp $"); 41 42#include "opt_sysv.h" 43#include "opt_multiprocessor.h" 44#include "opt_posix.h" 45#include "opt_verified_exec.h" 46#include "pty.h" 47#include "rnd.h" 48 49#include <sys/types.h> 50#include <sys/param.h> 51#include <sys/sysctl.h> 52#include <sys/errno.h> 53#include <sys/systm.h> 54#include <sys/kernel.h> 55#include <sys/unistd.h> 56#include <sys/disklabel.h> 57#include <sys/rnd.h> 58#include <sys/vnode.h> 59#include <sys/mount.h> 60#include <sys/namei.h> 61#include <sys/msgbuf.h> 62#include <dev/cons.h> 63#include <sys/socketvar.h> 64#include <sys/file.h> 65#include <sys/filedesc.h> 66#include <sys/tty.h> 67#include <sys/malloc.h> 68#include <sys/resource.h> 69#include <sys/resourcevar.h> 70#include <sys/exec.h> 71#include <sys/conf.h> 72#include <sys/device.h> 73#ifdef VERIFIED_EXEC 74#define VERIEXEC_NEED_NODE 75#include <sys/verified_exec.h> 76#endif /* VERIFIED_EXEC */ 77#include <sys/stat.h> 78 79#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 80#include <sys/ipc.h> 81#endif 82#ifdef SYSVMSG 83#include <sys/msg.h> 84#endif 85#ifdef SYSVSEM 86#include <sys/sem.h> 87#endif 88#ifdef SYSVSHM 89#include <sys/shm.h> 90#endif 91 92#include <machine/cpu.h> 93 94/* XXX this should not be here */ 95int security_curtain = 0; 96int security_setidcore_dump; 97char security_setidcore_path[MAXPATHLEN] = "/var/crash/%n.core"; 98uid_t security_setidcore_owner = 0; 99gid_t security_setidcore_group = 0; 100mode_t security_setidcore_mode = (S_IRUSR|S_IWUSR); 101 102/* 103 * try over estimating by 5 procs/lwps 104 */ 105#define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc)) 106#define KERN_LWPSLOP (5 * sizeof(struct kinfo_lwp)) 107 108#ifndef MULTIPROCESSOR 109#define sysctl_ncpus() (1) 110#else /* MULTIPROCESSOR */ 111#ifndef CPU_INFO_FOREACH 112#define CPU_INFO_ITERATOR int 113#define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = curcpu(); ci != NULL; ci = NULL 114#endif 115static int 116sysctl_ncpus(void) 117{ 118 struct cpu_info *ci; 119 CPU_INFO_ITERATOR cii; 120 121 int ncpus = 0; 122 for (CPU_INFO_FOREACH(cii, ci)) 123 ncpus++; 124 return (ncpus); 125} 126#endif /* MULTIPROCESSOR */ 127 128#ifdef DIAGNOSTIC 129static int sysctl_kern_trigger_panic(SYSCTLFN_PROTO); 130#endif 131static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO); 132static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO); 133static int sysctl_kern_maxproc(SYSCTLFN_PROTO); 134static int sysctl_kern_securelevel(SYSCTLFN_PROTO); 135static int sysctl_kern_hostid(SYSCTLFN_PROTO); 136static int sysctl_setlen(SYSCTLFN_PROTO); 137static int sysctl_kern_clockrate(SYSCTLFN_PROTO); 138static int sysctl_kern_file(SYSCTLFN_PROTO); 139static int sysctl_kern_autonice(SYSCTLFN_PROTO); 140static int sysctl_msgbuf(SYSCTLFN_PROTO); 141static int sysctl_kern_defcorename(SYSCTLFN_PROTO); 142static int sysctl_kern_cptime(SYSCTLFN_PROTO); 143#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 144static int sysctl_kern_sysvipc(SYSCTLFN_PROTO); 145#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */ 146#if NPTY > 0 147static int sysctl_kern_maxptys(SYSCTLFN_PROTO); 148#endif /* NPTY > 0 */ 149static int sysctl_kern_sbmax(SYSCTLFN_PROTO); 150static int sysctl_kern_urnd(SYSCTLFN_PROTO); 151static int sysctl_kern_lwp(SYSCTLFN_PROTO); 152static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); 153static int sysctl_kern_root_partition(SYSCTLFN_PROTO); 154static int sysctl_kern_drivers(SYSCTLFN_PROTO); 155static int sysctl_kern_file2(SYSCTLFN_PROTO); 156#ifdef VERIFIED_EXEC 157static int sysctl_kern_veriexec(SYSCTLFN_PROTO); 158#endif 159static int sysctl_security_setidcore(SYSCTLFN_PROTO); 160static int sysctl_security_setidcorename(SYSCTLFN_PROTO); 161static int sysctl_kern_cpid(SYSCTLFN_PROTO); 162static int sysctl_doeproc(SYSCTLFN_PROTO); 163static int sysctl_kern_proc_args(SYSCTLFN_PROTO); 164static int sysctl_hw_usermem(SYSCTLFN_PROTO); 165static int sysctl_hw_cnmagic(SYSCTLFN_PROTO); 166static int sysctl_hw_ncpu(SYSCTLFN_PROTO); 167 168static void fill_kproc2(struct proc *, struct kinfo_proc2 *); 169static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl); 170static void fill_file(struct kinfo_file *, const struct file *, struct proc *, 171 int); 172 173/* 174 * ******************************************************************** 175 * section 1: setup routines 176 * ******************************************************************** 177 * these functions are stuffed into a link set for sysctl setup 178 * functions. they're never called or referenced from anywhere else. 179 * ******************************************************************** 180 */ 181 182/* 183 * sets up the base nodes... 184 */ 185SYSCTL_SETUP(sysctl_root_setup, "sysctl base setup") 186{ 187 188 sysctl_createv(clog, 0, NULL, NULL, 189 CTLFLAG_PERMANENT, 190 CTLTYPE_NODE, "kern", 191 SYSCTL_DESCR("High kernel"), 192 NULL, 0, NULL, 0, 193 CTL_KERN, CTL_EOL); 194 sysctl_createv(clog, 0, NULL, NULL, 195 CTLFLAG_PERMANENT, 196 CTLTYPE_NODE, "vm", 197 SYSCTL_DESCR("Virtual memory"), 198 NULL, 0, NULL, 0, 199 CTL_VM, CTL_EOL); 200 sysctl_createv(clog, 0, NULL, NULL, 201 CTLFLAG_PERMANENT, 202 CTLTYPE_NODE, "vfs", 203 SYSCTL_DESCR("Filesystem"), 204 NULL, 0, NULL, 0, 205 CTL_VFS, CTL_EOL); 206 sysctl_createv(clog, 0, NULL, NULL, 207 CTLFLAG_PERMANENT, 208 CTLTYPE_NODE, "net", 209 SYSCTL_DESCR("Networking"), 210 NULL, 0, NULL, 0, 211 CTL_NET, CTL_EOL); 212 sysctl_createv(clog, 0, NULL, NULL, 213 CTLFLAG_PERMANENT, 214 CTLTYPE_NODE, "debug", 215 SYSCTL_DESCR("Debugging"), 216 NULL, 0, NULL, 0, 217 CTL_DEBUG, CTL_EOL); 218 sysctl_createv(clog, 0, NULL, NULL, 219 CTLFLAG_PERMANENT, 220 CTLTYPE_NODE, "hw", 221 SYSCTL_DESCR("Generic CPU, I/O"), 222 NULL, 0, NULL, 0, 223 CTL_HW, CTL_EOL); 224 sysctl_createv(clog, 0, NULL, NULL, 225 CTLFLAG_PERMANENT, 226 CTLTYPE_NODE, "machdep", 227 SYSCTL_DESCR("Machine dependent"), 228 NULL, 0, NULL, 0, 229 CTL_MACHDEP, CTL_EOL); 230 /* 231 * this node is inserted so that the sysctl nodes in libc can 232 * operate. 233 */ 234 sysctl_createv(clog, 0, NULL, NULL, 235 CTLFLAG_PERMANENT, 236 CTLTYPE_NODE, "user", 237 SYSCTL_DESCR("User-level"), 238 NULL, 0, NULL, 0, 239 CTL_USER, CTL_EOL); 240 sysctl_createv(clog, 0, NULL, NULL, 241 CTLFLAG_PERMANENT, 242 CTLTYPE_NODE, "ddb", 243 SYSCTL_DESCR("In-kernel debugger"), 244 NULL, 0, NULL, 0, 245 CTL_DDB, CTL_EOL); 246 sysctl_createv(clog, 0, NULL, NULL, 247 CTLFLAG_PERMANENT, 248 CTLTYPE_NODE, "proc", 249 SYSCTL_DESCR("Per-process"), 250 NULL, 0, NULL, 0, 251 CTL_PROC, CTL_EOL); 252 sysctl_createv(clog, 0, NULL, NULL, 253 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 254 CTLTYPE_NODE, "vendor", 255 SYSCTL_DESCR("Vendor specific"), 256 NULL, 0, NULL, 0, 257 CTL_VENDOR, CTL_EOL); 258 sysctl_createv(clog, 0, NULL, NULL, 259 CTLFLAG_PERMANENT, 260 CTLTYPE_NODE, "emul", 261 SYSCTL_DESCR("Emulation settings"), 262 NULL, 0, NULL, 0, 263 CTL_EMUL, CTL_EOL); 264 sysctl_createv(clog, 0, NULL, NULL, 265 CTLFLAG_PERMANENT, 266 CTLTYPE_NODE, "security", 267 SYSCTL_DESCR("Security"), 268 NULL, 0, NULL, 0, 269 CTL_SECURITY, CTL_EOL); 270} 271 272/* 273 * this setup routine is a replacement for kern_sysctl() 274 */ 275SYSCTL_SETUP(sysctl_kern_setup, "sysctl kern subtree setup") 276{ 277 extern int kern_logsigexit; /* defined in kern/kern_sig.c */ 278 extern fixpt_t ccpu; /* defined in kern/kern_synch.c */ 279 extern int dumponpanic; /* defined in kern/subr_prf.c */ 280 281 sysctl_createv(clog, 0, NULL, NULL, 282 CTLFLAG_PERMANENT, 283 CTLTYPE_NODE, "kern", NULL, 284 NULL, 0, NULL, 0, 285 CTL_KERN, CTL_EOL); 286 287 sysctl_createv(clog, 0, NULL, NULL, 288 CTLFLAG_PERMANENT, 289 CTLTYPE_STRING, "ostype", 290 SYSCTL_DESCR("Operating system type"), 291 NULL, 0, &ostype, 0, 292 CTL_KERN, KERN_OSTYPE, CTL_EOL); 293 sysctl_createv(clog, 0, NULL, NULL, 294 CTLFLAG_PERMANENT, 295 CTLTYPE_STRING, "osrelease", 296 SYSCTL_DESCR("Operating system release"), 297 NULL, 0, &osrelease, 0, 298 CTL_KERN, KERN_OSRELEASE, CTL_EOL); 299 sysctl_createv(clog, 0, NULL, NULL, 300 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 301 CTLTYPE_INT, "osrevision", 302 SYSCTL_DESCR("Operating system revision"), 303 NULL, __NetBSD_Version__, NULL, 0, 304 CTL_KERN, KERN_OSREV, CTL_EOL); 305 sysctl_createv(clog, 0, NULL, NULL, 306 CTLFLAG_PERMANENT, 307 CTLTYPE_STRING, "version", 308 SYSCTL_DESCR("Kernel version"), 309 NULL, 0, &version, 0, 310 CTL_KERN, KERN_VERSION, CTL_EOL); 311 sysctl_createv(clog, 0, NULL, NULL, 312 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 313 CTLTYPE_INT, "maxvnodes", 314 SYSCTL_DESCR("Maximum number of vnodes"), 315 sysctl_kern_maxvnodes, 0, NULL, 0, 316 CTL_KERN, KERN_MAXVNODES, CTL_EOL); 317 sysctl_createv(clog, 0, NULL, NULL, 318 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 319 CTLTYPE_INT, "maxproc", 320 SYSCTL_DESCR("Maximum number of simultaneous processes"), 321 sysctl_kern_maxproc, 0, NULL, 0, 322 CTL_KERN, KERN_MAXPROC, CTL_EOL); 323 sysctl_createv(clog, 0, NULL, NULL, 324 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 325 CTLTYPE_INT, "maxfiles", 326 SYSCTL_DESCR("Maximum number of open files"), 327 NULL, 0, &maxfiles, 0, 328 CTL_KERN, KERN_MAXFILES, CTL_EOL); 329 sysctl_createv(clog, 0, NULL, NULL, 330 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 331 CTLTYPE_INT, "argmax", 332 SYSCTL_DESCR("Maximum number of bytes of arguments to " 333 "execve(2)"), 334 NULL, ARG_MAX, NULL, 0, 335 CTL_KERN, KERN_ARGMAX, CTL_EOL); 336 sysctl_createv(clog, 0, NULL, NULL, 337 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 338 CTLTYPE_INT, "securelevel", 339 SYSCTL_DESCR("System security level"), 340 sysctl_kern_securelevel, 0, &securelevel, 0, 341 CTL_KERN, KERN_SECURELVL, CTL_EOL); 342 sysctl_createv(clog, 0, NULL, NULL, 343 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 344 CTLTYPE_STRING, "hostname", 345 SYSCTL_DESCR("System hostname"), 346 sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN, 347 CTL_KERN, KERN_HOSTNAME, CTL_EOL); 348 sysctl_createv(clog, 0, NULL, NULL, 349 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 350 CTLTYPE_INT, "hostid", 351 SYSCTL_DESCR("System host ID number"), 352 sysctl_kern_hostid, 0, NULL, 0, 353 CTL_KERN, KERN_HOSTID, CTL_EOL); 354 sysctl_createv(clog, 0, NULL, NULL, 355 CTLFLAG_PERMANENT, 356 CTLTYPE_STRUCT, "clockrate", 357 SYSCTL_DESCR("Kernel clock rates"), 358 sysctl_kern_clockrate, 0, NULL, 359 sizeof(struct clockinfo), 360 CTL_KERN, KERN_CLOCKRATE, CTL_EOL); 361 sysctl_createv(clog, 0, NULL, NULL, 362 CTLFLAG_PERMANENT, 363 CTLTYPE_INT, "hardclock_ticks", 364 SYSCTL_DESCR("Number of hardclock ticks"), 365 NULL, 0, &hardclock_ticks, sizeof(hardclock_ticks), 366 CTL_KERN, KERN_HARDCLOCK_TICKS, CTL_EOL); 367 sysctl_createv(clog, 0, NULL, NULL, 368 CTLFLAG_PERMANENT, 369 CTLTYPE_STRUCT, "vnode", 370 SYSCTL_DESCR("System vnode table"), 371 sysctl_kern_vnode, 0, NULL, 0, 372 CTL_KERN, KERN_VNODE, CTL_EOL); 373 sysctl_createv(clog, 0, NULL, NULL, 374 CTLFLAG_PERMANENT, 375 CTLTYPE_STRUCT, "file", 376 SYSCTL_DESCR("System open file table"), 377 sysctl_kern_file, 0, NULL, 0, 378 CTL_KERN, KERN_FILE, CTL_EOL); 379#ifndef GPROF 380 sysctl_createv(clog, 0, NULL, NULL, 381 CTLFLAG_PERMANENT, 382 CTLTYPE_NODE, "profiling", 383 SYSCTL_DESCR("Profiling information (not available)"), 384 sysctl_notavail, 0, NULL, 0, 385 CTL_KERN, KERN_PROF, CTL_EOL); 386#endif 387 sysctl_createv(clog, 0, NULL, NULL, 388 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 389 CTLTYPE_INT, "posix1version", 390 SYSCTL_DESCR("Version of ISO/IEC 9945 (POSIX 1003.1) " 391 "with which the operating system attempts " 392 "to comply"), 393 NULL, _POSIX_VERSION, NULL, 0, 394 CTL_KERN, KERN_POSIX1, CTL_EOL); 395 sysctl_createv(clog, 0, NULL, NULL, 396 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 397 CTLTYPE_INT, "ngroups", 398 SYSCTL_DESCR("Maximum number of supplemental groups"), 399 NULL, NGROUPS_MAX, NULL, 0, 400 CTL_KERN, KERN_NGROUPS, CTL_EOL); 401 sysctl_createv(clog, 0, NULL, NULL, 402 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 403 CTLTYPE_INT, "job_control", 404 SYSCTL_DESCR("Whether job control is available"), 405 NULL, 1, NULL, 0, 406 CTL_KERN, KERN_JOB_CONTROL, CTL_EOL); 407 sysctl_createv(clog, 0, NULL, NULL, 408 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 409 CTLTYPE_INT, "saved_ids", 410 SYSCTL_DESCR("Whether POSIX saved set-group/user ID is " 411 "available"), NULL, 412#ifdef _POSIX_SAVED_IDS 413 1, 414#else /* _POSIX_SAVED_IDS */ 415 0, 416#endif /* _POSIX_SAVED_IDS */ 417 NULL, 0, CTL_KERN, KERN_SAVED_IDS, CTL_EOL); 418 sysctl_createv(clog, 0, NULL, NULL, 419 CTLFLAG_PERMANENT, 420 CTLTYPE_STRUCT, "boottime", 421 SYSCTL_DESCR("System boot time"), 422 NULL, 0, &boottime, sizeof(boottime), 423 CTL_KERN, KERN_BOOTTIME, CTL_EOL); 424 sysctl_createv(clog, 0, NULL, NULL, 425 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 426 CTLTYPE_STRING, "domainname", 427 SYSCTL_DESCR("YP domain name"), 428 sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN, 429 CTL_KERN, KERN_DOMAINNAME, CTL_EOL); 430 sysctl_createv(clog, 0, NULL, NULL, 431 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 432 CTLTYPE_INT, "maxpartitions", 433 SYSCTL_DESCR("Maximum number of partitions allowed per " 434 "disk"), 435 NULL, MAXPARTITIONS, NULL, 0, 436 CTL_KERN, KERN_MAXPARTITIONS, CTL_EOL); 437 sysctl_createv(clog, 0, NULL, NULL, 438 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 439 CTLTYPE_INT, "rawpartition", 440 SYSCTL_DESCR("Raw partition of a disk"), 441 NULL, RAW_PART, NULL, 0, 442 CTL_KERN, KERN_RAWPARTITION, CTL_EOL); 443 sysctl_createv(clog, 0, NULL, NULL, 444 CTLFLAG_PERMANENT, 445 CTLTYPE_STRUCT, "timex", NULL, 446 sysctl_notavail, 0, NULL, 0, 447 CTL_KERN, KERN_TIMEX, CTL_EOL); 448 sysctl_createv(clog, 0, NULL, NULL, 449 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 450 CTLTYPE_INT, "autonicetime", 451 SYSCTL_DESCR("CPU clock seconds before non-root " 452 "process priority is lowered"), 453 sysctl_kern_autonice, 0, &autonicetime, 0, 454 CTL_KERN, KERN_AUTONICETIME, CTL_EOL); 455 sysctl_createv(clog, 0, NULL, NULL, 456 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 457 CTLTYPE_INT, "autoniceval", 458 SYSCTL_DESCR("Automatic reniced non-root process " 459 "priority"), 460 sysctl_kern_autonice, 0, &autoniceval, 0, 461 CTL_KERN, KERN_AUTONICEVAL, CTL_EOL); 462 sysctl_createv(clog, 0, NULL, NULL, 463 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 464 CTLTYPE_INT, "rtc_offset", 465 SYSCTL_DESCR("Offset of real time clock from UTC in " 466 "minutes"), 467 sysctl_kern_rtc_offset, 0, &rtc_offset, 0, 468 CTL_KERN, KERN_RTC_OFFSET, CTL_EOL); 469 sysctl_createv(clog, 0, NULL, NULL, 470 CTLFLAG_PERMANENT, 471 CTLTYPE_STRING, "root_device", 472 SYSCTL_DESCR("Name of the root device"), 473 sysctl_root_device, 0, NULL, 0, 474 CTL_KERN, KERN_ROOT_DEVICE, CTL_EOL); 475 sysctl_createv(clog, 0, NULL, NULL, 476 CTLFLAG_PERMANENT, 477 CTLTYPE_INT, "msgbufsize", 478 SYSCTL_DESCR("Size of the kernel message buffer"), 479 sysctl_msgbuf, 0, NULL, 0, 480 CTL_KERN, KERN_MSGBUFSIZE, CTL_EOL); 481 sysctl_createv(clog, 0, NULL, NULL, 482 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 483 CTLTYPE_INT, "fsync", 484 SYSCTL_DESCR("Whether the POSIX 1003.1b File " 485 "Synchronization Option is available on " 486 "this system"), 487 NULL, 1, NULL, 0, 488 CTL_KERN, KERN_FSYNC, CTL_EOL); 489 sysctl_createv(clog, 0, NULL, NULL, 490 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 491 CTLTYPE_INT, "sysvmsg", 492 SYSCTL_DESCR("System V style message support available"), 493 NULL, 494#ifdef SYSVMSG 495 1, 496#else /* SYSVMSG */ 497 0, 498#endif /* SYSVMSG */ 499 NULL, 0, CTL_KERN, KERN_SYSVMSG, CTL_EOL); 500 sysctl_createv(clog, 0, NULL, NULL, 501 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 502 CTLTYPE_INT, "sysvsem", 503 SYSCTL_DESCR("System V style semaphore support " 504 "available"), NULL, 505#ifdef SYSVSEM 506 1, 507#else /* SYSVSEM */ 508 0, 509#endif /* SYSVSEM */ 510 NULL, 0, CTL_KERN, KERN_SYSVSEM, CTL_EOL); 511 sysctl_createv(clog, 0, NULL, NULL, 512 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 513 CTLTYPE_INT, "sysvshm", 514 SYSCTL_DESCR("System V style shared memory support " 515 "available"), NULL, 516#ifdef SYSVSHM 517 1, 518#else /* SYSVSHM */ 519 0, 520#endif /* SYSVSHM */ 521 NULL, 0, CTL_KERN, KERN_SYSVSHM, CTL_EOL); 522 sysctl_createv(clog, 0, NULL, NULL, 523 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 524 CTLTYPE_INT, "synchronized_io", 525 SYSCTL_DESCR("Whether the POSIX 1003.1b Synchronized " 526 "I/O Option is available on this system"), 527 NULL, 1, NULL, 0, 528 CTL_KERN, KERN_SYNCHRONIZED_IO, CTL_EOL); 529 sysctl_createv(clog, 0, NULL, NULL, 530 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 531 CTLTYPE_INT, "iov_max", 532 SYSCTL_DESCR("Maximum number of iovec structures per " 533 "process"), 534 NULL, IOV_MAX, NULL, 0, 535 CTL_KERN, KERN_IOV_MAX, CTL_EOL); 536 sysctl_createv(clog, 0, NULL, NULL, 537 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 538 CTLTYPE_INT, "mapped_files", 539 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory Mapped " 540 "Files Option is available on this system"), 541 NULL, 1, NULL, 0, 542 CTL_KERN, KERN_MAPPED_FILES, CTL_EOL); 543 sysctl_createv(clog, 0, NULL, NULL, 544 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 545 CTLTYPE_INT, "memlock", 546 SYSCTL_DESCR("Whether the POSIX 1003.1b Process Memory " 547 "Locking Option is available on this " 548 "system"), 549 NULL, 1, NULL, 0, 550 CTL_KERN, KERN_MEMLOCK, CTL_EOL); 551 sysctl_createv(clog, 0, NULL, NULL, 552 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 553 CTLTYPE_INT, "memlock_range", 554 SYSCTL_DESCR("Whether the POSIX 1003.1b Range Memory " 555 "Locking Option is available on this " 556 "system"), 557 NULL, 1, NULL, 0, 558 CTL_KERN, KERN_MEMLOCK_RANGE, CTL_EOL); 559 sysctl_createv(clog, 0, NULL, NULL, 560 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 561 CTLTYPE_INT, "memory_protection", 562 SYSCTL_DESCR("Whether the POSIX 1003.1b Memory " 563 "Protection Option is available on this " 564 "system"), 565 NULL, 1, NULL, 0, 566 CTL_KERN, KERN_MEMORY_PROTECTION, CTL_EOL); 567 sysctl_createv(clog, 0, NULL, NULL, 568 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 569 CTLTYPE_INT, "login_name_max", 570 SYSCTL_DESCR("Maximum login name length"), 571 NULL, LOGIN_NAME_MAX, NULL, 0, 572 CTL_KERN, KERN_LOGIN_NAME_MAX, CTL_EOL); 573 sysctl_createv(clog, 0, NULL, NULL, 574 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 575 CTLTYPE_STRING, "defcorename", 576 SYSCTL_DESCR("Default core file name"), 577 sysctl_kern_defcorename, 0, defcorename, MAXPATHLEN, 578 CTL_KERN, KERN_DEFCORENAME, CTL_EOL); 579 sysctl_createv(clog, 0, NULL, NULL, 580 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 581 CTLTYPE_INT, "logsigexit", 582 SYSCTL_DESCR("Log process exit when caused by signals"), 583 NULL, 0, &kern_logsigexit, 0, 584 CTL_KERN, KERN_LOGSIGEXIT, CTL_EOL); 585 sysctl_createv(clog, 0, NULL, NULL, 586 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 587 CTLTYPE_INT, "fscale", 588 SYSCTL_DESCR("Kernel fixed-point scale factor"), 589 NULL, FSCALE, NULL, 0, 590 CTL_KERN, KERN_FSCALE, CTL_EOL); 591 sysctl_createv(clog, 0, NULL, NULL, 592 CTLFLAG_PERMANENT, 593 CTLTYPE_INT, "ccpu", 594 SYSCTL_DESCR("Scheduler exponential decay value"), 595 NULL, 0, &ccpu, 0, 596 CTL_KERN, KERN_CCPU, CTL_EOL); 597 sysctl_createv(clog, 0, NULL, NULL, 598 CTLFLAG_PERMANENT, 599 CTLTYPE_STRUCT, "cp_time", 600 SYSCTL_DESCR("Clock ticks spent in different CPU states"), 601 sysctl_kern_cptime, 0, NULL, 0, 602 CTL_KERN, KERN_CP_TIME, CTL_EOL); 603#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 604 sysctl_createv(clog, 0, NULL, NULL, 605 CTLFLAG_PERMANENT, 606 CTLTYPE_STRUCT, "sysvipc_info", 607 SYSCTL_DESCR("System V style IPC information"), 608 sysctl_kern_sysvipc, 0, NULL, 0, 609 CTL_KERN, KERN_SYSVIPC_INFO, CTL_EOL); 610#endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 611 sysctl_createv(clog, 0, NULL, NULL, 612 CTLFLAG_PERMANENT, 613 CTLTYPE_INT, "msgbuf", 614 SYSCTL_DESCR("Kernel message buffer"), 615 sysctl_msgbuf, 0, NULL, 0, 616 CTL_KERN, KERN_MSGBUF, CTL_EOL); 617 sysctl_createv(clog, 0, NULL, NULL, 618 CTLFLAG_PERMANENT, 619 CTLTYPE_STRUCT, "consdev", 620 SYSCTL_DESCR("Console device"), 621 sysctl_consdev, 0, NULL, sizeof(dev_t), 622 CTL_KERN, KERN_CONSDEV, CTL_EOL); 623#if NPTY > 0 624 sysctl_createv(clog, 0, NULL, NULL, 625 CTLFLAG_PERMANENT, 626 CTLTYPE_INT, "maxptys", 627 SYSCTL_DESCR("Maximum number of pseudo-ttys"), 628 sysctl_kern_maxptys, 0, NULL, 0, 629 CTL_KERN, KERN_MAXPTYS, CTL_EOL); 630#endif /* NPTY > 0 */ 631 sysctl_createv(clog, 0, NULL, NULL, 632 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 633 CTLTYPE_INT, "maxphys", 634 SYSCTL_DESCR("Maximum raw I/O transfer size"), 635 NULL, MAXPHYS, NULL, 0, 636 CTL_KERN, KERN_MAXPHYS, CTL_EOL); 637 sysctl_createv(clog, 0, NULL, NULL, 638 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 639 CTLTYPE_INT, "sbmax", 640 SYSCTL_DESCR("Maximum socket buffer size"), 641 sysctl_kern_sbmax, 0, NULL, 0, 642 CTL_KERN, KERN_SBMAX, CTL_EOL); 643 sysctl_createv(clog, 0, NULL, NULL, 644 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 645 CTLTYPE_INT, "monotonic_clock", 646 SYSCTL_DESCR("Implementation version of the POSIX " 647 "1003.1b Monotonic Clock Option"), 648 /* XXX _POSIX_VERSION */ 649 NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0, 650 CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL); 651 sysctl_createv(clog, 0, NULL, NULL, 652 CTLFLAG_PERMANENT, 653 CTLTYPE_INT, "urandom", 654 SYSCTL_DESCR("Random integer value"), 655 sysctl_kern_urnd, 0, NULL, 0, 656 CTL_KERN, KERN_URND, CTL_EOL); 657 sysctl_createv(clog, 0, NULL, NULL, 658 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 659 CTLTYPE_INT, "labelsector", 660 SYSCTL_DESCR("Sector number containing the disklabel"), 661 NULL, LABELSECTOR, NULL, 0, 662 CTL_KERN, KERN_LABELSECTOR, CTL_EOL); 663 sysctl_createv(clog, 0, NULL, NULL, 664 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 665 CTLTYPE_INT, "labeloffset", 666 SYSCTL_DESCR("Offset of the disklabel within the " 667 "sector"), 668 NULL, LABELOFFSET, NULL, 0, 669 CTL_KERN, KERN_LABELOFFSET, CTL_EOL); 670 sysctl_createv(clog, 0, NULL, NULL, 671 CTLFLAG_PERMANENT, 672 CTLTYPE_NODE, "lwp", 673 SYSCTL_DESCR("System-wide LWP information"), 674 sysctl_kern_lwp, 0, NULL, 0, 675 CTL_KERN, KERN_LWP, CTL_EOL); 676 sysctl_createv(clog, 0, NULL, NULL, 677 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 678 CTLTYPE_INT, "forkfsleep", 679 SYSCTL_DESCR("Milliseconds to sleep on fork failure due " 680 "to process limits"), 681 sysctl_kern_forkfsleep, 0, NULL, 0, 682 CTL_KERN, KERN_FORKFSLEEP, CTL_EOL); 683 sysctl_createv(clog, 0, NULL, NULL, 684 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 685 CTLTYPE_INT, "posix_threads", 686 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 687 "Threads option to which the system " 688 "attempts to conform"), 689 /* XXX _POSIX_VERSION */ 690 NULL, _POSIX_THREADS, NULL, 0, 691 CTL_KERN, KERN_POSIX_THREADS, CTL_EOL); 692 sysctl_createv(clog, 0, NULL, NULL, 693 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 694 CTLTYPE_INT, "posix_semaphores", 695 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 696 "Semaphores option to which the system " 697 "attempts to conform"), NULL, 698#ifdef P1003_1B_SEMAPHORE 699 200112, 700#else /* P1003_1B_SEMAPHORE */ 701 0, 702#endif /* P1003_1B_SEMAPHORE */ 703 NULL, 0, CTL_KERN, KERN_POSIX_SEMAPHORES, CTL_EOL); 704 sysctl_createv(clog, 0, NULL, NULL, 705 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 706 CTLTYPE_INT, "posix_barriers", 707 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 708 "Barriers option to which the system " 709 "attempts to conform"), 710 /* XXX _POSIX_VERSION */ 711 NULL, _POSIX_BARRIERS, NULL, 0, 712 CTL_KERN, KERN_POSIX_BARRIERS, CTL_EOL); 713 sysctl_createv(clog, 0, NULL, NULL, 714 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 715 CTLTYPE_INT, "posix_timers", 716 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 717 "Timers option to which the system " 718 "attempts to conform"), 719 /* XXX _POSIX_VERSION */ 720 NULL, _POSIX_TIMERS, NULL, 0, 721 CTL_KERN, KERN_POSIX_TIMERS, CTL_EOL); 722 sysctl_createv(clog, 0, NULL, NULL, 723 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 724 CTLTYPE_INT, "posix_spin_locks", 725 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its Spin " 726 "Locks option to which the system attempts " 727 "to conform"), 728 /* XXX _POSIX_VERSION */ 729 NULL, _POSIX_SPIN_LOCKS, NULL, 0, 730 CTL_KERN, KERN_POSIX_SPIN_LOCKS, CTL_EOL); 731 sysctl_createv(clog, 0, NULL, NULL, 732 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 733 CTLTYPE_INT, "posix_reader_writer_locks", 734 SYSCTL_DESCR("Version of IEEE Std 1003.1 and its " 735 "Read-Write Locks option to which the " 736 "system attempts to conform"), 737 /* XXX _POSIX_VERSION */ 738 NULL, _POSIX_READER_WRITER_LOCKS, NULL, 0, 739 CTL_KERN, KERN_POSIX_READER_WRITER_LOCKS, CTL_EOL); 740 sysctl_createv(clog, 0, NULL, NULL, 741 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 742 CTLTYPE_INT, "dump_on_panic", 743 SYSCTL_DESCR("Perform a crash dump on system panic"), 744 NULL, 0, &dumponpanic, 0, 745 CTL_KERN, KERN_DUMP_ON_PANIC, CTL_EOL); 746#ifdef DIAGNOSTIC 747 sysctl_createv(clog, 0, NULL, NULL, 748 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 749 CTLTYPE_INT, "panic_now", 750 SYSCTL_DESCR("Trigger a panic"), 751 sysctl_kern_trigger_panic, 0, NULL, 0, 752 CTL_KERN, CTL_CREATE, CTL_EOL); 753#endif 754 sysctl_createv(clog, 0, NULL, NULL, 755 CTLFLAG_PERMANENT, 756 CTLTYPE_INT, "root_partition", 757 SYSCTL_DESCR("Root partition on the root device"), 758 sysctl_kern_root_partition, 0, NULL, 0, 759 CTL_KERN, KERN_ROOT_PARTITION, CTL_EOL); 760 sysctl_createv(clog, 0, NULL, NULL, 761 CTLFLAG_PERMANENT, 762 CTLTYPE_STRUCT, "drivers", 763 SYSCTL_DESCR("List of all drivers with block and " 764 "character device numbers"), 765 sysctl_kern_drivers, 0, NULL, 0, 766 CTL_KERN, KERN_DRIVERS, CTL_EOL); 767 sysctl_createv(clog, 0, NULL, NULL, 768 CTLFLAG_PERMANENT, 769 CTLTYPE_STRUCT, "file2", 770 SYSCTL_DESCR("System open file table"), 771 sysctl_kern_file2, 0, NULL, 0, 772 CTL_KERN, KERN_FILE2, CTL_EOL); 773#ifdef VERIFIED_EXEC 774 sysctl_createv(clog, 0, NULL, NULL, 775 CTLFLAG_PERMANENT, 776 CTLTYPE_NODE, "veriexec", 777 SYSCTL_DESCR("Verified Exec"), 778 NULL, 0, NULL, 0, 779 CTL_KERN, KERN_VERIEXEC, CTL_EOL); 780 sysctl_createv(clog, 0, NULL, NULL, 781 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 782 CTLTYPE_INT, "verbose", 783 SYSCTL_DESCR("Verified Exec verbose level"), 784 NULL, 0, &veriexec_verbose, 0, 785 CTL_KERN, KERN_VERIEXEC, VERIEXEC_VERBOSE, 786 CTL_EOL); 787 sysctl_createv(clog, 0, NULL, NULL, 788 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 789 CTLTYPE_INT, "strict", 790 SYSCTL_DESCR("Verified Exec strict level"), 791 sysctl_kern_veriexec, 0, NULL, 0, 792 CTL_KERN, KERN_VERIEXEC, VERIEXEC_STRICT, CTL_EOL); 793 sysctl_createv(clog, 0, NULL, NULL, 794 CTLFLAG_PERMANENT, 795 CTLTYPE_STRING, "algorithms", 796 SYSCTL_DESCR("Verified Exec supported hashing " 797 "algorithms"), 798 sysctl_kern_veriexec, 0, NULL, 0, 799 CTL_KERN, KERN_VERIEXEC, VERIEXEC_ALGORITHMS, CTL_EOL); 800 sysctl_createv(clog, 0, NULL, &veriexec_count_node, 801 CTLFLAG_PERMANENT, 802 CTLTYPE_NODE, "count", 803 SYSCTL_DESCR("Number of fingerprints on device(s)"), 804 NULL, 0, NULL, 0, 805 CTL_KERN, KERN_VERIEXEC, VERIEXEC_COUNT, CTL_EOL); 806#endif /* VERIFIED_EXEC */ 807 sysctl_createv(clog, 0, NULL, NULL, 808 CTLFLAG_PERMANENT, 809 CTLTYPE_STRUCT, "cp_id", 810 SYSCTL_DESCR("Mapping of CPU number to CPU id"), 811 sysctl_kern_cpid, 0, NULL, 0, 812 CTL_KERN, KERN_CP_ID, CTL_EOL); 813} 814 815SYSCTL_SETUP(sysctl_kern_proc_setup, 816 "sysctl kern.proc/proc2/proc_args subtree setup") 817{ 818 819 sysctl_createv(clog, 0, NULL, NULL, 820 CTLFLAG_PERMANENT, 821 CTLTYPE_NODE, "kern", NULL, 822 NULL, 0, NULL, 0, 823 CTL_KERN, CTL_EOL); 824 825 sysctl_createv(clog, 0, NULL, NULL, 826 CTLFLAG_PERMANENT, 827 CTLTYPE_NODE, "proc", 828 SYSCTL_DESCR("System-wide process information"), 829 sysctl_doeproc, 0, NULL, 0, 830 CTL_KERN, KERN_PROC, CTL_EOL); 831 sysctl_createv(clog, 0, NULL, NULL, 832 CTLFLAG_PERMANENT, 833 CTLTYPE_NODE, "proc2", 834 SYSCTL_DESCR("Machine-independent process information"), 835 sysctl_doeproc, 0, NULL, 0, 836 CTL_KERN, KERN_PROC2, CTL_EOL); 837 sysctl_createv(clog, 0, NULL, NULL, 838 CTLFLAG_PERMANENT, 839 CTLTYPE_NODE, "proc_args", 840 SYSCTL_DESCR("Process argument information"), 841 sysctl_kern_proc_args, 0, NULL, 0, 842 CTL_KERN, KERN_PROC_ARGS, CTL_EOL); 843 844 /* 845 "nodes" under these: 846 847 KERN_PROC_ALL 848 KERN_PROC_PID pid 849 KERN_PROC_PGRP pgrp 850 KERN_PROC_SESSION sess 851 KERN_PROC_TTY tty 852 KERN_PROC_UID uid 853 KERN_PROC_RUID uid 854 KERN_PROC_GID gid 855 KERN_PROC_RGID gid 856 857 all in all, probably not worth the effort... 858 */ 859} 860 861SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup") 862{ 863 u_int u; 864 u_quad_t q; 865 866 sysctl_createv(clog, 0, NULL, NULL, 867 CTLFLAG_PERMANENT, 868 CTLTYPE_NODE, "hw", NULL, 869 NULL, 0, NULL, 0, 870 CTL_HW, CTL_EOL); 871 872 sysctl_createv(clog, 0, NULL, NULL, 873 CTLFLAG_PERMANENT, 874 CTLTYPE_STRING, "machine", 875 SYSCTL_DESCR("Machine class"), 876 NULL, 0, machine, 0, 877 CTL_HW, HW_MACHINE, CTL_EOL); 878 sysctl_createv(clog, 0, NULL, NULL, 879 CTLFLAG_PERMANENT, 880 CTLTYPE_STRING, "model", 881 SYSCTL_DESCR("Machine model"), 882 NULL, 0, cpu_model, 0, 883 CTL_HW, HW_MODEL, CTL_EOL); 884 sysctl_createv(clog, 0, NULL, NULL, 885 CTLFLAG_PERMANENT, 886 CTLTYPE_INT, "ncpu", 887 SYSCTL_DESCR("Number of active CPUs"), 888 sysctl_hw_ncpu, 0, NULL, 0, 889 CTL_HW, HW_NCPU, CTL_EOL); 890 sysctl_createv(clog, 0, NULL, NULL, 891 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 892 CTLTYPE_INT, "byteorder", 893 SYSCTL_DESCR("System byte order"), 894 NULL, BYTE_ORDER, NULL, 0, 895 CTL_HW, HW_BYTEORDER, CTL_EOL); 896 u = ((u_int)physmem > (UINT_MAX / PAGE_SIZE)) ? 897 UINT_MAX : physmem * PAGE_SIZE; 898 sysctl_createv(clog, 0, NULL, NULL, 899 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 900 CTLTYPE_INT, "physmem", 901 SYSCTL_DESCR("Bytes of physical memory"), 902 NULL, u, NULL, 0, 903 CTL_HW, HW_PHYSMEM, CTL_EOL); 904 sysctl_createv(clog, 0, NULL, NULL, 905 CTLFLAG_PERMANENT, 906 CTLTYPE_INT, "usermem", 907 SYSCTL_DESCR("Bytes of non-kernel memory"), 908 sysctl_hw_usermem, 0, NULL, 0, 909 CTL_HW, HW_USERMEM, CTL_EOL); 910 sysctl_createv(clog, 0, NULL, NULL, 911 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 912 CTLTYPE_INT, "pagesize", 913 SYSCTL_DESCR("Software page size"), 914 NULL, PAGE_SIZE, NULL, 0, 915 CTL_HW, HW_PAGESIZE, CTL_EOL); 916 sysctl_createv(clog, 0, NULL, NULL, 917 CTLFLAG_PERMANENT, 918 CTLTYPE_STRING, "machine_arch", 919 SYSCTL_DESCR("Machine CPU class"), 920 NULL, 0, machine_arch, 0, 921 CTL_HW, HW_MACHINE_ARCH, CTL_EOL); 922 sysctl_createv(clog, 0, NULL, NULL, 923 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 924 CTLTYPE_INT, "alignbytes", 925 SYSCTL_DESCR("Alignment constraint for all possible " 926 "data types"), 927 NULL, ALIGNBYTES, NULL, 0, 928 CTL_HW, HW_ALIGNBYTES, CTL_EOL); 929 sysctl_createv(clog, 0, NULL, NULL, 930 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX, 931 CTLTYPE_STRING, "cnmagic", 932 SYSCTL_DESCR("Console magic key sequence"), 933 sysctl_hw_cnmagic, 0, NULL, CNS_LEN, 934 CTL_HW, HW_CNMAGIC, CTL_EOL); 935 q = (u_quad_t)physmem * PAGE_SIZE; 936 sysctl_createv(clog, 0, NULL, NULL, 937 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 938 CTLTYPE_QUAD, "physmem64", 939 SYSCTL_DESCR("Bytes of physical memory"), 940 NULL, q, NULL, 0, 941 CTL_HW, HW_PHYSMEM64, CTL_EOL); 942 sysctl_createv(clog, 0, NULL, NULL, 943 CTLFLAG_PERMANENT, 944 CTLTYPE_QUAD, "usermem64", 945 SYSCTL_DESCR("Bytes of non-kernel memory"), 946 sysctl_hw_usermem, 0, NULL, 0, 947 CTL_HW, HW_USERMEM64, CTL_EOL); 948} 949 950#ifdef DEBUG 951/* 952 * Debugging related system variables. 953 */ 954struct ctldebug /* debug0, */ /* debug1, */ debug2, debug3, debug4; 955struct ctldebug debug5, debug6, debug7, debug8, debug9; 956struct ctldebug debug10, debug11, debug12, debug13, debug14; 957struct ctldebug debug15, debug16, debug17, debug18, debug19; 958static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 959 &debug0, &debug1, &debug2, &debug3, &debug4, 960 &debug5, &debug6, &debug7, &debug8, &debug9, 961 &debug10, &debug11, &debug12, &debug13, &debug14, 962 &debug15, &debug16, &debug17, &debug18, &debug19, 963}; 964 965/* 966 * this setup routine is a replacement for debug_sysctl() 967 * 968 * note that it creates several nodes per defined debug variable 969 */ 970SYSCTL_SETUP(sysctl_debug_setup, "sysctl debug subtree setup") 971{ 972 struct ctldebug *cdp; 973 char nodename[20]; 974 int i; 975 976 /* 977 * two ways here: 978 * 979 * the "old" way (debug.name -> value) which was emulated by 980 * the sysctl(8) binary 981 * 982 * the new way, which the sysctl(8) binary was actually using 983 984 node debug 985 node debug.0 986 string debug.0.name 987 int debug.0.value 988 int debug.name 989 990 */ 991 992 sysctl_createv(clog, 0, NULL, NULL, 993 CTLFLAG_PERMANENT, 994 CTLTYPE_NODE, "debug", NULL, 995 NULL, 0, NULL, 0, 996 CTL_DEBUG, CTL_EOL); 997 998 for (i = 0; i < CTL_DEBUG_MAXID; i++) { 999 cdp = debugvars[i]; 1000 if (cdp->debugname == NULL || cdp->debugvar == NULL) 1001 continue; 1002 1003 snprintf(nodename, sizeof(nodename), "debug%d", i); 1004 sysctl_createv(clog, 0, NULL, NULL, 1005 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 1006 CTLTYPE_NODE, nodename, NULL, 1007 NULL, 0, NULL, 0, 1008 CTL_DEBUG, i, CTL_EOL); 1009 sysctl_createv(clog, 0, NULL, NULL, 1010 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 1011 CTLTYPE_STRING, "name", NULL, 1012 /*XXXUNCONST*/ 1013 NULL, 0, __UNCONST(cdp->debugname), 0, 1014 CTL_DEBUG, i, CTL_DEBUG_NAME, CTL_EOL); 1015 sysctl_createv(clog, 0, NULL, NULL, 1016 CTLFLAG_PERMANENT|CTLFLAG_HIDDEN, 1017 CTLTYPE_INT, "value", NULL, 1018 NULL, 0, cdp->debugvar, 0, 1019 CTL_DEBUG, i, CTL_DEBUG_VALUE, CTL_EOL); 1020 sysctl_createv(clog, 0, NULL, NULL, 1021 CTLFLAG_PERMANENT, 1022 CTLTYPE_INT, cdp->debugname, NULL, 1023 NULL, 0, cdp->debugvar, 0, 1024 CTL_DEBUG, CTL_CREATE, CTL_EOL); 1025 } 1026} 1027#endif /* DEBUG */ 1028 1029SYSCTL_SETUP(sysctl_security_setup, "sysctl security subtree setup") 1030{ 1031 const struct sysctlnode *rnode = NULL; 1032 1033 sysctl_createv(clog, 0, NULL, &rnode, 1034 CTLFLAG_PERMANENT, 1035 CTLTYPE_NODE, "security", NULL, 1036 NULL, 0, NULL, 0, 1037 CTL_SECURITY, CTL_EOL); 1038 1039 sysctl_createv(clog, 0, &rnode, NULL, 1040 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1041 CTLTYPE_INT, "curtain", 1042 SYSCTL_DESCR("Curtain information about objects" 1043 " to users not owning them."), 1044 NULL, 0, &security_curtain, 0, 1045 CTL_CREATE, CTL_EOL); 1046 1047 sysctl_createv(clog, 0, &rnode, &rnode, 1048 CTLFLAG_PERMANENT, 1049 CTLTYPE_NODE, "setid_core", 1050 SYSCTL_DESCR("Set-id processes' coredump settings."), 1051 NULL, 0, NULL, 0, 1052 CTL_CREATE, CTL_EOL); 1053 sysctl_createv(clog, 0, &rnode, NULL, 1054 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1055 CTLTYPE_INT, "dump", 1056 SYSCTL_DESCR("Allow set-id processes to dump core."), 1057 sysctl_security_setidcore, 0, &security_setidcore_dump, 1058 sizeof(security_setidcore_dump), 1059 CTL_CREATE, CTL_EOL); 1060 sysctl_createv(clog, 0, &rnode, NULL, 1061 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1062 CTLTYPE_STRING, "path", 1063 SYSCTL_DESCR("Path pattern for set-id coredumps."), 1064 sysctl_security_setidcorename, 0, 1065 &security_setidcore_path, 1066 sizeof(security_setidcore_path), 1067 CTL_CREATE, CTL_EOL); 1068 sysctl_createv(clog, 0, &rnode, NULL, 1069 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1070 CTLTYPE_INT, "owner", 1071 SYSCTL_DESCR("Owner id for set-id processes' cores."), 1072 sysctl_security_setidcore, 0, &security_setidcore_owner, 1073 0, 1074 CTL_CREATE, CTL_EOL); 1075 sysctl_createv(clog, 0, &rnode, NULL, 1076 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1077 CTLTYPE_INT, "group", 1078 SYSCTL_DESCR("Group id for set-id processes' cores."), 1079 sysctl_security_setidcore, 0, &security_setidcore_group, 1080 0, 1081 CTL_CREATE, CTL_EOL); 1082 sysctl_createv(clog, 0, &rnode, NULL, 1083 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1084 CTLTYPE_INT, "mode", 1085 SYSCTL_DESCR("Mode for set-id processes' cores."), 1086 sysctl_security_setidcore, 0, &security_setidcore_mode, 1087 0, 1088 CTL_CREATE, CTL_EOL); 1089} 1090 1091/* 1092 * ******************************************************************** 1093 * section 2: private node-specific helper routines. 1094 * ******************************************************************** 1095 */ 1096 1097#ifdef DIAGNOSTIC 1098static int 1099sysctl_kern_trigger_panic(SYSCTLFN_ARGS) 1100{ 1101 int newtrig, error; 1102 struct sysctlnode node; 1103 1104 newtrig = 0; 1105 node = *rnode; 1106 node.sysctl_data = &newtrig; 1107 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1108 if (error || newp == NULL) 1109 return (error); 1110 1111 if (newtrig != 0) 1112 panic("Panic triggered"); 1113 1114 return (error); 1115} 1116#endif 1117 1118/* 1119 * sysctl helper routine for kern.maxvnodes. drain vnodes if 1120 * new value is lower than desiredvnodes and then calls reinit 1121 * routines that needs to adjust to the new value. 1122 */ 1123static int 1124sysctl_kern_maxvnodes(SYSCTLFN_ARGS) 1125{ 1126 int error, new_vnodes, old_vnodes; 1127 struct sysctlnode node; 1128 1129 new_vnodes = desiredvnodes; 1130 node = *rnode; 1131 node.sysctl_data = &new_vnodes; 1132 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1133 if (error || newp == NULL) 1134 return (error); 1135 1136 old_vnodes = desiredvnodes; 1137 desiredvnodes = new_vnodes; 1138 if (new_vnodes < old_vnodes) { 1139 error = vfs_drainvnodes(new_vnodes, l); 1140 if (error) { 1141 desiredvnodes = old_vnodes; 1142 return (error); 1143 } 1144 } 1145 vfs_reinit(); 1146 nchreinit(); 1147 1148 return (0); 1149} 1150 1151/* 1152 * sysctl helper routine for rtc_offset - set time after changes 1153 */ 1154static int 1155sysctl_kern_rtc_offset(SYSCTLFN_ARGS) 1156{ 1157 struct timespec ts, delta; 1158 int error, new_rtc_offset; 1159 struct sysctlnode node; 1160 1161 new_rtc_offset = rtc_offset; 1162 node = *rnode; 1163 node.sysctl_data = &new_rtc_offset; 1164 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1165 if (error || newp == NULL) 1166 return (error); 1167 1168 if (securelevel > 0) 1169 return (EPERM); 1170 if (rtc_offset == new_rtc_offset) 1171 return (0); 1172 1173 /* if we change the offset, adjust the time */ 1174 nanotime(&ts); 1175 delta.tv_sec = 60 * (new_rtc_offset - rtc_offset); 1176 delta.tv_nsec = 0; 1177 timespecadd(&ts, &delta, &ts); 1178 rtc_offset = new_rtc_offset; 1179 settime(l->l_proc, &ts); 1180 1181 return (0); 1182} 1183 1184/* 1185 * sysctl helper routine for kern.maxproc. ensures that the new 1186 * values are not too low or too high. 1187 */ 1188static int 1189sysctl_kern_maxproc(SYSCTLFN_ARGS) 1190{ 1191 int error, nmaxproc; 1192 struct sysctlnode node; 1193 1194 nmaxproc = maxproc; 1195 node = *rnode; 1196 node.sysctl_data = &nmaxproc; 1197 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1198 if (error || newp == NULL) 1199 return (error); 1200 1201 if (nmaxproc < 0 || nmaxproc >= PID_MAX) 1202 return (EINVAL); 1203#ifdef __HAVE_CPU_MAXPROC 1204 if (nmaxproc > cpu_maxproc()) 1205 return (EINVAL); 1206#endif 1207 maxproc = nmaxproc; 1208 1209 return (0); 1210} 1211 1212/* 1213 * sysctl helper routine for kern.securelevel. ensures that the value 1214 * only rises unless the caller has pid 1 (assumed to be init). 1215 */ 1216static int 1217sysctl_kern_securelevel(SYSCTLFN_ARGS) 1218{ 1219 int newsecurelevel, error; 1220 struct sysctlnode node; 1221 1222 newsecurelevel = securelevel; 1223 node = *rnode; 1224 node.sysctl_data = &newsecurelevel; 1225 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1226 if (error || newp == NULL) 1227 return (error); 1228 1229 if (newsecurelevel < securelevel && l && l->l_proc->p_pid != 1) 1230 return (EPERM); 1231 securelevel = newsecurelevel; 1232 1233 return (error); 1234} 1235 1236/* 1237 * sysctl helper function for kern.hostid. the hostid is a long, but 1238 * we export it as an int, so we need to give it a little help. 1239 */ 1240static int 1241sysctl_kern_hostid(SYSCTLFN_ARGS) 1242{ 1243 int error, inthostid; 1244 struct sysctlnode node; 1245 1246 inthostid = hostid; /* XXX assumes sizeof int <= sizeof long */ 1247 node = *rnode; 1248 node.sysctl_data = &inthostid; 1249 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1250 if (error || newp == NULL) 1251 return (error); 1252 1253 hostid = (unsigned)inthostid; 1254 1255 return (0); 1256} 1257 1258/* 1259 * sysctl helper function for kern.hostname and kern.domainnname. 1260 * resets the relevant recorded length when the underlying name is 1261 * changed. 1262 */ 1263static int 1264sysctl_setlen(SYSCTLFN_ARGS) 1265{ 1266 int error; 1267 1268 error = sysctl_lookup(SYSCTLFN_CALL(rnode)); 1269 if (error || newp == NULL) 1270 return (error); 1271 1272 switch (rnode->sysctl_num) { 1273 case KERN_HOSTNAME: 1274 hostnamelen = strlen((const char*)rnode->sysctl_data); 1275 break; 1276 case KERN_DOMAINNAME: 1277 domainnamelen = strlen((const char*)rnode->sysctl_data); 1278 break; 1279 } 1280 1281 return (0); 1282} 1283 1284/* 1285 * sysctl helper routine for kern.clockrate. assembles a struct on 1286 * the fly to be returned to the caller. 1287 */ 1288static int 1289sysctl_kern_clockrate(SYSCTLFN_ARGS) 1290{ 1291 struct clockinfo clkinfo; 1292 struct sysctlnode node; 1293 1294 clkinfo.tick = tick; 1295 clkinfo.tickadj = tickadj; 1296 clkinfo.hz = hz; 1297 clkinfo.profhz = profhz; 1298 clkinfo.stathz = stathz ? stathz : hz; 1299 1300 node = *rnode; 1301 node.sysctl_data = &clkinfo; 1302 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1303} 1304 1305 1306/* 1307 * sysctl helper routine for kern.file pseudo-subtree. 1308 */ 1309static int 1310sysctl_kern_file(SYSCTLFN_ARGS) 1311{ 1312 int error; 1313 size_t buflen; 1314 struct file *fp; 1315 char *start, *where; 1316 1317 start = where = oldp; 1318 buflen = *oldlenp; 1319 if (where == NULL) { 1320 /* 1321 * overestimate by 10 files 1322 */ 1323 *oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 1324 return (0); 1325 } 1326 1327 /* 1328 * first copyout filehead 1329 */ 1330 if (buflen < sizeof(filehead)) { 1331 *oldlenp = 0; 1332 return (0); 1333 } 1334 error = copyout(&filehead, where, sizeof(filehead)); 1335 if (error) 1336 return (error); 1337 buflen -= sizeof(filehead); 1338 where += sizeof(filehead); 1339 1340 /* 1341 * followed by an array of file structures 1342 */ 1343 LIST_FOREACH(fp, &filehead, f_list) { 1344 if (CURTAIN(l->l_proc->p_ucred->cr_uid, fp->f_cred->cr_uid)) 1345 continue; 1346 if (buflen < sizeof(struct file)) { 1347 *oldlenp = where - start; 1348 return (ENOMEM); 1349 } 1350 error = copyout(fp, where, sizeof(struct file)); 1351 if (error) 1352 return (error); 1353 buflen -= sizeof(struct file); 1354 where += sizeof(struct file); 1355 } 1356 *oldlenp = where - start; 1357 return (0); 1358} 1359 1360/* 1361 * sysctl helper routine for kern.autonicetime and kern.autoniceval. 1362 * asserts that the assigned value is in the correct range. 1363 */ 1364static int 1365sysctl_kern_autonice(SYSCTLFN_ARGS) 1366{ 1367 int error, t = 0; 1368 struct sysctlnode node; 1369 1370 node = *rnode; 1371 t = *(int*)node.sysctl_data; 1372 node.sysctl_data = &t; 1373 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1374 if (error || newp == NULL) 1375 return (error); 1376 1377 switch (node.sysctl_num) { 1378 case KERN_AUTONICETIME: 1379 if (t >= 0) 1380 autonicetime = t; 1381 break; 1382 case KERN_AUTONICEVAL: 1383 if (t < PRIO_MIN) 1384 t = PRIO_MIN; 1385 else if (t > PRIO_MAX) 1386 t = PRIO_MAX; 1387 autoniceval = t; 1388 break; 1389 } 1390 1391 return (0); 1392} 1393 1394/* 1395 * sysctl helper routine for kern.msgbufsize and kern.msgbuf. for the 1396 * former it merely checks the message buffer is set up. for the latter, 1397 * it also copies out the data if necessary. 1398 */ 1399static int 1400sysctl_msgbuf(SYSCTLFN_ARGS) 1401{ 1402 char *where = oldp; 1403 size_t len, maxlen; 1404 long beg, end; 1405 int error; 1406 1407 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { 1408 msgbufenabled = 0; 1409 return (ENXIO); 1410 } 1411 1412 switch (rnode->sysctl_num) { 1413 case KERN_MSGBUFSIZE: { 1414 struct sysctlnode node = *rnode; 1415 int msg_bufs = (int)msgbufp->msg_bufs; 1416 node.sysctl_data = &msg_bufs; 1417 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1418 } 1419 case KERN_MSGBUF: 1420 break; 1421 default: 1422 return (EOPNOTSUPP); 1423 } 1424 1425 if (newp != NULL) 1426 return (EPERM); 1427 1428 if (oldp == NULL) { 1429 /* always return full buffer size */ 1430 *oldlenp = msgbufp->msg_bufs; 1431 return (0); 1432 } 1433 1434 error = 0; 1435 maxlen = MIN(msgbufp->msg_bufs, *oldlenp); 1436 1437 /* 1438 * First, copy from the write pointer to the end of 1439 * message buffer. 1440 */ 1441 beg = msgbufp->msg_bufx; 1442 end = msgbufp->msg_bufs; 1443 while (maxlen > 0) { 1444 len = MIN(end - beg, maxlen); 1445 if (len == 0) 1446 break; 1447 error = copyout(&msgbufp->msg_bufc[beg], where, len); 1448 if (error) 1449 break; 1450 where += len; 1451 maxlen -= len; 1452 1453 /* 1454 * ... then, copy from the beginning of message buffer to 1455 * the write pointer. 1456 */ 1457 beg = 0; 1458 end = msgbufp->msg_bufx; 1459 } 1460 1461 return (error); 1462} 1463 1464/* 1465 * sysctl helper routine for kern.defcorename. in the case of a new 1466 * string being assigned, check that it's not a zero-length string. 1467 * (XXX the check in -current doesn't work, but do we really care?) 1468 */ 1469static int 1470sysctl_kern_defcorename(SYSCTLFN_ARGS) 1471{ 1472 int error; 1473 char *newcorename; 1474 struct sysctlnode node; 1475 1476 newcorename = PNBUF_GET(); 1477 node = *rnode; 1478 node.sysctl_data = &newcorename[0]; 1479 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 1480 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1481 if (error || newp == NULL) { 1482 goto done; 1483 } 1484 1485 /* 1486 * when sysctl_lookup() deals with a string, it's guaranteed 1487 * to come back nul terminated. so there. :) 1488 */ 1489 if (strlen(newcorename) == 0) { 1490 error = EINVAL; 1491 } else { 1492 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 1493 error = 0; 1494 } 1495done: 1496 PNBUF_PUT(newcorename); 1497 return error; 1498} 1499 1500/* 1501 * sysctl helper routine for kern.cp_time node. adds up cpu time 1502 * across all cpus. 1503 */ 1504static int 1505sysctl_kern_cptime(SYSCTLFN_ARGS) 1506{ 1507 struct sysctlnode node = *rnode; 1508 1509#ifndef MULTIPROCESSOR 1510 1511 if (namelen == 1) { 1512 if (name[0] != 0) 1513 return (ENOENT); 1514 /* 1515 * you're allowed to ask for the zero'th processor 1516 */ 1517 name++; 1518 namelen--; 1519 } 1520 node.sysctl_data = curcpu()->ci_schedstate.spc_cp_time; 1521 node.sysctl_size = sizeof(curcpu()->ci_schedstate.spc_cp_time); 1522 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1523 1524#else /* MULTIPROCESSOR */ 1525 1526 uint64_t *cp_time = NULL; 1527 int error, n = sysctl_ncpus(), i; 1528 struct cpu_info *ci; 1529 CPU_INFO_ITERATOR cii; 1530 1531 /* 1532 * if you specifically pass a buffer that is the size of the 1533 * sum, or if you are probing for the size, you get the "sum" 1534 * of cp_time (and the size thereof) across all processors. 1535 * 1536 * alternately, you can pass an additional mib number and get 1537 * cp_time for that particular processor. 1538 */ 1539 switch (namelen) { 1540 case 0: 1541 if (*oldlenp == sizeof(uint64_t) * CPUSTATES || oldp == NULL) { 1542 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 1543 n = -1; /* SUM */ 1544 } 1545 else { 1546 node.sysctl_size = n * sizeof(uint64_t) * CPUSTATES; 1547 n = -2; /* ALL */ 1548 } 1549 break; 1550 case 1: 1551 if (name[0] < 0 || name[0] >= n) 1552 return (ENOENT); /* ENOSUCHPROCESSOR */ 1553 node.sysctl_size = sizeof(uint64_t) * CPUSTATES; 1554 n = name[0]; 1555 /* 1556 * adjust these so that sysctl_lookup() will be happy 1557 */ 1558 name++; 1559 namelen--; 1560 break; 1561 default: 1562 return (EINVAL); 1563 } 1564 1565 cp_time = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL); 1566 if (cp_time == NULL) 1567 return (ENOMEM); 1568 node.sysctl_data = cp_time; 1569 memset(cp_time, 0, node.sysctl_size); 1570 1571 for (CPU_INFO_FOREACH(cii, ci)) { 1572 if (n <= 0) 1573 for (i = 0; i < CPUSTATES; i++) 1574 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 1575 /* 1576 * if a specific processor was requested and we just 1577 * did it, we're done here 1578 */ 1579 if (n == 0) 1580 break; 1581 /* 1582 * if doing "all", skip to next cp_time set for next processor 1583 */ 1584 if (n == -2) 1585 cp_time += CPUSTATES; 1586 /* 1587 * if we're doing a specific processor, we're one 1588 * processor closer 1589 */ 1590 if (n > 0) 1591 n--; 1592 } 1593 1594 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1595 free(node.sysctl_data, M_TEMP); 1596 return (error); 1597 1598#endif /* MULTIPROCESSOR */ 1599} 1600 1601#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 1602/* 1603 * sysctl helper routine for kern.sysvipc_info subtree. 1604 */ 1605 1606#define FILL_PERM(src, dst) do { \ 1607 (dst)._key = (src)._key; \ 1608 (dst).uid = (src).uid; \ 1609 (dst).gid = (src).gid; \ 1610 (dst).cuid = (src).cuid; \ 1611 (dst).cgid = (src).cgid; \ 1612 (dst).mode = (src).mode; \ 1613 (dst)._seq = (src)._seq; \ 1614} while (/*CONSTCOND*/ 0); 1615#define FILL_MSG(src, dst) do { \ 1616 FILL_PERM((src).msg_perm, (dst).msg_perm); \ 1617 (dst).msg_qnum = (src).msg_qnum; \ 1618 (dst).msg_qbytes = (src).msg_qbytes; \ 1619 (dst)._msg_cbytes = (src)._msg_cbytes; \ 1620 (dst).msg_lspid = (src).msg_lspid; \ 1621 (dst).msg_lrpid = (src).msg_lrpid; \ 1622 (dst).msg_stime = (src).msg_stime; \ 1623 (dst).msg_rtime = (src).msg_rtime; \ 1624 (dst).msg_ctime = (src).msg_ctime; \ 1625} while (/*CONSTCOND*/ 0) 1626#define FILL_SEM(src, dst) do { \ 1627 FILL_PERM((src).sem_perm, (dst).sem_perm); \ 1628 (dst).sem_nsems = (src).sem_nsems; \ 1629 (dst).sem_otime = (src).sem_otime; \ 1630 (dst).sem_ctime = (src).sem_ctime; \ 1631} while (/*CONSTCOND*/ 0) 1632#define FILL_SHM(src, dst) do { \ 1633 FILL_PERM((src).shm_perm, (dst).shm_perm); \ 1634 (dst).shm_segsz = (src).shm_segsz; \ 1635 (dst).shm_lpid = (src).shm_lpid; \ 1636 (dst).shm_cpid = (src).shm_cpid; \ 1637 (dst).shm_atime = (src).shm_atime; \ 1638 (dst).shm_dtime = (src).shm_dtime; \ 1639 (dst).shm_ctime = (src).shm_ctime; \ 1640 (dst).shm_nattch = (src).shm_nattch; \ 1641} while (/*CONSTCOND*/ 0) 1642 1643static int 1644sysctl_kern_sysvipc(SYSCTLFN_ARGS) 1645{ 1646 void *where = oldp; 1647 size_t *sizep = oldlenp; 1648#ifdef SYSVMSG 1649 struct msg_sysctl_info *msgsi = NULL; 1650#endif 1651#ifdef SYSVSEM 1652 struct sem_sysctl_info *semsi = NULL; 1653#endif 1654#ifdef SYSVSHM 1655 struct shm_sysctl_info *shmsi = NULL; 1656#endif 1657 size_t infosize, dssize, tsize, buflen; 1658 void *bf = NULL; 1659 char *start; 1660 int32_t nds; 1661 int i, error, ret; 1662 1663 if (namelen != 1) 1664 return (EINVAL); 1665 1666 start = where; 1667 buflen = *sizep; 1668 1669 switch (*name) { 1670 case KERN_SYSVIPC_MSG_INFO: 1671#ifdef SYSVMSG 1672 infosize = sizeof(msgsi->msginfo); 1673 nds = msginfo.msgmni; 1674 dssize = sizeof(msgsi->msgids[0]); 1675 break; 1676#else 1677 return (EINVAL); 1678#endif 1679 case KERN_SYSVIPC_SEM_INFO: 1680#ifdef SYSVSEM 1681 infosize = sizeof(semsi->seminfo); 1682 nds = seminfo.semmni; 1683 dssize = sizeof(semsi->semids[0]); 1684 break; 1685#else 1686 return (EINVAL); 1687#endif 1688 case KERN_SYSVIPC_SHM_INFO: 1689#ifdef SYSVSHM 1690 infosize = sizeof(shmsi->shminfo); 1691 nds = shminfo.shmmni; 1692 dssize = sizeof(shmsi->shmids[0]); 1693 break; 1694#else 1695 return (EINVAL); 1696#endif 1697 default: 1698 return (EINVAL); 1699 } 1700 /* 1701 * Round infosize to 64 bit boundary if requesting more than just 1702 * the info structure or getting the total data size. 1703 */ 1704 if (where == NULL || *sizep > infosize) 1705 infosize = ((infosize + 7) / 8) * 8; 1706 tsize = infosize + nds * dssize; 1707 1708 /* Return just the total size required. */ 1709 if (where == NULL) { 1710 *sizep = tsize; 1711 return (0); 1712 } 1713 1714 /* Not enough room for even the info struct. */ 1715 if (buflen < infosize) { 1716 *sizep = 0; 1717 return (ENOMEM); 1718 } 1719 bf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK); 1720 memset(bf, 0, min(tsize, buflen)); 1721 1722 switch (*name) { 1723#ifdef SYSVMSG 1724 case KERN_SYSVIPC_MSG_INFO: 1725 msgsi = (struct msg_sysctl_info *)bf; 1726 msgsi->msginfo = msginfo; 1727 break; 1728#endif 1729#ifdef SYSVSEM 1730 case KERN_SYSVIPC_SEM_INFO: 1731 semsi = (struct sem_sysctl_info *)bf; 1732 semsi->seminfo = seminfo; 1733 break; 1734#endif 1735#ifdef SYSVSHM 1736 case KERN_SYSVIPC_SHM_INFO: 1737 shmsi = (struct shm_sysctl_info *)bf; 1738 shmsi->shminfo = shminfo; 1739 break; 1740#endif 1741 } 1742 buflen -= infosize; 1743 1744 ret = 0; 1745 if (buflen > 0) { 1746 /* Fill in the IPC data structures. */ 1747 for (i = 0; i < nds; i++) { 1748 if (buflen < dssize) { 1749 ret = ENOMEM; 1750 break; 1751 } 1752 switch (*name) { 1753#ifdef SYSVMSG 1754 case KERN_SYSVIPC_MSG_INFO: 1755 FILL_MSG(msqids[i], msgsi->msgids[i]); 1756 break; 1757#endif 1758#ifdef SYSVSEM 1759 case KERN_SYSVIPC_SEM_INFO: 1760 FILL_SEM(sema[i], semsi->semids[i]); 1761 break; 1762#endif 1763#ifdef SYSVSHM 1764 case KERN_SYSVIPC_SHM_INFO: 1765 FILL_SHM(shmsegs[i], shmsi->shmids[i]); 1766 break; 1767#endif 1768 } 1769 buflen -= dssize; 1770 } 1771 } 1772 *sizep -= buflen; 1773 error = copyout(bf, start, *sizep); 1774 /* If copyout succeeded, use return code set earlier. */ 1775 if (error == 0) 1776 error = ret; 1777 if (bf) 1778 free(bf, M_TEMP); 1779 return (error); 1780} 1781 1782#undef FILL_PERM 1783#undef FILL_MSG 1784#undef FILL_SEM 1785#undef FILL_SHM 1786 1787#endif /* defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) */ 1788 1789#if NPTY > 0 1790/* 1791 * sysctl helper routine for kern.maxptys. ensures that any new value 1792 * is acceptable to the pty subsystem. 1793 */ 1794static int 1795sysctl_kern_maxptys(SYSCTLFN_ARGS) 1796{ 1797 int pty_maxptys(int, int); /* defined in kern/tty_pty.c */ 1798 int error, xmax; 1799 struct sysctlnode node; 1800 1801 /* get current value of maxptys */ 1802 xmax = pty_maxptys(0, 0); 1803 1804 node = *rnode; 1805 node.sysctl_data = &xmax; 1806 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1807 if (error || newp == NULL) 1808 return (error); 1809 1810 if (xmax != pty_maxptys(xmax, 1)) 1811 return (EINVAL); 1812 1813 return (0); 1814} 1815#endif /* NPTY > 0 */ 1816 1817/* 1818 * sysctl helper routine for kern.sbmax. basically just ensures that 1819 * any new value is not too small. 1820 */ 1821static int 1822sysctl_kern_sbmax(SYSCTLFN_ARGS) 1823{ 1824 int error, new_sbmax; 1825 struct sysctlnode node; 1826 1827 new_sbmax = sb_max; 1828 node = *rnode; 1829 node.sysctl_data = &new_sbmax; 1830 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1831 if (error || newp == NULL) 1832 return (error); 1833 1834 error = sb_max_set(new_sbmax); 1835 1836 return (error); 1837} 1838 1839/* 1840 * sysctl helper routine for kern.urandom node. picks a random number 1841 * for you. 1842 */ 1843static int 1844sysctl_kern_urnd(SYSCTLFN_ARGS) 1845{ 1846#if NRND > 0 1847 int v; 1848 1849 if (rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY) == sizeof(v)) { 1850 struct sysctlnode node = *rnode; 1851 node.sysctl_data = &v; 1852 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1853 } 1854 else 1855 return (EIO); /*XXX*/ 1856#else 1857 return (EOPNOTSUPP); 1858#endif 1859} 1860 1861/* 1862 * sysctl helper routine to do kern.lwp.* work. 1863 */ 1864static int 1865sysctl_kern_lwp(SYSCTLFN_ARGS) 1866{ 1867 struct kinfo_lwp klwp; 1868 struct proc *p; 1869 struct lwp *l2; 1870 char *where, *dp; 1871 int pid, elem_size, elem_count; 1872 int buflen, needed, error; 1873 1874 if (namelen == 1 && name[0] == CTL_QUERY) 1875 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1876 1877 dp = where = oldp; 1878 buflen = where != NULL ? *oldlenp : 0; 1879 error = needed = 0; 1880 1881 if (newp != NULL || namelen != 3) 1882 return (EINVAL); 1883 pid = name[0]; 1884 elem_size = name[1]; 1885 elem_count = name[2]; 1886 1887 p = pfind(pid); 1888 if (p == NULL) 1889 return (ESRCH); 1890 LIST_FOREACH(l2, &p->p_lwps, l_sibling) { 1891 if (buflen >= elem_size && elem_count > 0) { 1892 fill_lwp(l2, &klwp); 1893 /* 1894 * Copy out elem_size, but not larger than 1895 * the size of a struct kinfo_proc2. 1896 */ 1897 error = copyout(&klwp, dp, 1898 min(sizeof(klwp), elem_size)); 1899 if (error) 1900 goto cleanup; 1901 dp += elem_size; 1902 buflen -= elem_size; 1903 elem_count--; 1904 } 1905 needed += elem_size; 1906 } 1907 1908 if (where != NULL) { 1909 *oldlenp = dp - where; 1910 if (needed > *oldlenp) 1911 return (ENOMEM); 1912 } else { 1913 needed += KERN_LWPSLOP; 1914 *oldlenp = needed; 1915 } 1916 return (0); 1917 cleanup: 1918 return (error); 1919} 1920 1921/* 1922 * sysctl helper routine for kern.forkfsleep node. ensures that the 1923 * given value is not too large or two small, and is at least one 1924 * timer tick if not zero. 1925 */ 1926static int 1927sysctl_kern_forkfsleep(SYSCTLFN_ARGS) 1928{ 1929 /* userland sees value in ms, internally is in ticks */ 1930 extern int forkfsleep; /* defined in kern/kern_fork.c */ 1931 int error, timo, lsleep; 1932 struct sysctlnode node; 1933 1934 lsleep = forkfsleep * 1000 / hz; 1935 node = *rnode; 1936 node.sysctl_data = &lsleep; 1937 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1938 if (error || newp == NULL) 1939 return (error); 1940 1941 /* refuse negative values, and overly 'long time' */ 1942 if (lsleep < 0 || lsleep > MAXSLP * 1000) 1943 return (EINVAL); 1944 1945 timo = mstohz(lsleep); 1946 1947 /* if the interval is >0 ms && <1 tick, use 1 tick */ 1948 if (lsleep != 0 && timo == 0) 1949 forkfsleep = 1; 1950 else 1951 forkfsleep = timo; 1952 1953 return (0); 1954} 1955 1956/* 1957 * sysctl helper routine for kern.root_partition 1958 */ 1959static int 1960sysctl_kern_root_partition(SYSCTLFN_ARGS) 1961{ 1962 int rootpart = DISKPART(rootdev); 1963 struct sysctlnode node = *rnode; 1964 1965 node.sysctl_data = &rootpart; 1966 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1967} 1968 1969/* 1970 * sysctl helper function for kern.drivers 1971 */ 1972static int 1973sysctl_kern_drivers(SYSCTLFN_ARGS) 1974{ 1975 int error; 1976 size_t buflen; 1977 struct kinfo_drivers kd; 1978 char *start, *where; 1979 const char *dname; 1980 int i; 1981 extern struct devsw_conv *devsw_conv; 1982 extern int max_devsw_convs; 1983 1984 if (newp != NULL || namelen != 0) 1985 return (EINVAL); 1986 1987 start = where = oldp; 1988 buflen = *oldlenp; 1989 if (where == NULL) { 1990 *oldlenp = max_devsw_convs * sizeof kd; 1991 return 0; 1992 } 1993 1994 /* 1995 * An array of kinfo_drivers structures 1996 */ 1997 error = 0; 1998 for (i = 0; i < max_devsw_convs; i++) { 1999 dname = devsw_conv[i].d_name; 2000 if (dname == NULL) 2001 continue; 2002 if (buflen < sizeof kd) { 2003 error = ENOMEM; 2004 break; 2005 } 2006 memset(&kd, 0, sizeof(kd)); 2007 kd.d_bmajor = devsw_conv[i].d_bmajor; 2008 kd.d_cmajor = devsw_conv[i].d_cmajor; 2009 strlcpy(kd.d_name, dname, sizeof kd.d_name); 2010 error = copyout(&kd, where, sizeof kd); 2011 if (error != 0) 2012 break; 2013 buflen -= sizeof kd; 2014 where += sizeof kd; 2015 } 2016 *oldlenp = where - start; 2017 return error; 2018} 2019 2020/* 2021 * sysctl helper function for kern.file2 2022 */ 2023static int 2024sysctl_kern_file2(SYSCTLFN_ARGS) 2025{ 2026 struct proc *p; 2027 struct file *fp; 2028 struct filedesc *fd; 2029 struct kinfo_file kf; 2030 char *dp; 2031 u_int i, op; 2032 size_t len, needed, elem_size, out_size; 2033 int error, arg, elem_count; 2034 2035 if (namelen == 1 && name[0] == CTL_QUERY) 2036 return (sysctl_query(SYSCTLFN_CALL(rnode))); 2037 2038 if (namelen != 4) 2039 return (EINVAL); 2040 2041 error = 0; 2042 dp = oldp; 2043 len = (oldp != NULL) ? *oldlenp : 0; 2044 op = name[0]; 2045 arg = name[1]; 2046 elem_size = name[2]; 2047 elem_count = name[3]; 2048 out_size = MIN(sizeof(kf), elem_size); 2049 needed = 0; 2050 2051 if (elem_size < 1 || elem_count < 0) 2052 return (EINVAL); 2053 2054 switch (op) { 2055 case KERN_FILE_BYFILE: 2056 /* 2057 * doesn't use arg so it must be zero 2058 */ 2059 if (arg != 0) 2060 return (EINVAL); 2061 LIST_FOREACH(fp, &filehead, f_list) { 2062 if (CURTAIN(l->l_proc->p_ucred->cr_uid, 2063 fp->f_cred->cr_uid)) 2064 continue; 2065 if (len >= elem_size && elem_count > 0) { 2066 fill_file(&kf, fp, NULL, 0); 2067 error = copyout(&kf, dp, out_size); 2068 if (error) 2069 break; 2070 dp += elem_size; 2071 len -= elem_size; 2072 } 2073 if (elem_count > 0) { 2074 needed += elem_size; 2075 if (elem_count != INT_MAX) 2076 elem_count--; 2077 } 2078 } 2079 break; 2080 case KERN_FILE_BYPID: 2081 if (arg < -1) 2082 /* -1 means all processes */ 2083 return (EINVAL); 2084 proclist_lock_read(); 2085 PROCLIST_FOREACH(p, &allproc) { 2086 if (p->p_stat == SIDL) 2087 /* skip embryonic processes */ 2088 continue; 2089 if (CURTAIN(l->l_proc->p_ucred->cr_uid, 2090 p->p_ucred->cr_uid)) 2091 continue; 2092 if (arg > 0 && p->p_pid != arg) 2093 /* pick only the one we want */ 2094 /* XXX want 0 to mean "kernel files" */ 2095 continue; 2096 fd = p->p_fd; 2097 for (i = 0; i < fd->fd_nfiles; i++) { 2098 fp = fd->fd_ofiles[i]; 2099 if (fp == NULL || !FILE_IS_USABLE(fp)) 2100 continue; 2101 if (len >= elem_size && elem_count > 0) { 2102 fill_file(&kf, fd->fd_ofiles[i], 2103 p, i); 2104 error = copyout(&kf, dp, out_size); 2105 if (error) 2106 break; 2107 dp += elem_size; 2108 len -= elem_size; 2109 } 2110 if (elem_count > 0) { 2111 needed += elem_size; 2112 if (elem_count != INT_MAX) 2113 elem_count--; 2114 } 2115 } 2116 } 2117 proclist_unlock_read(); 2118 break; 2119 default: 2120 return (EINVAL); 2121 } 2122 2123 if (oldp == NULL) 2124 needed += KERN_FILESLOP * elem_size; 2125 *oldlenp = needed; 2126 2127 return (error); 2128} 2129 2130static void 2131fill_file(struct kinfo_file *kp, const struct file *fp, struct proc *p, int i) 2132{ 2133 2134 memset(kp, 0, sizeof(*kp)); 2135 2136 kp->ki_fileaddr = PTRTOUINT64(fp); 2137 kp->ki_flag = fp->f_flag; 2138 kp->ki_iflags = fp->f_iflags; 2139 kp->ki_ftype = fp->f_type; 2140 kp->ki_count = fp->f_count; 2141 kp->ki_msgcount = fp->f_msgcount; 2142 kp->ki_usecount = fp->f_usecount; 2143 kp->ki_fucred = PTRTOUINT64(fp->f_cred); 2144 kp->ki_fuid = fp->f_cred->cr_uid; 2145 kp->ki_fgid = fp->f_cred->cr_gid; 2146 kp->ki_fops = PTRTOUINT64(fp->f_ops); 2147 kp->ki_foffset = fp->f_offset; 2148 kp->ki_fdata = PTRTOUINT64(fp->f_data); 2149 2150 /* vnode information to glue this file to something */ 2151 if (fp->f_type == DTYPE_VNODE) { 2152 struct vnode *vp = (struct vnode *)fp->f_data; 2153 2154 kp->ki_vun = PTRTOUINT64(vp->v_un.vu_socket); 2155 kp->ki_vsize = vp->v_size; 2156 kp->ki_vtype = vp->v_type; 2157 kp->ki_vtag = vp->v_tag; 2158 kp->ki_vdata = PTRTOUINT64(vp->v_data); 2159 } 2160 2161 /* process information when retrieved via KERN_FILE_BYPID */ 2162 if (p) { 2163 kp->ki_pid = p->p_pid; 2164 kp->ki_fd = i; 2165 kp->ki_ofileflags = p->p_fd->fd_ofileflags[i]; 2166 } 2167} 2168 2169static int 2170sysctl_doeproc(SYSCTLFN_ARGS) 2171{ 2172 struct eproc eproc; 2173 struct kinfo_proc2 kproc2; 2174 struct kinfo_proc *dp; 2175 struct proc *p; 2176 const struct proclist_desc *pd; 2177 char *where, *dp2; 2178 int type, op, arg; 2179 u_int elem_size, elem_count; 2180 size_t buflen, needed; 2181 int error; 2182 2183 if (namelen == 1 && name[0] == CTL_QUERY) 2184 return (sysctl_query(SYSCTLFN_CALL(rnode))); 2185 2186 dp = oldp; 2187 dp2 = where = oldp; 2188 buflen = where != NULL ? *oldlenp : 0; 2189 error = 0; 2190 needed = 0; 2191 type = rnode->sysctl_num; 2192 2193 if (type == KERN_PROC) { 2194 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL)) 2195 return (EINVAL); 2196 op = name[0]; 2197 if (op != KERN_PROC_ALL) 2198 arg = name[1]; 2199 else 2200 arg = 0; /* Quell compiler warning */ 2201 elem_size = elem_count = 0; /* Ditto */ 2202 } else { 2203 if (namelen != 4) 2204 return (EINVAL); 2205 op = name[0]; 2206 arg = name[1]; 2207 elem_size = name[2]; 2208 elem_count = name[3]; 2209 } 2210 2211 proclist_lock_read(); 2212 2213 pd = proclists; 2214again: 2215 PROCLIST_FOREACH(p, pd->pd_list) { 2216 /* 2217 * Skip embryonic processes. 2218 */ 2219 if (p->p_stat == SIDL) 2220 continue; 2221 2222 if (CURTAIN(l->l_proc->p_ucred->cr_uid, p->p_ucred->cr_uid)) 2223 continue; 2224 2225 /* 2226 * TODO - make more efficient (see notes below). 2227 * do by session. 2228 */ 2229 switch (op) { 2230 2231 case KERN_PROC_PID: 2232 /* could do this with just a lookup */ 2233 if (p->p_pid != (pid_t)arg) 2234 continue; 2235 break; 2236 2237 case KERN_PROC_PGRP: 2238 /* could do this by traversing pgrp */ 2239 if (p->p_pgrp->pg_id != (pid_t)arg) 2240 continue; 2241 break; 2242 2243 case KERN_PROC_SESSION: 2244 if (p->p_session->s_sid != (pid_t)arg) 2245 continue; 2246 break; 2247 2248 case KERN_PROC_TTY: 2249 if (arg == (int) KERN_PROC_TTY_REVOKE) { 2250 if ((p->p_flag & P_CONTROLT) == 0 || 2251 p->p_session->s_ttyp == NULL || 2252 p->p_session->s_ttyvp != NULL) 2253 continue; 2254 } else if ((p->p_flag & P_CONTROLT) == 0 || 2255 p->p_session->s_ttyp == NULL) { 2256 if ((dev_t)arg != KERN_PROC_TTY_NODEV) 2257 continue; 2258 } else if (p->p_session->s_ttyp->t_dev != (dev_t)arg) 2259 continue; 2260 break; 2261 2262 case KERN_PROC_UID: 2263 if (p->p_ucred->cr_uid != (uid_t)arg) 2264 continue; 2265 break; 2266 2267 case KERN_PROC_RUID: 2268 if (p->p_cred->p_ruid != (uid_t)arg) 2269 continue; 2270 break; 2271 2272 case KERN_PROC_GID: 2273 if (p->p_ucred->cr_gid != (uid_t)arg) 2274 continue; 2275 break; 2276 2277 case KERN_PROC_RGID: 2278 if (p->p_cred->p_rgid != (uid_t)arg) 2279 continue; 2280 break; 2281 2282 case KERN_PROC_ALL: 2283 /* allow everything */ 2284 break; 2285 2286 default: 2287 error = EINVAL; 2288 goto cleanup; 2289 } 2290 if (type == KERN_PROC) { 2291 if (buflen >= sizeof(struct kinfo_proc)) { 2292 fill_eproc(p, &eproc); 2293 error = copyout(p, &dp->kp_proc, 2294 sizeof(struct proc)); 2295 if (error) 2296 goto cleanup; 2297 error = copyout(&eproc, &dp->kp_eproc, 2298 sizeof(eproc)); 2299 if (error) 2300 goto cleanup; 2301 dp++; 2302 buflen -= sizeof(struct kinfo_proc); 2303 } 2304 needed += sizeof(struct kinfo_proc); 2305 } else { /* KERN_PROC2 */ 2306 if (buflen >= elem_size && elem_count > 0) { 2307 fill_kproc2(p, &kproc2); 2308 /* 2309 * Copy out elem_size, but not larger than 2310 * the size of a struct kinfo_proc2. 2311 */ 2312 error = copyout(&kproc2, dp2, 2313 min(sizeof(kproc2), elem_size)); 2314 if (error) 2315 goto cleanup; 2316 dp2 += elem_size; 2317 buflen -= elem_size; 2318 elem_count--; 2319 } 2320 needed += elem_size; 2321 } 2322 } 2323 pd++; 2324 if (pd->pd_list != NULL) 2325 goto again; 2326 proclist_unlock_read(); 2327 2328 if (where != NULL) { 2329 if (type == KERN_PROC) 2330 *oldlenp = (char *)dp - where; 2331 else 2332 *oldlenp = dp2 - where; 2333 if (needed > *oldlenp) 2334 return (ENOMEM); 2335 } else { 2336 needed += KERN_PROCSLOP; 2337 *oldlenp = needed; 2338 } 2339 return (0); 2340 cleanup: 2341 proclist_unlock_read(); 2342 return (error); 2343} 2344 2345/* 2346 * sysctl helper routine for kern.proc_args pseudo-subtree. 2347 */ 2348static int 2349sysctl_kern_proc_args(SYSCTLFN_ARGS) 2350{ 2351 struct ps_strings pss; 2352 struct proc *p, *up = l->l_proc; 2353 size_t len, upper_bound, xlen, i; 2354 struct uio auio; 2355 struct iovec aiov; 2356 vaddr_t argv; 2357 pid_t pid; 2358 int nargv, type, error; 2359 char *arg; 2360 char *tmp; 2361 struct vmspace *vmspace; 2362 vaddr_t psstr_addr; 2363 vaddr_t offsetn; 2364 vaddr_t offsetv; 2365 2366 if (namelen == 1 && name[0] == CTL_QUERY) 2367 return (sysctl_query(SYSCTLFN_CALL(rnode))); 2368 2369 if (newp != NULL || namelen != 2) 2370 return (EINVAL); 2371 pid = name[0]; 2372 type = name[1]; 2373 2374 switch (type) { 2375 case KERN_PROC_ARGV: 2376 case KERN_PROC_NARGV: 2377 case KERN_PROC_ENV: 2378 case KERN_PROC_NENV: 2379 /* ok */ 2380 break; 2381 default: 2382 return (EINVAL); 2383 } 2384 2385 proclist_lock_read(); 2386 2387 /* check pid */ 2388 if ((p = p_find(pid, PFIND_LOCKED)) == NULL) { 2389 error = EINVAL; 2390 goto out_locked; 2391 } 2392 2393 if (CURTAIN(l->l_proc->p_ucred->cr_uid, p->p_ucred->cr_uid)) { 2394 error = EPERM; 2395 goto out_locked; 2396 } 2397 2398 /* only root or same user change look at the environment */ 2399 if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) { 2400 if (up->p_ucred->cr_uid != 0) { 2401 if (up->p_cred->p_ruid != p->p_cred->p_ruid || 2402 up->p_cred->p_ruid != p->p_cred->p_svuid) { 2403 error = EPERM; 2404 goto out_locked; 2405 } 2406 } 2407 } 2408 2409 if (oldp == NULL) { 2410 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) 2411 *oldlenp = sizeof (int); 2412 else 2413 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 2414 error = 0; 2415 goto out_locked; 2416 } 2417 2418 /* 2419 * Zombies don't have a stack, so we can't read their psstrings. 2420 * System processes also don't have a user stack. 2421 */ 2422 if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) { 2423 error = EINVAL; 2424 goto out_locked; 2425 } 2426 2427 /* 2428 * Lock the process down in memory. 2429 */ 2430 /* XXXCDC: how should locking work here? */ 2431 if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) { 2432 error = EFAULT; 2433 goto out_locked; 2434 } 2435 2436 psstr_addr = (vaddr_t)p->p_psstr; 2437 if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) { 2438 offsetn = p->p_psnargv; 2439 offsetv = p->p_psargv; 2440 } else { 2441 offsetn = p->p_psnenv; 2442 offsetv = p->p_psenv; 2443 } 2444 vmspace = p->p_vmspace; 2445 vmspace->vm_refcnt++; /* XXX */ 2446 2447 proclist_unlock_read(); 2448 2449 /* 2450 * Allocate a temporary buffer to hold the arguments. 2451 */ 2452 arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 2453 2454 /* 2455 * Read in the ps_strings structure. 2456 */ 2457 aiov.iov_base = &pss; 2458 aiov.iov_len = sizeof(pss); 2459 auio.uio_iov = &aiov; 2460 auio.uio_iovcnt = 1; 2461 auio.uio_offset = psstr_addr; 2462 auio.uio_resid = sizeof(pss); 2463 auio.uio_rw = UIO_READ; 2464 UIO_SETUP_SYSSPACE(&auio); 2465 error = uvm_io(&vmspace->vm_map, &auio); 2466 if (error) 2467 goto done; 2468 2469 memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv)); 2470 if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) { 2471 error = copyout(&nargv, oldp, sizeof(nargv)); 2472 *oldlenp = sizeof(nargv); 2473 goto done; 2474 } 2475 /* 2476 * Now read the address of the argument vector. 2477 */ 2478 switch (type) { 2479 case KERN_PROC_ARGV: 2480 /* XXX compat32 stuff here */ 2481 /* FALLTHROUGH */ 2482 case KERN_PROC_ENV: 2483 memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp)); 2484 break; 2485 default: 2486 return (EINVAL); 2487 } 2488 auio.uio_offset = (off_t)(unsigned long)tmp; 2489 aiov.iov_base = &argv; 2490 aiov.iov_len = sizeof(argv); 2491 auio.uio_iov = &aiov; 2492 auio.uio_iovcnt = 1; 2493 auio.uio_resid = sizeof(argv); 2494 auio.uio_rw = UIO_READ; 2495 UIO_SETUP_SYSSPACE(&auio); 2496 error = uvm_io(&vmspace->vm_map, &auio); 2497 if (error) 2498 goto done; 2499 2500 /* 2501 * Now copy in the actual argument vector, one page at a time, 2502 * since we don't know how long the vector is (though, we do 2503 * know how many NUL-terminated strings are in the vector). 2504 */ 2505 len = 0; 2506 upper_bound = *oldlenp; 2507 for (; nargv != 0 && len < upper_bound; len += xlen) { 2508 aiov.iov_base = arg; 2509 aiov.iov_len = PAGE_SIZE; 2510 auio.uio_iov = &aiov; 2511 auio.uio_iovcnt = 1; 2512 auio.uio_offset = argv + len; 2513 xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK); 2514 auio.uio_resid = xlen; 2515 auio.uio_rw = UIO_READ; 2516 UIO_SETUP_SYSSPACE(&auio); 2517 error = uvm_io(&vmspace->vm_map, &auio); 2518 if (error) 2519 goto done; 2520 2521 for (i = 0; i < xlen && nargv != 0; i++) { 2522 if (arg[i] == '\0') 2523 nargv--; /* one full string */ 2524 } 2525 2526 /* 2527 * Make sure we don't copyout past the end of the user's 2528 * buffer. 2529 */ 2530 if (len + i > upper_bound) 2531 i = upper_bound - len; 2532 2533 error = copyout(arg, (char *)oldp + len, i); 2534 if (error) 2535 break; 2536 2537 if (nargv == 0) { 2538 len += i; 2539 break; 2540 } 2541 } 2542 *oldlenp = len; 2543 2544done: 2545 uvmspace_free(vmspace); 2546 2547 free(arg, M_TEMP); 2548 return error; 2549 2550out_locked: 2551 proclist_unlock_read(); 2552 return error; 2553} 2554 2555/* 2556 * Sysctl helper routine for Verified Exec. 2557 */ 2558#ifdef VERIFIED_EXEC 2559static int 2560sysctl_kern_veriexec(SYSCTLFN_ARGS) 2561{ 2562 int newval, error; 2563 int *var = NULL, raise_only = 0; 2564 struct sysctlnode node; 2565 2566 node = *rnode; 2567 2568 switch (rnode->sysctl_num) { 2569 case VERIEXEC_STRICT: 2570 raise_only = 1; 2571 var = &veriexec_strict; 2572 break; 2573 case VERIEXEC_ALGORITHMS: 2574 node.sysctl_data = veriexec_fp_names; 2575 node.sysctl_size = strlen(veriexec_fp_names) + 1; 2576 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2577 default: 2578 return (EINVAL); 2579 } 2580 2581 newval = *var; 2582 2583 node.sysctl_data = &newval; 2584 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2585 if (error || newp == NULL) { 2586 return (error); 2587 } 2588 2589 if (raise_only && (newval < *var)) 2590 return (EPERM); 2591 2592 *var = newval; 2593 2594 return (error); 2595} 2596#endif /* VERIFIED_EXEC */ 2597 2598static int 2599sysctl_security_setidcore(SYSCTLFN_ARGS) 2600{ 2601 int newsize, error; 2602 struct sysctlnode node; 2603 2604 node = *rnode; 2605 node.sysctl_data = &newsize; 2606 newsize = *(int *)rnode->sysctl_data; 2607 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2608 if (error || newp == NULL) 2609 return error; 2610 2611 if (securelevel > 0) 2612 return (EPERM); 2613 2614 *(int *)rnode->sysctl_data = newsize; 2615 2616 return 0; 2617} 2618 2619static int 2620sysctl_security_setidcorename(SYSCTLFN_ARGS) 2621{ 2622 int error; 2623 char newsetidcorename[MAXPATHLEN]; 2624 struct sysctlnode node; 2625 2626 node = *rnode; 2627 node.sysctl_data = &newsetidcorename[0]; 2628 memcpy(node.sysctl_data, rnode->sysctl_data, MAXPATHLEN); 2629 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2630 if (error || newp == NULL) 2631 return (error); 2632 2633 if (securelevel > 0) 2634 return (EPERM); 2635 2636 if (strlen(newsetidcorename) == 0) 2637 return (EINVAL); 2638 2639 memcpy(rnode->sysctl_data, node.sysctl_data, MAXPATHLEN); 2640 2641 return (0); 2642} 2643 2644/* 2645 * sysctl helper routine for kern.cp_id node. maps cpus to their 2646 * cpuids. 2647 */ 2648static int 2649sysctl_kern_cpid(SYSCTLFN_ARGS) 2650{ 2651 struct sysctlnode node = *rnode; 2652 2653#ifndef MULTIPROCESSOR 2654 uint64_t id; 2655 2656 if (namelen == 1) { 2657 if (name[0] != 0) 2658 return (ENOENT); 2659 /* 2660 * you're allowed to ask for the zero'th processor 2661 */ 2662 name++; 2663 namelen--; 2664 } 2665 node.sysctl_data = &id; 2666 node.sysctl_size = sizeof(id); 2667 id = cpu_number(); 2668 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2669 2670#else /* MULTIPROCESSOR */ 2671 uint64_t *cp_id = NULL; 2672 int error, n = sysctl_ncpus(); 2673 struct cpu_info *ci; 2674 CPU_INFO_ITERATOR cii; 2675 2676 /* 2677 * here you may either retrieve a single cpu id or the whole 2678 * set. the size you get back when probing depends on what 2679 * you ask for. 2680 */ 2681 switch (namelen) { 2682 case 0: 2683 node.sysctl_size = n * sizeof(uint64_t); 2684 n = -2; /* ALL */ 2685 break; 2686 case 1: 2687 if (name[0] < 0 || name[0] >= n) 2688 return (ENOENT); /* ENOSUCHPROCESSOR */ 2689 node.sysctl_size = sizeof(uint64_t); 2690 n = name[0]; 2691 /* 2692 * adjust these so that sysctl_lookup() will be happy 2693 */ 2694 name++; 2695 namelen--; 2696 break; 2697 default: 2698 return (EINVAL); 2699 } 2700 2701 cp_id = malloc(node.sysctl_size, M_TEMP, M_WAITOK|M_CANFAIL); 2702 if (cp_id == NULL) 2703 return (ENOMEM); 2704 node.sysctl_data = cp_id; 2705 memset(cp_id, 0, node.sysctl_size); 2706 2707 for (CPU_INFO_FOREACH(cii, ci)) { 2708 if (n <= 0) 2709 cp_id[0] = ci->ci_cpuid; 2710 /* 2711 * if a specific processor was requested and we just 2712 * did it, we're done here 2713 */ 2714 if (n == 0) 2715 break; 2716 /* 2717 * if doing "all", skip to next cp_id slot for next processor 2718 */ 2719 if (n == -2) 2720 cp_id++; 2721 /* 2722 * if we're doing a specific processor, we're one 2723 * processor closer 2724 */ 2725 if (n > 0) 2726 n--; 2727 } 2728 2729 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2730 free(node.sysctl_data, M_TEMP); 2731 return (error); 2732 2733#endif /* MULTIPROCESSOR */ 2734} 2735 2736/* 2737 * sysctl helper routine for hw.usermem and hw.usermem64. values are 2738 * calculate on the fly taking into account integer overflow and the 2739 * current wired count. 2740 */ 2741static int 2742sysctl_hw_usermem(SYSCTLFN_ARGS) 2743{ 2744 u_int ui; 2745 u_quad_t uq; 2746 struct sysctlnode node; 2747 2748 node = *rnode; 2749 switch (rnode->sysctl_num) { 2750 case HW_USERMEM: 2751 if ((ui = physmem - uvmexp.wired) > (UINT_MAX / PAGE_SIZE)) 2752 ui = UINT_MAX; 2753 else 2754 ui *= PAGE_SIZE; 2755 node.sysctl_data = &ui; 2756 break; 2757 case HW_USERMEM64: 2758 uq = (u_quad_t)(physmem - uvmexp.wired) * PAGE_SIZE; 2759 node.sysctl_data = &uq; 2760 break; 2761 default: 2762 return (EINVAL); 2763 } 2764 2765 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2766} 2767 2768/* 2769 * sysctl helper routine for kern.cnmagic node. pulls the old value 2770 * out, encoded, and stuffs the new value in for decoding. 2771 */ 2772static int 2773sysctl_hw_cnmagic(SYSCTLFN_ARGS) 2774{ 2775 char magic[CNS_LEN]; 2776 int error; 2777 struct sysctlnode node; 2778 2779 if (oldp) 2780 cn_get_magic(magic, CNS_LEN); 2781 node = *rnode; 2782 node.sysctl_data = &magic[0]; 2783 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2784 if (error || newp == NULL) 2785 return (error); 2786 2787 return (cn_set_magic(magic)); 2788} 2789 2790static int 2791sysctl_hw_ncpu(SYSCTLFN_ARGS) 2792{ 2793 int ncpu; 2794 struct sysctlnode node; 2795 2796 ncpu = sysctl_ncpus(); 2797 node = *rnode; 2798 node.sysctl_data = &ncpu; 2799 2800 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2801} 2802 2803 2804/* 2805 * ******************************************************************** 2806 * section 3: public helper routines that are used for more than one 2807 * node 2808 * ******************************************************************** 2809 */ 2810 2811/* 2812 * sysctl helper routine for the kern.root_device node and some ports' 2813 * machdep.root_device nodes. 2814 */ 2815int 2816sysctl_root_device(SYSCTLFN_ARGS) 2817{ 2818 struct sysctlnode node; 2819 2820 node = *rnode; 2821 node.sysctl_data = root_device->dv_xname; 2822 node.sysctl_size = strlen(root_device->dv_xname) + 1; 2823 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2824} 2825 2826/* 2827 * sysctl helper routine for kern.consdev, dependent on the current 2828 * state of the console. also used for machdep.console_device on some 2829 * ports. 2830 */ 2831int 2832sysctl_consdev(SYSCTLFN_ARGS) 2833{ 2834 dev_t consdev; 2835 struct sysctlnode node; 2836 2837 if (cn_tab != NULL) 2838 consdev = cn_tab->cn_dev; 2839 else 2840 consdev = NODEV; 2841 node = *rnode; 2842 node.sysctl_data = &consdev; 2843 node.sysctl_size = sizeof(consdev); 2844 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 2845} 2846 2847/* 2848 * ******************************************************************** 2849 * section 4: support for some helpers 2850 * ******************************************************************** 2851 */ 2852 2853/* 2854 * Fill in a kinfo_proc2 structure for the specified process. 2855 */ 2856static void 2857fill_kproc2(struct proc *p, struct kinfo_proc2 *ki) 2858{ 2859 struct tty *tp; 2860 struct lwp *l; 2861 struct timeval ut, st; 2862 2863 memset(ki, 0, sizeof(*ki)); 2864 2865 ki->p_paddr = PTRTOUINT64(p); 2866 ki->p_fd = PTRTOUINT64(p->p_fd); 2867 ki->p_cwdi = PTRTOUINT64(p->p_cwdi); 2868 ki->p_stats = PTRTOUINT64(p->p_stats); 2869 ki->p_limit = PTRTOUINT64(p->p_limit); 2870 ki->p_vmspace = PTRTOUINT64(p->p_vmspace); 2871 ki->p_sigacts = PTRTOUINT64(p->p_sigacts); 2872 ki->p_sess = PTRTOUINT64(p->p_session); 2873 ki->p_tsess = 0; /* may be changed if controlling tty below */ 2874 ki->p_ru = PTRTOUINT64(p->p_ru); 2875 2876 ki->p_eflag = 0; 2877 ki->p_exitsig = p->p_exitsig; 2878 ki->p_flag = p->p_flag; 2879 2880 ki->p_pid = p->p_pid; 2881 if (p->p_pptr) 2882 ki->p_ppid = p->p_pptr->p_pid; 2883 else 2884 ki->p_ppid = 0; 2885 ki->p_sid = p->p_session->s_sid; 2886 ki->p__pgid = p->p_pgrp->pg_id; 2887 2888 ki->p_tpgid = NO_PGID; /* may be changed if controlling tty below */ 2889 2890 ki->p_uid = p->p_ucred->cr_uid; 2891 ki->p_ruid = p->p_cred->p_ruid; 2892 ki->p_gid = p->p_ucred->cr_gid; 2893 ki->p_rgid = p->p_cred->p_rgid; 2894 ki->p_svuid = p->p_cred->p_svuid; 2895 ki->p_svgid = p->p_cred->p_svgid; 2896 2897 memcpy(ki->p_groups, p->p_cred->pc_ucred->cr_groups, 2898 min(sizeof(ki->p_groups), sizeof(p->p_cred->pc_ucred->cr_groups))); 2899 ki->p_ngroups = p->p_cred->pc_ucred->cr_ngroups; 2900 2901 ki->p_jobc = p->p_pgrp->pg_jobc; 2902 if ((p->p_flag & P_CONTROLT) && (tp = p->p_session->s_ttyp)) { 2903 ki->p_tdev = tp->t_dev; 2904 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 2905 ki->p_tsess = PTRTOUINT64(tp->t_session); 2906 } else { 2907 ki->p_tdev = NODEV; 2908 } 2909 2910 ki->p_estcpu = p->p_estcpu; 2911 ki->p_rtime_sec = p->p_rtime.tv_sec; 2912 ki->p_rtime_usec = p->p_rtime.tv_usec; 2913 ki->p_cpticks = p->p_cpticks; 2914 ki->p_pctcpu = p->p_pctcpu; 2915 2916 ki->p_uticks = p->p_uticks; 2917 ki->p_sticks = p->p_sticks; 2918 ki->p_iticks = p->p_iticks; 2919 2920 ki->p_tracep = PTRTOUINT64(p->p_tracep); 2921 ki->p_traceflag = p->p_traceflag; 2922 2923 2924 memcpy(&ki->p_siglist, &p->p_sigctx.ps_siglist, sizeof(ki_sigset_t)); 2925 memcpy(&ki->p_sigmask, &p->p_sigctx.ps_sigmask, sizeof(ki_sigset_t)); 2926 memcpy(&ki->p_sigignore, &p->p_sigctx.ps_sigignore,sizeof(ki_sigset_t)); 2927 memcpy(&ki->p_sigcatch, &p->p_sigctx.ps_sigcatch, sizeof(ki_sigset_t)); 2928 2929 ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */ 2930 ki->p_realstat = p->p_stat; 2931 ki->p_nice = p->p_nice; 2932 2933 ki->p_xstat = p->p_xstat; 2934 ki->p_acflag = p->p_acflag; 2935 2936 strncpy(ki->p_comm, p->p_comm, 2937 min(sizeof(ki->p_comm), sizeof(p->p_comm))); 2938 2939 strncpy(ki->p_login, p->p_session->s_login, 2940 min(sizeof ki->p_login - 1, sizeof p->p_session->s_login)); 2941 2942 ki->p_nlwps = p->p_nlwps; 2943 ki->p_nrlwps = p->p_nrlwps; 2944 ki->p_realflag = p->p_flag; 2945 2946 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 2947 ki->p_vm_rssize = 0; 2948 ki->p_vm_tsize = 0; 2949 ki->p_vm_dsize = 0; 2950 ki->p_vm_ssize = 0; 2951 l = NULL; 2952 } else { 2953 struct vmspace *vm = p->p_vmspace; 2954 2955 ki->p_vm_rssize = vm_resident_count(vm); 2956 ki->p_vm_tsize = vm->vm_tsize; 2957 ki->p_vm_dsize = vm->vm_dsize; 2958 ki->p_vm_ssize = vm->vm_ssize; 2959 2960 /* Pick a "representative" LWP */ 2961 l = proc_representative_lwp(p); 2962 ki->p_forw = PTRTOUINT64(l->l_forw); 2963 ki->p_back = PTRTOUINT64(l->l_back); 2964 ki->p_addr = PTRTOUINT64(l->l_addr); 2965 ki->p_stat = l->l_stat; 2966 ki->p_flag |= l->l_flag & P_SHARED; 2967 ki->p_swtime = l->l_swtime; 2968 ki->p_slptime = l->l_slptime; 2969 if (l->l_stat == LSONPROC) { 2970 KDASSERT(l->l_cpu != NULL); 2971 ki->p_schedflags = l->l_cpu->ci_schedstate.spc_flags; 2972 } else 2973 ki->p_schedflags = 0; 2974 ki->p_holdcnt = l->l_holdcnt; 2975 ki->p_priority = l->l_priority; 2976 ki->p_usrpri = l->l_usrpri; 2977 if (l->l_wmesg) 2978 strncpy(ki->p_wmesg, l->l_wmesg, sizeof(ki->p_wmesg)); 2979 ki->p_wchan = PTRTOUINT64(l->l_wchan); 2980 2981 } 2982 2983 if (p->p_session->s_ttyvp) 2984 ki->p_eflag |= EPROC_CTTY; 2985 if (SESS_LEADER(p)) 2986 ki->p_eflag |= EPROC_SLEADER; 2987 2988 /* XXX Is this double check necessary? */ 2989 if (P_ZOMBIE(p)) { 2990 ki->p_uvalid = 0; 2991 } else { 2992 ki->p_uvalid = 1; 2993 2994 ki->p_ustart_sec = p->p_stats->p_start.tv_sec; 2995 ki->p_ustart_usec = p->p_stats->p_start.tv_usec; 2996 2997 calcru(p, &ut, &st, 0); 2998 ki->p_uutime_sec = ut.tv_sec; 2999 ki->p_uutime_usec = ut.tv_usec; 3000 ki->p_ustime_sec = st.tv_sec; 3001 ki->p_ustime_usec = st.tv_usec; 3002 3003 ki->p_uru_maxrss = p->p_stats->p_ru.ru_maxrss; 3004 ki->p_uru_ixrss = p->p_stats->p_ru.ru_ixrss; 3005 ki->p_uru_idrss = p->p_stats->p_ru.ru_idrss; 3006 ki->p_uru_isrss = p->p_stats->p_ru.ru_isrss; 3007 ki->p_uru_minflt = p->p_stats->p_ru.ru_minflt; 3008 ki->p_uru_majflt = p->p_stats->p_ru.ru_majflt; 3009 ki->p_uru_nswap = p->p_stats->p_ru.ru_nswap; 3010 ki->p_uru_inblock = p->p_stats->p_ru.ru_inblock; 3011 ki->p_uru_oublock = p->p_stats->p_ru.ru_oublock; 3012 ki->p_uru_msgsnd = p->p_stats->p_ru.ru_msgsnd; 3013 ki->p_uru_msgrcv = p->p_stats->p_ru.ru_msgrcv; 3014 ki->p_uru_nsignals = p->p_stats->p_ru.ru_nsignals; 3015 ki->p_uru_nvcsw = p->p_stats->p_ru.ru_nvcsw; 3016 ki->p_uru_nivcsw = p->p_stats->p_ru.ru_nivcsw; 3017 3018 timeradd(&p->p_stats->p_cru.ru_utime, 3019 &p->p_stats->p_cru.ru_stime, &ut); 3020 ki->p_uctime_sec = ut.tv_sec; 3021 ki->p_uctime_usec = ut.tv_usec; 3022 } 3023#ifdef MULTIPROCESSOR 3024 if (l && l->l_cpu != NULL) 3025 ki->p_cpuid = l->l_cpu->ci_cpuid; 3026 else 3027#endif 3028 ki->p_cpuid = KI_NOCPU; 3029} 3030 3031/* 3032 * Fill in a kinfo_lwp structure for the specified lwp. 3033 */ 3034static void 3035fill_lwp(struct lwp *l, struct kinfo_lwp *kl) 3036{ 3037 3038 kl->l_forw = PTRTOUINT64(l->l_forw); 3039 kl->l_back = PTRTOUINT64(l->l_back); 3040 kl->l_laddr = PTRTOUINT64(l); 3041 kl->l_addr = PTRTOUINT64(l->l_addr); 3042 kl->l_stat = l->l_stat; 3043 kl->l_lid = l->l_lid; 3044 kl->l_flag = l->l_flag; 3045 3046 kl->l_swtime = l->l_swtime; 3047 kl->l_slptime = l->l_slptime; 3048 if (l->l_stat == LSONPROC) { 3049 KDASSERT(l->l_cpu != NULL); 3050 kl->l_schedflags = l->l_cpu->ci_schedstate.spc_flags; 3051 } else 3052 kl->l_schedflags = 0; 3053 kl->l_holdcnt = l->l_holdcnt; 3054 kl->l_priority = l->l_priority; 3055 kl->l_usrpri = l->l_usrpri; 3056 if (l->l_wmesg) 3057 strncpy(kl->l_wmesg, l->l_wmesg, sizeof(kl->l_wmesg)); 3058 kl->l_wchan = PTRTOUINT64(l->l_wchan); 3059#ifdef MULTIPROCESSOR 3060 if (l->l_cpu != NULL) 3061 kl->l_cpuid = l->l_cpu->ci_cpuid; 3062 else 3063#endif 3064 kl->l_cpuid = KI_NOCPU; 3065} 3066 3067/* 3068 * Fill in an eproc structure for the specified process. 3069 */ 3070void 3071fill_eproc(struct proc *p, struct eproc *ep) 3072{ 3073 struct tty *tp; 3074 struct lwp *l; 3075 3076 ep->e_paddr = p; 3077 ep->e_sess = p->p_session; 3078 ep->e_pcred = *p->p_cred; 3079 ep->e_ucred = *p->p_ucred; 3080 if (p->p_stat == SIDL || P_ZOMBIE(p)) { 3081 ep->e_vm.vm_rssize = 0; 3082 ep->e_vm.vm_tsize = 0; 3083 ep->e_vm.vm_dsize = 0; 3084 ep->e_vm.vm_ssize = 0; 3085 /* ep->e_vm.vm_pmap = XXX; */ 3086 } else { 3087 struct vmspace *vm = p->p_vmspace; 3088 3089 ep->e_vm.vm_rssize = vm_resident_count(vm); 3090 ep->e_vm.vm_tsize = vm->vm_tsize; 3091 ep->e_vm.vm_dsize = vm->vm_dsize; 3092 ep->e_vm.vm_ssize = vm->vm_ssize; 3093 3094 /* Pick a "representative" LWP */ 3095 l = proc_representative_lwp(p); 3096 3097 if (l->l_wmesg) 3098 strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN); 3099 } 3100 if (p->p_pptr) 3101 ep->e_ppid = p->p_pptr->p_pid; 3102 else 3103 ep->e_ppid = 0; 3104 ep->e_pgid = p->p_pgrp->pg_id; 3105 ep->e_sid = ep->e_sess->s_sid; 3106 ep->e_jobc = p->p_pgrp->pg_jobc; 3107 if ((p->p_flag & P_CONTROLT) && 3108 (tp = ep->e_sess->s_ttyp)) { 3109 ep->e_tdev = tp->t_dev; 3110 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 3111 ep->e_tsess = tp->t_session; 3112 } else 3113 ep->e_tdev = NODEV; 3114 3115 ep->e_xsize = ep->e_xrssize = 0; 3116 ep->e_xccount = ep->e_xswrss = 0; 3117 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 3118 if (SESS_LEADER(p)) 3119 ep->e_flag |= EPROC_SLEADER; 3120 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME); 3121} 3122