openat-syscall-tp-fields.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdbool.h>
  3. #include <linux/err.h>
  4. #include <linux/string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include "evlist.h"
  9. #include "evsel.h"
  10. #include "thread_map.h"
  11. #include "record.h"
  12. #include "tests.h"
  13. #include "debug.h"
  14. #include "util/mmap.h"
  15. #include <errno.h>
  16. #include <perf/mmap.h>
  17. #include "util/sample.h"
  18. #ifndef O_DIRECTORY
  19. #define O_DIRECTORY 00200000
  20. #endif
  21. #ifndef AT_FDCWD
  22. #define AT_FDCWD -100
  23. #endif
  24. static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused,
  25. int subtest __maybe_unused)
  26. {
  27. struct record_opts opts = {
  28. .target = {
  29. .uid = UINT_MAX,
  30. .uses_mmap = true,
  31. },
  32. .no_buffering = true,
  33. .freq = 1,
  34. .mmap_pages = 256,
  35. .raw_samples = true,
  36. };
  37. const char *filename = "/etc/passwd";
  38. int flags = O_RDONLY | O_DIRECTORY;
  39. struct evlist *evlist = evlist__new();
  40. struct evsel *evsel;
  41. int err = -1, i, nr_events = 0, nr_polls = 0;
  42. char sbuf[STRERR_BUFSIZE];
  43. if (evlist == NULL) {
  44. pr_debug("%s: evlist__new\n", __func__);
  45. goto out;
  46. }
  47. evsel = evsel__newtp("syscalls", "sys_enter_openat");
  48. if (IS_ERR(evsel)) {
  49. pr_debug("%s: evsel__newtp\n", __func__);
  50. goto out_delete_evlist;
  51. }
  52. evlist__add(evlist, evsel);
  53. err = evlist__create_maps(evlist, &opts.target);
  54. if (err < 0) {
  55. pr_debug("%s: evlist__create_maps\n", __func__);
  56. goto out_delete_evlist;
  57. }
  58. evsel__config(evsel, &opts, NULL);
  59. perf_thread_map__set_pid(evlist->core.threads, 0, getpid());
  60. err = evlist__open(evlist);
  61. if (err < 0) {
  62. pr_debug("perf_evlist__open: %s\n",
  63. str_error_r(errno, sbuf, sizeof(sbuf)));
  64. goto out_delete_evlist;
  65. }
  66. err = evlist__mmap(evlist, UINT_MAX);
  67. if (err < 0) {
  68. pr_debug("evlist__mmap: %s\n",
  69. str_error_r(errno, sbuf, sizeof(sbuf)));
  70. goto out_delete_evlist;
  71. }
  72. evlist__enable(evlist);
  73. /*
  74. * Generate the event:
  75. */
  76. openat(AT_FDCWD, filename, flags);
  77. while (1) {
  78. int before = nr_events;
  79. for (i = 0; i < evlist->core.nr_mmaps; i++) {
  80. union perf_event *event;
  81. struct mmap *md;
  82. md = &evlist->mmap[i];
  83. if (perf_mmap__read_init(&md->core) < 0)
  84. continue;
  85. while ((event = perf_mmap__read_event(&md->core)) != NULL) {
  86. const u32 type = event->header.type;
  87. int tp_flags;
  88. struct perf_sample sample;
  89. ++nr_events;
  90. if (type != PERF_RECORD_SAMPLE) {
  91. perf_mmap__consume(&md->core);
  92. continue;
  93. }
  94. err = evsel__parse_sample(evsel, event, &sample);
  95. if (err) {
  96. pr_debug("Can't parse sample, err = %d\n", err);
  97. goto out_delete_evlist;
  98. }
  99. tp_flags = evsel__intval(evsel, &sample, "flags");
  100. if (flags != tp_flags) {
  101. pr_debug("%s: Expected flags=%#x, got %#x\n",
  102. __func__, flags, tp_flags);
  103. goto out_delete_evlist;
  104. }
  105. goto out_ok;
  106. }
  107. perf_mmap__read_done(&md->core);
  108. }
  109. if (nr_events == before)
  110. evlist__poll(evlist, 10);
  111. if (++nr_polls > 5) {
  112. pr_debug("%s: no events!\n", __func__);
  113. goto out_delete_evlist;
  114. }
  115. }
  116. out_ok:
  117. err = 0;
  118. out_delete_evlist:
  119. evlist__delete(evlist);
  120. out:
  121. return err;
  122. }
  123. DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields);