1 /*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Mike Karels at Berkeley Software Design, Inc. 7 * 8 * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD 9 * project, to make these variables more userfriendly. 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 * $FreeBSD: src/sys/kern/kern_sysctl.c,v 1.92.2.9 2003/05/01 22:48:09 trhodes Exp $ 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/buf.h> 43 #include <sys/sysctl.h> 44 #include <sys/malloc.h> 45 #include <sys/proc.h> 46 #include <sys/priv.h> 47 #include <sys/sysproto.h> 48 #include <sys/lock.h> 49 #include <sys/sbuf.h> 50 51 #include <sys/mplock2.h> 52 53 #include <vm/vm.h> 54 #include <vm/vm_extern.h> 55 56 static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic"); 57 static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids"); 58 59 /* 60 * The sysctllock protects the MIB tree. It also protects sysctl 61 * contexts used with dynamic sysctls. The sysctl_register_oid() and 62 * sysctl_unregister_oid() routines require the sysctllock to already 63 * be held, so the sysctl_lock() and sysctl_unlock() routines are 64 * provided for the few places in the kernel which need to use that 65 * API rather than using the dynamic API. Use of the dynamic API is 66 * strongly encouraged for most code. 67 * 68 * The sysctlmemlock is used to limit the amount of user memory wired for 69 * sysctl requests. This is implemented by serializing any userland 70 * sysctl requests larger than a single page via an exclusive lock. 71 */ 72 struct lock sysctllock; 73 static struct lock sysctlmemlock; 74 75 #define SYSCTL_INIT() lockinit(&sysctllock, \ 76 "sysctl lock", 0, LK_CANRECURSE) 77 #define SYSCTL_SLEEP(ch, wmesg, timo) \ 78 lksleep(ch, &sysctllock, 0, wmesg, timo) 79 80 static int sysctl_root(SYSCTL_HANDLER_ARGS); 81 static void sysctl_register_oid_int(struct sysctl_oid *oipd); 82 static void sysctl_unregister_oid_int(struct sysctl_oid *oipd); 83 84 struct sysctl_oid_list sysctl__children; /* root list */ 85 86 static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, 87 int recurse); 88 89 static struct sysctl_oid * 90 sysctl_find_oidname(const char *name, struct sysctl_oid_list *list, int lock) 91 { 92 struct sysctl_oid *oidp; 93 94 SLIST_FOREACH(oidp, list, oid_link) { 95 if (strcmp(oidp->oid_name, name) == 0) { 96 break; 97 } 98 } 99 return (oidp); 100 } 101 102 /* 103 * Initialization of the MIB tree. 104 * 105 * Order by number in each list. 106 */ 107 108 void 109 sysctl_register_oid(struct sysctl_oid *oidp) 110 { 111 SYSCTL_XLOCK(); 112 sysctl_register_oid_int(oidp); 113 SYSCTL_XUNLOCK(); 114 } 115 116 static void 117 sysctl_register_oid_int(struct sysctl_oid *oidp) 118 { 119 struct sysctl_oid_list *parent = oidp->oid_parent; 120 struct sysctl_oid *p; 121 struct sysctl_oid *q; 122 123 /* 124 * Finish initialization from sysctl_set or add. 125 */ 126 lockinit(&oidp->oid_lock, "oidlk", 0, LK_CANRECURSE); 127 128 /* 129 * First check if another oid with the same name already 130 * exists in the parent's list. 131 */ 132 p = sysctl_find_oidname(oidp->oid_name, parent, 0); 133 if (p != NULL) { 134 if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) 135 p->oid_refcnt++; 136 else 137 kprintf("can't re-use a leaf (%s)!\n", p->oid_name); 138 return; 139 } 140 141 /* 142 * If this oid has a number OID_AUTO, give it a number which 143 * is greater than any current oid. Make sure it is at least 144 * 256 to leave space for pre-assigned oid numbers. 145 */ 146 if (oidp->oid_number == OID_AUTO) { 147 int newoid = 0x100; /* minimum AUTO oid */ 148 149 /* 150 * Adjust based on highest oid in parent list 151 */ 152 SLIST_FOREACH(p, parent, oid_link) { 153 if (newoid <= p->oid_number) 154 newoid = p->oid_number + 1; 155 } 156 oidp->oid_number = newoid; 157 } 158 159 /* 160 * Insert the oid into the parent's list in order. 161 */ 162 q = NULL; 163 SLIST_FOREACH(p, parent, oid_link) { 164 if (oidp->oid_number < p->oid_number) 165 break; 166 q = p; 167 } 168 if (q) 169 SLIST_INSERT_AFTER(q, oidp, oid_link); 170 else 171 SLIST_INSERT_HEAD(parent, oidp, oid_link); 172 } 173 174 void 175 sysctl_unregister_oid(struct sysctl_oid *oidp) 176 { 177 SYSCTL_XLOCK(); 178 sysctl_unregister_oid_int(oidp); 179 SYSCTL_XUNLOCK(); 180 } 181 182 static void 183 sysctl_unregister_oid_int(struct sysctl_oid *oidp) 184 { 185 struct sysctl_oid *p; 186 187 if (oidp->oid_number == OID_AUTO) 188 panic("Trying to unregister OID_AUTO entry: %p", oidp); 189 190 SLIST_FOREACH(p, oidp->oid_parent, oid_link) { 191 if (p != oidp) 192 continue; 193 SLIST_REMOVE(oidp->oid_parent, oidp, sysctl_oid, oid_link); 194 return; 195 } 196 197 /* 198 * This can happen when a module fails to register and is 199 * being unloaded afterwards. It should not be a panic() 200 * for normal use. 201 */ 202 kprintf("%s: failed to unregister sysctl\n", __func__); 203 } 204 205 /* Initialize a new context to keep track of dynamically added sysctls. */ 206 int 207 sysctl_ctx_init(struct sysctl_ctx_list *c) 208 { 209 if (c == NULL) 210 return(EINVAL); 211 TAILQ_INIT(c); 212 return(0); 213 } 214 215 /* Free the context, and destroy all dynamic oids registered in this context */ 216 int 217 sysctl_ctx_free(struct sysctl_ctx_list *clist) 218 { 219 struct sysctl_ctx_entry *e, *e1; 220 int error; 221 222 error = 0; 223 /* 224 * First perform a "dry run" to check if it's ok to remove oids. 225 * XXX FIXME 226 * XXX This algorithm is a hack. But I don't know any 227 * XXX better solution for now... 228 */ 229 SYSCTL_XLOCK(); 230 TAILQ_FOREACH(e, clist, link) { 231 error = sysctl_remove_oid_locked(e->entry, 0, 0); 232 if (error) 233 break; 234 } 235 /* 236 * Restore deregistered entries, either from the end, 237 * or from the place where error occured. 238 * e contains the entry that was not unregistered 239 */ 240 if (error) 241 e1 = TAILQ_PREV(e, sysctl_ctx_list, link); 242 else 243 e1 = TAILQ_LAST(clist, sysctl_ctx_list); 244 while (e1 != NULL) { 245 sysctl_register_oid(e1->entry); 246 e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); 247 } 248 if (error) { 249 SYSCTL_XUNLOCK(); 250 return(EBUSY); 251 } 252 /* Now really delete the entries */ 253 e = TAILQ_FIRST(clist); 254 while (e != NULL) { 255 e1 = TAILQ_NEXT(e, link); 256 error = sysctl_remove_oid_locked(e->entry, 1, 0); 257 if (error) 258 panic("sysctl_remove_oid: corrupt tree, entry: %s", 259 e->entry->oid_name); 260 kfree(e, M_SYSCTLOID); 261 e = e1; 262 } 263 SYSCTL_XUNLOCK(); 264 return (error); 265 } 266 267 /* Add an entry to the context */ 268 struct sysctl_ctx_entry * 269 sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 270 { 271 struct sysctl_ctx_entry *e; 272 273 SYSCTL_ASSERT_LOCKED(); 274 if (clist == NULL || oidp == NULL) 275 return(NULL); 276 e = kmalloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK); 277 e->entry = oidp; 278 TAILQ_INSERT_HEAD(clist, e, link); 279 return (e); 280 } 281 282 /* Find an entry in the context */ 283 struct sysctl_ctx_entry * 284 sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 285 { 286 struct sysctl_ctx_entry *e; 287 288 SYSCTL_ASSERT_LOCKED(); 289 if (clist == NULL || oidp == NULL) 290 return(NULL); 291 TAILQ_FOREACH(e, clist, link) { 292 if(e->entry == oidp) 293 return(e); 294 } 295 return (e); 296 } 297 298 /* 299 * Delete an entry from the context. 300 * NOTE: this function doesn't free oidp! You have to remove it 301 * with sysctl_remove_oid(). 302 */ 303 int 304 sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 305 { 306 struct sysctl_ctx_entry *e; 307 308 if (clist == NULL || oidp == NULL) 309 return (EINVAL); 310 SYSCTL_XLOCK(); 311 e = sysctl_ctx_entry_find(clist, oidp); 312 if (e != NULL) { 313 TAILQ_REMOVE(clist, e, link); 314 SYSCTL_XUNLOCK(); 315 kfree(e, M_SYSCTLOID); 316 return (0); 317 } else { 318 SYSCTL_XUNLOCK(); 319 return (ENOENT); 320 } 321 } 322 323 /* 324 * Remove dynamically created sysctl trees. 325 * oidp - top of the tree to be removed 326 * del - if 0 - just deregister, otherwise free up entries as well 327 * recurse - if != 0 traverse the subtree to be deleted 328 */ 329 int 330 sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) 331 { 332 int error; 333 334 SYSCTL_XLOCK(); 335 error = sysctl_remove_oid_locked(oidp, del, recurse); 336 SYSCTL_XUNLOCK(); 337 return (error); 338 } 339 340 static int 341 sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) 342 { 343 struct sysctl_oid *p, *tmp; 344 int error; 345 346 SYSCTL_ASSERT_LOCKED(); 347 if (oidp == NULL) 348 return(EINVAL); 349 if ((oidp->oid_kind & CTLFLAG_DYN) == 0) { 350 kprintf("can't remove non-dynamic nodes!\n"); 351 return (EINVAL); 352 } 353 /* 354 * WARNING: normal method to do this should be through 355 * sysctl_ctx_free(). Use recursing as the last resort 356 * method to purge your sysctl tree of leftovers... 357 * However, if some other code still references these nodes, 358 * it will panic. 359 */ 360 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 361 if (oidp->oid_refcnt == 1) { 362 SLIST_FOREACH_MUTABLE(p, 363 SYSCTL_CHILDREN(oidp), oid_link, tmp) { 364 if (!recurse) { 365 kprintf("Warning: failed attempt to " 366 "remove oid %s with child %s\n", 367 oidp->oid_name, p->oid_name); 368 return (ENOTEMPTY); 369 } 370 error = sysctl_remove_oid_locked(p, del, 371 recurse); 372 if (error) 373 return (error); 374 } 375 if (del) 376 kfree(SYSCTL_CHILDREN(oidp), M_SYSCTLOID); 377 } 378 } 379 if (oidp->oid_refcnt > 1 ) { 380 oidp->oid_refcnt--; 381 } else { 382 if (oidp->oid_refcnt == 0) { 383 kprintf("Warning: bad oid_refcnt=%u (%s)!\n", 384 oidp->oid_refcnt, oidp->oid_name); 385 return (EINVAL); 386 } 387 sysctl_unregister_oid(oidp); 388 if (del) { 389 /* 390 * Wait for all threads running the handler to drain. 391 * This preserves the previous behavior when the 392 * sysctl lock was held across a handler invocation, 393 * and is necessary for module unload correctness. 394 */ 395 while (oidp->oid_running > 0) { 396 oidp->oid_kind |= CTLFLAG_DYING; 397 SYSCTL_SLEEP(&oidp->oid_running, "oidrm", 0); 398 } 399 if (oidp->oid_descr) 400 kfree(__DECONST(char *, oidp->oid_descr), 401 M_SYSCTLOID); 402 kfree(__DECONST(char *, oidp->oid_name), M_SYSCTLOID); 403 lockuninit(&oidp->oid_lock); 404 kfree(oidp, M_SYSCTLOID); 405 } 406 } 407 return (0); 408 } 409 410 int 411 sysctl_remove_name(struct sysctl_oid *parent, const char *name, 412 int del, int recurse) 413 { 414 struct sysctl_oid *p, *tmp; 415 int error; 416 417 error = ENOENT; 418 SYSCTL_XLOCK(); 419 SLIST_FOREACH_MUTABLE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) { 420 if (strcmp(p->oid_name, name) == 0) { 421 error = sysctl_remove_oid_locked(p, del, recurse); 422 break; 423 } 424 } 425 SYSCTL_XUNLOCK(); 426 427 return (error); 428 } 429 430 /* 431 * Create new sysctls at run time. 432 * clist may point to a valid context initialized with sysctl_ctx_init(). 433 */ 434 struct sysctl_oid * 435 sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, 436 int number, const char *name, int kind, void *arg1, int arg2, 437 int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) 438 { 439 struct sysctl_oid *oidp; 440 ssize_t len; 441 char *newname; 442 443 /* You have to hook up somewhere.. */ 444 if (parent == NULL) 445 return(NULL); 446 SYSCTL_XLOCK(); 447 /* Check if the node already exists, otherwise create it */ 448 oidp = sysctl_find_oidname(name, parent, 0); 449 if (oidp != NULL) { 450 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 451 oidp->oid_refcnt++; 452 /* Update the context */ 453 if (clist != NULL) 454 sysctl_ctx_entry_add(clist, oidp); 455 SYSCTL_XUNLOCK(); 456 return (oidp); 457 } else { 458 kprintf("can't re-use a leaf (%s)!\n", name); 459 SYSCTL_XUNLOCK(); 460 return (NULL); 461 } 462 } 463 oidp = kmalloc(sizeof(struct sysctl_oid), M_SYSCTLOID, 464 M_WAITOK | M_ZERO); 465 oidp->oid_parent = parent; 466 SLIST_NEXT(oidp, oid_link) = NULL; 467 oidp->oid_number = number; 468 oidp->oid_refcnt = 1; 469 len = strlen(name); 470 newname = kmalloc(len + 1, M_SYSCTLOID, M_WAITOK); 471 bcopy(name, newname, len + 1); 472 newname[len] = '\0'; 473 oidp->oid_name = newname; 474 oidp->oid_handler = handler; 475 oidp->oid_kind = CTLFLAG_DYN | kind; 476 if ((kind & CTLTYPE) == CTLTYPE_NODE) { 477 struct sysctl_oid_list *children; 478 479 /* Allocate space for children */ 480 children = kmalloc(sizeof(*children), M_SYSCTLOID, M_WAITOK); 481 SYSCTL_SET_CHILDREN(oidp, children); 482 SLIST_INIT(children); 483 } else { 484 oidp->oid_arg1 = arg1; 485 oidp->oid_arg2 = arg2; 486 } 487 oidp->oid_fmt = fmt; 488 if (descr) { 489 int len = strlen(descr) + 1; 490 oidp->oid_descr = kmalloc(len, M_SYSCTLOID, M_WAITOK); 491 strcpy((char *)(uintptr_t)(const void *)oidp->oid_descr, descr); 492 }; 493 /* Update the context, if used */ 494 if (clist != NULL) 495 sysctl_ctx_entry_add(clist, oidp); 496 /* Register this oid */ 497 sysctl_register_oid_int(oidp); 498 SYSCTL_XUNLOCK(); 499 return (oidp); 500 } 501 502 /* 503 * Rename an existing oid. 504 */ 505 void 506 sysctl_rename_oid(struct sysctl_oid *oidp, const char *name) 507 { 508 char *newname; 509 char *oldname; 510 511 newname = kstrdup(name, M_SYSCTLOID); 512 SYSCTL_XLOCK(); 513 oldname = __DECONST(char *, oidp->oid_name); 514 oidp->oid_name = newname; 515 SYSCTL_XUNLOCK(); 516 kfree(oldname, M_SYSCTLOID); 517 } 518 519 /* 520 * Register the kernel's oids on startup. 521 */ 522 SET_DECLARE(sysctl_set, struct sysctl_oid); 523 524 static void 525 sysctl_register_all(void *arg) 526 { 527 struct sysctl_oid **oidp; 528 529 lockinit(&sysctlmemlock, "sysctl mem", 0, LK_CANRECURSE); 530 SYSCTL_INIT(); 531 SYSCTL_XLOCK(); 532 SET_FOREACH(oidp, sysctl_set) 533 sysctl_register_oid(*oidp); 534 SYSCTL_XUNLOCK(); 535 } 536 SYSINIT(sysctl, SI_BOOT1_POST, SI_ORDER_ANY, sysctl_register_all, 0); 537 538 /* 539 * "Staff-functions" 540 * 541 * These functions implement a presently undocumented interface 542 * used by the sysctl program to walk the tree, and get the type 543 * so it can print the value. 544 * This interface is under work and consideration, and should probably 545 * be killed with a big axe by the first person who can find the time. 546 * (be aware though, that the proper interface isn't as obvious as it 547 * may seem, there are various conflicting requirements. 548 * 549 * {0,0} kprintf the entire MIB-tree. 550 * {0,1,...} return the name of the "..." OID. 551 * {0,2,...} return the next OID. 552 * {0,3} return the OID of the name in "new" 553 * {0,4,...} return the kind & format info for the "..." OID. 554 */ 555 556 static void 557 sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) 558 { 559 int k; 560 struct sysctl_oid *oidp; 561 562 SLIST_FOREACH(oidp, l, oid_link) { 563 564 for (k=0; k<i; k++) 565 kprintf(" "); 566 567 kprintf("%d %s ", oidp->oid_number, oidp->oid_name); 568 569 kprintf("%c%c", 570 oidp->oid_kind & CTLFLAG_RD ? 'R':' ', 571 oidp->oid_kind & CTLFLAG_WR ? 'W':' '); 572 573 if (oidp->oid_handler) 574 kprintf(" *Handler"); 575 576 switch (oidp->oid_kind & CTLTYPE) { 577 case CTLTYPE_NODE: 578 kprintf(" Node\n"); 579 if (!oidp->oid_handler) { 580 sysctl_sysctl_debug_dump_node( 581 oidp->oid_arg1, i+2); 582 } 583 break; 584 case CTLTYPE_INT: kprintf(" Int\n"); break; 585 case CTLTYPE_STRING: kprintf(" String\n"); break; 586 case CTLTYPE_QUAD: kprintf(" Quad\n"); break; 587 case CTLTYPE_OPAQUE: kprintf(" Opaque/struct\n"); break; 588 default: kprintf("\n"); 589 } 590 591 } 592 } 593 594 static int 595 sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS) 596 { 597 int error; 598 599 error = priv_check(req->td, PRIV_SYSCTL_DEBUG); 600 if (error) 601 return (error); 602 sysctl_sysctl_debug_dump_node(&sysctl__children, 0); 603 604 return (ENOENT); 605 } 606 607 SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD, 608 0, 0, sysctl_sysctl_debug, "-", ""); 609 610 static int 611 sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) 612 { 613 int *name = (int *) arg1; 614 u_int namelen = arg2; 615 int error = 0; 616 struct sysctl_oid *oid; 617 struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; 618 char buf[10]; 619 620 while (namelen) { 621 if (!lsp) { 622 ksnprintf(buf, sizeof(buf), "%d", *name); 623 if (req->oldidx) 624 error = SYSCTL_OUT(req, ".", 1); 625 if (!error) 626 error = SYSCTL_OUT(req, buf, strlen(buf)); 627 if (error) 628 goto out; 629 namelen--; 630 name++; 631 continue; 632 } 633 lsp2 = NULL; 634 SLIST_FOREACH(oid, lsp, oid_link) { 635 if (oid->oid_number != *name) 636 continue; 637 638 if (req->oldidx) 639 error = SYSCTL_OUT(req, ".", 1); 640 if (!error) 641 error = SYSCTL_OUT(req, oid->oid_name, 642 strlen(oid->oid_name)); 643 if (error) 644 goto out; 645 646 namelen--; 647 name++; 648 649 if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) 650 break; 651 652 if (oid->oid_handler) 653 break; 654 655 lsp2 = SYSCTL_CHILDREN(oid); 656 break; 657 } 658 lsp = lsp2; 659 } 660 error = SYSCTL_OUT(req, "", 1); 661 out: 662 return (error); 663 } 664 665 SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD, sysctl_sysctl_name, ""); 666 667 static int 668 sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, 669 int *next, int *len, int level, struct sysctl_oid **oidpp) 670 { 671 struct sysctl_oid *oidp; 672 673 *len = level; 674 SLIST_FOREACH(oidp, lsp, oid_link) { 675 *next = oidp->oid_number; 676 *oidpp = oidp; 677 678 if (oidp->oid_kind & CTLFLAG_SKIP) 679 continue; 680 681 if (!namelen) { 682 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 683 return (0); 684 if (oidp->oid_handler) 685 /* We really should call the handler here...*/ 686 return (0); 687 lsp = SYSCTL_CHILDREN(oidp); 688 if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, 689 len, level+1, oidpp)) 690 return (0); 691 goto emptynode; 692 } 693 694 if (oidp->oid_number < *name) 695 continue; 696 697 if (oidp->oid_number > *name) { 698 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 699 return (0); 700 if (oidp->oid_handler) 701 return (0); 702 lsp = SYSCTL_CHILDREN(oidp); 703 if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, 704 next+1, len, level+1, oidpp)) 705 return (0); 706 goto next; 707 } 708 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 709 continue; 710 711 if (oidp->oid_handler) 712 continue; 713 714 lsp = SYSCTL_CHILDREN(oidp); 715 if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1, 716 len, level+1, oidpp)) 717 return (0); 718 next: 719 namelen = 1; 720 emptynode: 721 *len = level; 722 } 723 return (1); 724 } 725 726 static int 727 sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) 728 { 729 int *name = (int *) arg1; 730 u_int namelen = arg2; 731 int i, j, error; 732 struct sysctl_oid *oid; 733 struct sysctl_oid_list *lsp = &sysctl__children; 734 int newoid[CTL_MAXNAME]; 735 736 i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid); 737 if (i) 738 return ENOENT; 739 error = SYSCTL_OUT(req, newoid, j * sizeof (int)); 740 741 return (error); 742 } 743 744 SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, ""); 745 746 static int 747 name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp) 748 { 749 struct sysctl_oid *oidp; 750 struct sysctl_oid_list *lsp = &sysctl__children; 751 char *p; 752 753 SYSCTL_ASSERT_LOCKED(); 754 755 for (*len = 0; *len < CTL_MAXNAME;) { 756 p = strsep(&name, "."); 757 758 oidp = SLIST_FIRST(lsp); 759 for (;; oidp = SLIST_NEXT(oidp, oid_link)) { 760 if (oidp == NULL) 761 return (ENOENT); 762 if (strcmp(p, oidp->oid_name) == 0) 763 break; 764 } 765 *oid++ = oidp->oid_number; 766 (*len)++; 767 768 if (name == NULL || *name == '\0') { 769 if (oidpp) 770 *oidpp = oidp; 771 return (0); 772 } 773 774 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 775 break; 776 777 if (oidp->oid_handler) 778 break; 779 780 lsp = SYSCTL_CHILDREN(oidp); 781 } 782 return (ENOENT); 783 } 784 785 static int 786 sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) 787 { 788 char *p; 789 int error, oid[CTL_MAXNAME], len; 790 struct sysctl_oid *op = NULL; 791 792 if (!req->newlen) 793 return ENOENT; 794 if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */ 795 return (ENAMETOOLONG); 796 797 p = kmalloc(req->newlen+1, M_SYSCTL, M_WAITOK); 798 799 error = SYSCTL_IN(req, p, req->newlen); 800 if (error) { 801 kfree(p, M_SYSCTL); 802 return (error); 803 } 804 805 p [req->newlen] = '\0'; 806 807 error = name2oid(p, oid, &len, &op); 808 809 kfree(p, M_SYSCTL); 810 811 if (error) 812 return (error); 813 814 error = SYSCTL_OUT(req, oid, len * sizeof *oid); 815 return (error); 816 } 817 818 SYSCTL_PROC(_sysctl, 3, name2oid, CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_SHLOCK, 819 0, 0, sysctl_sysctl_name2oid, "I", ""); 820 821 static int 822 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) 823 { 824 struct sysctl_oid *oid; 825 int error; 826 827 error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); 828 if (error) 829 return (error); 830 831 if (!oid->oid_fmt) 832 return (ENOENT); 833 error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind)); 834 if (error) 835 return (error); 836 error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); 837 return (error); 838 } 839 840 841 SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD, sysctl_sysctl_oidfmt, ""); 842 843 static int 844 sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) 845 { 846 struct sysctl_oid *oid; 847 int error; 848 849 error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); 850 if (error) 851 return (error); 852 853 if (!oid->oid_descr) 854 return (ENOENT); 855 error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1); 856 return (error); 857 } 858 859 SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD, sysctl_sysctl_oiddescr, ""); 860 861 /* 862 * Default "handler" functions. 863 */ 864 865 /* 866 * Handle an int, signed or unsigned. 867 * Two cases: 868 * a variable: point arg1 at it. 869 * a constant: pass it in arg2. 870 */ 871 872 int 873 sysctl_handle_int(SYSCTL_HANDLER_ARGS) 874 { 875 int error = 0; 876 877 if (arg1) 878 error = SYSCTL_OUT(req, arg1, sizeof(int)); 879 else 880 error = SYSCTL_OUT(req, &arg2, sizeof(int)); 881 882 if (error || !req->newptr) 883 return (error); 884 885 if (!arg1) 886 error = EPERM; 887 else 888 error = SYSCTL_IN(req, arg1, sizeof(int)); 889 return (error); 890 } 891 892 /* 893 * Handle a long, signed or unsigned. arg1 points to it. 894 */ 895 896 int 897 sysctl_handle_long(SYSCTL_HANDLER_ARGS) 898 { 899 int error = 0; 900 901 if (!arg1) 902 return (EINVAL); 903 error = SYSCTL_OUT(req, arg1, sizeof(long)); 904 905 if (error || !req->newptr) 906 return (error); 907 908 error = SYSCTL_IN(req, arg1, sizeof(long)); 909 return (error); 910 } 911 912 /* 913 * Handle a quad, signed or unsigned. arg1 points to it. 914 */ 915 916 int 917 sysctl_handle_quad(SYSCTL_HANDLER_ARGS) 918 { 919 int error = 0; 920 921 if (!arg1) 922 return (EINVAL); 923 error = SYSCTL_OUT(req, arg1, sizeof(quad_t)); 924 925 if (error || !req->newptr) 926 return (error); 927 928 error = SYSCTL_IN(req, arg1, sizeof(quad_t)); 929 return (error); 930 } 931 932 /* 933 * Handle our generic '\0' terminated 'C' string. 934 * Two cases: 935 * a variable string: point arg1 at it, arg2 is max length. 936 * a constant string: point arg1 at it, arg2 is zero. 937 */ 938 939 int 940 sysctl_handle_string(SYSCTL_HANDLER_ARGS) 941 { 942 int error=0; 943 944 error = SYSCTL_OUT(req, arg1, strlen((char *)arg1)+1); 945 946 if (error || !req->newptr) 947 return (error); 948 949 if ((req->newlen - req->newidx) >= arg2) { 950 error = EINVAL; 951 } else { 952 arg2 = (req->newlen - req->newidx); 953 error = SYSCTL_IN(req, arg1, arg2); 954 ((char *)arg1)[arg2] = '\0'; 955 } 956 957 return (error); 958 } 959 960 /* 961 * Handle any kind of opaque data. 962 * arg1 points to it, arg2 is the size. 963 */ 964 965 int 966 sysctl_handle_opaque(SYSCTL_HANDLER_ARGS) 967 { 968 int error; 969 970 error = SYSCTL_OUT(req, arg1, arg2); 971 972 if (error || !req->newptr) 973 return (error); 974 975 error = SYSCTL_IN(req, arg1, arg2); 976 977 return (error); 978 } 979 980 /* 981 * Transfer functions to/from kernel space. 982 * XXX: rather untested at this point 983 */ 984 static int 985 sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) 986 { 987 size_t i = 0; 988 989 if (req->oldptr) { 990 i = l; 991 if (i > req->oldlen - req->oldidx) 992 i = req->oldlen - req->oldidx; 993 if (i > 0) 994 bcopy(p, (char *)req->oldptr + req->oldidx, i); 995 } 996 req->oldidx += l; 997 if (req->oldptr && i != l) 998 return (ENOMEM); 999 return (0); 1000 } 1001 1002 static int 1003 sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l) 1004 { 1005 1006 if (!req->newptr) 1007 return 0; 1008 if (req->newlen - req->newidx < l) 1009 return (EINVAL); 1010 bcopy((char *)req->newptr + req->newidx, p, l); 1011 req->newidx += l; 1012 return (0); 1013 } 1014 1015 int 1016 kernel_sysctl(int *name, u_int namelen, 1017 void *old, size_t *oldlenp, 1018 void *new, size_t newlen, size_t *retval) 1019 { 1020 int error = 0; 1021 struct sysctl_req req; 1022 1023 bzero(&req, sizeof req); 1024 1025 req.td = curthread; 1026 1027 if (oldlenp) { 1028 req.oldlen = *oldlenp; 1029 } 1030 req.validlen = req.oldlen; 1031 1032 if (old) { 1033 req.oldptr= old; 1034 } 1035 1036 if (new != NULL) { 1037 req.newlen = newlen; 1038 req.newptr = new; 1039 } 1040 1041 req.oldfunc = sysctl_old_kernel; 1042 req.newfunc = sysctl_new_kernel; 1043 #if 0 1044 req.lock = REQ_UNWIRED; 1045 #endif 1046 1047 SYSCTL_SLOCK(); 1048 error = sysctl_root(0, name, namelen, &req); 1049 SYSCTL_SUNLOCK(); 1050 1051 #if 0 1052 if (req.lock == REQ_WIRED && req.validlen > 0) 1053 vsunlock(req.oldptr, req.validlen); 1054 #endif 1055 1056 if (error && error != ENOMEM) 1057 return (error); 1058 1059 if (retval) { 1060 if (req.oldptr && req.oldidx > req.validlen) 1061 *retval = req.validlen; 1062 else 1063 *retval = req.oldidx; 1064 } 1065 return (error); 1066 } 1067 1068 int 1069 kernel_sysctlbyname(char *name, 1070 void *old, size_t *oldlenp, 1071 void *new, size_t newlen, size_t *retval) 1072 { 1073 int oid[CTL_MAXNAME]; 1074 size_t oidlen, plen; 1075 int error; 1076 1077 oid[0] = 0; /* sysctl internal magic */ 1078 oid[1] = 3; /* name2oid */ 1079 oidlen = sizeof(oid); 1080 1081 error = kernel_sysctl(oid, 2, oid, &oidlen, name, strlen(name), &plen); 1082 if (error) 1083 return (error); 1084 1085 error = kernel_sysctl(oid, plen / sizeof(int), old, oldlenp, 1086 new, newlen, retval); 1087 return (error); 1088 } 1089 1090 /* 1091 * Transfer function to/from user space. 1092 */ 1093 static int 1094 sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) 1095 { 1096 int error = 0; 1097 size_t i = 0; 1098 1099 #if 0 1100 if (req->lock == 1 && req->oldptr) { 1101 vslock(req->oldptr, req->oldlen); 1102 req->lock = 2; 1103 } 1104 #endif 1105 if (req->oldptr) { 1106 i = l; 1107 if (i > req->oldlen - req->oldidx) 1108 i = req->oldlen - req->oldidx; 1109 if (i > 0) 1110 error = copyout(p, (char *)req->oldptr + req->oldidx, 1111 i); 1112 } 1113 req->oldidx += l; 1114 if (error) 1115 return (error); 1116 if (req->oldptr && i < l) 1117 return (ENOMEM); 1118 return (0); 1119 } 1120 1121 static int 1122 sysctl_new_user(struct sysctl_req *req, void *p, size_t l) 1123 { 1124 int error; 1125 1126 if (!req->newptr) 1127 return 0; 1128 if (req->newlen - req->newidx < l) 1129 return (EINVAL); 1130 error = copyin((char *)req->newptr + req->newidx, p, l); 1131 req->newidx += l; 1132 return (error); 1133 } 1134 1135 int 1136 sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, 1137 int *nindx, struct sysctl_req *req) 1138 { 1139 struct sysctl_oid_list *lsp; 1140 struct sysctl_oid *oid; 1141 int indx; 1142 1143 lsp = &sysctl__children; 1144 indx = 0; 1145 while (indx < CTL_MAXNAME) { 1146 SLIST_FOREACH(oid, lsp, oid_link) { 1147 if (oid->oid_number == name[indx]) 1148 break; 1149 } 1150 if (oid == NULL) 1151 return (ENOENT); 1152 1153 indx++; 1154 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 1155 if (oid->oid_handler != NULL || indx == namelen) { 1156 *noid = oid; 1157 if (nindx != NULL) 1158 *nindx = indx; 1159 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, 1160 ("%s found DYING node %p", __func__, oid)); 1161 return (0); 1162 } 1163 lsp = SYSCTL_CHILDREN(oid); 1164 } else if (indx == namelen) { 1165 *noid = oid; 1166 if (nindx != NULL) 1167 *nindx = indx; 1168 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, 1169 ("%s found DYING node %p", __func__, oid)); 1170 return (0); 1171 } else { 1172 return (ENOTDIR); 1173 } 1174 } 1175 return (ENOENT); 1176 } 1177 1178 /* 1179 * Traverse our tree, and find the right node, execute whatever it points 1180 * to, and return the resulting error code. 1181 */ 1182 static int 1183 sysctl_root(SYSCTL_HANDLER_ARGS) 1184 { 1185 struct thread *td = req->td; 1186 struct proc *p = td ? td->td_proc : NULL; 1187 struct sysctl_oid *oid; 1188 int error, indx; 1189 int lktype; 1190 1191 error = sysctl_find_oid(arg1, arg2, &oid, &indx, req); 1192 if (error) 1193 return (error); 1194 1195 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 1196 /* 1197 * You can't call a sysctl when it's a node, but has 1198 * no handler. Inform the user that it's a node. 1199 * The indx may or may not be the same as namelen. 1200 */ 1201 if (oid->oid_handler == NULL) 1202 return (EISDIR); 1203 } 1204 1205 /* If writing isn't allowed */ 1206 if (req->newptr && (!(oid->oid_kind & CTLFLAG_WR) || 1207 ((oid->oid_kind & CTLFLAG_SECURE) && securelevel > 0))) 1208 return (EPERM); 1209 1210 /* Most likely only root can write */ 1211 if (!(oid->oid_kind & CTLFLAG_ANYBODY) && req->newptr && p && 1212 (error = priv_check_cred(td->td_ucred, 1213 (oid->oid_kind & CTLFLAG_PRISON) ? PRIV_SYSCTL_WRITEJAIL : 1214 PRIV_SYSCTL_WRITE, 0))) 1215 return (error); 1216 1217 if (oid->oid_handler == NULL) 1218 return EINVAL; 1219 1220 /* 1221 * Default oid locking is exclusive when modifying (newptr), 1222 * shared otherwise, unless overridden with a control flag. 1223 */ 1224 lktype = (req->newptr != NULL) ? LK_EXCLUSIVE : LK_SHARED; 1225 if (oid->oid_kind & CTLFLAG_SHLOCK) 1226 lktype = LK_SHARED; 1227 if (oid->oid_kind & CTLFLAG_EXLOCK) 1228 lktype = LK_EXCLUSIVE; 1229 lockmgr(&oid->oid_lock, lktype); 1230 1231 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) 1232 error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx, 1233 req); 1234 else 1235 error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2, 1236 req); 1237 lockmgr(&oid->oid_lock, LK_RELEASE); 1238 1239 return (error); 1240 } 1241 1242 int 1243 sys___sysctl(struct sysctl_args *uap) 1244 { 1245 int error, i, name[CTL_MAXNAME]; 1246 size_t j; 1247 1248 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1249 return (EINVAL); 1250 1251 error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1252 if (error) 1253 return (error); 1254 1255 error = userland_sysctl(name, uap->namelen, 1256 uap->old, uap->oldlenp, 0, 1257 uap->new, uap->newlen, &j); 1258 if (error && error != ENOMEM) 1259 return (error); 1260 if (uap->oldlenp) { 1261 i = copyout(&j, uap->oldlenp, sizeof(j)); 1262 if (i) 1263 return (i); 1264 } 1265 return (error); 1266 } 1267 1268 /* 1269 * This is used from various compatibility syscalls too. That's why name 1270 * must be in kernel space. 1271 */ 1272 int 1273 userland_sysctl(int *name, u_int namelen, 1274 void *old, size_t *oldlenp, int inkernel, 1275 void *new, size_t newlen, size_t *retval) 1276 { 1277 int error = 0, memlocked; 1278 struct sysctl_req req; 1279 1280 bzero(&req, sizeof req); 1281 1282 req.td = curthread; 1283 req.flags = 0; 1284 1285 if (oldlenp) { 1286 if (inkernel) { 1287 req.oldlen = *oldlenp; 1288 } else { 1289 error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp)); 1290 if (error) 1291 return (error); 1292 } 1293 } 1294 req.validlen = req.oldlen; 1295 1296 if (old) { 1297 if (!useracc(old, req.oldlen, VM_PROT_WRITE)) 1298 return (EFAULT); 1299 req.oldptr= old; 1300 } 1301 1302 if (new != NULL) { 1303 if (!useracc(new, newlen, VM_PROT_READ)) 1304 return (EFAULT); 1305 req.newlen = newlen; 1306 req.newptr = new; 1307 } 1308 1309 req.oldfunc = sysctl_old_user; 1310 req.newfunc = sysctl_new_user; 1311 #if 0 1312 req.lock = REQ_UNWIRED; 1313 #endif 1314 1315 #ifdef KTRACE 1316 if (KTRPOINT(curthread, KTR_SYSCTL)) 1317 ktrsysctl(name, namelen); 1318 #endif 1319 1320 if (req.oldlen > PAGE_SIZE) { 1321 memlocked = 1; 1322 lockmgr(&sysctlmemlock, LK_EXCLUSIVE); 1323 } else 1324 memlocked = 0; 1325 1326 for (;;) { 1327 req.oldidx = 0; 1328 req.newidx = 0; 1329 SYSCTL_SLOCK(); 1330 error = sysctl_root(0, name, namelen, &req); 1331 SYSCTL_SUNLOCK(); 1332 if (error != EAGAIN) 1333 break; 1334 lwkt_yield(); 1335 } 1336 1337 #if 0 1338 if (req.lock == REQ_WIRED && req.validlen > 0) 1339 vsunlock(req.oldptr, req.validlen); 1340 #endif 1341 if (memlocked) 1342 lockmgr(&sysctlmemlock, LK_RELEASE); 1343 1344 if (error && error != ENOMEM) 1345 return (error); 1346 1347 if (retval) { 1348 if (req.oldptr && req.oldidx > req.validlen) 1349 *retval = req.validlen; 1350 else 1351 *retval = req.oldidx; 1352 } 1353 return (error); 1354 } 1355 1356 int 1357 sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high) 1358 { 1359 int error, value; 1360 1361 value = *(int *)arg1; 1362 error = sysctl_handle_int(oidp, &value, 0, req); 1363 if (error || !req->newptr) 1364 return (error); 1365 if (value < low || value > high) 1366 return (EINVAL); 1367 *(int *)arg1 = value; 1368 return (0); 1369 } 1370 1371 /* 1372 * Drain into a sysctl struct. The user buffer should be wired if a page 1373 * fault would cause issue. 1374 */ 1375 static int 1376 sbuf_sysctl_drain(void *arg, const char *data, int len) 1377 { 1378 struct sysctl_req *req = arg; 1379 int error; 1380 1381 error = SYSCTL_OUT(req, data, len); 1382 KASSERT(error >= 0, ("Got unexpected negative value %d", error)); 1383 return (error == 0 ? len : -error); 1384 } 1385 1386 struct sbuf * 1387 sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, 1388 struct sysctl_req *req) 1389 { 1390 1391 s = sbuf_new(s, buf, length, SBUF_FIXEDLEN); 1392 sbuf_set_drain(s, sbuf_sysctl_drain, req); 1393 return (s); 1394 } 1395