Free the context, and destroy all dynamic oids registered in this context */
| 604 | |
| 605 | /* Free the context, and destroy all dynamic oids registered in this context */ |
| 606 | int |
| 607 | sysctl_ctx_free(struct sysctl_ctx_list *clist) |
| 608 | { |
| 609 | struct sysctl_ctx_entry *e, *e1; |
| 610 | int error; |
| 611 | |
| 612 | error = 0; |
| 613 | /* |
| 614 | * First perform a "dry run" to check if it's ok to remove oids. |
| 615 | * XXX FIXME |
| 616 | * XXX This algorithm is a hack. But I don't know any |
| 617 | * XXX better solution for now... |
| 618 | */ |
| 619 | SYSCTL_WLOCK(); |
| 620 | TAILQ_FOREACH(e, clist, link) { |
| 621 | error = sysctl_remove_oid_locked(e->entry, 0, 0); |
| 622 | if (error) |
| 623 | break; |
| 624 | } |
| 625 | /* |
| 626 | * Restore deregistered entries, either from the end, |
| 627 | * or from the place where error occurred. |
| 628 | * e contains the entry that was not unregistered |
| 629 | */ |
| 630 | if (error) |
| 631 | e1 = TAILQ_PREV(e, sysctl_ctx_list, link); |
| 632 | else |
| 633 | e1 = TAILQ_LAST(clist, sysctl_ctx_list); |
| 634 | while (e1 != NULL) { |
| 635 | sysctl_register_oid(e1->entry); |
| 636 | e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); |
| 637 | } |
| 638 | if (error) { |
| 639 | SYSCTL_WUNLOCK(); |
| 640 | return(EBUSY); |
| 641 | } |
| 642 | /* Now really delete the entries */ |
| 643 | e = TAILQ_FIRST(clist); |
| 644 | while (e != NULL) { |
| 645 | e1 = TAILQ_NEXT(e, link); |
| 646 | error = sysctl_remove_oid_locked(e->entry, 1, 0); |
| 647 | if (error) |
| 648 | panic("sysctl_remove_oid: corrupt tree, entry: %s", |
| 649 | e->entry->oid_name); |
| 650 | free(e, M_SYSCTLOID); |
| 651 | e = e1; |
| 652 | } |
| 653 | SYSCTL_WUNLOCK(); |
| 654 | return (error); |
| 655 | } |
| 656 | |
| 657 | /* Add an entry to the context */ |
| 658 | struct sysctl_ctx_entry * |
no test coverage detected