| 673 | } |
| 674 | |
| 675 | static int |
| 676 | div_pcblist(SYSCTL_HANDLER_ARGS) |
| 677 | { |
| 678 | struct xinpgen xig; |
| 679 | struct epoch_tracker et; |
| 680 | struct inpcb *inp; |
| 681 | int error; |
| 682 | |
| 683 | if (req->newptr != 0) |
| 684 | return EPERM; |
| 685 | |
| 686 | if (req->oldptr == 0) { |
| 687 | int n; |
| 688 | |
| 689 | n = V_divcbinfo.ipi_count; |
| 690 | n += imax(n / 8, 10); |
| 691 | req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xinpcb); |
| 692 | return 0; |
| 693 | } |
| 694 | |
| 695 | if ((error = sysctl_wire_old_buffer(req, 0)) != 0) |
| 696 | return (error); |
| 697 | |
| 698 | bzero(&xig, sizeof(xig)); |
| 699 | xig.xig_len = sizeof xig; |
| 700 | xig.xig_count = V_divcbinfo.ipi_count; |
| 701 | xig.xig_gen = V_divcbinfo.ipi_gencnt; |
| 702 | xig.xig_sogen = so_gencnt; |
| 703 | error = SYSCTL_OUT(req, &xig, sizeof xig); |
| 704 | if (error) |
| 705 | return error; |
| 706 | |
| 707 | NET_EPOCH_ENTER(et); |
| 708 | for (inp = CK_LIST_FIRST(V_divcbinfo.ipi_listhead); |
| 709 | inp != NULL; |
| 710 | inp = CK_LIST_NEXT(inp, inp_list)) { |
| 711 | INP_RLOCK(inp); |
| 712 | if (inp->inp_gencnt <= xig.xig_gen) { |
| 713 | struct xinpcb xi; |
| 714 | |
| 715 | in_pcbtoxinpcb(inp, &xi); |
| 716 | INP_RUNLOCK(inp); |
| 717 | error = SYSCTL_OUT(req, &xi, sizeof xi); |
| 718 | } else |
| 719 | INP_RUNLOCK(inp); |
| 720 | } |
| 721 | NET_EPOCH_EXIT(et); |
| 722 | |
| 723 | if (!error) { |
| 724 | /* |
| 725 | * Give the user an updated idea of our state. |
| 726 | * If the generation differs from what we told |
| 727 | * her before, she knows that something happened |
| 728 | * while we were processing this request, and it |
| 729 | * might be necessary to retry. |
| 730 | */ |
| 731 | xig.xig_gen = V_divcbinfo.ipi_gencnt; |
| 732 | xig.xig_sogen = so_gencnt; |
nothing calls this directly
no test coverage detected