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