Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

libbpf: Streamline error reporting for low-level APIs

Ensure that low-level APIs behave uniformly across the libbpf as follows:
- in case of an error, errno is always set to the correct error code;
- when libbpf 1.0 mode is enabled with LIBBPF_STRICT_DIRECT_ERRS option to
libbpf_set_strict_mode(), return -Exxx error value directly, instead of -1;
- by default, until libbpf 1.0 is released, keep returning -1 directly.

More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).

[0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-4-andrii@kernel.org

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
f12b6543 bad2e478

+156 -50
+118 -50
tools/lib/bpf/bpf.c
··· 80 80 int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr) 81 81 { 82 82 union bpf_attr attr; 83 + int fd; 83 84 84 85 memset(&attr, '\0', sizeof(attr)); 85 86 ··· 103 102 else 104 103 attr.inner_map_fd = create_attr->inner_map_fd; 105 104 106 - return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 105 + fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 106 + return libbpf_err_errno(fd); 107 107 } 108 108 109 109 int bpf_create_map_node(enum bpf_map_type map_type, const char *name, ··· 162 160 __u32 map_flags, int node) 163 161 { 164 162 union bpf_attr attr; 163 + int fd; 165 164 166 165 memset(&attr, '\0', sizeof(attr)); 167 166 ··· 181 178 attr.numa_node = node; 182 179 } 183 180 184 - return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 181 + fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 182 + return libbpf_err_errno(fd); 185 183 } 186 184 187 185 int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name, ··· 226 222 int fd; 227 223 228 224 if (!load_attr->log_buf != !load_attr->log_buf_sz) 229 - return -EINVAL; 225 + return libbpf_err(-EINVAL); 230 226 231 227 if (load_attr->log_level > (4 | 2 | 1) || (load_attr->log_level && !load_attr->log_buf)) 232 - return -EINVAL; 228 + return libbpf_err(-EINVAL); 233 229 234 230 memset(&attr, 0, sizeof(attr)); 235 231 attr.prog_type = load_attr->prog_type; ··· 285 281 load_attr->func_info_cnt, 286 282 load_attr->func_info_rec_size, 287 283 attr.func_info_rec_size); 288 - if (!finfo) 284 + if (!finfo) { 285 + errno = E2BIG; 289 286 goto done; 287 + } 290 288 291 289 attr.func_info = ptr_to_u64(finfo); 292 290 attr.func_info_rec_size = load_attr->func_info_rec_size; ··· 299 293 load_attr->line_info_cnt, 300 294 load_attr->line_info_rec_size, 301 295 attr.line_info_rec_size); 302 - if (!linfo) 296 + if (!linfo) { 297 + errno = E2BIG; 303 298 goto done; 299 + } 304 300 305 301 attr.line_info = ptr_to_u64(linfo); 306 302 attr.line_info_rec_size = load_attr->line_info_rec_size; ··· 326 318 327 319 fd = sys_bpf_prog_load(&attr, sizeof(attr)); 328 320 done: 321 + /* free() doesn't affect errno, so we don't need to restore it */ 329 322 free(finfo); 330 323 free(linfo); 331 - return fd; 324 + return libbpf_err_errno(fd); 332 325 } 333 326 334 327 int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, ··· 338 329 struct bpf_prog_load_params p = {}; 339 330 340 331 if (!load_attr || !log_buf != !log_buf_sz) 341 - return -EINVAL; 332 + return libbpf_err(-EINVAL); 342 333 343 334 p.prog_type = load_attr->prog_type; 344 335 p.expected_attach_type = load_attr->expected_attach_type; ··· 400 391 int log_level) 401 392 { 402 393 union bpf_attr attr; 394 + int fd; 403 395 404 396 memset(&attr, 0, sizeof(attr)); 405 397 attr.prog_type = type; ··· 414 404 attr.kern_version = kern_version; 415 405 attr.prog_flags = prog_flags; 416 406 417 - return sys_bpf_prog_load(&attr, sizeof(attr)); 407 + fd = sys_bpf_prog_load(&attr, sizeof(attr)); 408 + return libbpf_err_errno(fd); 418 409 } 419 410 420 411 int bpf_map_update_elem(int fd, const void *key, const void *value, 421 412 __u64 flags) 422 413 { 423 414 union bpf_attr attr; 415 + int ret; 424 416 425 417 memset(&attr, 0, sizeof(attr)); 426 418 attr.map_fd = fd; ··· 430 418 attr.value = ptr_to_u64(value); 431 419 attr.flags = flags; 432 420 433 - return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 421 + ret = sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 422 + return libbpf_err_errno(ret); 434 423 } 435 424 436 425 int bpf_map_lookup_elem(int fd, const void *key, void *value) 437 426 { 438 427 union bpf_attr attr; 428 + int ret; 439 429 440 430 memset(&attr, 0, sizeof(attr)); 441 431 attr.map_fd = fd; 442 432 attr.key = ptr_to_u64(key); 443 433 attr.value = ptr_to_u64(value); 444 434 445 - return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 435 + ret = sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 436 + return libbpf_err_errno(ret); 446 437 } 447 438 448 439 int bpf_map_lookup_elem_flags(int fd, const void *key, void *value, __u64 flags) 449 440 { 450 441 union bpf_attr attr; 442 + int ret; 451 443 452 444 memset(&attr, 0, sizeof(attr)); 453 445 attr.map_fd = fd; ··· 459 443 attr.value = ptr_to_u64(value); 460 444 attr.flags = flags; 461 445 462 - return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 446 + ret = sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 447 + return libbpf_err_errno(ret); 463 448 } 464 449 465 450 int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value) 466 451 { 467 452 union bpf_attr attr; 453 + int ret; 468 454 469 455 memset(&attr, 0, sizeof(attr)); 470 456 attr.map_fd = fd; 471 457 attr.key = ptr_to_u64(key); 472 458 attr.value = ptr_to_u64(value); 473 459 474 - return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); 460 + ret = sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); 461 + return libbpf_err_errno(ret); 475 462 } 476 463 477 464 int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, __u64 flags) ··· 493 474 int bpf_map_delete_elem(int fd, const void *key) 494 475 { 495 476 union bpf_attr attr; 477 + int ret; 496 478 497 479 memset(&attr, 0, sizeof(attr)); 498 480 attr.map_fd = fd; 499 481 attr.key = ptr_to_u64(key); 500 482 501 - return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); 483 + ret = sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); 484 + return libbpf_err_errno(ret); 502 485 } 503 486 504 487 int bpf_map_get_next_key(int fd, const void *key, void *next_key) 505 488 { 506 489 union bpf_attr attr; 490 + int ret; 507 491 508 492 memset(&attr, 0, sizeof(attr)); 509 493 attr.map_fd = fd; 510 494 attr.key = ptr_to_u64(key); 511 495 attr.next_key = ptr_to_u64(next_key); 512 496 513 - return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr)); 497 + ret = sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr)); 498 + return libbpf_err_errno(ret); 514 499 } 515 500 516 501 int bpf_map_freeze(int fd) 517 502 { 518 503 union bpf_attr attr; 504 + int ret; 519 505 520 506 memset(&attr, 0, sizeof(attr)); 521 507 attr.map_fd = fd; 522 508 523 - return sys_bpf(BPF_MAP_FREEZE, &attr, sizeof(attr)); 509 + ret = sys_bpf(BPF_MAP_FREEZE, &attr, sizeof(attr)); 510 + return libbpf_err_errno(ret); 524 511 } 525 512 526 513 static int bpf_map_batch_common(int cmd, int fd, void *in_batch, ··· 538 513 int ret; 539 514 540 515 if (!OPTS_VALID(opts, bpf_map_batch_opts)) 541 - return -EINVAL; 516 + return libbpf_err(-EINVAL); 542 517 543 518 memset(&attr, 0, sizeof(attr)); 544 519 attr.batch.map_fd = fd; ··· 553 528 ret = sys_bpf(cmd, &attr, sizeof(attr)); 554 529 *count = attr.batch.count; 555 530 556 - return ret; 531 + return libbpf_err_errno(ret); 557 532 } 558 533 559 534 int bpf_map_delete_batch(int fd, void *keys, __u32 *count, ··· 590 565 int bpf_obj_pin(int fd, const char *pathname) 591 566 { 592 567 union bpf_attr attr; 568 + int ret; 593 569 594 570 memset(&attr, 0, sizeof(attr)); 595 571 attr.pathname = ptr_to_u64((void *)pathname); 596 572 attr.bpf_fd = fd; 597 573 598 - return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr)); 574 + ret = sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr)); 575 + return libbpf_err_errno(ret); 599 576 } 600 577 601 578 int bpf_obj_get(const char *pathname) 602 579 { 603 580 union bpf_attr attr; 581 + int fd; 604 582 605 583 memset(&attr, 0, sizeof(attr)); 606 584 attr.pathname = ptr_to_u64((void *)pathname); 607 585 608 - return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr)); 586 + fd = sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr)); 587 + return libbpf_err_errno(fd); 609 588 } 610 589 611 590 int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type, ··· 627 598 const struct bpf_prog_attach_opts *opts) 628 599 { 629 600 union bpf_attr attr; 601 + int ret; 630 602 631 603 if (!OPTS_VALID(opts, bpf_prog_attach_opts)) 632 - return -EINVAL; 604 + return libbpf_err(-EINVAL); 633 605 634 606 memset(&attr, 0, sizeof(attr)); 635 607 attr.target_fd = target_fd; ··· 639 609 attr.attach_flags = OPTS_GET(opts, flags, 0); 640 610 attr.replace_bpf_fd = OPTS_GET(opts, replace_prog_fd, 0); 641 611 642 - return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); 612 + ret = sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); 613 + return libbpf_err_errno(ret); 643 614 } 644 615 645 616 int bpf_prog_detach(int target_fd, enum bpf_attach_type type) 646 617 { 647 618 union bpf_attr attr; 619 + int ret; 648 620 649 621 memset(&attr, 0, sizeof(attr)); 650 622 attr.target_fd = target_fd; 651 623 attr.attach_type = type; 652 624 653 - return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); 625 + ret = sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); 626 + return libbpf_err_errno(ret); 654 627 } 655 628 656 629 int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type) 657 630 { 658 631 union bpf_attr attr; 632 + int ret; 659 633 660 634 memset(&attr, 0, sizeof(attr)); 661 635 attr.target_fd = target_fd; 662 636 attr.attach_bpf_fd = prog_fd; 663 637 attr.attach_type = type; 664 638 665 - return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); 639 + ret = sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); 640 + return libbpf_err_errno(ret); 666 641 } 667 642 668 643 int bpf_link_create(int prog_fd, int target_fd, ··· 676 641 { 677 642 __u32 target_btf_id, iter_info_len; 678 643 union bpf_attr attr; 644 + int fd; 679 645 680 646 if (!OPTS_VALID(opts, bpf_link_create_opts)) 681 - return -EINVAL; 647 + return libbpf_err(-EINVAL); 682 648 683 649 iter_info_len = OPTS_GET(opts, iter_info_len, 0); 684 650 target_btf_id = OPTS_GET(opts, target_btf_id, 0); 685 651 686 652 if (iter_info_len && target_btf_id) 687 - return -EINVAL; 653 + return libbpf_err(-EINVAL); 688 654 689 655 memset(&attr, 0, sizeof(attr)); 690 656 attr.link_create.prog_fd = prog_fd; ··· 701 665 attr.link_create.target_btf_id = target_btf_id; 702 666 } 703 667 704 - return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr)); 668 + fd = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr)); 669 + return libbpf_err_errno(fd); 705 670 } 706 671 707 672 int bpf_link_detach(int link_fd) 708 673 { 709 674 union bpf_attr attr; 675 + int ret; 710 676 711 677 memset(&attr, 0, sizeof(attr)); 712 678 attr.link_detach.link_fd = link_fd; 713 679 714 - return sys_bpf(BPF_LINK_DETACH, &attr, sizeof(attr)); 680 + ret = sys_bpf(BPF_LINK_DETACH, &attr, sizeof(attr)); 681 + return libbpf_err_errno(ret); 715 682 } 716 683 717 684 int bpf_link_update(int link_fd, int new_prog_fd, 718 685 const struct bpf_link_update_opts *opts) 719 686 { 720 687 union bpf_attr attr; 688 + int ret; 721 689 722 690 if (!OPTS_VALID(opts, bpf_link_update_opts)) 723 - return -EINVAL; 691 + return libbpf_err(-EINVAL); 724 692 725 693 memset(&attr, 0, sizeof(attr)); 726 694 attr.link_update.link_fd = link_fd; ··· 732 692 attr.link_update.flags = OPTS_GET(opts, flags, 0); 733 693 attr.link_update.old_prog_fd = OPTS_GET(opts, old_prog_fd, 0); 734 694 735 - return sys_bpf(BPF_LINK_UPDATE, &attr, sizeof(attr)); 695 + ret = sys_bpf(BPF_LINK_UPDATE, &attr, sizeof(attr)); 696 + return libbpf_err_errno(ret); 736 697 } 737 698 738 699 int bpf_iter_create(int link_fd) 739 700 { 740 701 union bpf_attr attr; 702 + int fd; 741 703 742 704 memset(&attr, 0, sizeof(attr)); 743 705 attr.iter_create.link_fd = link_fd; 744 706 745 - return sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr)); 707 + fd = sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr)); 708 + return libbpf_err_errno(fd); 746 709 } 747 710 748 711 int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags, ··· 762 719 attr.query.prog_ids = ptr_to_u64(prog_ids); 763 720 764 721 ret = sys_bpf(BPF_PROG_QUERY, &attr, sizeof(attr)); 722 + 765 723 if (attach_flags) 766 724 *attach_flags = attr.query.attach_flags; 767 725 *prog_cnt = attr.query.prog_cnt; 768 - return ret; 726 + 727 + return libbpf_err_errno(ret); 769 728 } 770 729 771 730 int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size, ··· 785 740 attr.test.repeat = repeat; 786 741 787 742 ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr)); 743 + 788 744 if (size_out) 789 745 *size_out = attr.test.data_size_out; 790 746 if (retval) 791 747 *retval = attr.test.retval; 792 748 if (duration) 793 749 *duration = attr.test.duration; 794 - return ret; 750 + 751 + return libbpf_err_errno(ret); 795 752 } 796 753 797 754 int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr) ··· 802 755 int ret; 803 756 804 757 if (!test_attr->data_out && test_attr->data_size_out > 0) 805 - return -EINVAL; 758 + return libbpf_err(-EINVAL); 806 759 807 760 memset(&attr, 0, sizeof(attr)); 808 761 attr.test.prog_fd = test_attr->prog_fd; ··· 817 770 attr.test.repeat = test_attr->repeat; 818 771 819 772 ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr)); 773 + 820 774 test_attr->data_size_out = attr.test.data_size_out; 821 775 test_attr->ctx_size_out = attr.test.ctx_size_out; 822 776 test_attr->retval = attr.test.retval; 823 777 test_attr->duration = attr.test.duration; 824 - return ret; 778 + 779 + return libbpf_err_errno(ret); 825 780 } 826 781 827 782 int bpf_prog_test_run_opts(int prog_fd, struct bpf_test_run_opts *opts) ··· 832 783 int ret; 833 784 834 785 if (!OPTS_VALID(opts, bpf_test_run_opts)) 835 - return -EINVAL; 786 + return libbpf_err(-EINVAL); 836 787 837 788 memset(&attr, 0, sizeof(attr)); 838 789 attr.test.prog_fd = prog_fd; ··· 850 801 attr.test.data_out = ptr_to_u64(OPTS_GET(opts, data_out, NULL)); 851 802 852 803 ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr)); 804 + 853 805 OPTS_SET(opts, data_size_out, attr.test.data_size_out); 854 806 OPTS_SET(opts, ctx_size_out, attr.test.ctx_size_out); 855 807 OPTS_SET(opts, duration, attr.test.duration); 856 808 OPTS_SET(opts, retval, attr.test.retval); 857 - return ret; 809 + 810 + return libbpf_err_errno(ret); 858 811 } 859 812 860 813 static int bpf_obj_get_next_id(__u32 start_id, __u32 *next_id, int cmd) ··· 871 820 if (!err) 872 821 *next_id = attr.next_id; 873 822 874 - return err; 823 + return libbpf_err_errno(err); 875 824 } 876 825 877 826 int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id) ··· 897 846 int bpf_prog_get_fd_by_id(__u32 id) 898 847 { 899 848 union bpf_attr attr; 849 + int fd; 900 850 901 851 memset(&attr, 0, sizeof(attr)); 902 852 attr.prog_id = id; 903 853 904 - return sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); 854 + fd = sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); 855 + return libbpf_err_errno(fd); 905 856 } 906 857 907 858 int bpf_map_get_fd_by_id(__u32 id) 908 859 { 909 860 union bpf_attr attr; 861 + int fd; 910 862 911 863 memset(&attr, 0, sizeof(attr)); 912 864 attr.map_id = id; 913 865 914 - return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); 866 + fd = sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); 867 + return libbpf_err_errno(fd); 915 868 } 916 869 917 870 int bpf_btf_get_fd_by_id(__u32 id) 918 871 { 919 872 union bpf_attr attr; 873 + int fd; 920 874 921 875 memset(&attr, 0, sizeof(attr)); 922 876 attr.btf_id = id; 923 877 924 - return sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr)); 878 + fd = sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr)); 879 + return libbpf_err_errno(fd); 925 880 } 926 881 927 882 int bpf_link_get_fd_by_id(__u32 id) 928 883 { 929 884 union bpf_attr attr; 885 + int fd; 930 886 931 887 memset(&attr, 0, sizeof(attr)); 932 888 attr.link_id = id; 933 889 934 - return sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr)); 890 + fd = sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr)); 891 + return libbpf_err_errno(fd); 935 892 } 936 893 937 894 int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len) ··· 953 894 attr.info.info = ptr_to_u64(info); 954 895 955 896 err = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr)); 897 + 956 898 if (!err) 957 899 *info_len = attr.info.info_len; 958 900 959 - return err; 901 + return libbpf_err_errno(err); 960 902 } 961 903 962 904 int bpf_raw_tracepoint_open(const char *name, int prog_fd) 963 905 { 964 906 union bpf_attr attr; 907 + int fd; 965 908 966 909 memset(&attr, 0, sizeof(attr)); 967 910 attr.raw_tracepoint.name = ptr_to_u64(name); 968 911 attr.raw_tracepoint.prog_fd = prog_fd; 969 912 970 - return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr)); 913 + fd = sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr)); 914 + return libbpf_err_errno(fd); 971 915 } 972 916 973 917 int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size, ··· 990 928 } 991 929 992 930 fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr)); 993 - if (fd == -1 && !do_log && log_buf && log_buf_size) { 931 + 932 + if (fd < 0 && !do_log && log_buf && log_buf_size) { 994 933 do_log = true; 995 934 goto retry; 996 935 } 997 936 998 - return fd; 937 + return libbpf_err_errno(fd); 999 938 } 1000 939 1001 940 int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf, __u32 *buf_len, ··· 1013 950 attr.task_fd_query.buf_len = *buf_len; 1014 951 1015 952 err = sys_bpf(BPF_TASK_FD_QUERY, &attr, sizeof(attr)); 953 + 1016 954 *buf_len = attr.task_fd_query.buf_len; 1017 955 *prog_id = attr.task_fd_query.prog_id; 1018 956 *fd_type = attr.task_fd_query.fd_type; 1019 957 *probe_offset = attr.task_fd_query.probe_offset; 1020 958 *probe_addr = attr.task_fd_query.probe_addr; 1021 959 1022 - return err; 960 + return libbpf_err_errno(err); 1023 961 } 1024 962 1025 963 int bpf_enable_stats(enum bpf_stats_type type) 1026 964 { 1027 965 union bpf_attr attr; 966 + int fd; 1028 967 1029 968 memset(&attr, 0, sizeof(attr)); 1030 969 attr.enable_stats.type = type; 1031 970 1032 - return sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr)); 971 + fd = sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr)); 972 + return libbpf_err_errno(fd); 1033 973 } 1034 974 1035 975 int bpf_prog_bind_map(int prog_fd, int map_fd, 1036 976 const struct bpf_prog_bind_opts *opts) 1037 977 { 1038 978 union bpf_attr attr; 979 + int ret; 1039 980 1040 981 if (!OPTS_VALID(opts, bpf_prog_bind_opts)) 1041 - return -EINVAL; 982 + return libbpf_err(-EINVAL); 1042 983 1043 984 memset(&attr, 0, sizeof(attr)); 1044 985 attr.prog_bind_map.prog_fd = prog_fd; 1045 986 attr.prog_bind_map.map_fd = map_fd; 1046 987 attr.prog_bind_map.flags = OPTS_GET(opts, flags, 0); 1047 988 1048 - return sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr)); 989 + ret = sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr)); 990 + return libbpf_err_errno(ret); 1049 991 }
+26
tools/lib/bpf/libbpf_internal.h
··· 11 11 12 12 #include <stdlib.h> 13 13 #include <limits.h> 14 + #include <errno.h> 15 + #include <linux/err.h> 16 + #include "libbpf_legacy.h" 14 17 15 18 /* make sure libbpf doesn't use kernel-only integer typedefs */ 16 19 #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64 ··· 438 435 int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx); 439 436 int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx); 440 437 int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx); 438 + 439 + extern enum libbpf_strict_mode libbpf_mode; 440 + 441 + /* handle direct returned errors */ 442 + static inline int libbpf_err(int ret) 443 + { 444 + if (ret < 0) 445 + errno = -ret; 446 + return ret; 447 + } 448 + 449 + /* handle errno-based (e.g., syscall or libc) errors according to libbpf's 450 + * strict mode settings 451 + */ 452 + static inline int libbpf_err_errno(int ret) 453 + { 454 + if (libbpf_mode & LIBBPF_STRICT_DIRECT_ERRS) 455 + /* errno is already assumed to be set on error */ 456 + return ret < 0 ? -errno : ret; 457 + 458 + /* legacy: on error return -1 directly and don't touch errno */ 459 + return ret; 460 + } 441 461 442 462 #endif /* __LIBBPF_LIBBPF_INTERNAL_H */
+12
tools/lib/bpf/libbpf_legacy.h
··· 33 33 * code so that it handles LIBBPF_STRICT_ALL mode before libbpf v1.0. 34 34 */ 35 35 LIBBPF_STRICT_NONE = 0x00, 36 + /* 37 + * Return NULL pointers on error, not ERR_PTR(err). 38 + * Additionally, libbpf also always sets errno to corresponding Exx 39 + * (positive) error code. 40 + */ 41 + LIBBPF_STRICT_CLEAN_PTRS = 0x01, 42 + /* 43 + * Return actual error codes from low-level APIs directly, not just -1. 44 + * Additionally, libbpf also always sets errno to corresponding Exx 45 + * (positive) error code. 46 + */ 47 + LIBBPF_STRICT_DIRECT_ERRS = 0x02, 36 48 37 49 __LIBBPF_STRICT_LAST, 38 50 };