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