1 /* $OpenBSD: kern_sysctl.c,v 1.259 2014/07/17 13:44:21 tedu Exp $ */ 2 /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ 3 4 /*- 5 * Copyright (c) 1982, 1986, 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Mike Karels at Berkeley Software Design, Inc. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 36 */ 37 38 /* 39 * sysctl system call. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/malloc.h> 46 #include <sys/proc.h> 47 #include <sys/resourcevar.h> 48 #include <sys/signalvar.h> 49 #include <sys/file.h> 50 #include <sys/filedesc.h> 51 #include <sys/vnode.h> 52 #include <sys/unistd.h> 53 #include <sys/buf.h> 54 #include <sys/ioctl.h> 55 #include <sys/tty.h> 56 #include <sys/disklabel.h> 57 #include <sys/disk.h> 58 #include <sys/sysctl.h> 59 #include <sys/msgbuf.h> 60 #include <sys/dkstat.h> 61 #include <sys/vmmeter.h> 62 #include <sys/namei.h> 63 #include <sys/exec.h> 64 #include <sys/mbuf.h> 65 #include <sys/sensors.h> 66 #include <sys/pipe.h> 67 #include <sys/eventvar.h> 68 #include <sys/socketvar.h> 69 #include <sys/socket.h> 70 #include <sys/domain.h> 71 #include <sys/protosw.h> 72 #include <sys/timetc.h> 73 #include <sys/evcount.h> 74 #include <sys/un.h> 75 #include <sys/unpcb.h> 76 77 #include <sys/mount.h> 78 #include <sys/syscallargs.h> 79 80 #include <dev/cons.h> 81 #include <dev/rndvar.h> 82 #include <dev/systrace.h> 83 84 #include <net/route.h> 85 #include <netinet/in.h> 86 #include <netinet/in_systm.h> 87 #include <netinet/ip.h> 88 #include <netinet/in_pcb.h> 89 #include <netinet/ip6.h> 90 #include <netinet6/ip6_var.h> 91 92 #ifdef DDB 93 #include <ddb/db_var.h> 94 #endif 95 96 #ifdef SYSVMSG 97 #include <sys/msg.h> 98 #endif 99 #ifdef SYSVSEM 100 #include <sys/sem.h> 101 #endif 102 #ifdef SYSVSHM 103 #include <sys/shm.h> 104 #endif 105 106 extern struct forkstat forkstat; 107 extern struct nchstats nchstats; 108 extern int nselcoll, fscale; 109 extern struct disklist_head disklist; 110 extern fixpt_t ccpu; 111 extern long numvnodes; 112 extern u_int net_livelocks; 113 114 extern void nmbclust_update(void); 115 116 int sysctl_diskinit(int, struct proc *); 117 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *); 118 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *); 119 int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *, 120 struct proc *); 121 int sysctl_intrcnt(int *, u_int, void *, size_t *); 122 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t); 123 int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t); 124 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t); 125 126 void fill_file(struct kinfo_file *, struct file *, struct filedesc *, 127 int, struct vnode *, struct process *, struct proc *, int); 128 void fill_kproc(struct process *, struct kinfo_proc *, struct proc *, int); 129 130 int (*cpu_cpuspeed)(int *); 131 void (*cpu_setperf)(int); 132 int perflevel = 100; 133 134 /* 135 * Lock to avoid too many processes vslocking a large amount of memory 136 * at the same time. 137 */ 138 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk"); 139 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk"); 140 141 int 142 sys___sysctl(struct proc *p, void *v, register_t *retval) 143 { 144 struct sys___sysctl_args /* { 145 syscallarg(const int *) name; 146 syscallarg(u_int) namelen; 147 syscallarg(void *) old; 148 syscallarg(size_t *) oldlenp; 149 syscallarg(void *) new; 150 syscallarg(size_t) newlen; 151 } */ *uap = v; 152 int error, dolock = 1; 153 size_t savelen = 0, oldlen = 0; 154 sysctlfn *fn; 155 int name[CTL_MAXNAME]; 156 157 if (SCARG(uap, new) != NULL && 158 (error = suser(p, 0))) 159 return (error); 160 /* 161 * all top-level sysctl names are non-terminal 162 */ 163 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2) 164 return (EINVAL); 165 error = copyin(SCARG(uap, name), name, 166 SCARG(uap, namelen) * sizeof(int)); 167 if (error) 168 return (error); 169 170 switch (name[0]) { 171 case CTL_KERN: 172 fn = kern_sysctl; 173 if (name[1] == KERN_VNODE) /* XXX */ 174 dolock = 0; 175 break; 176 case CTL_HW: 177 fn = hw_sysctl; 178 break; 179 case CTL_VM: 180 fn = uvm_sysctl; 181 break; 182 case CTL_NET: 183 fn = net_sysctl; 184 break; 185 case CTL_FS: 186 fn = fs_sysctl; 187 break; 188 case CTL_VFS: 189 fn = vfs_sysctl; 190 break; 191 case CTL_MACHDEP: 192 fn = cpu_sysctl; 193 break; 194 #ifdef DEBUG 195 case CTL_DEBUG: 196 fn = debug_sysctl; 197 break; 198 #endif 199 #ifdef DDB 200 case CTL_DDB: 201 fn = ddb_sysctl; 202 break; 203 #endif 204 default: 205 return (EOPNOTSUPP); 206 } 207 208 if (SCARG(uap, oldlenp) && 209 (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen)))) 210 return (error); 211 if (SCARG(uap, old) != NULL) { 212 if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0) 213 return (error); 214 if (dolock) { 215 if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) { 216 rw_exit_write(&sysctl_lock); 217 return (ENOMEM); 218 } 219 error = uvm_vslock(p, SCARG(uap, old), oldlen, 220 VM_PROT_READ|VM_PROT_WRITE); 221 if (error) { 222 rw_exit_write(&sysctl_lock); 223 return (error); 224 } 225 } 226 savelen = oldlen; 227 } 228 error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old), 229 &oldlen, SCARG(uap, new), SCARG(uap, newlen), p); 230 if (SCARG(uap, old) != NULL) { 231 if (dolock) 232 uvm_vsunlock(p, SCARG(uap, old), savelen); 233 rw_exit_write(&sysctl_lock); 234 } 235 if (error) 236 return (error); 237 if (SCARG(uap, oldlenp)) 238 error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen)); 239 return (error); 240 } 241 242 /* 243 * Attributes stored in the kernel. 244 */ 245 char hostname[MAXHOSTNAMELEN]; 246 int hostnamelen; 247 char domainname[MAXHOSTNAMELEN]; 248 int domainnamelen; 249 long hostid; 250 char *disknames = NULL; 251 struct diskstats *diskstats = NULL; 252 #ifdef INSECURE 253 int securelevel = -1; 254 #else 255 int securelevel; 256 #endif 257 258 /* 259 * kernel related system variables. 260 */ 261 int 262 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 263 size_t newlen, struct proc *p) 264 { 265 int error, level, inthostid, stackgap; 266 dev_t dev; 267 extern int somaxconn, sominconn; 268 extern int usermount, nosuidcoredump; 269 extern long cp_time[CPUSTATES]; 270 extern int stackgap_random; 271 #ifdef CRYPTO 272 extern int usercrypto; 273 extern int userasymcrypto; 274 extern int cryptodevallowsoft; 275 #endif 276 extern int maxlocksperuid; 277 extern int pool_debug; 278 279 /* all sysctl names at this level are terminal except a ton of them */ 280 if (namelen != 1) { 281 switch (name[0]) { 282 case KERN_PROC: 283 case KERN_PROF: 284 case KERN_MALLOCSTATS: 285 case KERN_TTY: 286 case KERN_POOL: 287 case KERN_PROC_ARGS: 288 case KERN_PROC_CWD: 289 case KERN_PROC_NOBROADCASTKILL: 290 case KERN_SYSVIPC_INFO: 291 case KERN_SEMINFO: 292 case KERN_SHMINFO: 293 case KERN_INTRCNT: 294 case KERN_WATCHDOG: 295 case KERN_EMUL: 296 case KERN_EVCOUNT: 297 case KERN_TIMECOUNTER: 298 case KERN_CPTIME2: 299 case KERN_FILE: 300 break; 301 default: 302 return (ENOTDIR); /* overloaded */ 303 } 304 } 305 306 switch (name[0]) { 307 case KERN_OSTYPE: 308 return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 309 case KERN_OSRELEASE: 310 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 311 case KERN_OSREV: 312 return (sysctl_rdint(oldp, oldlenp, newp, OpenBSD)); 313 case KERN_OSVERSION: 314 return (sysctl_rdstring(oldp, oldlenp, newp, osversion)); 315 case KERN_VERSION: 316 return (sysctl_rdstring(oldp, oldlenp, newp, version)); 317 case KERN_MAXVNODES: 318 return(sysctl_int(oldp, oldlenp, newp, newlen, &maxvnodes)); 319 case KERN_MAXPROC: 320 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxprocess)); 321 case KERN_MAXFILES: 322 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 323 case KERN_NFILES: 324 return (sysctl_rdint(oldp, oldlenp, newp, nfiles)); 325 case KERN_TTYCOUNT: 326 return (sysctl_rdint(oldp, oldlenp, newp, tty_count)); 327 case KERN_NUMVNODES: 328 return (sysctl_rdint(oldp, oldlenp, newp, numvnodes)); 329 case KERN_ARGMAX: 330 return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 331 case KERN_NSELCOLL: 332 return (sysctl_rdint(oldp, oldlenp, newp, nselcoll)); 333 case KERN_SECURELVL: 334 level = securelevel; 335 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 336 newp == NULL) 337 return (error); 338 if ((securelevel > 0 || level < -1) && 339 level < securelevel && p->p_p->ps_pid != 1) 340 return (EPERM); 341 securelevel = level; 342 return (0); 343 case KERN_HOSTNAME: 344 error = sysctl_tstring(oldp, oldlenp, newp, newlen, 345 hostname, sizeof(hostname)); 346 if (newp && !error) 347 hostnamelen = newlen; 348 return (error); 349 case KERN_DOMAINNAME: 350 error = sysctl_tstring(oldp, oldlenp, newp, newlen, 351 domainname, sizeof(domainname)); 352 if (newp && !error) 353 domainnamelen = newlen; 354 return (error); 355 case KERN_HOSTID: 356 inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */ 357 error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid); 358 hostid = inthostid; 359 return (error); 360 case KERN_CLOCKRATE: 361 return (sysctl_clockrate(oldp, oldlenp, newp)); 362 case KERN_BOOTTIME: { 363 struct timeval bt; 364 TIMESPEC_TO_TIMEVAL(&bt, &boottime); 365 return (sysctl_rdstruct(oldp, oldlenp, newp, &bt, sizeof bt)); 366 } 367 case KERN_VNODE: 368 return (sysctl_vnode(oldp, oldlenp, p)); 369 #ifndef SMALL_KERNEL 370 case KERN_PROC: 371 return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); 372 case KERN_PROC_ARGS: 373 return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp, 374 p)); 375 case KERN_PROC_CWD: 376 return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp, 377 p)); 378 case KERN_PROC_NOBROADCASTKILL: 379 return (sysctl_proc_nobroadcastkill(name + 1, namelen - 1, 380 newp, newlen, oldp, oldlenp, p)); 381 case KERN_FILE: 382 return (sysctl_file(name + 1, namelen - 1, oldp, oldlenp, p)); 383 #endif 384 case KERN_MBSTAT: 385 return (sysctl_rdstruct(oldp, oldlenp, newp, &mbstat, 386 sizeof(mbstat))); 387 #ifdef GPROF 388 case KERN_PROF: 389 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp, 390 newp, newlen)); 391 #endif 392 case KERN_POSIX1: 393 return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 394 case KERN_NGROUPS: 395 return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX)); 396 case KERN_JOB_CONTROL: 397 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 398 case KERN_SAVED_IDS: 399 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 400 case KERN_MAXPARTITIONS: 401 return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS)); 402 case KERN_RAWPARTITION: 403 return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART)); 404 case KERN_MAXTHREAD: 405 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxthread)); 406 case KERN_NTHREADS: 407 return (sysctl_rdint(oldp, oldlenp, newp, nthreads)); 408 case KERN_SOMAXCONN: 409 return (sysctl_int(oldp, oldlenp, newp, newlen, &somaxconn)); 410 case KERN_SOMINCONN: 411 return (sysctl_int(oldp, oldlenp, newp, newlen, &sominconn)); 412 case KERN_USERMOUNT: 413 return (sysctl_int(oldp, oldlenp, newp, newlen, &usermount)); 414 case KERN_RND: 415 return (sysctl_rdstruct(oldp, oldlenp, newp, &rndstats, 416 sizeof(rndstats))); 417 case KERN_ARND: { 418 char buf[512]; 419 420 if (*oldlenp > sizeof(buf)) 421 return (EINVAL); 422 if (oldp) { 423 arc4random_buf(buf, *oldlenp); 424 if ((error = copyout(buf, oldp, *oldlenp))) 425 return (error); 426 explicit_bzero(buf, sizeof(buf)); 427 } 428 return (0); 429 } 430 case KERN_NOSUIDCOREDUMP: 431 return (sysctl_int(oldp, oldlenp, newp, newlen, &nosuidcoredump)); 432 case KERN_FSYNC: 433 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 434 case KERN_SYSVMSG: 435 #ifdef SYSVMSG 436 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 437 #else 438 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 439 #endif 440 case KERN_SYSVSEM: 441 #ifdef SYSVSEM 442 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 443 #else 444 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 445 #endif 446 case KERN_SYSVSHM: 447 #ifdef SYSVSHM 448 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 449 #else 450 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 451 #endif 452 case KERN_MSGBUFSIZE: 453 /* 454 * deal with cases where the message buffer has 455 * become corrupted. 456 */ 457 if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC) 458 return (ENXIO); 459 return (sysctl_rdint(oldp, oldlenp, newp, msgbufp->msg_bufs)); 460 case KERN_MSGBUF: 461 /* see note above */ 462 if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC) 463 return (ENXIO); 464 return (sysctl_rdstruct(oldp, oldlenp, newp, msgbufp, 465 msgbufp->msg_bufs + offsetof(struct msgbuf, msg_bufc))); 466 case KERN_MALLOCSTATS: 467 return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp, 468 newp, newlen, p)); 469 case KERN_CPTIME: 470 { 471 CPU_INFO_ITERATOR cii; 472 struct cpu_info *ci; 473 int i; 474 475 memset(cp_time, 0, sizeof(cp_time)); 476 477 CPU_INFO_FOREACH(cii, ci) { 478 for (i = 0; i < CPUSTATES; i++) 479 cp_time[i] += ci->ci_schedstate.spc_cp_time[i]; 480 } 481 482 for (i = 0; i < CPUSTATES; i++) 483 cp_time[i] /= ncpus; 484 485 return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time, 486 sizeof(cp_time))); 487 } 488 case KERN_NCHSTATS: 489 return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats, 490 sizeof(struct nchstats))); 491 case KERN_FORKSTAT: 492 return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat, 493 sizeof(struct forkstat))); 494 case KERN_TTY: 495 return (sysctl_tty(name + 1, namelen - 1, oldp, oldlenp, 496 newp, newlen)); 497 case KERN_FSCALE: 498 return (sysctl_rdint(oldp, oldlenp, newp, fscale)); 499 case KERN_CCPU: 500 return (sysctl_rdint(oldp, oldlenp, newp, ccpu)); 501 case KERN_NPROCS: 502 return (sysctl_rdint(oldp, oldlenp, newp, nprocesses)); 503 case KERN_POOL: 504 return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp)); 505 case KERN_STACKGAPRANDOM: 506 stackgap = stackgap_random; 507 error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap); 508 if (error) 509 return (error); 510 /* 511 * Safety harness. 512 */ 513 if ((stackgap < ALIGNBYTES && stackgap != 0) || 514 !powerof2(stackgap) || stackgap >= MAXSSIZ) 515 return (EINVAL); 516 stackgap_random = stackgap; 517 return (0); 518 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 519 case KERN_SYSVIPC_INFO: 520 return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp)); 521 #endif 522 #ifdef CRYPTO 523 case KERN_USERCRYPTO: 524 return (sysctl_int(oldp, oldlenp, newp, newlen, &usercrypto)); 525 case KERN_USERASYMCRYPTO: 526 return (sysctl_int(oldp, oldlenp, newp, newlen, 527 &userasymcrypto)); 528 case KERN_CRYPTODEVALLOWSOFT: 529 return (sysctl_int(oldp, oldlenp, newp, newlen, 530 &cryptodevallowsoft)); 531 #endif 532 case KERN_SPLASSERT: 533 return (sysctl_int(oldp, oldlenp, newp, newlen, 534 &splassert_ctl)); 535 #ifdef SYSVSEM 536 case KERN_SEMINFO: 537 return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp, 538 newp, newlen)); 539 #endif 540 #ifdef SYSVSHM 541 case KERN_SHMINFO: 542 return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp, 543 newp, newlen)); 544 #endif 545 #ifndef SMALL_KERNEL 546 case KERN_INTRCNT: 547 return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp)); 548 case KERN_WATCHDOG: 549 return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp, 550 newp, newlen)); 551 case KERN_EMUL: 552 return (sysctl_emul(name + 1, namelen - 1, oldp, oldlenp, 553 newp, newlen)); 554 #endif 555 case KERN_MAXCLUSTERS: 556 error = sysctl_int(oldp, oldlenp, newp, newlen, &nmbclust); 557 if (!error) 558 nmbclust_update(); 559 return (error); 560 #ifndef SMALL_KERNEL 561 case KERN_EVCOUNT: 562 return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp, 563 newp, newlen)); 564 #endif 565 case KERN_TIMECOUNTER: 566 return (sysctl_tc(name + 1, namelen - 1, oldp, oldlenp, 567 newp, newlen)); 568 case KERN_MAXLOCKSPERUID: 569 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxlocksperuid)); 570 case KERN_CPTIME2: 571 return (sysctl_cptime2(name + 1, namelen -1, oldp, oldlenp, 572 newp, newlen)); 573 case KERN_CACHEPCT: { 574 u_int64_t dmapages; 575 int opct, pgs; 576 opct = bufcachepercent; 577 error = sysctl_int(oldp, oldlenp, newp, newlen, 578 &bufcachepercent); 579 if (error) 580 return(error); 581 if (bufcachepercent > 90 || bufcachepercent < 5) { 582 bufcachepercent = opct; 583 return (EINVAL); 584 } 585 dmapages = uvm_pagecount(&dma_constraint); 586 if (bufcachepercent != opct) { 587 pgs = bufcachepercent * dmapages / 100; 588 bufadjust(pgs); /* adjust bufpages */ 589 bufhighpages = bufpages; /* set high water mark */ 590 } 591 return(0); 592 } 593 case KERN_CONSDEV: 594 if (cn_tab != NULL) 595 dev = cn_tab->cn_dev; 596 else 597 dev = NODEV; 598 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev)); 599 case KERN_NETLIVELOCKS: 600 return (sysctl_rdint(oldp, oldlenp, newp, net_livelocks)); 601 case KERN_POOL_DEBUG: { 602 int old_pool_debug = pool_debug; 603 604 error = sysctl_int(oldp, oldlenp, newp, newlen, 605 &pool_debug); 606 if (error == 0 && pool_debug != old_pool_debug) 607 pool_reclaim_all(); 608 return (error); 609 } 610 default: 611 return (EOPNOTSUPP); 612 } 613 /* NOTREACHED */ 614 } 615 616 /* 617 * hardware related system variables. 618 */ 619 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver; 620 int allowpowerdown = 1; 621 622 int 623 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 624 size_t newlen, struct proc *p) 625 { 626 extern char machine[], cpu_model[]; 627 int err, cpuspeed; 628 629 /* all sysctl names at this level except sensors are terminal */ 630 if (name[0] != HW_SENSORS && namelen != 1) 631 return (ENOTDIR); /* overloaded */ 632 633 switch (name[0]) { 634 case HW_MACHINE: 635 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 636 case HW_MODEL: 637 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 638 case HW_NCPU: 639 return (sysctl_rdint(oldp, oldlenp, newp, ncpus)); 640 case HW_NCPUFOUND: 641 return (sysctl_rdint(oldp, oldlenp, newp, ncpusfound)); 642 case HW_BYTEORDER: 643 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER)); 644 case HW_PHYSMEM: 645 return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem))); 646 case HW_USERMEM: 647 return (sysctl_rdint(oldp, oldlenp, newp, 648 ptoa(physmem - uvmexp.wired))); 649 case HW_PAGESIZE: 650 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 651 case HW_DISKNAMES: 652 err = sysctl_diskinit(0, p); 653 if (err) 654 return err; 655 if (disknames) 656 return (sysctl_rdstring(oldp, oldlenp, newp, 657 disknames)); 658 else 659 return (sysctl_rdstring(oldp, oldlenp, newp, "")); 660 case HW_DISKSTATS: 661 err = sysctl_diskinit(1, p); 662 if (err) 663 return err; 664 return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats, 665 disk_count * sizeof(struct diskstats))); 666 case HW_DISKCOUNT: 667 return (sysctl_rdint(oldp, oldlenp, newp, disk_count)); 668 #ifndef SMALL_KERNEL 669 case HW_SENSORS: 670 return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp, 671 newp, newlen)); 672 #endif 673 case HW_CPUSPEED: 674 if (!cpu_cpuspeed) 675 return (EOPNOTSUPP); 676 err = cpu_cpuspeed(&cpuspeed); 677 if (err) 678 return err; 679 return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); 680 case HW_SETPERF: 681 if (!cpu_setperf) 682 return (EOPNOTSUPP); 683 err = sysctl_int(oldp, oldlenp, newp, newlen, &perflevel); 684 if (err) 685 return err; 686 if (perflevel > 100) 687 perflevel = 100; 688 if (perflevel < 0) 689 perflevel = 0; 690 if (newp) 691 cpu_setperf(perflevel); 692 return (0); 693 case HW_VENDOR: 694 if (hw_vendor) 695 return (sysctl_rdstring(oldp, oldlenp, newp, 696 hw_vendor)); 697 else 698 return (EOPNOTSUPP); 699 case HW_PRODUCT: 700 if (hw_prod) 701 return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod)); 702 else 703 return (EOPNOTSUPP); 704 case HW_VERSION: 705 if (hw_ver) 706 return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver)); 707 else 708 return (EOPNOTSUPP); 709 case HW_SERIALNO: 710 if (hw_serial) 711 return (sysctl_rdstring(oldp, oldlenp, newp, 712 hw_serial)); 713 else 714 return (EOPNOTSUPP); 715 case HW_UUID: 716 if (hw_uuid) 717 return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid)); 718 else 719 return (EOPNOTSUPP); 720 case HW_PHYSMEM64: 721 return (sysctl_rdquad(oldp, oldlenp, newp, 722 ptoa((psize_t)physmem))); 723 case HW_USERMEM64: 724 return (sysctl_rdquad(oldp, oldlenp, newp, 725 ptoa((psize_t)physmem - uvmexp.wired))); 726 case HW_ALLOWPOWERDOWN: 727 if (securelevel > 0) 728 return (sysctl_rdint(oldp, oldlenp, newp, 729 allowpowerdown)); 730 return (sysctl_int(oldp, oldlenp, newp, newlen, 731 &allowpowerdown)); 732 default: 733 return (EOPNOTSUPP); 734 } 735 /* NOTREACHED */ 736 } 737 738 #ifdef DEBUG 739 /* 740 * Debugging related system variables. 741 */ 742 extern struct ctldebug debug0, debug1; 743 struct ctldebug debug2, debug3, debug4; 744 struct ctldebug debug5, debug6, debug7, debug8, debug9; 745 struct ctldebug debug10, debug11, debug12, debug13, debug14; 746 struct ctldebug debug15, debug16, debug17, debug18, debug19; 747 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 748 &debug0, &debug1, &debug2, &debug3, &debug4, 749 &debug5, &debug6, &debug7, &debug8, &debug9, 750 &debug10, &debug11, &debug12, &debug13, &debug14, 751 &debug15, &debug16, &debug17, &debug18, &debug19, 752 }; 753 int 754 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 755 size_t newlen, struct proc *p) 756 { 757 struct ctldebug *cdp; 758 759 /* all sysctl names at this level are name and field */ 760 if (namelen != 2) 761 return (ENOTDIR); /* overloaded */ 762 if (name[0] < 0 || name[0] >= nitems(debugvars)) 763 return (EOPNOTSUPP); 764 cdp = debugvars[name[0]]; 765 if (cdp->debugname == 0) 766 return (EOPNOTSUPP); 767 switch (name[1]) { 768 case CTL_DEBUG_NAME: 769 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 770 case CTL_DEBUG_VALUE: 771 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 772 default: 773 return (EOPNOTSUPP); 774 } 775 /* NOTREACHED */ 776 } 777 #endif /* DEBUG */ 778 779 /* 780 * Reads, or writes that lower the value 781 */ 782 int 783 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp) 784 { 785 unsigned int oval = *valp, val = *valp; 786 int error; 787 788 if (newp == NULL) 789 return (sysctl_rdint(oldp, oldlenp, newp, *valp)); 790 791 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val))) 792 return (error); 793 if (val > oval) 794 return (EPERM); /* do not allow raising */ 795 *(unsigned int *)valp = val; 796 return (0); 797 } 798 799 /* 800 * Validate parameters and get old / set new parameters 801 * for an integer-valued sysctl function. 802 */ 803 int 804 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp) 805 { 806 int error = 0; 807 808 if (oldp && *oldlenp < sizeof(int)) 809 return (ENOMEM); 810 if (newp && newlen != sizeof(int)) 811 return (EINVAL); 812 *oldlenp = sizeof(int); 813 if (oldp) 814 error = copyout(valp, oldp, sizeof(int)); 815 if (error == 0 && newp) 816 error = copyin(newp, valp, sizeof(int)); 817 return (error); 818 } 819 820 /* 821 * As above, but read-only. 822 */ 823 int 824 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val) 825 { 826 int error = 0; 827 828 if (oldp && *oldlenp < sizeof(int)) 829 return (ENOMEM); 830 if (newp) 831 return (EPERM); 832 *oldlenp = sizeof(int); 833 if (oldp) 834 error = copyout((caddr_t)&val, oldp, sizeof(int)); 835 return (error); 836 } 837 838 /* 839 * Array of integer values. 840 */ 841 int 842 sysctl_int_arr(int **valpp, int *name, u_int namelen, void *oldp, 843 size_t *oldlenp, void *newp, size_t newlen) 844 { 845 if (namelen > 1) 846 return (ENOTDIR); 847 if (name[0] < 0 || valpp[name[0]] == NULL) 848 return (EOPNOTSUPP); 849 return (sysctl_int(oldp, oldlenp, newp, newlen, valpp[name[0]])); 850 } 851 852 /* 853 * Validate parameters and get old / set new parameters 854 * for an integer-valued sysctl function. 855 */ 856 int 857 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 858 int64_t *valp) 859 { 860 int error = 0; 861 862 if (oldp && *oldlenp < sizeof(int64_t)) 863 return (ENOMEM); 864 if (newp && newlen != sizeof(int64_t)) 865 return (EINVAL); 866 *oldlenp = sizeof(int64_t); 867 if (oldp) 868 error = copyout(valp, oldp, sizeof(int64_t)); 869 if (error == 0 && newp) 870 error = copyin(newp, valp, sizeof(int64_t)); 871 return (error); 872 } 873 874 /* 875 * As above, but read-only. 876 */ 877 int 878 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val) 879 { 880 int error = 0; 881 882 if (oldp && *oldlenp < sizeof(int64_t)) 883 return (ENOMEM); 884 if (newp) 885 return (EPERM); 886 *oldlenp = sizeof(int64_t); 887 if (oldp) 888 error = copyout((caddr_t)&val, oldp, sizeof(int64_t)); 889 return (error); 890 } 891 892 /* 893 * Validate parameters and get old / set new parameters 894 * for a string-valued sysctl function. 895 */ 896 int 897 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str, 898 int maxlen) 899 { 900 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0); 901 } 902 903 int 904 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 905 char *str, int maxlen) 906 { 907 return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1); 908 } 909 910 int 911 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, 912 char *str, int maxlen, int trunc) 913 { 914 int len, error = 0; 915 916 len = strlen(str) + 1; 917 if (oldp && *oldlenp < len) { 918 if (trunc == 0 || *oldlenp == 0) 919 return (ENOMEM); 920 } 921 if (newp && newlen >= maxlen) 922 return (EINVAL); 923 if (oldp) { 924 if (trunc && *oldlenp < len) { 925 len = *oldlenp; 926 error = copyout(str, oldp, len - 1); 927 if (error == 0) 928 error = copyout("", (char *)oldp + len - 1, 1); 929 } else { 930 error = copyout(str, oldp, len); 931 } 932 } 933 *oldlenp = len; 934 if (error == 0 && newp) { 935 error = copyin(newp, str, newlen); 936 str[newlen] = 0; 937 } 938 return (error); 939 } 940 941 /* 942 * As above, but read-only. 943 */ 944 int 945 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str) 946 { 947 int len, error = 0; 948 949 len = strlen(str) + 1; 950 if (oldp && *oldlenp < len) 951 return (ENOMEM); 952 if (newp) 953 return (EPERM); 954 *oldlenp = len; 955 if (oldp) 956 error = copyout(str, oldp, len); 957 return (error); 958 } 959 960 /* 961 * Validate parameters and get old / set new parameters 962 * for a structure oriented sysctl function. 963 */ 964 int 965 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp, 966 int len) 967 { 968 int error = 0; 969 970 if (oldp && *oldlenp < len) 971 return (ENOMEM); 972 if (newp && newlen > len) 973 return (EINVAL); 974 if (oldp) { 975 *oldlenp = len; 976 error = copyout(sp, oldp, len); 977 } 978 if (error == 0 && newp) 979 error = copyin(newp, sp, len); 980 return (error); 981 } 982 983 /* 984 * Validate parameters and get old parameters 985 * for a structure oriented sysctl function. 986 */ 987 int 988 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp, 989 int len) 990 { 991 int error = 0; 992 993 if (oldp && *oldlenp < len) 994 return (ENOMEM); 995 if (newp) 996 return (EPERM); 997 *oldlenp = len; 998 if (oldp) 999 error = copyout(sp, oldp, len); 1000 return (error); 1001 } 1002 1003 #ifndef SMALL_KERNEL 1004 void 1005 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp, 1006 int fd, struct vnode *vp, struct process *pr, struct proc *p, 1007 int show_pointers) 1008 { 1009 struct vattr va; 1010 1011 memset(kf, 0, sizeof(*kf)); 1012 1013 kf->fd_fd = fd; /* might not really be an fd */ 1014 1015 if (fp != NULL) { 1016 if (show_pointers) 1017 kf->f_fileaddr = PTRTOINT64(fp); 1018 kf->f_flag = fp->f_flag; 1019 kf->f_iflags = fp->f_iflags; 1020 kf->f_type = fp->f_type; 1021 kf->f_count = fp->f_count; 1022 kf->f_msgcount = fp->f_msgcount; 1023 if (show_pointers) 1024 kf->f_ucred = PTRTOINT64(fp->f_cred); 1025 kf->f_uid = fp->f_cred->cr_uid; 1026 kf->f_gid = fp->f_cred->cr_gid; 1027 if (show_pointers) 1028 kf->f_ops = PTRTOINT64(fp->f_ops); 1029 if (show_pointers) 1030 kf->f_data = PTRTOINT64(fp->f_data); 1031 kf->f_usecount = 0; 1032 1033 if (suser(p, 0) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) { 1034 kf->f_offset = fp->f_offset; 1035 kf->f_rxfer = fp->f_rxfer; 1036 kf->f_rwfer = fp->f_wxfer; 1037 kf->f_seek = fp->f_seek; 1038 kf->f_rbytes = fp->f_rbytes; 1039 kf->f_wbytes = fp->f_wbytes; 1040 } else 1041 kf->f_offset = -1; 1042 } else if (vp != NULL) { 1043 /* fake it */ 1044 kf->f_type = DTYPE_VNODE; 1045 kf->f_flag = FREAD; 1046 if (fd == KERN_FILE_TRACE) 1047 kf->f_flag |= FWRITE; 1048 } 1049 1050 /* information about the object associated with this file */ 1051 switch (kf->f_type) { 1052 case DTYPE_VNODE: 1053 if (fp != NULL) 1054 vp = (struct vnode *)fp->f_data; 1055 1056 if (show_pointers) 1057 kf->v_un = PTRTOINT64(vp->v_un.vu_socket); 1058 kf->v_type = vp->v_type; 1059 kf->v_tag = vp->v_tag; 1060 kf->v_flag = vp->v_flag; 1061 if (show_pointers) 1062 kf->v_data = PTRTOINT64(vp->v_data); 1063 if (show_pointers) 1064 kf->v_mount = PTRTOINT64(vp->v_mount); 1065 if (vp->v_mount) 1066 strlcpy(kf->f_mntonname, 1067 vp->v_mount->mnt_stat.f_mntonname, 1068 sizeof(kf->f_mntonname)); 1069 1070 if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) { 1071 kf->va_fileid = va.va_fileid; 1072 kf->va_mode = MAKEIMODE(va.va_type, va.va_mode); 1073 kf->va_size = va.va_size; 1074 kf->va_rdev = va.va_rdev; 1075 kf->va_fsid = va.va_fsid & 0xffffffff; 1076 } 1077 break; 1078 1079 case DTYPE_SOCKET: { 1080 struct socket *so = (struct socket *)fp->f_data; 1081 1082 kf->so_type = so->so_type; 1083 kf->so_state = so->so_state; 1084 if (show_pointers) 1085 kf->so_pcb = PTRTOINT64(so->so_pcb); 1086 else 1087 kf->so_pcb = -1; 1088 kf->so_protocol = so->so_proto->pr_protocol; 1089 kf->so_family = so->so_proto->pr_domain->dom_family; 1090 kf->so_rcv_cc = so->so_rcv.sb_cc; 1091 kf->so_snd_cc = so->so_snd.sb_cc; 1092 if (so->so_splice) { 1093 if (show_pointers) 1094 kf->so_splice = PTRTOINT64(so->so_splice); 1095 kf->so_splicelen = so->so_splicelen; 1096 } else if (so->so_spliceback) 1097 kf->so_splicelen = -1; 1098 if (!so->so_pcb) 1099 break; 1100 switch (kf->so_family) { 1101 case AF_INET: { 1102 struct inpcb *inpcb = so->so_pcb; 1103 1104 if (show_pointers) 1105 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1106 kf->inp_lport = inpcb->inp_lport; 1107 kf->inp_laddru[0] = inpcb->inp_laddr.s_addr; 1108 kf->inp_fport = inpcb->inp_fport; 1109 kf->inp_faddru[0] = inpcb->inp_faddr.s_addr; 1110 kf->inp_rtableid = inpcb->inp_rtableid; 1111 break; 1112 } 1113 case AF_INET6: { 1114 struct inpcb *inpcb = so->so_pcb; 1115 1116 kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb); 1117 kf->inp_lport = inpcb->inp_lport; 1118 kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0]; 1119 kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1]; 1120 kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2]; 1121 kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3]; 1122 kf->inp_fport = inpcb->inp_fport; 1123 kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0]; 1124 kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1]; 1125 kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2]; 1126 kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3]; 1127 kf->inp_rtableid = inpcb->inp_rtableid; 1128 break; 1129 } 1130 case AF_UNIX: { 1131 struct unpcb *unpcb = so->so_pcb; 1132 1133 if (show_pointers) { 1134 kf->unp_conn = PTRTOINT64(unpcb->unp_conn); 1135 kf->unp_refs = PTRTOINT64(unpcb->unp_refs); 1136 kf->unp_nextref = PTRTOINT64(unpcb->unp_nextref); 1137 kf->v_un = PTRTOINT64(unpcb->unp_vnode); 1138 kf->unp_addr = PTRTOINT64(unpcb->unp_addr); 1139 } 1140 if (unpcb->unp_addr != NULL) { 1141 struct sockaddr_un *un = mtod(unpcb->unp_addr, 1142 struct sockaddr_un *); 1143 memcpy(kf->unp_path, un->sun_path, un->sun_len 1144 - offsetof(struct sockaddr_un,sun_path)); 1145 } 1146 break; 1147 } 1148 } 1149 break; 1150 } 1151 1152 case DTYPE_PIPE: { 1153 struct pipe *pipe = (struct pipe *)fp->f_data; 1154 1155 if (show_pointers) 1156 kf->pipe_peer = PTRTOINT64(pipe->pipe_peer); 1157 kf->pipe_state = pipe->pipe_state; 1158 break; 1159 } 1160 1161 case DTYPE_KQUEUE: { 1162 struct kqueue *kqi = (struct kqueue *)fp->f_data; 1163 1164 kf->kq_count = kqi->kq_count; 1165 kf->kq_state = kqi->kq_state; 1166 break; 1167 } 1168 case DTYPE_SYSTRACE: { 1169 struct fsystrace *f = (struct fsystrace *)fp->f_data; 1170 1171 kf->str_npolicies = f->npolicies; 1172 break; 1173 } 1174 } 1175 1176 /* per-process information for KERN_FILE_BY[PU]ID */ 1177 if (pr != NULL) { 1178 kf->p_pid = pr->ps_pid; 1179 kf->p_uid = pr->ps_ucred->cr_uid; 1180 kf->p_gid = pr->ps_ucred->cr_gid; 1181 kf->p_tid = -1; 1182 strlcpy(kf->p_comm, pr->ps_mainproc->p_comm, 1183 sizeof(kf->p_comm)); 1184 } 1185 if (fdp != NULL) 1186 kf->fd_ofileflags = fdp->fd_ofileflags[fd]; 1187 } 1188 1189 /* 1190 * Get file structures. 1191 */ 1192 int 1193 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, 1194 struct proc *p) 1195 { 1196 struct kinfo_file *kf; 1197 struct filedesc *fdp; 1198 struct file *fp; 1199 struct process *pr; 1200 size_t buflen, elem_size, elem_count, outsize; 1201 char *dp = where; 1202 int arg, i, error = 0, needed = 0; 1203 u_int op; 1204 int show_pointers; 1205 1206 if (namelen > 4) 1207 return (ENOTDIR); 1208 if (namelen < 4 || name[2] > sizeof(*kf)) 1209 return (EINVAL); 1210 1211 buflen = where != NULL ? *sizep : 0; 1212 op = name[0]; 1213 arg = name[1]; 1214 elem_size = name[2]; 1215 elem_count = name[3]; 1216 outsize = MIN(sizeof(*kf), elem_size); 1217 1218 if (elem_size < 1) 1219 return (EINVAL); 1220 1221 show_pointers = suser(curproc, 0) == 0; 1222 1223 kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK); 1224 1225 #define FILLIT(fp, fdp, i, vp, pr) do { \ 1226 if (buflen >= elem_size && elem_count > 0) { \ 1227 fill_file(kf, fp, fdp, i, vp, pr, p, show_pointers); \ 1228 error = copyout(kf, dp, outsize); \ 1229 if (error) \ 1230 break; \ 1231 dp += elem_size; \ 1232 buflen -= elem_size; \ 1233 elem_count--; \ 1234 } \ 1235 needed += elem_size; \ 1236 } while (0) 1237 1238 switch (op) { 1239 case KERN_FILE_BYFILE: 1240 if (arg != 0) { 1241 /* no arg in file mode */ 1242 error = EINVAL; 1243 break; 1244 } 1245 LIST_FOREACH(fp, &filehead, f_list) { 1246 if (fp->f_count == 0) 1247 continue; 1248 FILLIT(fp, NULL, 0, NULL, NULL); 1249 } 1250 break; 1251 case KERN_FILE_BYPID: 1252 /* A arg of -1 indicates all processes */ 1253 if (arg < -1) { 1254 error = EINVAL; 1255 break; 1256 } 1257 LIST_FOREACH(pr, &allprocess, ps_list) { 1258 /* 1259 * skip system, exiting, embryonic and undead 1260 * processes 1261 */ 1262 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1263 continue; 1264 if (arg > 0 && pr->ps_pid != (pid_t)arg) { 1265 /* not the pid we are looking for */ 1266 continue; 1267 } 1268 fdp = pr->ps_fd; 1269 if (pr->ps_textvp) 1270 FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr); 1271 if (fdp->fd_cdir) 1272 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1273 if (fdp->fd_rdir) 1274 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1275 if (pr->ps_tracevp) 1276 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1277 for (i = 0; i < fdp->fd_nfiles; i++) { 1278 if ((fp = fdp->fd_ofiles[i]) == NULL) 1279 continue; 1280 if (!FILE_IS_USABLE(fp)) 1281 continue; 1282 FILLIT(fp, fdp, i, NULL, pr); 1283 } 1284 } 1285 break; 1286 case KERN_FILE_BYUID: 1287 LIST_FOREACH(pr, &allprocess, ps_list) { 1288 /* 1289 * skip system, exiting, embryonic and undead 1290 * processes 1291 */ 1292 if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING)) 1293 continue; 1294 if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) { 1295 /* not the uid we are looking for */ 1296 continue; 1297 } 1298 fdp = pr->ps_fd; 1299 if (fdp->fd_cdir) 1300 FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr); 1301 if (fdp->fd_rdir) 1302 FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr); 1303 if (pr->ps_tracevp) 1304 FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr); 1305 for (i = 0; i < fdp->fd_nfiles; i++) { 1306 if ((fp = fdp->fd_ofiles[i]) == NULL) 1307 continue; 1308 if (!FILE_IS_USABLE(fp)) 1309 continue; 1310 FILLIT(fp, fdp, i, NULL, pr); 1311 } 1312 } 1313 break; 1314 default: 1315 error = EINVAL; 1316 break; 1317 } 1318 free(kf, M_TEMP, 0); 1319 1320 if (!error) { 1321 if (where == NULL) 1322 needed += KERN_FILESLOP * elem_size; 1323 else if (*sizep < needed) 1324 error = ENOMEM; 1325 *sizep = needed; 1326 } 1327 1328 return (error); 1329 } 1330 1331 /* 1332 * try over estimating by 5 procs 1333 */ 1334 #define KERN_PROCSLOP 5 1335 1336 int 1337 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep) 1338 { 1339 struct kinfo_proc *kproc = NULL; 1340 struct proc *p; 1341 struct process *pr; 1342 char *dp; 1343 int arg, buflen, doingzomb, elem_size, elem_count; 1344 int error, needed, op; 1345 int dothreads = 0; 1346 int show_pointers; 1347 1348 dp = where; 1349 buflen = where != NULL ? *sizep : 0; 1350 needed = error = 0; 1351 1352 if (namelen != 4 || name[2] < 0 || name[3] < 0 || 1353 name[2] > sizeof(*kproc)) 1354 return (EINVAL); 1355 op = name[0]; 1356 arg = name[1]; 1357 elem_size = name[2]; 1358 elem_count = name[3]; 1359 1360 dothreads = op & KERN_PROC_SHOW_THREADS; 1361 op &= ~KERN_PROC_SHOW_THREADS; 1362 1363 show_pointers = suser(curproc, 0) == 0; 1364 1365 if (where != NULL) 1366 kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK); 1367 1368 pr = LIST_FIRST(&allprocess); 1369 doingzomb = 0; 1370 again: 1371 for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) { 1372 /* XXX skip processes in the middle of being zapped */ 1373 if (pr->ps_pgrp == NULL) 1374 continue; 1375 1376 /* 1377 * Skip embryonic processes. 1378 */ 1379 if (pr->ps_flags & PS_EMBRYO) 1380 continue; 1381 1382 /* 1383 * TODO - make more efficient (see notes below). 1384 */ 1385 switch (op) { 1386 1387 case KERN_PROC_PID: 1388 /* could do this with just a lookup */ 1389 if (pr->ps_pid != (pid_t)arg) 1390 continue; 1391 break; 1392 1393 case KERN_PROC_PGRP: 1394 /* could do this by traversing pgrp */ 1395 if (pr->ps_pgrp->pg_id != (pid_t)arg) 1396 continue; 1397 break; 1398 1399 case KERN_PROC_SESSION: 1400 if (pr->ps_session->s_leader == NULL || 1401 pr->ps_session->s_leader->ps_pid != (pid_t)arg) 1402 continue; 1403 break; 1404 1405 case KERN_PROC_TTY: 1406 if ((pr->ps_flags & PS_CONTROLT) == 0 || 1407 pr->ps_session->s_ttyp == NULL || 1408 pr->ps_session->s_ttyp->t_dev != (dev_t)arg) 1409 continue; 1410 break; 1411 1412 case KERN_PROC_UID: 1413 if (pr->ps_ucred->cr_uid != (uid_t)arg) 1414 continue; 1415 break; 1416 1417 case KERN_PROC_RUID: 1418 if (pr->ps_ucred->cr_ruid != (uid_t)arg) 1419 continue; 1420 break; 1421 1422 case KERN_PROC_ALL: 1423 if (pr->ps_flags & PS_SYSTEM) 1424 continue; 1425 break; 1426 1427 case KERN_PROC_KTHREAD: 1428 /* no filtering */ 1429 break; 1430 1431 default: 1432 error = EINVAL; 1433 goto err; 1434 } 1435 1436 if (buflen >= elem_size && elem_count > 0) { 1437 fill_kproc(pr, kproc, NULL, show_pointers); 1438 error = copyout(kproc, dp, elem_size); 1439 if (error) 1440 goto err; 1441 dp += elem_size; 1442 buflen -= elem_size; 1443 elem_count--; 1444 } 1445 needed += elem_size; 1446 1447 /* Skip per-thread entries if not required by op */ 1448 if (!dothreads) 1449 continue; 1450 1451 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1452 if (buflen >= elem_size && elem_count > 0) { 1453 fill_kproc(pr, kproc, p, show_pointers); 1454 error = copyout(kproc, dp, elem_size); 1455 if (error) 1456 goto err; 1457 dp += elem_size; 1458 buflen -= elem_size; 1459 elem_count--; 1460 } 1461 needed += elem_size; 1462 } 1463 } 1464 if (doingzomb == 0) { 1465 pr = LIST_FIRST(&zombprocess); 1466 doingzomb++; 1467 goto again; 1468 } 1469 if (where != NULL) { 1470 *sizep = dp - where; 1471 if (needed > *sizep) { 1472 error = ENOMEM; 1473 goto err; 1474 } 1475 } else { 1476 needed += KERN_PROCSLOP * elem_size; 1477 *sizep = needed; 1478 } 1479 err: 1480 if (kproc) 1481 free(kproc, M_TEMP, 0); 1482 return (error); 1483 } 1484 1485 /* 1486 * Fill in a kproc structure for the specified process. 1487 */ 1488 void 1489 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p, 1490 int show_pointers) 1491 { 1492 struct session *s = pr->ps_session; 1493 struct tty *tp; 1494 struct timespec ut, st; 1495 int isthread; 1496 1497 isthread = p != NULL; 1498 if (!isthread) 1499 p = pr->ps_mainproc; /* XXX */ 1500 1501 FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp, 1502 p, pr, s, pr->ps_vmspace, pr->ps_limit, pr->ps_sigacts, isthread, 1503 show_pointers); 1504 1505 /* stuff that's too painful to generalize into the macros */ 1506 ki->p_pid = pr->ps_pid; 1507 if (pr->ps_pptr) 1508 ki->p_ppid = pr->ps_pptr->ps_pid; 1509 if (s->s_leader) 1510 ki->p_sid = s->s_leader->ps_pid; 1511 1512 if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) { 1513 ki->p_tdev = tp->t_dev; 1514 ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1; 1515 if (show_pointers) 1516 ki->p_tsess = PTRTOINT64(tp->t_session); 1517 } else { 1518 ki->p_tdev = NODEV; 1519 ki->p_tpgid = -1; 1520 } 1521 1522 /* fixups that can only be done in the kernel */ 1523 if ((pr->ps_flags & PS_ZOMBIE) == 0) { 1524 if ((pr->ps_flags & PS_EMBRYO) == 0) 1525 ki->p_vm_rssize = vm_resident_count(pr->ps_vmspace); 1526 calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL); 1527 ki->p_uutime_sec = ut.tv_sec; 1528 ki->p_uutime_usec = ut.tv_nsec/1000; 1529 ki->p_ustime_sec = st.tv_sec; 1530 ki->p_ustime_usec = st.tv_nsec/1000; 1531 1532 #ifdef MULTIPROCESSOR 1533 if (isthread && p->p_cpu != NULL) 1534 ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu); 1535 #endif 1536 } 1537 1538 /* get %cpu and schedule state: just one thread or sum of all? */ 1539 if (isthread) { 1540 ki->p_pctcpu = p->p_pctcpu; 1541 ki->p_stat = p->p_stat; 1542 } else { 1543 ki->p_pctcpu = 0; 1544 ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL; 1545 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 1546 ki->p_pctcpu += p->p_pctcpu; 1547 /* find best state: ONPROC > RUN > STOP > SLEEP > .. */ 1548 if (p->p_stat == SONPROC || ki->p_stat == SONPROC) 1549 ki->p_stat = SONPROC; 1550 else if (p->p_stat == SRUN || ki->p_stat == SRUN) 1551 ki->p_stat = SRUN; 1552 else if (p->p_stat == SSTOP || ki->p_stat == SSTOP) 1553 ki->p_stat = SSTOP; 1554 else if (p->p_stat == SSLEEP) 1555 ki->p_stat = SSLEEP; 1556 } 1557 } 1558 } 1559 1560 int 1561 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1562 struct proc *cp) 1563 { 1564 struct process *vpr; 1565 pid_t pid; 1566 struct ps_strings pss; 1567 struct iovec iov; 1568 struct uio uio; 1569 int error, cnt, op; 1570 size_t limit; 1571 char **rargv, **vargv; /* reader vs. victim */ 1572 char *rarg, *varg, *buf; 1573 struct vmspace *vm; 1574 1575 if (namelen > 2) 1576 return (ENOTDIR); 1577 if (namelen < 2) 1578 return (EINVAL); 1579 1580 pid = name[0]; 1581 op = name[1]; 1582 1583 switch (op) { 1584 case KERN_PROC_ARGV: 1585 case KERN_PROC_NARGV: 1586 case KERN_PROC_ENV: 1587 case KERN_PROC_NENV: 1588 break; 1589 default: 1590 return (EOPNOTSUPP); 1591 } 1592 1593 if ((vpr = prfind(pid)) == NULL) 1594 return (ESRCH); 1595 1596 if (oldp == NULL) { 1597 if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV) 1598 *oldlenp = sizeof(int); 1599 else 1600 *oldlenp = ARG_MAX; /* XXX XXX XXX */ 1601 return (0); 1602 } 1603 1604 /* Either system process or exiting/zombie */ 1605 if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1606 return (EINVAL); 1607 1608 /* Execing - danger. */ 1609 if ((vpr->ps_flags & PS_INEXEC)) 1610 return (EBUSY); 1611 1612 /* Only owner or root can get env */ 1613 if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) && 1614 (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 1615 (error = suser(cp, 0)) != 0)) 1616 return (error); 1617 1618 vm = vpr->ps_vmspace; 1619 vm->vm_refcnt++; 1620 vpr = NULL; 1621 1622 buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 1623 1624 iov.iov_base = &pss; 1625 iov.iov_len = sizeof(pss); 1626 uio.uio_iov = &iov; 1627 uio.uio_iovcnt = 1; 1628 uio.uio_offset = (off_t)(vaddr_t)PS_STRINGS; 1629 uio.uio_resid = sizeof(pss); 1630 uio.uio_segflg = UIO_SYSSPACE; 1631 uio.uio_rw = UIO_READ; 1632 uio.uio_procp = cp; 1633 1634 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1635 goto out; 1636 1637 if (op == KERN_PROC_NARGV) { 1638 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr); 1639 goto out; 1640 } 1641 if (op == KERN_PROC_NENV) { 1642 error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr); 1643 goto out; 1644 } 1645 1646 if (op == KERN_PROC_ARGV) { 1647 cnt = pss.ps_nargvstr; 1648 vargv = pss.ps_argvstr; 1649 } else { 1650 cnt = pss.ps_nenvstr; 1651 vargv = pss.ps_envstr; 1652 } 1653 1654 /* -1 to have space for a terminating NUL */ 1655 limit = *oldlenp - 1; 1656 *oldlenp = 0; 1657 1658 rargv = oldp; 1659 1660 /* 1661 * *oldlenp - number of bytes copied out into readers buffer. 1662 * limit - maximal number of bytes allowed into readers buffer. 1663 * rarg - pointer into readers buffer where next arg will be stored. 1664 * rargv - pointer into readers buffer where the next rarg pointer 1665 * will be stored. 1666 * vargv - pointer into victim address space where the next argument 1667 * will be read. 1668 */ 1669 1670 /* space for cnt pointers and a NULL */ 1671 rarg = (char *)(rargv + cnt + 1); 1672 *oldlenp += (cnt + 1) * sizeof(char **); 1673 1674 while (cnt > 0 && *oldlenp < limit) { 1675 size_t len, vstrlen; 1676 1677 /* Write to readers argv */ 1678 if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0) 1679 goto out; 1680 1681 /* read the victim argv */ 1682 iov.iov_base = &varg; 1683 iov.iov_len = sizeof(varg); 1684 uio.uio_iov = &iov; 1685 uio.uio_iovcnt = 1; 1686 uio.uio_offset = (off_t)(vaddr_t)vargv; 1687 uio.uio_resid = sizeof(varg); 1688 uio.uio_segflg = UIO_SYSSPACE; 1689 uio.uio_rw = UIO_READ; 1690 uio.uio_procp = cp; 1691 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1692 goto out; 1693 1694 if (varg == NULL) 1695 break; 1696 1697 /* 1698 * read the victim arg. We must jump through hoops to avoid 1699 * crossing a page boundary too much and returning an error. 1700 */ 1701 more: 1702 len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK); 1703 /* leave space for the terminating NUL */ 1704 iov.iov_base = buf; 1705 iov.iov_len = len; 1706 uio.uio_iov = &iov; 1707 uio.uio_iovcnt = 1; 1708 uio.uio_offset = (off_t)(vaddr_t)varg; 1709 uio.uio_resid = len; 1710 uio.uio_segflg = UIO_SYSSPACE; 1711 uio.uio_rw = UIO_READ; 1712 uio.uio_procp = cp; 1713 if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0) 1714 goto out; 1715 1716 for (vstrlen = 0; vstrlen < len; vstrlen++) { 1717 if (buf[vstrlen] == '\0') 1718 break; 1719 } 1720 1721 /* Don't overflow readers buffer. */ 1722 if (*oldlenp + vstrlen + 1 >= limit) { 1723 error = ENOMEM; 1724 goto out; 1725 } 1726 1727 if ((error = copyout(buf, rarg, vstrlen)) != 0) 1728 goto out; 1729 1730 *oldlenp += vstrlen; 1731 rarg += vstrlen; 1732 1733 /* The string didn't end in this page? */ 1734 if (vstrlen == len) { 1735 varg += vstrlen; 1736 goto more; 1737 } 1738 1739 /* End of string. Terminate it with a NUL */ 1740 buf[0] = '\0'; 1741 if ((error = copyout(buf, rarg, 1)) != 0) 1742 goto out; 1743 *oldlenp += 1; 1744 rarg += 1; 1745 1746 vargv++; 1747 rargv++; 1748 cnt--; 1749 } 1750 1751 if (*oldlenp >= limit) { 1752 error = ENOMEM; 1753 goto out; 1754 } 1755 1756 /* Write the terminating null */ 1757 rarg = NULL; 1758 error = copyout(&rarg, rargv, sizeof(rarg)); 1759 1760 out: 1761 uvmspace_free(vm); 1762 free(buf, M_TEMP, 0); 1763 return (error); 1764 } 1765 1766 int 1767 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1768 struct proc *cp) 1769 { 1770 struct process *findpr; 1771 struct vnode *vp; 1772 pid_t pid; 1773 int error; 1774 size_t lenused, len; 1775 char *path, *bp, *bend; 1776 1777 if (namelen > 1) 1778 return (ENOTDIR); 1779 if (namelen < 1) 1780 return (EINVAL); 1781 1782 pid = name[0]; 1783 if ((findpr = prfind(pid)) == NULL) 1784 return (ESRCH); 1785 1786 if (oldp == NULL) { 1787 *oldlenp = MAXPATHLEN * 4; 1788 return (0); 1789 } 1790 1791 /* Either system process or exiting/zombie */ 1792 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1793 return (EINVAL); 1794 1795 /* Only owner or root can get cwd */ 1796 if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid && 1797 (error = suser(cp, 0)) != 0) 1798 return (error); 1799 1800 len = *oldlenp; 1801 if (len > MAXPATHLEN * 4) 1802 len = MAXPATHLEN * 4; 1803 else if (len < 2) 1804 return (ERANGE); 1805 *oldlenp = 0; 1806 1807 /* snag a reference to the vnode before we can sleep */ 1808 vp = findpr->ps_fd->fd_cdir; 1809 vref(vp); 1810 1811 path = malloc(len, M_TEMP, M_WAITOK); 1812 1813 bp = &path[len]; 1814 bend = bp; 1815 *(--bp) = '\0'; 1816 1817 /* Same as sys__getcwd */ 1818 error = vfs_getcwd_common(vp, NULL, 1819 &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp); 1820 if (error == 0) { 1821 *oldlenp = lenused = bend - bp; 1822 error = copyout(bp, oldp, lenused); 1823 } 1824 1825 vrele(vp); 1826 free(path, M_TEMP, 0); 1827 1828 return (error); 1829 } 1830 1831 int 1832 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen, 1833 void *oldp, size_t *oldlenp, struct proc *cp) 1834 { 1835 struct process *findpr; 1836 pid_t pid; 1837 int error, flag; 1838 1839 if (namelen > 1) 1840 return (ENOTDIR); 1841 if (namelen < 1) 1842 return (EINVAL); 1843 1844 pid = name[0]; 1845 if ((findpr = prfind(pid)) == NULL) 1846 return (ESRCH); 1847 1848 /* Either system process or exiting/zombie */ 1849 if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING)) 1850 return (EINVAL); 1851 1852 /* Only root can change PS_NOBROADCASTKILL */ 1853 if (newp != 0 && (error = suser(cp, 0)) != 0) 1854 return (error); 1855 1856 /* get the PS_NOBROADCASTKILL flag */ 1857 flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0; 1858 1859 error = sysctl_int(oldp, oldlenp, newp, newlen, &flag); 1860 if (error == 0 && newp) { 1861 if (flag) 1862 atomic_setbits_int(&findpr->ps_flags, 1863 PS_NOBROADCASTKILL); 1864 else 1865 atomic_clearbits_int(&findpr->ps_flags, 1866 PS_NOBROADCASTKILL); 1867 } 1868 1869 return (error); 1870 } 1871 #endif 1872 1873 /* 1874 * Initialize disknames/diskstats for export by sysctl. If update is set, 1875 * then we simply update the disk statistics information. 1876 */ 1877 int 1878 sysctl_diskinit(int update, struct proc *p) 1879 { 1880 struct disklabel *dl; 1881 struct diskstats *sdk; 1882 struct disk *dk; 1883 char duid[17]; 1884 u_int64_t uid = 0; 1885 int i, tlen, l; 1886 1887 if ((i = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0) 1888 return i; 1889 1890 if (disk_change) { 1891 for (dk = TAILQ_FIRST(&disklist), tlen = 0; dk; 1892 dk = TAILQ_NEXT(dk, dk_link)) { 1893 if (dk->dk_name) 1894 tlen += strlen(dk->dk_name); 1895 tlen += 18; /* label uid + separators */ 1896 } 1897 tlen++; 1898 1899 if (disknames) 1900 free(disknames, M_SYSCTL, 0); 1901 if (diskstats) 1902 free(diskstats, M_SYSCTL, 0); 1903 diskstats = NULL; 1904 disknames = NULL; 1905 diskstats = mallocarray(disk_count, sizeof(struct diskstats), 1906 M_SYSCTL, M_WAITOK); 1907 disknames = malloc(tlen, M_SYSCTL, M_WAITOK); 1908 disknames[0] = '\0'; 1909 1910 for (dk = TAILQ_FIRST(&disklist), i = 0, l = 0; dk; 1911 dk = TAILQ_NEXT(dk, dk_link), i++) { 1912 dl = dk->dk_label; 1913 memset(duid, 0, sizeof(duid)); 1914 if (dl && memcmp(dl->d_uid, &uid, sizeof(dl->d_uid))) { 1915 snprintf(duid, sizeof(duid), 1916 "%02hx%02hx%02hx%02hx" 1917 "%02hx%02hx%02hx%02hx", 1918 dl->d_uid[0], dl->d_uid[1], dl->d_uid[2], 1919 dl->d_uid[3], dl->d_uid[4], dl->d_uid[5], 1920 dl->d_uid[6], dl->d_uid[7]); 1921 } 1922 snprintf(disknames + l, tlen - l, "%s:%s,", 1923 dk->dk_name ? dk->dk_name : "", duid); 1924 l += strlen(disknames + l); 1925 sdk = diskstats + i; 1926 strlcpy(sdk->ds_name, dk->dk_name, 1927 sizeof(sdk->ds_name)); 1928 mtx_enter(&dk->dk_mtx); 1929 sdk->ds_busy = dk->dk_busy; 1930 sdk->ds_rxfer = dk->dk_rxfer; 1931 sdk->ds_wxfer = dk->dk_wxfer; 1932 sdk->ds_seek = dk->dk_seek; 1933 sdk->ds_rbytes = dk->dk_rbytes; 1934 sdk->ds_wbytes = dk->dk_wbytes; 1935 sdk->ds_attachtime = dk->dk_attachtime; 1936 sdk->ds_timestamp = dk->dk_timestamp; 1937 sdk->ds_time = dk->dk_time; 1938 mtx_leave(&dk->dk_mtx); 1939 } 1940 1941 /* Eliminate trailing comma */ 1942 if (l != 0) 1943 disknames[l - 1] = '\0'; 1944 disk_change = 0; 1945 } else if (update) { 1946 /* Just update, number of drives hasn't changed */ 1947 for (dk = TAILQ_FIRST(&disklist), i = 0; dk; 1948 dk = TAILQ_NEXT(dk, dk_link), i++) { 1949 sdk = diskstats + i; 1950 strlcpy(sdk->ds_name, dk->dk_name, 1951 sizeof(sdk->ds_name)); 1952 mtx_enter(&dk->dk_mtx); 1953 sdk->ds_busy = dk->dk_busy; 1954 sdk->ds_rxfer = dk->dk_rxfer; 1955 sdk->ds_wxfer = dk->dk_wxfer; 1956 sdk->ds_seek = dk->dk_seek; 1957 sdk->ds_rbytes = dk->dk_rbytes; 1958 sdk->ds_wbytes = dk->dk_wbytes; 1959 sdk->ds_attachtime = dk->dk_attachtime; 1960 sdk->ds_timestamp = dk->dk_timestamp; 1961 sdk->ds_time = dk->dk_time; 1962 mtx_leave(&dk->dk_mtx); 1963 } 1964 } 1965 rw_exit_write(&sysctl_disklock); 1966 return 0; 1967 } 1968 1969 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) 1970 int 1971 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep) 1972 { 1973 #ifdef SYSVSEM 1974 struct sem_sysctl_info *semsi; 1975 #endif 1976 #ifdef SYSVSHM 1977 struct shm_sysctl_info *shmsi; 1978 #endif 1979 size_t infosize, dssize, tsize, buflen; 1980 int i, nds, error, ret; 1981 void *buf; 1982 1983 if (namelen != 1) 1984 return (EINVAL); 1985 1986 buflen = *sizep; 1987 1988 switch (*name) { 1989 case KERN_SYSVIPC_MSG_INFO: 1990 #ifdef SYSVMSG 1991 return (sysctl_sysvmsg(name, namelen, where, sizep)); 1992 #else 1993 return (EOPNOTSUPP); 1994 #endif 1995 case KERN_SYSVIPC_SEM_INFO: 1996 #ifdef SYSVSEM 1997 infosize = sizeof(semsi->seminfo); 1998 nds = seminfo.semmni; 1999 dssize = sizeof(semsi->semids[0]); 2000 break; 2001 #else 2002 return (EOPNOTSUPP); 2003 #endif 2004 case KERN_SYSVIPC_SHM_INFO: 2005 #ifdef SYSVSHM 2006 infosize = sizeof(shmsi->shminfo); 2007 nds = shminfo.shmmni; 2008 dssize = sizeof(shmsi->shmids[0]); 2009 break; 2010 #else 2011 return (EOPNOTSUPP); 2012 #endif 2013 default: 2014 return (EINVAL); 2015 } 2016 tsize = infosize + (nds * dssize); 2017 2018 /* Return just the total size required. */ 2019 if (where == NULL) { 2020 *sizep = tsize; 2021 return (0); 2022 } 2023 2024 /* Not enough room for even the info struct. */ 2025 if (buflen < infosize) { 2026 *sizep = 0; 2027 return (ENOMEM); 2028 } 2029 buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK|M_ZERO); 2030 2031 switch (*name) { 2032 #ifdef SYSVSEM 2033 case KERN_SYSVIPC_SEM_INFO: 2034 semsi = (struct sem_sysctl_info *)buf; 2035 semsi->seminfo = seminfo; 2036 break; 2037 #endif 2038 #ifdef SYSVSHM 2039 case KERN_SYSVIPC_SHM_INFO: 2040 shmsi = (struct shm_sysctl_info *)buf; 2041 shmsi->shminfo = shminfo; 2042 break; 2043 #endif 2044 } 2045 buflen -= infosize; 2046 2047 ret = 0; 2048 if (buflen > 0) { 2049 /* Fill in the IPC data structures. */ 2050 for (i = 0; i < nds; i++) { 2051 if (buflen < dssize) { 2052 ret = ENOMEM; 2053 break; 2054 } 2055 switch (*name) { 2056 #ifdef SYSVSEM 2057 case KERN_SYSVIPC_SEM_INFO: 2058 if (sema[i] != NULL) 2059 bcopy(sema[i], &semsi->semids[i], 2060 dssize); 2061 else 2062 memset(&semsi->semids[i], 0, dssize); 2063 break; 2064 #endif 2065 #ifdef SYSVSHM 2066 case KERN_SYSVIPC_SHM_INFO: 2067 if (shmsegs[i] != NULL) 2068 bcopy(shmsegs[i], &shmsi->shmids[i], 2069 dssize); 2070 else 2071 memset(&shmsi->shmids[i], 0, dssize); 2072 break; 2073 #endif 2074 } 2075 buflen -= dssize; 2076 } 2077 } 2078 *sizep -= buflen; 2079 error = copyout(buf, where, *sizep); 2080 free(buf, M_TEMP, 0); 2081 /* If copyout succeeded, use return code set earlier. */ 2082 return (error ? error : ret); 2083 } 2084 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */ 2085 2086 #ifndef SMALL_KERNEL 2087 2088 int 2089 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp) 2090 { 2091 return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0)); 2092 } 2093 2094 2095 int 2096 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2097 void *newp, size_t newlen) 2098 { 2099 struct ksensor *ks; 2100 struct sensor *us; 2101 struct ksensordev *ksd; 2102 struct sensordev *usd; 2103 int dev, numt, ret; 2104 enum sensor_type type; 2105 2106 if (namelen != 1 && namelen != 3) 2107 return (ENOTDIR); 2108 2109 dev = name[0]; 2110 if (namelen == 1) { 2111 ret = sensordev_get(dev, &ksd); 2112 if (ret) 2113 return (ret); 2114 2115 /* Grab a copy, to clear the kernel pointers */ 2116 usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO); 2117 usd->num = ksd->num; 2118 strlcpy(usd->xname, ksd->xname, sizeof(usd->xname)); 2119 memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt)); 2120 usd->sensors_count = ksd->sensors_count; 2121 2122 ret = sysctl_rdstruct(oldp, oldlenp, newp, usd, 2123 sizeof(struct sensordev)); 2124 2125 free(usd, M_TEMP, 0); 2126 return (ret); 2127 } 2128 2129 type = name[1]; 2130 numt = name[2]; 2131 2132 ret = sensor_find(dev, type, numt, &ks); 2133 if (ret) 2134 return (ret); 2135 2136 /* Grab a copy, to clear the kernel pointers */ 2137 us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO); 2138 memcpy(us->desc, ks->desc, sizeof(us->desc)); 2139 us->tv = ks->tv; 2140 us->value = ks->value; 2141 us->type = ks->type; 2142 us->status = ks->status; 2143 us->numt = ks->numt; 2144 us->flags = ks->flags; 2145 2146 ret = sysctl_rdstruct(oldp, oldlenp, newp, us, 2147 sizeof(struct sensor)); 2148 free(us, M_TEMP, 0); 2149 return (ret); 2150 } 2151 2152 int 2153 sysctl_emul(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2154 void *newp, size_t newlen) 2155 { 2156 int enabled, error; 2157 struct emul *e; 2158 2159 if (name[0] == KERN_EMUL_NUM) { 2160 if (namelen != 1) 2161 return (ENOTDIR); 2162 return (sysctl_rdint(oldp, oldlenp, newp, nexecs)); 2163 } 2164 2165 if (namelen != 2) 2166 return (ENOTDIR); 2167 if (name[0] > nexecs || name[0] < 0) 2168 return (EINVAL); 2169 e = execsw[name[0] - 1].es_emul; 2170 if (e == NULL) 2171 return (EINVAL); 2172 2173 switch (name[1]) { 2174 case KERN_EMUL_NAME: 2175 return (sysctl_rdstring(oldp, oldlenp, newp, e->e_name)); 2176 case KERN_EMUL_ENABLED: 2177 enabled = (e->e_flags & EMUL_ENABLED); 2178 error = sysctl_int(oldp, oldlenp, newp, newlen, 2179 &enabled); 2180 e->e_flags = (enabled & EMUL_ENABLED); 2181 return (error); 2182 default: 2183 return (EINVAL); 2184 } 2185 } 2186 2187 #endif /* SMALL_KERNEL */ 2188 2189 int 2190 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2191 void *newp, size_t newlen) 2192 { 2193 CPU_INFO_ITERATOR cii; 2194 struct cpu_info *ci; 2195 int i; 2196 2197 if (namelen != 1) 2198 return (ENOTDIR); 2199 2200 i = name[0]; 2201 2202 CPU_INFO_FOREACH(cii, ci) { 2203 if (i-- == 0) 2204 break; 2205 } 2206 if (i > 0) 2207 return (ENOENT); 2208 2209 return (sysctl_rdstruct(oldp, oldlenp, newp, 2210 &ci->ci_schedstate.spc_cp_time, 2211 sizeof(ci->ci_schedstate.spc_cp_time))); 2212 } 2213