openat-syscall-tp-fields.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. .uses_mmap = true,
  30. },
  31. .no_buffering = true,
  32. .freq = 1,
  33. .mmap_pages = 256,
  34. .raw_samples = true,
  35. };
  36. const char *filename = "/etc/passwd";
  37. int flags = O_RDONLY | O_DIRECTORY;
  38. struct evlist *evlist = evlist__new();
  39. struct evsel *evsel;
  40. int ret = TEST_FAIL, err, i, nr_events = 0, nr_polls = 0;
  41. char sbuf[STRERR_BUFSIZE];
  42. if (evlist == NULL) {
  43. pr_debug("%s: evlist__new\n", __func__);
  44. goto out;
  45. }
  46. evsel = evsel__newtp("syscalls", "sys_enter_openat");
  47. if (IS_ERR(evsel)) {
  48. pr_debug("%s: evsel__newtp\n", __func__);
  49. ret = PTR_ERR(evsel) == -EACCES ? TEST_SKIP : TEST_FAIL;
  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. perf_sample__init(&sample, /*all=*/false);
  95. err = evsel__parse_sample(evsel, event, &sample);
  96. if (err) {
  97. pr_debug("Can't parse sample, err = %d\n", err);
  98. perf_sample__exit(&sample);
  99. goto out_delete_evlist;
  100. }
  101. tp_flags = evsel__intval(evsel, &sample, "flags");
  102. perf_sample__exit(&sample);
  103. if (flags != tp_flags) {
  104. pr_debug("%s: Expected flags=%#x, got %#x\n",
  105. __func__, flags, tp_flags);
  106. goto out_delete_evlist;
  107. }
  108. goto out_ok;
  109. }
  110. perf_mmap__read_done(&md->core);
  111. }
  112. if (nr_events == before)
  113. evlist__poll(evlist, 10);
  114. if (++nr_polls > 5) {
  115. pr_debug("%s: no events!\n", __func__);
  116. goto out_delete_evlist;
  117. }
  118. }
  119. out_ok:
  120. ret = TEST_OK;
  121. out_delete_evlist:
  122. evlist__delete(evlist);
  123. out:
  124. return ret;
  125. }
  126. static struct test_case tests__syscall_openat_tp_fields[] = {
  127. TEST_CASE_REASON("syscalls:sys_enter_openat event fields",
  128. syscall_openat_tp_fields,
  129. "permissions"),
  130. { .name = NULL, }
  131. };
  132. struct test_suite suite__syscall_openat_tp_fields = {
  133. .desc = "syscalls:sys_enter_openat event fields",
  134. .test_cases = tests__syscall_openat_tp_fields,
  135. };