iter.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
  2. // Copyright (C) 2020 Facebook
  3. #ifndef _GNU_SOURCE
  4. #define _GNU_SOURCE
  5. #endif
  6. #include <errno.h>
  7. #include <unistd.h>
  8. #include <linux/err.h>
  9. #include <bpf/libbpf.h>
  10. #include "main.h"
  11. static int do_pin(int argc, char **argv)
  12. {
  13. DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
  14. union bpf_iter_link_info linfo;
  15. const char *objfile, *path;
  16. struct bpf_program *prog;
  17. struct bpf_object *obj;
  18. struct bpf_link *link;
  19. int err = -1, map_fd = -1;
  20. if (!REQ_ARGS(2))
  21. usage();
  22. objfile = GET_ARG();
  23. path = GET_ARG();
  24. /* optional arguments */
  25. if (argc) {
  26. if (is_prefix(*argv, "map")) {
  27. NEXT_ARG();
  28. if (!REQ_ARGS(2)) {
  29. p_err("incorrect map spec");
  30. return -1;
  31. }
  32. map_fd = map_parse_fd(&argc, &argv, BPF_F_RDONLY);
  33. if (map_fd < 0)
  34. return -1;
  35. memset(&linfo, 0, sizeof(linfo));
  36. linfo.map.map_fd = map_fd;
  37. iter_opts.link_info = &linfo;
  38. iter_opts.link_info_len = sizeof(linfo);
  39. }
  40. }
  41. obj = bpf_object__open(objfile);
  42. if (!obj) {
  43. err = -errno;
  44. p_err("can't open objfile %s", objfile);
  45. goto close_map_fd;
  46. }
  47. err = bpf_object__load(obj);
  48. if (err) {
  49. p_err("can't load objfile %s", objfile);
  50. goto close_obj;
  51. }
  52. prog = bpf_object__next_program(obj, NULL);
  53. if (!prog) {
  54. err = -errno;
  55. p_err("can't find bpf program in objfile %s", objfile);
  56. goto close_obj;
  57. }
  58. link = bpf_program__attach_iter(prog, &iter_opts);
  59. if (!link) {
  60. err = -errno;
  61. p_err("attach_iter failed for program %s",
  62. bpf_program__name(prog));
  63. goto close_obj;
  64. }
  65. err = mount_bpffs_for_file(path);
  66. if (err)
  67. goto close_link;
  68. err = bpf_link__pin(link, path);
  69. if (err) {
  70. p_err("pin_iter failed for program %s to path %s",
  71. bpf_program__name(prog), path);
  72. goto close_link;
  73. }
  74. close_link:
  75. bpf_link__destroy(link);
  76. close_obj:
  77. bpf_object__close(obj);
  78. close_map_fd:
  79. if (map_fd >= 0)
  80. close(map_fd);
  81. return err;
  82. }
  83. static int do_help(int argc, char **argv)
  84. {
  85. fprintf(stderr,
  86. "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
  87. " %1$s %2$s help\n"
  88. "\n"
  89. " " HELP_SPEC_MAP "\n"
  90. " " HELP_SPEC_OPTIONS " }\n"
  91. "",
  92. bin_name, "iter");
  93. return 0;
  94. }
  95. static const struct cmd cmds[] = {
  96. { "help", do_help },
  97. { "pin", do_pin },
  98. { 0 }
  99. };
  100. int do_iter(int argc, char **argv)
  101. {
  102. return cmd_select(cmds, argc, argv, do_help);
  103. }