Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <stdbool.h>
0003 #include <linux/err.h>
0004 #include <linux/string.h>
0005 #include <sys/types.h>
0006 #include <sys/stat.h>
0007 #include <fcntl.h>
0008 #include "evlist.h"
0009 #include "evsel.h"
0010 #include "thread_map.h"
0011 #include "record.h"
0012 #include "tests.h"
0013 #include "debug.h"
0014 #include "util/mmap.h"
0015 #include <errno.h>
0016 #include <perf/mmap.h>
0017 
0018 #ifndef O_DIRECTORY
0019 #define O_DIRECTORY    00200000
0020 #endif
0021 #ifndef AT_FDCWD
0022 #define AT_FDCWD       -100
0023 #endif
0024 
0025 static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused,
0026                       int subtest __maybe_unused)
0027 {
0028     struct record_opts opts = {
0029         .target = {
0030             .uid = UINT_MAX,
0031             .uses_mmap = true,
0032         },
0033         .no_buffering = true,
0034         .freq         = 1,
0035         .mmap_pages   = 256,
0036         .raw_samples  = true,
0037     };
0038     const char *filename = "/etc/passwd";
0039     int flags = O_RDONLY | O_DIRECTORY;
0040     struct evlist *evlist = evlist__new();
0041     struct evsel *evsel;
0042     int err = -1, i, nr_events = 0, nr_polls = 0;
0043     char sbuf[STRERR_BUFSIZE];
0044 
0045     if (evlist == NULL) {
0046         pr_debug("%s: evlist__new\n", __func__);
0047         goto out;
0048     }
0049 
0050     evsel = evsel__newtp("syscalls", "sys_enter_openat");
0051     if (IS_ERR(evsel)) {
0052         pr_debug("%s: evsel__newtp\n", __func__);
0053         goto out_delete_evlist;
0054     }
0055 
0056     evlist__add(evlist, evsel);
0057 
0058     err = evlist__create_maps(evlist, &opts.target);
0059     if (err < 0) {
0060         pr_debug("%s: evlist__create_maps\n", __func__);
0061         goto out_delete_evlist;
0062     }
0063 
0064     evsel__config(evsel, &opts, NULL);
0065 
0066     perf_thread_map__set_pid(evlist->core.threads, 0, getpid());
0067 
0068     err = evlist__open(evlist);
0069     if (err < 0) {
0070         pr_debug("perf_evlist__open: %s\n",
0071              str_error_r(errno, sbuf, sizeof(sbuf)));
0072         goto out_delete_evlist;
0073     }
0074 
0075     err = evlist__mmap(evlist, UINT_MAX);
0076     if (err < 0) {
0077         pr_debug("evlist__mmap: %s\n",
0078              str_error_r(errno, sbuf, sizeof(sbuf)));
0079         goto out_delete_evlist;
0080     }
0081 
0082     evlist__enable(evlist);
0083 
0084     /*
0085      * Generate the event:
0086      */
0087     openat(AT_FDCWD, filename, flags);
0088 
0089     while (1) {
0090         int before = nr_events;
0091 
0092         for (i = 0; i < evlist->core.nr_mmaps; i++) {
0093             union perf_event *event;
0094             struct mmap *md;
0095 
0096             md = &evlist->mmap[i];
0097             if (perf_mmap__read_init(&md->core) < 0)
0098                 continue;
0099 
0100             while ((event = perf_mmap__read_event(&md->core)) != NULL) {
0101                 const u32 type = event->header.type;
0102                 int tp_flags;
0103                 struct perf_sample sample;
0104 
0105                 ++nr_events;
0106 
0107                 if (type != PERF_RECORD_SAMPLE) {
0108                     perf_mmap__consume(&md->core);
0109                     continue;
0110                 }
0111 
0112                 err = evsel__parse_sample(evsel, event, &sample);
0113                 if (err) {
0114                     pr_debug("Can't parse sample, err = %d\n", err);
0115                     goto out_delete_evlist;
0116                 }
0117 
0118                 tp_flags = evsel__intval(evsel, &sample, "flags");
0119 
0120                 if (flags != tp_flags) {
0121                     pr_debug("%s: Expected flags=%#x, got %#x\n",
0122                          __func__, flags, tp_flags);
0123                     goto out_delete_evlist;
0124                 }
0125 
0126                 goto out_ok;
0127             }
0128             perf_mmap__read_done(&md->core);
0129         }
0130 
0131         if (nr_events == before)
0132             evlist__poll(evlist, 10);
0133 
0134         if (++nr_polls > 5) {
0135             pr_debug("%s: no events!\n", __func__);
0136             goto out_delete_evlist;
0137         }
0138     }
0139 out_ok:
0140     err = 0;
0141 out_delete_evlist:
0142     evlist__delete(evlist);
0143 out:
0144     return err;
0145 }
0146 
0147 DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields);