1#include "perf.h"
2#include "evlist.h"
3#include "evsel.h"
4#include "thread_map.h"
5#include "tests.h"
6
7int test__syscall_open_tp_fields(void)
8{
9	struct perf_record_opts opts = {
10		.target = {
11			.uid = UINT_MAX,
12			.uses_mmap = true,
13		},
14		.no_delay   = true,
15		.freq	    = 1,
16		.mmap_pages = 256,
17		.raw_samples = true,
18	};
19	const char *filename = "/etc/passwd";
20	int flags = O_RDONLY | O_DIRECTORY;
21	struct perf_evlist *evlist = perf_evlist__new();
22	struct perf_evsel *evsel;
23	int err = -1, i, nr_events = 0, nr_polls = 0;
24
25	if (evlist == NULL) {
26		pr_debug("%s: perf_evlist__new\n", __func__);
27		goto out;
28	}
29
30	evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
31	if (evsel == NULL) {
32		pr_debug("%s: perf_evsel__newtp\n", __func__);
33		goto out_delete_evlist;
34	}
35
36	perf_evlist__add(evlist, evsel);
37
38	err = perf_evlist__create_maps(evlist, &opts.target);
39	if (err < 0) {
40		pr_debug("%s: perf_evlist__create_maps\n", __func__);
41		goto out_delete_evlist;
42	}
43
44	perf_evsel__config(evsel, &opts);
45
46	evlist->threads->map[0] = getpid();
47
48	err = perf_evlist__open(evlist);
49	if (err < 0) {
50		pr_debug("perf_evlist__open: %s\n", strerror(errno));
51		goto out_delete_maps;
52	}
53
54	err = perf_evlist__mmap(evlist, UINT_MAX, false);
55	if (err < 0) {
56		pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
57		goto out_close_evlist;
58	}
59
60	perf_evlist__enable(evlist);
61
62	/*
63	 * Generate the event:
64	 */
65	open(filename, flags);
66
67	while (1) {
68		int before = nr_events;
69
70		for (i = 0; i < evlist->nr_mmaps; i++) {
71			union perf_event *event;
72
73			while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
74				const u32 type = event->header.type;
75				int tp_flags;
76				struct perf_sample sample;
77
78				++nr_events;
79
80				if (type != PERF_RECORD_SAMPLE) {
81					perf_evlist__mmap_consume(evlist, i);
82					continue;
83				}
84
85				err = perf_evsel__parse_sample(evsel, event, &sample);
86				if (err) {
87					pr_err("Can't parse sample, err = %d\n", err);
88					goto out_munmap;
89				}
90
91				tp_flags = perf_evsel__intval(evsel, &sample, "flags");
92
93				if (flags != tp_flags) {
94					pr_debug("%s: Expected flags=%#x, got %#x\n",
95						 __func__, flags, tp_flags);
96					goto out_munmap;
97				}
98
99				goto out_ok;
100			}
101		}
102
103		if (nr_events == before)
104			poll(evlist->pollfd, evlist->nr_fds, 10);
105
106		if (++nr_polls > 5) {
107			pr_debug("%s: no events!\n", __func__);
108			goto out_munmap;
109		}
110	}
111out_ok:
112	err = 0;
113out_munmap:
114	perf_evlist__munmap(evlist);
115out_close_evlist:
116	perf_evlist__close(evlist);
117out_delete_maps:
118	perf_evlist__delete_maps(evlist);
119out_delete_evlist:
120	perf_evlist__delete(evlist);
121out:
122	return err;
123}
124