1*287e80b3SSadaf Ebrahimi // SPDX-License-Identifier: LGPL-2.1
2*287e80b3SSadaf Ebrahimi /*
3*287e80b3SSadaf Ebrahimi * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <[email protected]>
4*287e80b3SSadaf Ebrahimi *
5*287e80b3SSadaf Ebrahimi */
6*287e80b3SSadaf Ebrahimi #include <stdio.h>
7*287e80b3SSadaf Ebrahimi #include <stdlib.h>
8*287e80b3SSadaf Ebrahimi #include <sys/stat.h>
9*287e80b3SSadaf Ebrahimi #include <fcntl.h>
10*287e80b3SSadaf Ebrahimi #include <unistd.h>
11*287e80b3SSadaf Ebrahimi #include <time.h>
12*287e80b3SSadaf Ebrahimi #include <dirent.h>
13*287e80b3SSadaf Ebrahimi #include <ftw.h>
14*287e80b3SSadaf Ebrahimi #include <libgen.h>
15*287e80b3SSadaf Ebrahimi #include <kbuffer.h>
16*287e80b3SSadaf Ebrahimi #include <pthread.h>
17*287e80b3SSadaf Ebrahimi
18*287e80b3SSadaf Ebrahimi #include <sys/mount.h>
19*287e80b3SSadaf Ebrahimi
20*287e80b3SSadaf Ebrahimi #include <CUnit/CUnit.h>
21*287e80b3SSadaf Ebrahimi #include <CUnit/Basic.h>
22*287e80b3SSadaf Ebrahimi
23*287e80b3SSadaf Ebrahimi #include "tracefs.h"
24*287e80b3SSadaf Ebrahimi
25*287e80b3SSadaf Ebrahimi #define TRACEFS_SUITE "tracefs library"
26*287e80b3SSadaf Ebrahimi #define TEST_INSTANCE_NAME "cunit_test_iter"
27*287e80b3SSadaf Ebrahimi #define TEST_TRACE_DIR "/tmp/trace_utest.XXXXXX"
28*287e80b3SSadaf Ebrahimi #define TEST_ARRAY_SIZE 5000
29*287e80b3SSadaf Ebrahimi
30*287e80b3SSadaf Ebrahimi #define ALL_TRACERS "available_tracers"
31*287e80b3SSadaf Ebrahimi #define CUR_TRACER "current_tracer"
32*287e80b3SSadaf Ebrahimi #define PER_CPU "per_cpu"
33*287e80b3SSadaf Ebrahimi #define TRACE_ON "tracing_on"
34*287e80b3SSadaf Ebrahimi #define TRACE_CLOCK "trace_clock"
35*287e80b3SSadaf Ebrahimi
36*287e80b3SSadaf Ebrahimi #define SQL_1_EVENT "wakeup_1"
37*287e80b3SSadaf Ebrahimi #define SQL_1_SQL "select sched_switch.next_pid as woke_pid, sched_waking.common_pid as waking_pid from sched_waking join sched_switch on sched_switch.next_pid = sched_waking.pid"
38*287e80b3SSadaf Ebrahimi
39*287e80b3SSadaf Ebrahimi #define SQL_2_EVENT "wakeup_2"
40*287e80b3SSadaf Ebrahimi #define SQL_2_SQL "select woke.next_pid as woke_pid, wake.common_pid as waking_pid from sched_waking as wake join sched_switch as woke on woke.next_pid = wake.pid"
41*287e80b3SSadaf Ebrahimi
42*287e80b3SSadaf Ebrahimi #define SQL_3_EVENT "wakeup_lat"
43*287e80b3SSadaf Ebrahimi #define SQL_3_SQL "select sched_switch.next_prio as prio, end.prev_prio as pprio, (sched.sched_waking.common_timestamp.usecs - end.TIMESTAMP_USECS) as lat from sched_waking as start join sched_switch as end on start.pid = end.next_pid"
44*287e80b3SSadaf Ebrahimi
45*287e80b3SSadaf Ebrahimi #define SQL_4_EVENT "wakeup_lat_2"
46*287e80b3SSadaf Ebrahimi #define SQL_4_SQL "select start.pid, end.next_prio as prio, (end.TIMESTAMP_USECS - start.TIMESTAMP_USECS) as lat from sched_waking as start join sched_switch as end on start.pid = end.next_pid where (start.prio >= 1 && start.prio < 100) || !(start.pid >= 0 && start.pid <= 1) && end.prev_pid != 0"
47*287e80b3SSadaf Ebrahimi
48*287e80b3SSadaf Ebrahimi #define SQL_5_EVENT "irq_lat"
49*287e80b3SSadaf Ebrahimi #define SQL_5_SQL "select end.common_pid as pid, (end.common_timestamp.usecs - start.common_timestamp.usecs) as irq_lat from irq_disable as start join irq_enable as end on start.common_pid = end.common_pid, start.parent_offs == end.parent_offs where start.common_pid != 0"
50*287e80b3SSadaf Ebrahimi #define SQL_5_START "irq_disable"
51*287e80b3SSadaf Ebrahimi
52*287e80b3SSadaf Ebrahimi #define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
53*287e80b3SSadaf Ebrahimi #define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing"
54*287e80b3SSadaf Ebrahimi #define TRACEFS_DEFAULT2_PATH "/sys/kernel/debug/tracing"
55*287e80b3SSadaf Ebrahimi
56*287e80b3SSadaf Ebrahimi static struct tracefs_instance *test_instance;
57*287e80b3SSadaf Ebrahimi static struct tep_handle *test_tep;
58*287e80b3SSadaf Ebrahimi struct test_sample {
59*287e80b3SSadaf Ebrahimi int cpu;
60*287e80b3SSadaf Ebrahimi int value;
61*287e80b3SSadaf Ebrahimi };
62*287e80b3SSadaf Ebrahimi static struct test_sample test_array[TEST_ARRAY_SIZE];
63*287e80b3SSadaf Ebrahimi static int test_found;
64*287e80b3SSadaf Ebrahimi static unsigned long long last_ts;
65*287e80b3SSadaf Ebrahimi
test_callback(struct tep_event * event,struct tep_record * record,int cpu,void * context)66*287e80b3SSadaf Ebrahimi static int test_callback(struct tep_event *event, struct tep_record *record,
67*287e80b3SSadaf Ebrahimi int cpu, void *context)
68*287e80b3SSadaf Ebrahimi {
69*287e80b3SSadaf Ebrahimi struct tep_format_field *field;
70*287e80b3SSadaf Ebrahimi struct test_sample *sample;
71*287e80b3SSadaf Ebrahimi int *cpu_test = (int *)context;
72*287e80b3SSadaf Ebrahimi int i;
73*287e80b3SSadaf Ebrahimi
74*287e80b3SSadaf Ebrahimi CU_TEST(last_ts <= record->ts);
75*287e80b3SSadaf Ebrahimi last_ts = record->ts;
76*287e80b3SSadaf Ebrahimi
77*287e80b3SSadaf Ebrahimi if (cpu_test && *cpu_test >= 0) {
78*287e80b3SSadaf Ebrahimi CU_TEST(*cpu_test == cpu);
79*287e80b3SSadaf Ebrahimi }
80*287e80b3SSadaf Ebrahimi CU_TEST(cpu == record->cpu);
81*287e80b3SSadaf Ebrahimi
82*287e80b3SSadaf Ebrahimi field = tep_find_field(event, "buf");
83*287e80b3SSadaf Ebrahimi if (field) {
84*287e80b3SSadaf Ebrahimi sample = ((struct test_sample *)(record->data + field->offset));
85*287e80b3SSadaf Ebrahimi for (i = 0; i < TEST_ARRAY_SIZE; i++) {
86*287e80b3SSadaf Ebrahimi if (test_array[i].value == sample->value &&
87*287e80b3SSadaf Ebrahimi test_array[i].cpu == cpu) {
88*287e80b3SSadaf Ebrahimi test_array[i].value = 0;
89*287e80b3SSadaf Ebrahimi test_found++;
90*287e80b3SSadaf Ebrahimi break;
91*287e80b3SSadaf Ebrahimi }
92*287e80b3SSadaf Ebrahimi }
93*287e80b3SSadaf Ebrahimi }
94*287e80b3SSadaf Ebrahimi
95*287e80b3SSadaf Ebrahimi return 0;
96*287e80b3SSadaf Ebrahimi }
97*287e80b3SSadaf Ebrahimi
98*287e80b3SSadaf Ebrahimi static cpu_set_t *cpuset_save;
99*287e80b3SSadaf Ebrahimi static cpu_set_t *cpuset;
100*287e80b3SSadaf Ebrahimi static int cpu_size;
101*287e80b3SSadaf Ebrahimi
save_affinity(void)102*287e80b3SSadaf Ebrahimi static void save_affinity(void)
103*287e80b3SSadaf Ebrahimi {
104*287e80b3SSadaf Ebrahimi int cpus;
105*287e80b3SSadaf Ebrahimi
106*287e80b3SSadaf Ebrahimi cpus = sysconf(_SC_NPROCESSORS_CONF);
107*287e80b3SSadaf Ebrahimi cpuset_save = CPU_ALLOC(cpus);
108*287e80b3SSadaf Ebrahimi cpuset = CPU_ALLOC(cpus);
109*287e80b3SSadaf Ebrahimi cpu_size = CPU_ALLOC_SIZE(cpus);
110*287e80b3SSadaf Ebrahimi CU_TEST(cpuset_save != NULL && cpuset != NULL);
111*287e80b3SSadaf Ebrahimi CU_TEST(sched_getaffinity(0, cpu_size, cpuset_save) == 0);
112*287e80b3SSadaf Ebrahimi }
113*287e80b3SSadaf Ebrahimi
thread_affinity(void)114*287e80b3SSadaf Ebrahimi static void thread_affinity(void)
115*287e80b3SSadaf Ebrahimi {
116*287e80b3SSadaf Ebrahimi sched_setaffinity(0, cpu_size, cpuset_save);
117*287e80b3SSadaf Ebrahimi }
118*287e80b3SSadaf Ebrahimi
reset_affinity(void)119*287e80b3SSadaf Ebrahimi static void reset_affinity(void)
120*287e80b3SSadaf Ebrahimi {
121*287e80b3SSadaf Ebrahimi sched_setaffinity(0, cpu_size, cpuset_save);
122*287e80b3SSadaf Ebrahimi CPU_FREE(cpuset_save);
123*287e80b3SSadaf Ebrahimi CPU_FREE(cpuset);
124*287e80b3SSadaf Ebrahimi }
125*287e80b3SSadaf Ebrahimi
set_affinity(int cpu)126*287e80b3SSadaf Ebrahimi static void set_affinity(int cpu)
127*287e80b3SSadaf Ebrahimi {
128*287e80b3SSadaf Ebrahimi CPU_ZERO_S(cpu_size, cpuset);
129*287e80b3SSadaf Ebrahimi CPU_SET_S(cpu, cpu_size, cpuset);
130*287e80b3SSadaf Ebrahimi CU_TEST(sched_setaffinity(0, cpu_size, cpuset) == 0);
131*287e80b3SSadaf Ebrahimi sched_yield(); /* Force schedule */
132*287e80b3SSadaf Ebrahimi }
133*287e80b3SSadaf Ebrahimi
test_iter_write(struct tracefs_instance * instance)134*287e80b3SSadaf Ebrahimi static void test_iter_write(struct tracefs_instance *instance)
135*287e80b3SSadaf Ebrahimi {
136*287e80b3SSadaf Ebrahimi char *path;
137*287e80b3SSadaf Ebrahimi int i, fd;
138*287e80b3SSadaf Ebrahimi int cpus;
139*287e80b3SSadaf Ebrahimi int ret;
140*287e80b3SSadaf Ebrahimi
141*287e80b3SSadaf Ebrahimi cpus = sysconf(_SC_NPROCESSORS_CONF);
142*287e80b3SSadaf Ebrahimi save_affinity();
143*287e80b3SSadaf Ebrahimi
144*287e80b3SSadaf Ebrahimi path = tracefs_instance_get_file(instance, "trace_marker");
145*287e80b3SSadaf Ebrahimi CU_TEST(path != NULL);
146*287e80b3SSadaf Ebrahimi fd = open(path, O_WRONLY);
147*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(path);
148*287e80b3SSadaf Ebrahimi CU_TEST(fd >= 0);
149*287e80b3SSadaf Ebrahimi
150*287e80b3SSadaf Ebrahimi for (i = 0; i < TEST_ARRAY_SIZE; i++) {
151*287e80b3SSadaf Ebrahimi test_array[i].cpu = rand() % cpus;
152*287e80b3SSadaf Ebrahimi test_array[i].value = random();
153*287e80b3SSadaf Ebrahimi if (!test_array[i].value)
154*287e80b3SSadaf Ebrahimi test_array[i].value++;
155*287e80b3SSadaf Ebrahimi CU_TEST(test_array[i].cpu < cpus);
156*287e80b3SSadaf Ebrahimi set_affinity(test_array[i].cpu);
157*287e80b3SSadaf Ebrahimi ret = write(fd, test_array + i, sizeof(struct test_sample));
158*287e80b3SSadaf Ebrahimi CU_TEST(ret == sizeof(struct test_sample));
159*287e80b3SSadaf Ebrahimi }
160*287e80b3SSadaf Ebrahimi
161*287e80b3SSadaf Ebrahimi reset_affinity();
162*287e80b3SSadaf Ebrahimi close(fd);
163*287e80b3SSadaf Ebrahimi }
164*287e80b3SSadaf Ebrahimi
165*287e80b3SSadaf Ebrahimi
iter_raw_events_on_cpu(struct tracefs_instance * instance,int cpu)166*287e80b3SSadaf Ebrahimi static void iter_raw_events_on_cpu(struct tracefs_instance *instance, int cpu)
167*287e80b3SSadaf Ebrahimi {
168*287e80b3SSadaf Ebrahimi int cpus = sysconf(_SC_NPROCESSORS_CONF);
169*287e80b3SSadaf Ebrahimi cpu_set_t *cpuset = NULL;
170*287e80b3SSadaf Ebrahimi int cpu_size = 0;
171*287e80b3SSadaf Ebrahimi int check = 0;
172*287e80b3SSadaf Ebrahimi int ret;
173*287e80b3SSadaf Ebrahimi int i;
174*287e80b3SSadaf Ebrahimi
175*287e80b3SSadaf Ebrahimi if (cpu >= 0) {
176*287e80b3SSadaf Ebrahimi cpuset = CPU_ALLOC(cpus);
177*287e80b3SSadaf Ebrahimi cpu_size = CPU_ALLOC_SIZE(cpus);
178*287e80b3SSadaf Ebrahimi CPU_ZERO_S(cpu_size, cpuset);
179*287e80b3SSadaf Ebrahimi CPU_SET(cpu, cpuset);
180*287e80b3SSadaf Ebrahimi }
181*287e80b3SSadaf Ebrahimi test_found = 0;
182*287e80b3SSadaf Ebrahimi last_ts = 0;
183*287e80b3SSadaf Ebrahimi test_iter_write(instance);
184*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(test_tep, instance, cpuset, cpu_size,
185*287e80b3SSadaf Ebrahimi test_callback, &cpu);
186*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
187*287e80b3SSadaf Ebrahimi if (cpu < 0) {
188*287e80b3SSadaf Ebrahimi CU_TEST(test_found == TEST_ARRAY_SIZE);
189*287e80b3SSadaf Ebrahimi } else {
190*287e80b3SSadaf Ebrahimi for (i = 0; i < TEST_ARRAY_SIZE; i++) {
191*287e80b3SSadaf Ebrahimi if (test_array[i].cpu == cpu) {
192*287e80b3SSadaf Ebrahimi check++;
193*287e80b3SSadaf Ebrahimi CU_TEST(test_array[i].value == 0)
194*287e80b3SSadaf Ebrahimi } else {
195*287e80b3SSadaf Ebrahimi CU_TEST(test_array[i].value != 0)
196*287e80b3SSadaf Ebrahimi }
197*287e80b3SSadaf Ebrahimi }
198*287e80b3SSadaf Ebrahimi CU_TEST(test_found == check);
199*287e80b3SSadaf Ebrahimi }
200*287e80b3SSadaf Ebrahimi
201*287e80b3SSadaf Ebrahimi if (cpuset)
202*287e80b3SSadaf Ebrahimi CPU_FREE(cpuset);
203*287e80b3SSadaf Ebrahimi }
204*287e80b3SSadaf Ebrahimi
test_instance_iter_raw_events(struct tracefs_instance * instance)205*287e80b3SSadaf Ebrahimi static void test_instance_iter_raw_events(struct tracefs_instance *instance)
206*287e80b3SSadaf Ebrahimi {
207*287e80b3SSadaf Ebrahimi int cpus = sysconf(_SC_NPROCESSORS_CONF);
208*287e80b3SSadaf Ebrahimi int ret;
209*287e80b3SSadaf Ebrahimi int i;
210*287e80b3SSadaf Ebrahimi
211*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(NULL, instance, NULL, 0, test_callback, NULL);
212*287e80b3SSadaf Ebrahimi CU_TEST(ret < 0);
213*287e80b3SSadaf Ebrahimi last_ts = 0;
214*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(test_tep, NULL, NULL, 0, test_callback, NULL);
215*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
216*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(test_tep, instance, NULL, 0, NULL, NULL);
217*287e80b3SSadaf Ebrahimi CU_TEST(ret < 0);
218*287e80b3SSadaf Ebrahimi
219*287e80b3SSadaf Ebrahimi iter_raw_events_on_cpu(instance, -1);
220*287e80b3SSadaf Ebrahimi for (i = 0; i < cpus; i++)
221*287e80b3SSadaf Ebrahimi iter_raw_events_on_cpu(instance, i);
222*287e80b3SSadaf Ebrahimi }
223*287e80b3SSadaf Ebrahimi
test_iter_raw_events(void)224*287e80b3SSadaf Ebrahimi static void test_iter_raw_events(void)
225*287e80b3SSadaf Ebrahimi {
226*287e80b3SSadaf Ebrahimi test_instance_iter_raw_events(test_instance);
227*287e80b3SSadaf Ebrahimi }
228*287e80b3SSadaf Ebrahimi
229*287e80b3SSadaf Ebrahimi #define RAND_STR_SIZE 20
230*287e80b3SSadaf Ebrahimi #define RAND_ASCII "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
get_rand_str(void)231*287e80b3SSadaf Ebrahimi static const char *get_rand_str(void)
232*287e80b3SSadaf Ebrahimi {
233*287e80b3SSadaf Ebrahimi static char str[RAND_STR_SIZE];
234*287e80b3SSadaf Ebrahimi static char sym[] = RAND_ASCII;
235*287e80b3SSadaf Ebrahimi struct timespec clk;
236*287e80b3SSadaf Ebrahimi int i;
237*287e80b3SSadaf Ebrahimi
238*287e80b3SSadaf Ebrahimi clock_gettime(CLOCK_REALTIME, &clk);
239*287e80b3SSadaf Ebrahimi srand(clk.tv_nsec);
240*287e80b3SSadaf Ebrahimi for (i = 0; i < RAND_STR_SIZE; i++)
241*287e80b3SSadaf Ebrahimi str[i] = sym[rand() % (sizeof(sym) - 1)];
242*287e80b3SSadaf Ebrahimi
243*287e80b3SSadaf Ebrahimi str[RAND_STR_SIZE - 1] = 0;
244*287e80b3SSadaf Ebrahimi return str;
245*287e80b3SSadaf Ebrahimi }
246*287e80b3SSadaf Ebrahimi
247*287e80b3SSadaf Ebrahimi struct marker_find {
248*287e80b3SSadaf Ebrahimi int data_offset;
249*287e80b3SSadaf Ebrahimi int event_id;
250*287e80b3SSadaf Ebrahimi int count;
251*287e80b3SSadaf Ebrahimi int len;
252*287e80b3SSadaf Ebrahimi void *data;
253*287e80b3SSadaf Ebrahimi };
254*287e80b3SSadaf Ebrahimi
test_marker_callback(struct tep_event * event,struct tep_record * record,int cpu,void * context)255*287e80b3SSadaf Ebrahimi static int test_marker_callback(struct tep_event *event, struct tep_record *record,
256*287e80b3SSadaf Ebrahimi int cpu, void *context)
257*287e80b3SSadaf Ebrahimi {
258*287e80b3SSadaf Ebrahimi struct marker_find *walk = context;
259*287e80b3SSadaf Ebrahimi
260*287e80b3SSadaf Ebrahimi if (!walk)
261*287e80b3SSadaf Ebrahimi return -1;
262*287e80b3SSadaf Ebrahimi if (event->id != walk->event_id)
263*287e80b3SSadaf Ebrahimi return 0;
264*287e80b3SSadaf Ebrahimi if (record->size < (walk->data_offset + walk->len))
265*287e80b3SSadaf Ebrahimi return 0;
266*287e80b3SSadaf Ebrahimi
267*287e80b3SSadaf Ebrahimi if (memcmp(walk->data, record->data + walk->data_offset, walk->len) == 0)
268*287e80b3SSadaf Ebrahimi walk->count++;
269*287e80b3SSadaf Ebrahimi
270*287e80b3SSadaf Ebrahimi return 0;
271*287e80b3SSadaf Ebrahimi }
272*287e80b3SSadaf Ebrahimi
find_test_marker(struct tracefs_instance * instance,void * data,int len,int expected,bool raw)273*287e80b3SSadaf Ebrahimi static bool find_test_marker(struct tracefs_instance *instance,
274*287e80b3SSadaf Ebrahimi void *data, int len, int expected, bool raw)
275*287e80b3SSadaf Ebrahimi {
276*287e80b3SSadaf Ebrahimi struct tep_format_field *field;
277*287e80b3SSadaf Ebrahimi struct tep_event *event;
278*287e80b3SSadaf Ebrahimi struct marker_find walk;
279*287e80b3SSadaf Ebrahimi int ret;
280*287e80b3SSadaf Ebrahimi
281*287e80b3SSadaf Ebrahimi if (raw) {
282*287e80b3SSadaf Ebrahimi event = tep_find_event_by_name(test_tep, "ftrace", "raw_data");
283*287e80b3SSadaf Ebrahimi if (event)
284*287e80b3SSadaf Ebrahimi field = tep_find_field(event, "id");
285*287e80b3SSadaf Ebrahimi
286*287e80b3SSadaf Ebrahimi } else {
287*287e80b3SSadaf Ebrahimi event = tep_find_event_by_name(test_tep, "ftrace", "print");
288*287e80b3SSadaf Ebrahimi if (event)
289*287e80b3SSadaf Ebrahimi field = tep_find_field(event, "buf");
290*287e80b3SSadaf Ebrahimi }
291*287e80b3SSadaf Ebrahimi
292*287e80b3SSadaf Ebrahimi if (!event || !field)
293*287e80b3SSadaf Ebrahimi return false;
294*287e80b3SSadaf Ebrahimi
295*287e80b3SSadaf Ebrahimi walk.data = data;
296*287e80b3SSadaf Ebrahimi walk.len = len;
297*287e80b3SSadaf Ebrahimi walk.count = 0;
298*287e80b3SSadaf Ebrahimi walk.event_id = event->id;
299*287e80b3SSadaf Ebrahimi walk.data_offset = field->offset;
300*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(test_tep, instance, NULL, 0,
301*287e80b3SSadaf Ebrahimi test_marker_callback, &walk);
302*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
303*287e80b3SSadaf Ebrahimi
304*287e80b3SSadaf Ebrahimi return walk.count == expected;
305*287e80b3SSadaf Ebrahimi }
306*287e80b3SSadaf Ebrahimi
marker_vprint(struct tracefs_instance * instance,char * fmt,...)307*287e80b3SSadaf Ebrahimi static int marker_vprint(struct tracefs_instance *instance, char *fmt, ...)
308*287e80b3SSadaf Ebrahimi {
309*287e80b3SSadaf Ebrahimi va_list ap;
310*287e80b3SSadaf Ebrahimi int ret;
311*287e80b3SSadaf Ebrahimi
312*287e80b3SSadaf Ebrahimi va_start(ap, fmt);
313*287e80b3SSadaf Ebrahimi ret = tracefs_vprintf(instance, fmt, ap);
314*287e80b3SSadaf Ebrahimi va_end(ap);
315*287e80b3SSadaf Ebrahimi
316*287e80b3SSadaf Ebrahimi return ret;
317*287e80b3SSadaf Ebrahimi }
318*287e80b3SSadaf Ebrahimi
319*287e80b3SSadaf Ebrahimi #define MARKERS_WRITE_COUNT 100
test_instance_ftrace_marker(struct tracefs_instance * instance)320*287e80b3SSadaf Ebrahimi static void test_instance_ftrace_marker(struct tracefs_instance *instance)
321*287e80b3SSadaf Ebrahimi {
322*287e80b3SSadaf Ebrahimi const char *string = get_rand_str();
323*287e80b3SSadaf Ebrahimi unsigned int data = 0xdeadbeef;
324*287e80b3SSadaf Ebrahimi char *str;
325*287e80b3SSadaf Ebrahimi int i;
326*287e80b3SSadaf Ebrahimi
327*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_print_init(instance) == 0);
328*287e80b3SSadaf Ebrahimi tracefs_print_close(instance);
329*287e80b3SSadaf Ebrahimi
330*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_binary_init(instance) == 0);
331*287e80b3SSadaf Ebrahimi tracefs_binary_close(instance);
332*287e80b3SSadaf Ebrahimi
333*287e80b3SSadaf Ebrahimi for (i = 0; i < MARKERS_WRITE_COUNT; i++) {
334*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_binary_write(instance, &data, sizeof(data)) == 0);
335*287e80b3SSadaf Ebrahimi }
336*287e80b3SSadaf Ebrahimi CU_TEST(find_test_marker(instance, &data, sizeof(data), MARKERS_WRITE_COUNT, true));
337*287e80b3SSadaf Ebrahimi
338*287e80b3SSadaf Ebrahimi for (i = 0; i < MARKERS_WRITE_COUNT; i++) {
339*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_printf(instance, "Test marker: %s 0x%X", string, data) == 0);
340*287e80b3SSadaf Ebrahimi }
341*287e80b3SSadaf Ebrahimi asprintf(&str, "Test marker: %s 0x%X", string, data);
342*287e80b3SSadaf Ebrahimi CU_TEST(find_test_marker(instance, str, strlen(str), MARKERS_WRITE_COUNT, false));
343*287e80b3SSadaf Ebrahimi free(str);
344*287e80b3SSadaf Ebrahimi
345*287e80b3SSadaf Ebrahimi for (i = 0; i < MARKERS_WRITE_COUNT; i++) {
346*287e80b3SSadaf Ebrahimi CU_TEST(marker_vprint(instance, "Test marker V: %s 0x%X", string, data) == 0);
347*287e80b3SSadaf Ebrahimi }
348*287e80b3SSadaf Ebrahimi asprintf(&str, "Test marker V: %s 0x%X", string, data);
349*287e80b3SSadaf Ebrahimi CU_TEST(find_test_marker(instance, str, strlen(str), MARKERS_WRITE_COUNT, false));
350*287e80b3SSadaf Ebrahimi free(str);
351*287e80b3SSadaf Ebrahimi
352*287e80b3SSadaf Ebrahimi tracefs_print_close(instance);
353*287e80b3SSadaf Ebrahimi tracefs_binary_close(instance);
354*287e80b3SSadaf Ebrahimi }
355*287e80b3SSadaf Ebrahimi
test_ftrace_marker(void)356*287e80b3SSadaf Ebrahimi static void test_ftrace_marker(void)
357*287e80b3SSadaf Ebrahimi {
358*287e80b3SSadaf Ebrahimi test_instance_ftrace_marker(test_instance);
359*287e80b3SSadaf Ebrahimi }
360*287e80b3SSadaf Ebrahimi
test_instance_trace_sql(struct tracefs_instance * instance)361*287e80b3SSadaf Ebrahimi static void test_instance_trace_sql(struct tracefs_instance *instance)
362*287e80b3SSadaf Ebrahimi {
363*287e80b3SSadaf Ebrahimi struct tracefs_synth *synth;
364*287e80b3SSadaf Ebrahimi struct trace_seq seq;
365*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
366*287e80b3SSadaf Ebrahimi struct tep_event *event;
367*287e80b3SSadaf Ebrahimi int ret;
368*287e80b3SSadaf Ebrahimi
369*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(NULL);
370*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
371*287e80b3SSadaf Ebrahimi
372*287e80b3SSadaf Ebrahimi trace_seq_init(&seq);
373*287e80b3SSadaf Ebrahimi
374*287e80b3SSadaf Ebrahimi synth = tracefs_sql(tep, SQL_1_EVENT, SQL_1_SQL, NULL);
375*287e80b3SSadaf Ebrahimi CU_TEST(synth != NULL);
376*287e80b3SSadaf Ebrahimi ret = tracefs_synth_echo_cmd(&seq, synth);
377*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
378*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth);
379*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq);
380*287e80b3SSadaf Ebrahimi
381*287e80b3SSadaf Ebrahimi synth = tracefs_sql(tep, SQL_2_EVENT, SQL_2_SQL, NULL);
382*287e80b3SSadaf Ebrahimi CU_TEST(synth != NULL);
383*287e80b3SSadaf Ebrahimi ret = tracefs_synth_echo_cmd(&seq, synth);
384*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
385*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth);
386*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq);
387*287e80b3SSadaf Ebrahimi
388*287e80b3SSadaf Ebrahimi synth = tracefs_sql(tep, SQL_3_EVENT, SQL_3_SQL, NULL);
389*287e80b3SSadaf Ebrahimi CU_TEST(synth != NULL);
390*287e80b3SSadaf Ebrahimi ret = tracefs_synth_echo_cmd(&seq, synth);
391*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
392*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth);
393*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq);
394*287e80b3SSadaf Ebrahimi
395*287e80b3SSadaf Ebrahimi synth = tracefs_sql(tep, SQL_4_EVENT, SQL_4_SQL, NULL);
396*287e80b3SSadaf Ebrahimi CU_TEST(synth != NULL);
397*287e80b3SSadaf Ebrahimi ret = tracefs_synth_echo_cmd(&seq, synth);
398*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
399*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth);
400*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq);
401*287e80b3SSadaf Ebrahimi
402*287e80b3SSadaf Ebrahimi event = tep_find_event_by_name(tep, NULL, SQL_5_START);
403*287e80b3SSadaf Ebrahimi if (event) {
404*287e80b3SSadaf Ebrahimi synth = tracefs_sql(tep, SQL_5_EVENT, SQL_5_SQL, NULL);
405*287e80b3SSadaf Ebrahimi CU_TEST(synth != NULL);
406*287e80b3SSadaf Ebrahimi ret = tracefs_synth_echo_cmd(&seq, synth);
407*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
408*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth);
409*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq);
410*287e80b3SSadaf Ebrahimi }
411*287e80b3SSadaf Ebrahimi
412*287e80b3SSadaf Ebrahimi tep_free(tep);
413*287e80b3SSadaf Ebrahimi trace_seq_destroy(&seq);
414*287e80b3SSadaf Ebrahimi }
415*287e80b3SSadaf Ebrahimi
test_trace_sql(void)416*287e80b3SSadaf Ebrahimi static void test_trace_sql(void)
417*287e80b3SSadaf Ebrahimi {
418*287e80b3SSadaf Ebrahimi test_instance_trace_sql(test_instance);
419*287e80b3SSadaf Ebrahimi }
420*287e80b3SSadaf Ebrahimi
421*287e80b3SSadaf Ebrahimi struct test_cpu_data {
422*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance;
423*287e80b3SSadaf Ebrahimi struct tracefs_cpu *tcpu;
424*287e80b3SSadaf Ebrahimi struct kbuffer *kbuf;
425*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
426*287e80b3SSadaf Ebrahimi unsigned long long missed_events;
427*287e80b3SSadaf Ebrahimi void *buf;
428*287e80b3SSadaf Ebrahimi int events_per_buf;
429*287e80b3SSadaf Ebrahimi int bufsize;
430*287e80b3SSadaf Ebrahimi int data_size;
431*287e80b3SSadaf Ebrahimi int this_pid;
432*287e80b3SSadaf Ebrahimi int fd;
433*287e80b3SSadaf Ebrahimi bool done;
434*287e80b3SSadaf Ebrahimi };
435*287e80b3SSadaf Ebrahimi
cleanup_trace_cpu(struct test_cpu_data * data)436*287e80b3SSadaf Ebrahimi static void cleanup_trace_cpu(struct test_cpu_data *data)
437*287e80b3SSadaf Ebrahimi {
438*287e80b3SSadaf Ebrahimi close(data->fd);
439*287e80b3SSadaf Ebrahimi tep_free(data->tep);
440*287e80b3SSadaf Ebrahimi tracefs_cpu_close(data->tcpu);
441*287e80b3SSadaf Ebrahimi free(data->buf);
442*287e80b3SSadaf Ebrahimi kbuffer_free(data->kbuf);
443*287e80b3SSadaf Ebrahimi }
444*287e80b3SSadaf Ebrahimi
445*287e80b3SSadaf Ebrahimi #define EVENT_SYSTEM "syscalls"
446*287e80b3SSadaf Ebrahimi #define EVENT_NAME "sys_enter_getppid"
447*287e80b3SSadaf Ebrahimi
setup_trace_cpu(struct tracefs_instance * instance,struct test_cpu_data * data)448*287e80b3SSadaf Ebrahimi static int setup_trace_cpu(struct tracefs_instance *instance, struct test_cpu_data *data)
449*287e80b3SSadaf Ebrahimi {
450*287e80b3SSadaf Ebrahimi struct tep_format_field **fields;
451*287e80b3SSadaf Ebrahimi struct tep_event *event;
452*287e80b3SSadaf Ebrahimi char tmpfile[] = "/tmp/utest-libtracefsXXXXXX";
453*287e80b3SSadaf Ebrahimi int max = 0;
454*287e80b3SSadaf Ebrahimi int ret;
455*287e80b3SSadaf Ebrahimi int i;
456*287e80b3SSadaf Ebrahimi
457*287e80b3SSadaf Ebrahimi /* Make sure tracing is on */
458*287e80b3SSadaf Ebrahimi tracefs_trace_on(instance);
459*287e80b3SSadaf Ebrahimi
460*287e80b3SSadaf Ebrahimi memset (data, 0, sizeof(*data));
461*287e80b3SSadaf Ebrahimi
462*287e80b3SSadaf Ebrahimi data->instance = instance;
463*287e80b3SSadaf Ebrahimi
464*287e80b3SSadaf Ebrahimi data->fd = mkstemp(tmpfile);
465*287e80b3SSadaf Ebrahimi CU_TEST(data->fd >= 0);
466*287e80b3SSadaf Ebrahimi unlink(tmpfile);
467*287e80b3SSadaf Ebrahimi if (data->fd < 0)
468*287e80b3SSadaf Ebrahimi return -1;
469*287e80b3SSadaf Ebrahimi
470*287e80b3SSadaf Ebrahimi data->tep = tracefs_local_events(NULL);
471*287e80b3SSadaf Ebrahimi CU_TEST(data->tep != NULL);
472*287e80b3SSadaf Ebrahimi if (!data->tep)
473*287e80b3SSadaf Ebrahimi goto fail;
474*287e80b3SSadaf Ebrahimi
475*287e80b3SSadaf Ebrahimi data->tcpu = tracefs_cpu_open(instance, 0, true);
476*287e80b3SSadaf Ebrahimi CU_TEST(data->tcpu != NULL);
477*287e80b3SSadaf Ebrahimi if (!data->tcpu)
478*287e80b3SSadaf Ebrahimi goto fail;
479*287e80b3SSadaf Ebrahimi
480*287e80b3SSadaf Ebrahimi data->bufsize = tracefs_cpu_read_size(data->tcpu);
481*287e80b3SSadaf Ebrahimi
482*287e80b3SSadaf Ebrahimi data->buf = calloc(1, data->bufsize);
483*287e80b3SSadaf Ebrahimi CU_TEST(data->buf != NULL);
484*287e80b3SSadaf Ebrahimi if (!data->buf)
485*287e80b3SSadaf Ebrahimi goto fail;
486*287e80b3SSadaf Ebrahimi
487*287e80b3SSadaf Ebrahimi data->kbuf = kbuffer_alloc(sizeof(long) == 8, !tep_is_bigendian());
488*287e80b3SSadaf Ebrahimi CU_TEST(data->kbuf != NULL);
489*287e80b3SSadaf Ebrahimi if (!data->kbuf)
490*287e80b3SSadaf Ebrahimi goto fail;
491*287e80b3SSadaf Ebrahimi
492*287e80b3SSadaf Ebrahimi data->data_size = data->bufsize - kbuffer_start_of_data(data->kbuf);
493*287e80b3SSadaf Ebrahimi
494*287e80b3SSadaf Ebrahimi tracefs_instance_file_clear(instance, "trace");
495*287e80b3SSadaf Ebrahimi
496*287e80b3SSadaf Ebrahimi event = tep_find_event_by_name(data->tep, EVENT_SYSTEM, EVENT_NAME);
497*287e80b3SSadaf Ebrahimi CU_TEST(event != NULL);
498*287e80b3SSadaf Ebrahimi if (!event)
499*287e80b3SSadaf Ebrahimi goto fail;
500*287e80b3SSadaf Ebrahimi
501*287e80b3SSadaf Ebrahimi fields = tep_event_fields(event);
502*287e80b3SSadaf Ebrahimi CU_TEST(fields != NULL);
503*287e80b3SSadaf Ebrahimi if (!fields)
504*287e80b3SSadaf Ebrahimi goto fail;
505*287e80b3SSadaf Ebrahimi
506*287e80b3SSadaf Ebrahimi for (i = 0; fields[i]; i++) {
507*287e80b3SSadaf Ebrahimi int end = fields[i]->offset + fields[i]->size;
508*287e80b3SSadaf Ebrahimi if (end > max)
509*287e80b3SSadaf Ebrahimi max = end;
510*287e80b3SSadaf Ebrahimi }
511*287e80b3SSadaf Ebrahimi free(fields);
512*287e80b3SSadaf Ebrahimi
513*287e80b3SSadaf Ebrahimi CU_TEST(max != 0);
514*287e80b3SSadaf Ebrahimi if (!max)
515*287e80b3SSadaf Ebrahimi goto fail;
516*287e80b3SSadaf Ebrahimi
517*287e80b3SSadaf Ebrahimi data->events_per_buf = data->data_size / max;
518*287e80b3SSadaf Ebrahimi
519*287e80b3SSadaf Ebrahimi data->this_pid = getpid();
520*287e80b3SSadaf Ebrahimi ret = tracefs_event_enable(instance, EVENT_SYSTEM, EVENT_NAME);
521*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
522*287e80b3SSadaf Ebrahimi if (ret)
523*287e80b3SSadaf Ebrahimi goto fail;
524*287e80b3SSadaf Ebrahimi
525*287e80b3SSadaf Ebrahimi
526*287e80b3SSadaf Ebrahimi save_affinity();
527*287e80b3SSadaf Ebrahimi set_affinity(0);
528*287e80b3SSadaf Ebrahimi
529*287e80b3SSadaf Ebrahimi return 0;
530*287e80b3SSadaf Ebrahimi fail:
531*287e80b3SSadaf Ebrahimi cleanup_trace_cpu(data);
532*287e80b3SSadaf Ebrahimi return -1;
533*287e80b3SSadaf Ebrahimi }
534*287e80b3SSadaf Ebrahimi
shutdown_trace_cpu(struct test_cpu_data * data)535*287e80b3SSadaf Ebrahimi static void shutdown_trace_cpu(struct test_cpu_data *data)
536*287e80b3SSadaf Ebrahimi {
537*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance = data->instance;
538*287e80b3SSadaf Ebrahimi int ret;
539*287e80b3SSadaf Ebrahimi
540*287e80b3SSadaf Ebrahimi reset_affinity();
541*287e80b3SSadaf Ebrahimi
542*287e80b3SSadaf Ebrahimi ret = tracefs_event_disable(instance, EVENT_SYSTEM, EVENT_NAME);
543*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
544*287e80b3SSadaf Ebrahimi
545*287e80b3SSadaf Ebrahimi cleanup_trace_cpu(data);
546*287e80b3SSadaf Ebrahimi }
547*287e80b3SSadaf Ebrahimi
call_getppid(int cnt)548*287e80b3SSadaf Ebrahimi static void call_getppid(int cnt)
549*287e80b3SSadaf Ebrahimi {
550*287e80b3SSadaf Ebrahimi int i;
551*287e80b3SSadaf Ebrahimi
552*287e80b3SSadaf Ebrahimi for (i = 0; i < cnt; i++)
553*287e80b3SSadaf Ebrahimi getppid();
554*287e80b3SSadaf Ebrahimi }
555*287e80b3SSadaf Ebrahimi
test_cpu_read(struct test_cpu_data * data,int expect)556*287e80b3SSadaf Ebrahimi static void test_cpu_read(struct test_cpu_data *data, int expect)
557*287e80b3SSadaf Ebrahimi {
558*287e80b3SSadaf Ebrahimi struct tracefs_cpu *tcpu = data->tcpu;
559*287e80b3SSadaf Ebrahimi struct kbuffer *kbuf = data->kbuf;
560*287e80b3SSadaf Ebrahimi struct tep_record record;
561*287e80b3SSadaf Ebrahimi void *buf = data->buf;
562*287e80b3SSadaf Ebrahimi unsigned long long ts;
563*287e80b3SSadaf Ebrahimi bool first = true;
564*287e80b3SSadaf Ebrahimi int pid;
565*287e80b3SSadaf Ebrahimi int ret;
566*287e80b3SSadaf Ebrahimi int cnt = 0;
567*287e80b3SSadaf Ebrahimi
568*287e80b3SSadaf Ebrahimi call_getppid(expect);
569*287e80b3SSadaf Ebrahimi
570*287e80b3SSadaf Ebrahimi for (;;) {
571*287e80b3SSadaf Ebrahimi ret = tracefs_cpu_read(tcpu, buf, false);
572*287e80b3SSadaf Ebrahimi CU_TEST(ret > 0 || !first);
573*287e80b3SSadaf Ebrahimi if (ret <= 0)
574*287e80b3SSadaf Ebrahimi break;
575*287e80b3SSadaf Ebrahimi first = false;
576*287e80b3SSadaf Ebrahimi ret = kbuffer_load_subbuffer(kbuf, buf);
577*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
578*287e80b3SSadaf Ebrahimi for (;;) {
579*287e80b3SSadaf Ebrahimi record.data = kbuffer_read_event(kbuf, &ts);
580*287e80b3SSadaf Ebrahimi if (!record.data)
581*287e80b3SSadaf Ebrahimi break;
582*287e80b3SSadaf Ebrahimi record.ts = ts;
583*287e80b3SSadaf Ebrahimi pid = tep_data_pid(data->tep, &record);
584*287e80b3SSadaf Ebrahimi if (pid == data->this_pid)
585*287e80b3SSadaf Ebrahimi cnt++;
586*287e80b3SSadaf Ebrahimi kbuffer_next_event(kbuf, NULL);
587*287e80b3SSadaf Ebrahimi }
588*287e80b3SSadaf Ebrahimi }
589*287e80b3SSadaf Ebrahimi CU_TEST(cnt == expect);
590*287e80b3SSadaf Ebrahimi }
591*287e80b3SSadaf Ebrahimi
test_instance_trace_cpu_read(struct tracefs_instance * instance)592*287e80b3SSadaf Ebrahimi static void test_instance_trace_cpu_read(struct tracefs_instance *instance)
593*287e80b3SSadaf Ebrahimi {
594*287e80b3SSadaf Ebrahimi struct test_cpu_data data;
595*287e80b3SSadaf Ebrahimi
596*287e80b3SSadaf Ebrahimi if (setup_trace_cpu(instance, &data))
597*287e80b3SSadaf Ebrahimi return;
598*287e80b3SSadaf Ebrahimi
599*287e80b3SSadaf Ebrahimi test_cpu_read(&data, 1);
600*287e80b3SSadaf Ebrahimi test_cpu_read(&data, data.events_per_buf / 2);
601*287e80b3SSadaf Ebrahimi test_cpu_read(&data, data.events_per_buf);
602*287e80b3SSadaf Ebrahimi test_cpu_read(&data, data.events_per_buf + 1);
603*287e80b3SSadaf Ebrahimi test_cpu_read(&data, data.events_per_buf * 50);
604*287e80b3SSadaf Ebrahimi
605*287e80b3SSadaf Ebrahimi shutdown_trace_cpu(&data);
606*287e80b3SSadaf Ebrahimi }
607*287e80b3SSadaf Ebrahimi
test_trace_cpu_read(void)608*287e80b3SSadaf Ebrahimi static void test_trace_cpu_read(void)
609*287e80b3SSadaf Ebrahimi {
610*287e80b3SSadaf Ebrahimi test_instance_trace_cpu_read(NULL);
611*287e80b3SSadaf Ebrahimi test_instance_trace_cpu_read(test_instance);
612*287e80b3SSadaf Ebrahimi }
613*287e80b3SSadaf Ebrahimi
614*287e80b3SSadaf Ebrahimi struct follow_data {
615*287e80b3SSadaf Ebrahimi struct tep_event *sched_switch;
616*287e80b3SSadaf Ebrahimi struct tep_event *sched_waking;
617*287e80b3SSadaf Ebrahimi struct tep_event *function;
618*287e80b3SSadaf Ebrahimi int missed;
619*287e80b3SSadaf Ebrahimi };
620*287e80b3SSadaf Ebrahimi
switch_callback(struct tep_event * event,struct tep_record * record,int cpu,void * data)621*287e80b3SSadaf Ebrahimi static int switch_callback(struct tep_event *event, struct tep_record *record,
622*287e80b3SSadaf Ebrahimi int cpu, void *data)
623*287e80b3SSadaf Ebrahimi {
624*287e80b3SSadaf Ebrahimi struct follow_data *fdata = data;
625*287e80b3SSadaf Ebrahimi
626*287e80b3SSadaf Ebrahimi CU_TEST(cpu == record->cpu);
627*287e80b3SSadaf Ebrahimi CU_TEST(event->id == fdata->sched_switch->id);
628*287e80b3SSadaf Ebrahimi return 0;
629*287e80b3SSadaf Ebrahimi }
630*287e80b3SSadaf Ebrahimi
waking_callback(struct tep_event * event,struct tep_record * record,int cpu,void * data)631*287e80b3SSadaf Ebrahimi static int waking_callback(struct tep_event *event, struct tep_record *record,
632*287e80b3SSadaf Ebrahimi int cpu, void *data)
633*287e80b3SSadaf Ebrahimi {
634*287e80b3SSadaf Ebrahimi struct follow_data *fdata = data;
635*287e80b3SSadaf Ebrahimi
636*287e80b3SSadaf Ebrahimi CU_TEST(cpu == record->cpu);
637*287e80b3SSadaf Ebrahimi CU_TEST(event->id == fdata->sched_waking->id);
638*287e80b3SSadaf Ebrahimi return 0;
639*287e80b3SSadaf Ebrahimi }
640*287e80b3SSadaf Ebrahimi
function_callback(struct tep_event * event,struct tep_record * record,int cpu,void * data)641*287e80b3SSadaf Ebrahimi static int function_callback(struct tep_event *event, struct tep_record *record,
642*287e80b3SSadaf Ebrahimi int cpu, void *data)
643*287e80b3SSadaf Ebrahimi {
644*287e80b3SSadaf Ebrahimi struct follow_data *fdata = data;
645*287e80b3SSadaf Ebrahimi
646*287e80b3SSadaf Ebrahimi CU_TEST(cpu == record->cpu);
647*287e80b3SSadaf Ebrahimi CU_TEST(event->id == fdata->function->id);
648*287e80b3SSadaf Ebrahimi return 0;
649*287e80b3SSadaf Ebrahimi }
650*287e80b3SSadaf Ebrahimi
missed_callback(struct tep_event * event,struct tep_record * record,int cpu,void * data)651*287e80b3SSadaf Ebrahimi static int missed_callback(struct tep_event *event, struct tep_record *record,
652*287e80b3SSadaf Ebrahimi int cpu, void *data)
653*287e80b3SSadaf Ebrahimi {
654*287e80b3SSadaf Ebrahimi struct follow_data *fdata = data;
655*287e80b3SSadaf Ebrahimi
656*287e80b3SSadaf Ebrahimi fdata->missed = record->missed_events;
657*287e80b3SSadaf Ebrahimi return 0;
658*287e80b3SSadaf Ebrahimi }
659*287e80b3SSadaf Ebrahimi
all_callback(struct tep_event * event,struct tep_record * record,int cpu,void * data)660*287e80b3SSadaf Ebrahimi static int all_callback(struct tep_event *event, struct tep_record *record,
661*287e80b3SSadaf Ebrahimi int cpu, void *data)
662*287e80b3SSadaf Ebrahimi {
663*287e80b3SSadaf Ebrahimi struct follow_data *fdata = data;
664*287e80b3SSadaf Ebrahimi
665*287e80b3SSadaf Ebrahimi CU_TEST(fdata->missed == record->missed_events);
666*287e80b3SSadaf Ebrahimi fdata->missed = 0;
667*287e80b3SSadaf Ebrahimi return 0;
668*287e80b3SSadaf Ebrahimi }
669*287e80b3SSadaf Ebrahimi
stop_thread(void * arg)670*287e80b3SSadaf Ebrahimi static void *stop_thread(void *arg)
671*287e80b3SSadaf Ebrahimi {
672*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance = arg;
673*287e80b3SSadaf Ebrahimi
674*287e80b3SSadaf Ebrahimi sleep(1);
675*287e80b3SSadaf Ebrahimi tracefs_iterate_stop(instance);
676*287e80b3SSadaf Ebrahimi return NULL;
677*287e80b3SSadaf Ebrahimi }
678*287e80b3SSadaf Ebrahimi
test_instance_follow_events(struct tracefs_instance * instance)679*287e80b3SSadaf Ebrahimi static void test_instance_follow_events(struct tracefs_instance *instance)
680*287e80b3SSadaf Ebrahimi {
681*287e80b3SSadaf Ebrahimi struct follow_data fdata;
682*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
683*287e80b3SSadaf Ebrahimi pthread_t thread;
684*287e80b3SSadaf Ebrahimi int ret;
685*287e80b3SSadaf Ebrahimi
686*287e80b3SSadaf Ebrahimi memset(&fdata, 0, sizeof(fdata));
687*287e80b3SSadaf Ebrahimi
688*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(NULL);
689*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
690*287e80b3SSadaf Ebrahimi if (!tep)
691*287e80b3SSadaf Ebrahimi return;
692*287e80b3SSadaf Ebrahimi
693*287e80b3SSadaf Ebrahimi fdata.sched_switch = tep_find_event_by_name(tep, "sched", "sched_switch");
694*287e80b3SSadaf Ebrahimi CU_TEST(fdata.sched_switch != NULL);
695*287e80b3SSadaf Ebrahimi if (!fdata.sched_switch)
696*287e80b3SSadaf Ebrahimi return;
697*287e80b3SSadaf Ebrahimi
698*287e80b3SSadaf Ebrahimi fdata.sched_waking = tep_find_event_by_name(tep, "sched", "sched_waking");
699*287e80b3SSadaf Ebrahimi CU_TEST(fdata.sched_waking != NULL);
700*287e80b3SSadaf Ebrahimi if (!fdata.sched_waking)
701*287e80b3SSadaf Ebrahimi return;
702*287e80b3SSadaf Ebrahimi
703*287e80b3SSadaf Ebrahimi fdata.function = tep_find_event_by_name(tep, "ftrace", "function");
704*287e80b3SSadaf Ebrahimi CU_TEST(fdata.function != NULL);
705*287e80b3SSadaf Ebrahimi if (!fdata.function)
706*287e80b3SSadaf Ebrahimi return;
707*287e80b3SSadaf Ebrahimi
708*287e80b3SSadaf Ebrahimi ret = tracefs_follow_event(tep, instance, "sched", "sched_switch",
709*287e80b3SSadaf Ebrahimi switch_callback, &fdata);
710*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
711*287e80b3SSadaf Ebrahimi
712*287e80b3SSadaf Ebrahimi ret = tracefs_follow_event(tep, instance, "sched", "sched_waking",
713*287e80b3SSadaf Ebrahimi waking_callback, &fdata);
714*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
715*287e80b3SSadaf Ebrahimi
716*287e80b3SSadaf Ebrahimi ret = tracefs_follow_event(tep, instance, "ftrace", "function",
717*287e80b3SSadaf Ebrahimi function_callback, &fdata);
718*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
719*287e80b3SSadaf Ebrahimi
720*287e80b3SSadaf Ebrahimi ret = tracefs_follow_missed_events(instance, missed_callback, &fdata);
721*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
722*287e80b3SSadaf Ebrahimi
723*287e80b3SSadaf Ebrahimi ret = tracefs_event_enable(instance, "sched", "sched_switch");
724*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
725*287e80b3SSadaf Ebrahimi
726*287e80b3SSadaf Ebrahimi ret = tracefs_event_enable(instance, "sched", "sched_waking");
727*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
728*287e80b3SSadaf Ebrahimi
729*287e80b3SSadaf Ebrahimi ret = tracefs_tracer_set(instance, TRACEFS_TRACER_FUNCTION);
730*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
731*287e80b3SSadaf Ebrahimi
732*287e80b3SSadaf Ebrahimi pthread_create(&thread, NULL, stop_thread, instance);
733*287e80b3SSadaf Ebrahimi
734*287e80b3SSadaf Ebrahimi ret = tracefs_iterate_raw_events(tep, instance, NULL, 0, all_callback, &fdata);
735*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
736*287e80b3SSadaf Ebrahimi
737*287e80b3SSadaf Ebrahimi pthread_join(thread, NULL);
738*287e80b3SSadaf Ebrahimi
739*287e80b3SSadaf Ebrahimi tracefs_tracer_clear(instance);
740*287e80b3SSadaf Ebrahimi tracefs_event_disable(instance, NULL, NULL);
741*287e80b3SSadaf Ebrahimi }
742*287e80b3SSadaf Ebrahimi
test_follow_events(void)743*287e80b3SSadaf Ebrahimi static void test_follow_events(void)
744*287e80b3SSadaf Ebrahimi {
745*287e80b3SSadaf Ebrahimi test_instance_follow_events(NULL);
746*287e80b3SSadaf Ebrahimi test_instance_follow_events(test_instance);
747*287e80b3SSadaf Ebrahimi }
748*287e80b3SSadaf Ebrahimi
749*287e80b3SSadaf Ebrahimi extern char *find_tracing_dir(bool debugfs, bool mount);
test_mounting(void)750*287e80b3SSadaf Ebrahimi static void test_mounting(void)
751*287e80b3SSadaf Ebrahimi {
752*287e80b3SSadaf Ebrahimi const char *tracing_dir;
753*287e80b3SSadaf Ebrahimi const char *debug_dir;
754*287e80b3SSadaf Ebrahimi struct stat st;
755*287e80b3SSadaf Ebrahimi char *save_tracing = NULL;
756*287e80b3SSadaf Ebrahimi char *save_debug = NULL;
757*287e80b3SSadaf Ebrahimi char *path;
758*287e80b3SSadaf Ebrahimi char *dir;
759*287e80b3SSadaf Ebrahimi int ret;
760*287e80b3SSadaf Ebrahimi
761*287e80b3SSadaf Ebrahimi /* First, unmount all instances of debugfs */
762*287e80b3SSadaf Ebrahimi do {
763*287e80b3SSadaf Ebrahimi dir = find_tracing_dir(true, false);
764*287e80b3SSadaf Ebrahimi if (dir) {
765*287e80b3SSadaf Ebrahimi ret = umount(dir);
766*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
767*287e80b3SSadaf Ebrahimi if (ret < 0)
768*287e80b3SSadaf Ebrahimi return;
769*287e80b3SSadaf Ebrahimi /* Save the first instance that's not /sys/kernel/debug */
770*287e80b3SSadaf Ebrahimi if (!save_debug && strcmp(dir, DEBUGFS_DEFAULT_PATH) != 0)
771*287e80b3SSadaf Ebrahimi save_debug = dir;
772*287e80b3SSadaf Ebrahimi else
773*287e80b3SSadaf Ebrahimi free(dir);
774*287e80b3SSadaf Ebrahimi }
775*287e80b3SSadaf Ebrahimi } while (dir);
776*287e80b3SSadaf Ebrahimi
777*287e80b3SSadaf Ebrahimi /* Next, unmount all instances of tracefs */
778*287e80b3SSadaf Ebrahimi do {
779*287e80b3SSadaf Ebrahimi dir = find_tracing_dir(false, false);
780*287e80b3SSadaf Ebrahimi if (dir) {
781*287e80b3SSadaf Ebrahimi ret = umount(dir);
782*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
783*287e80b3SSadaf Ebrahimi if (ret < 0)
784*287e80b3SSadaf Ebrahimi return;
785*287e80b3SSadaf Ebrahimi /* Save the first instance that's not in /sys/kernel/ */
786*287e80b3SSadaf Ebrahimi if (!save_tracing && strncmp(dir, "/sys/kernel/", 12) != 0)
787*287e80b3SSadaf Ebrahimi save_tracing = dir;
788*287e80b3SSadaf Ebrahimi else
789*287e80b3SSadaf Ebrahimi free(dir);
790*287e80b3SSadaf Ebrahimi }
791*287e80b3SSadaf Ebrahimi } while (dir);
792*287e80b3SSadaf Ebrahimi
793*287e80b3SSadaf Ebrahimi /* Mount first the tracing dir (which should mount at /sys/kernel/tracing */
794*287e80b3SSadaf Ebrahimi tracing_dir = tracefs_tracing_dir();
795*287e80b3SSadaf Ebrahimi CU_TEST(tracing_dir != NULL);
796*287e80b3SSadaf Ebrahimi if (tracing_dir != NULL) {
797*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(tracing_dir, TRACEFS_DEFAULT_PATH) == 0 ||
798*287e80b3SSadaf Ebrahimi strcmp(tracing_dir, TRACEFS_DEFAULT2_PATH) == 0);
799*287e80b3SSadaf Ebrahimi if (strncmp(tracing_dir, "/sys/kernel/", 12) != 0)
800*287e80b3SSadaf Ebrahimi printf("Tracing directory mounted at '%s'\n",
801*287e80b3SSadaf Ebrahimi tracing_dir);
802*287e80b3SSadaf Ebrahimi
803*287e80b3SSadaf Ebrahimi /* Make sure the directory has content.*/
804*287e80b3SSadaf Ebrahimi asprintf(&path, "%s/trace", tracing_dir);
805*287e80b3SSadaf Ebrahimi CU_TEST(stat(path, &st) == 0);
806*287e80b3SSadaf Ebrahimi free(path);
807*287e80b3SSadaf Ebrahimi }
808*287e80b3SSadaf Ebrahimi
809*287e80b3SSadaf Ebrahimi /* Now mount debugfs dir, which should mount at /sys/kernel/debug */
810*287e80b3SSadaf Ebrahimi debug_dir = tracefs_debug_dir();
811*287e80b3SSadaf Ebrahimi CU_TEST(debug_dir != NULL);
812*287e80b3SSadaf Ebrahimi if (debug_dir != NULL) {
813*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(debug_dir, DEBUGFS_DEFAULT_PATH) == 0);
814*287e80b3SSadaf Ebrahimi if (strcmp(debug_dir, DEBUGFS_DEFAULT_PATH) != 0)
815*287e80b3SSadaf Ebrahimi printf("debug directory mounted at '%s'\n",
816*287e80b3SSadaf Ebrahimi debug_dir);
817*287e80b3SSadaf Ebrahimi
818*287e80b3SSadaf Ebrahimi /* Make sure the directory has content.*/
819*287e80b3SSadaf Ebrahimi asprintf(&path, "%s/tracing", debug_dir);
820*287e80b3SSadaf Ebrahimi CU_TEST(stat(path, &st) == 0);
821*287e80b3SSadaf Ebrahimi free(path);
822*287e80b3SSadaf Ebrahimi }
823*287e80b3SSadaf Ebrahimi
824*287e80b3SSadaf Ebrahimi if (save_debug)
825*287e80b3SSadaf Ebrahimi mount("debugfs", save_debug, "debugfs", 0, NULL);
826*287e80b3SSadaf Ebrahimi
827*287e80b3SSadaf Ebrahimi if (save_tracing &&
828*287e80b3SSadaf Ebrahimi (!save_debug || strncmp(save_debug, save_tracing, strlen(save_debug)) != 0))
829*287e80b3SSadaf Ebrahimi mount("tracefs", save_tracing, "tracefs", 0, NULL);
830*287e80b3SSadaf Ebrahimi
831*287e80b3SSadaf Ebrahimi free(save_debug);
832*287e80b3SSadaf Ebrahimi free(save_tracing);
833*287e80b3SSadaf Ebrahimi }
834*287e80b3SSadaf Ebrahimi
read_trace_cpu_file(struct test_cpu_data * data)835*287e80b3SSadaf Ebrahimi static int read_trace_cpu_file(struct test_cpu_data *data)
836*287e80b3SSadaf Ebrahimi {
837*287e80b3SSadaf Ebrahimi unsigned long long ts;
838*287e80b3SSadaf Ebrahimi struct tep_record record;
839*287e80b3SSadaf Ebrahimi struct kbuffer *kbuf = data->kbuf;
840*287e80b3SSadaf Ebrahimi void *buf = data->buf;
841*287e80b3SSadaf Ebrahimi bool first = true;
842*287e80b3SSadaf Ebrahimi int bufsize = data->bufsize;
843*287e80b3SSadaf Ebrahimi int fd = data->fd;
844*287e80b3SSadaf Ebrahimi int missed;
845*287e80b3SSadaf Ebrahimi int pid;
846*287e80b3SSadaf Ebrahimi int ret;
847*287e80b3SSadaf Ebrahimi int cnt = 0;
848*287e80b3SSadaf Ebrahimi
849*287e80b3SSadaf Ebrahimi ret = lseek64(fd, 0, SEEK_SET);
850*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
851*287e80b3SSadaf Ebrahimi if (ret)
852*287e80b3SSadaf Ebrahimi return -1;
853*287e80b3SSadaf Ebrahimi
854*287e80b3SSadaf Ebrahimi for (;;) {
855*287e80b3SSadaf Ebrahimi ret = read(fd, buf, bufsize);
856*287e80b3SSadaf Ebrahimi CU_TEST(ret > 0 || !first);
857*287e80b3SSadaf Ebrahimi if (ret <= 0)
858*287e80b3SSadaf Ebrahimi break;
859*287e80b3SSadaf Ebrahimi first = false;
860*287e80b3SSadaf Ebrahimi
861*287e80b3SSadaf Ebrahimi ret = kbuffer_load_subbuffer(kbuf, buf);
862*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
863*287e80b3SSadaf Ebrahimi missed = kbuffer_missed_events(kbuf);
864*287e80b3SSadaf Ebrahimi if (missed)
865*287e80b3SSadaf Ebrahimi printf("missed events %d\n", missed);
866*287e80b3SSadaf Ebrahimi for (;;) {
867*287e80b3SSadaf Ebrahimi record.data = kbuffer_read_event(kbuf, &ts);
868*287e80b3SSadaf Ebrahimi if (!record.data)
869*287e80b3SSadaf Ebrahimi break;
870*287e80b3SSadaf Ebrahimi record.ts = ts;
871*287e80b3SSadaf Ebrahimi pid = tep_data_pid(data->tep, &record);
872*287e80b3SSadaf Ebrahimi if (pid == data->this_pid)
873*287e80b3SSadaf Ebrahimi cnt++;
874*287e80b3SSadaf Ebrahimi kbuffer_next_event(kbuf, NULL);
875*287e80b3SSadaf Ebrahimi }
876*287e80b3SSadaf Ebrahimi }
877*287e80b3SSadaf Ebrahimi return ret == 0 ? cnt : ret;
878*287e80b3SSadaf Ebrahimi }
879*287e80b3SSadaf Ebrahimi
trace_cpu_thread(void * arg)880*287e80b3SSadaf Ebrahimi static void *trace_cpu_thread(void *arg)
881*287e80b3SSadaf Ebrahimi {
882*287e80b3SSadaf Ebrahimi struct test_cpu_data *data = arg;
883*287e80b3SSadaf Ebrahimi struct tracefs_cpu *tcpu = data->tcpu;
884*287e80b3SSadaf Ebrahimi int fd = data->fd;
885*287e80b3SSadaf Ebrahimi long ret = 0;
886*287e80b3SSadaf Ebrahimi
887*287e80b3SSadaf Ebrahimi thread_affinity();
888*287e80b3SSadaf Ebrahimi
889*287e80b3SSadaf Ebrahimi while (!data->done && ret >= 0) {
890*287e80b3SSadaf Ebrahimi ret = tracefs_cpu_write(tcpu, fd, false);
891*287e80b3SSadaf Ebrahimi if (ret < 0 && errno == EAGAIN)
892*287e80b3SSadaf Ebrahimi ret = 0;
893*287e80b3SSadaf Ebrahimi }
894*287e80b3SSadaf Ebrahimi if (ret >= 0 || errno == EAGAIN) {
895*287e80b3SSadaf Ebrahimi do {
896*287e80b3SSadaf Ebrahimi ret = tracefs_cpu_flush_write(tcpu, fd);
897*287e80b3SSadaf Ebrahimi } while (ret > 0);
898*287e80b3SSadaf Ebrahimi }
899*287e80b3SSadaf Ebrahimi
900*287e80b3SSadaf Ebrahimi return (void *)ret;
901*287e80b3SSadaf Ebrahimi }
902*287e80b3SSadaf Ebrahimi
test_cpu_pipe(struct test_cpu_data * data,int expect)903*287e80b3SSadaf Ebrahimi static void test_cpu_pipe(struct test_cpu_data *data, int expect)
904*287e80b3SSadaf Ebrahimi {
905*287e80b3SSadaf Ebrahimi pthread_t thread;
906*287e80b3SSadaf Ebrahimi void *retval;
907*287e80b3SSadaf Ebrahimi long ret;
908*287e80b3SSadaf Ebrahimi int cnt;
909*287e80b3SSadaf Ebrahimi
910*287e80b3SSadaf Ebrahimi tracefs_instance_file_clear(data->instance, "trace");
911*287e80b3SSadaf Ebrahimi ftruncate(data->fd, 0);
912*287e80b3SSadaf Ebrahimi
913*287e80b3SSadaf Ebrahimi data->done = false;
914*287e80b3SSadaf Ebrahimi
915*287e80b3SSadaf Ebrahimi pthread_create(&thread, NULL, trace_cpu_thread, data);
916*287e80b3SSadaf Ebrahimi sleep(1);
917*287e80b3SSadaf Ebrahimi
918*287e80b3SSadaf Ebrahimi call_getppid(expect);
919*287e80b3SSadaf Ebrahimi
920*287e80b3SSadaf Ebrahimi data->done = true;
921*287e80b3SSadaf Ebrahimi tracefs_cpu_stop(data->tcpu);
922*287e80b3SSadaf Ebrahimi pthread_join(thread, &retval);
923*287e80b3SSadaf Ebrahimi ret = (long)retval;
924*287e80b3SSadaf Ebrahimi CU_TEST(ret >= 0);
925*287e80b3SSadaf Ebrahimi
926*287e80b3SSadaf Ebrahimi cnt = read_trace_cpu_file(data);
927*287e80b3SSadaf Ebrahimi
928*287e80b3SSadaf Ebrahimi CU_TEST(cnt == expect);
929*287e80b3SSadaf Ebrahimi }
930*287e80b3SSadaf Ebrahimi
test_instance_trace_cpu_pipe(struct tracefs_instance * instance)931*287e80b3SSadaf Ebrahimi static void test_instance_trace_cpu_pipe(struct tracefs_instance *instance)
932*287e80b3SSadaf Ebrahimi {
933*287e80b3SSadaf Ebrahimi struct test_cpu_data data;
934*287e80b3SSadaf Ebrahimi
935*287e80b3SSadaf Ebrahimi if (setup_trace_cpu(instance, &data))
936*287e80b3SSadaf Ebrahimi return;
937*287e80b3SSadaf Ebrahimi
938*287e80b3SSadaf Ebrahimi test_cpu_pipe(&data, 1);
939*287e80b3SSadaf Ebrahimi test_cpu_pipe(&data, data.events_per_buf / 2);
940*287e80b3SSadaf Ebrahimi test_cpu_pipe(&data, data.events_per_buf);
941*287e80b3SSadaf Ebrahimi test_cpu_pipe(&data, data.events_per_buf + 1);
942*287e80b3SSadaf Ebrahimi test_cpu_pipe(&data, data.events_per_buf * 1000);
943*287e80b3SSadaf Ebrahimi
944*287e80b3SSadaf Ebrahimi shutdown_trace_cpu(&data);
945*287e80b3SSadaf Ebrahimi }
946*287e80b3SSadaf Ebrahimi
test_trace_cpu_pipe(void)947*287e80b3SSadaf Ebrahimi static void test_trace_cpu_pipe(void)
948*287e80b3SSadaf Ebrahimi {
949*287e80b3SSadaf Ebrahimi test_instance_trace_cpu_pipe(NULL);
950*287e80b3SSadaf Ebrahimi test_instance_trace_cpu_pipe(test_instance);
951*287e80b3SSadaf Ebrahimi }
952*287e80b3SSadaf Ebrahimi
get_dynevents_check(enum tracefs_dynevent_type types,int count)953*287e80b3SSadaf Ebrahimi static struct tracefs_dynevent **get_dynevents_check(enum tracefs_dynevent_type types, int count)
954*287e80b3SSadaf Ebrahimi {
955*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **devents;
956*287e80b3SSadaf Ebrahimi int i;
957*287e80b3SSadaf Ebrahimi
958*287e80b3SSadaf Ebrahimi devents = tracefs_dynevent_get_all(types, NULL);
959*287e80b3SSadaf Ebrahimi if (count) {
960*287e80b3SSadaf Ebrahimi CU_TEST(devents != NULL);
961*287e80b3SSadaf Ebrahimi if (!devents)
962*287e80b3SSadaf Ebrahimi return NULL;
963*287e80b3SSadaf Ebrahimi i = 0;
964*287e80b3SSadaf Ebrahimi while (devents[i])
965*287e80b3SSadaf Ebrahimi i++;
966*287e80b3SSadaf Ebrahimi CU_TEST(i == count);
967*287e80b3SSadaf Ebrahimi } else {
968*287e80b3SSadaf Ebrahimi CU_TEST(devents == NULL);
969*287e80b3SSadaf Ebrahimi }
970*287e80b3SSadaf Ebrahimi
971*287e80b3SSadaf Ebrahimi return devents;
972*287e80b3SSadaf Ebrahimi }
973*287e80b3SSadaf Ebrahimi
974*287e80b3SSadaf Ebrahimi
975*287e80b3SSadaf Ebrahimi struct test_synth {
976*287e80b3SSadaf Ebrahimi char *name;
977*287e80b3SSadaf Ebrahimi char *start_system;
978*287e80b3SSadaf Ebrahimi char *start_event;
979*287e80b3SSadaf Ebrahimi char *end_system;
980*287e80b3SSadaf Ebrahimi char *end_event;
981*287e80b3SSadaf Ebrahimi char *start_match_field;
982*287e80b3SSadaf Ebrahimi char *end_match_field;
983*287e80b3SSadaf Ebrahimi char *match_name;
984*287e80b3SSadaf Ebrahimi };
985*287e80b3SSadaf Ebrahimi
test_synth_compare(struct test_synth * synth,struct tracefs_dynevent ** devents)986*287e80b3SSadaf Ebrahimi static void test_synth_compare(struct test_synth *synth, struct tracefs_dynevent **devents)
987*287e80b3SSadaf Ebrahimi {
988*287e80b3SSadaf Ebrahimi enum tracefs_dynevent_type stype;
989*287e80b3SSadaf Ebrahimi char *format;
990*287e80b3SSadaf Ebrahimi char *event;
991*287e80b3SSadaf Ebrahimi int i;
992*287e80b3SSadaf Ebrahimi
993*287e80b3SSadaf Ebrahimi for (i = 0; devents && devents[i]; i++) {
994*287e80b3SSadaf Ebrahimi stype = tracefs_dynevent_info(devents[i], NULL,
995*287e80b3SSadaf Ebrahimi &event, NULL, NULL, &format);
996*287e80b3SSadaf Ebrahimi CU_TEST(stype == TRACEFS_DYNEVENT_SYNTH);
997*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(event, synth[i].name) == 0);
998*287e80b3SSadaf Ebrahimi if (synth[i].match_name) {
999*287e80b3SSadaf Ebrahimi CU_TEST(strstr(format, synth[i].match_name) != NULL);
1000*287e80b3SSadaf Ebrahimi }
1001*287e80b3SSadaf Ebrahimi free(event);
1002*287e80b3SSadaf Ebrahimi free(format);
1003*287e80b3SSadaf Ebrahimi }
1004*287e80b3SSadaf Ebrahimi CU_TEST(devents == NULL || devents[i] == NULL);
1005*287e80b3SSadaf Ebrahimi }
1006*287e80b3SSadaf Ebrahimi
test_instance_synthetic(struct tracefs_instance * instance)1007*287e80b3SSadaf Ebrahimi static void test_instance_synthetic(struct tracefs_instance *instance)
1008*287e80b3SSadaf Ebrahimi {
1009*287e80b3SSadaf Ebrahimi struct test_synth sevents[] = {
1010*287e80b3SSadaf Ebrahimi {"synth_1", "sched", "sched_waking", "sched", "sched_switch", "pid", "next_pid", "pid_match"},
1011*287e80b3SSadaf Ebrahimi {"synth_2", "syscalls", "sys_enter_openat2", "syscalls", "sys_exit_openat2", "__syscall_nr", "__syscall_nr", "nr_match"},
1012*287e80b3SSadaf Ebrahimi };
1013*287e80b3SSadaf Ebrahimi int sevents_count = sizeof(sevents) / sizeof((sevents)[0]);
1014*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **devents;
1015*287e80b3SSadaf Ebrahimi struct tracefs_synth **synth;
1016*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
1017*287e80b3SSadaf Ebrahimi int ret;
1018*287e80b3SSadaf Ebrahimi int i;
1019*287e80b3SSadaf Ebrahimi
1020*287e80b3SSadaf Ebrahimi synth = calloc(sevents_count + 1, sizeof(*synth));
1021*287e80b3SSadaf Ebrahimi
1022*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(NULL);
1023*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
1024*287e80b3SSadaf Ebrahimi
1025*287e80b3SSadaf Ebrahimi /* kprobes APIs */
1026*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_SYNTH, true);
1027*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1028*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
1029*287e80b3SSadaf Ebrahimi
1030*287e80b3SSadaf Ebrahimi for (i = 0; i < sevents_count; i++) {
1031*287e80b3SSadaf Ebrahimi synth[i] = tracefs_synth_alloc(tep, sevents[i].name,
1032*287e80b3SSadaf Ebrahimi sevents[i].start_system, sevents[i].start_event,
1033*287e80b3SSadaf Ebrahimi sevents[i].end_system, sevents[i].end_event,
1034*287e80b3SSadaf Ebrahimi sevents[i].start_match_field, sevents[i].end_match_field,
1035*287e80b3SSadaf Ebrahimi sevents[i].match_name);
1036*287e80b3SSadaf Ebrahimi CU_TEST(synth[i] != NULL);
1037*287e80b3SSadaf Ebrahimi }
1038*287e80b3SSadaf Ebrahimi
1039*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
1040*287e80b3SSadaf Ebrahimi
1041*287e80b3SSadaf Ebrahimi for (i = 0; i < sevents_count; i++) {
1042*287e80b3SSadaf Ebrahimi ret = tracefs_synth_create(synth[i]);
1043*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1044*287e80b3SSadaf Ebrahimi }
1045*287e80b3SSadaf Ebrahimi
1046*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, sevents_count);
1047*287e80b3SSadaf Ebrahimi CU_TEST(devents != NULL);
1048*287e80b3SSadaf Ebrahimi test_synth_compare(sevents, devents);
1049*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1050*287e80b3SSadaf Ebrahimi
1051*287e80b3SSadaf Ebrahimi for (i = 0; i < sevents_count; i++) {
1052*287e80b3SSadaf Ebrahimi ret = tracefs_synth_destroy(synth[i]);
1053*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1054*287e80b3SSadaf Ebrahimi }
1055*287e80b3SSadaf Ebrahimi
1056*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
1057*287e80b3SSadaf Ebrahimi
1058*287e80b3SSadaf Ebrahimi for (i = 0; i < sevents_count; i++)
1059*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth[i]);
1060*287e80b3SSadaf Ebrahimi
1061*287e80b3SSadaf Ebrahimi tep_free(tep);
1062*287e80b3SSadaf Ebrahimi free(synth);
1063*287e80b3SSadaf Ebrahimi }
1064*287e80b3SSadaf Ebrahimi
test_synthetic(void)1065*287e80b3SSadaf Ebrahimi static void test_synthetic(void)
1066*287e80b3SSadaf Ebrahimi {
1067*287e80b3SSadaf Ebrahimi test_instance_synthetic(test_instance);
1068*287e80b3SSadaf Ebrahimi }
1069*287e80b3SSadaf Ebrahimi
test_trace_file(void)1070*287e80b3SSadaf Ebrahimi static void test_trace_file(void)
1071*287e80b3SSadaf Ebrahimi {
1072*287e80b3SSadaf Ebrahimi const char *tmp = get_rand_str();
1073*287e80b3SSadaf Ebrahimi const char *tdir;
1074*287e80b3SSadaf Ebrahimi struct stat st;
1075*287e80b3SSadaf Ebrahimi char *file;
1076*287e80b3SSadaf Ebrahimi
1077*287e80b3SSadaf Ebrahimi tdir = tracefs_tracing_dir();
1078*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1079*287e80b3SSadaf Ebrahimi CU_TEST(stat(tdir, &st) == 0);
1080*287e80b3SSadaf Ebrahimi CU_TEST(S_ISDIR(st.st_mode));
1081*287e80b3SSadaf Ebrahimi
1082*287e80b3SSadaf Ebrahimi file = tracefs_get_tracing_file(NULL);
1083*287e80b3SSadaf Ebrahimi CU_TEST(file == NULL);
1084*287e80b3SSadaf Ebrahimi file = tracefs_get_tracing_file(tmp);
1085*287e80b3SSadaf Ebrahimi CU_TEST(file != NULL);
1086*287e80b3SSadaf Ebrahimi CU_TEST(stat(file, &st) != 0);
1087*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(file);
1088*287e80b3SSadaf Ebrahimi
1089*287e80b3SSadaf Ebrahimi file = tracefs_get_tracing_file("trace");
1090*287e80b3SSadaf Ebrahimi CU_TEST(file != NULL);
1091*287e80b3SSadaf Ebrahimi CU_TEST(stat(file, &st) == 0);
1092*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(file);
1093*287e80b3SSadaf Ebrahimi }
1094*287e80b3SSadaf Ebrahimi
test_instance_file_read(struct tracefs_instance * inst,const char * fname)1095*287e80b3SSadaf Ebrahimi static void test_instance_file_read(struct tracefs_instance *inst, const char *fname)
1096*287e80b3SSadaf Ebrahimi {
1097*287e80b3SSadaf Ebrahimi const char *tdir = tracefs_tracing_dir();
1098*287e80b3SSadaf Ebrahimi char buf[BUFSIZ];
1099*287e80b3SSadaf Ebrahimi char *fpath;
1100*287e80b3SSadaf Ebrahimi char *file;
1101*287e80b3SSadaf Ebrahimi size_t fsize = 0;
1102*287e80b3SSadaf Ebrahimi int size = 0;
1103*287e80b3SSadaf Ebrahimi int fd;
1104*287e80b3SSadaf Ebrahimi
1105*287e80b3SSadaf Ebrahimi if (inst) {
1106*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&fpath, "%s/instances/%s/%s",
1107*287e80b3SSadaf Ebrahimi tdir, tracefs_instance_get_name(inst), fname) > 0);
1108*287e80b3SSadaf Ebrahimi } else {
1109*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&fpath, "%s/%s", tdir, fname) > 0);
1110*287e80b3SSadaf Ebrahimi }
1111*287e80b3SSadaf Ebrahimi
1112*287e80b3SSadaf Ebrahimi memset(buf, 0, BUFSIZ);
1113*287e80b3SSadaf Ebrahimi fd = open(fpath, O_RDONLY);
1114*287e80b3SSadaf Ebrahimi CU_TEST(fd >= 0);
1115*287e80b3SSadaf Ebrahimi fsize = read(fd, buf, BUFSIZ);
1116*287e80b3SSadaf Ebrahimi CU_TEST(fsize >= 0);
1117*287e80b3SSadaf Ebrahimi close(fd);
1118*287e80b3SSadaf Ebrahimi buf[BUFSIZ - 1] = 0;
1119*287e80b3SSadaf Ebrahimi
1120*287e80b3SSadaf Ebrahimi file = tracefs_instance_file_read(inst, fname, &size);
1121*287e80b3SSadaf Ebrahimi CU_TEST(file != NULL);
1122*287e80b3SSadaf Ebrahimi CU_TEST(size == fsize);
1123*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(file, buf) == 0);
1124*287e80b3SSadaf Ebrahimi
1125*287e80b3SSadaf Ebrahimi free(fpath);
1126*287e80b3SSadaf Ebrahimi free(file);
1127*287e80b3SSadaf Ebrahimi }
1128*287e80b3SSadaf Ebrahimi
1129*287e80b3SSadaf Ebrahimi struct probe_test {
1130*287e80b3SSadaf Ebrahimi enum tracefs_dynevent_type type;
1131*287e80b3SSadaf Ebrahimi char *prefix;
1132*287e80b3SSadaf Ebrahimi char *system;
1133*287e80b3SSadaf Ebrahimi char *event;
1134*287e80b3SSadaf Ebrahimi char *address;
1135*287e80b3SSadaf Ebrahimi char *format;
1136*287e80b3SSadaf Ebrahimi };
1137*287e80b3SSadaf Ebrahimi
check_probes(struct probe_test * probes,int count,struct tracefs_dynevent ** devents,bool in_system,struct tracefs_instance * instance,struct tep_handle * tep)1138*287e80b3SSadaf Ebrahimi static bool check_probes(struct probe_test *probes, int count,
1139*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **devents, bool in_system,
1140*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance, struct tep_handle *tep)
1141*287e80b3SSadaf Ebrahimi {
1142*287e80b3SSadaf Ebrahimi enum tracefs_dynevent_type type;
1143*287e80b3SSadaf Ebrahimi struct tep_event *tevent;
1144*287e80b3SSadaf Ebrahimi char *ename;
1145*287e80b3SSadaf Ebrahimi char *address;
1146*287e80b3SSadaf Ebrahimi char *event;
1147*287e80b3SSadaf Ebrahimi char *system;
1148*287e80b3SSadaf Ebrahimi char *format;
1149*287e80b3SSadaf Ebrahimi char *prefix;
1150*287e80b3SSadaf Ebrahimi int found = 0;
1151*287e80b3SSadaf Ebrahimi int ret;
1152*287e80b3SSadaf Ebrahimi int i, j;
1153*287e80b3SSadaf Ebrahimi
1154*287e80b3SSadaf Ebrahimi for (i = 0; devents && devents[i]; i++) {
1155*287e80b3SSadaf Ebrahimi type = tracefs_dynevent_info(devents[i], &system,
1156*287e80b3SSadaf Ebrahimi &event, &prefix, &address, &format);
1157*287e80b3SSadaf Ebrahimi for (j = 0; j < count; j++) {
1158*287e80b3SSadaf Ebrahimi if (type != probes[j].type)
1159*287e80b3SSadaf Ebrahimi continue;
1160*287e80b3SSadaf Ebrahimi if (probes[j].event)
1161*287e80b3SSadaf Ebrahimi ename = probes[j].event;
1162*287e80b3SSadaf Ebrahimi else
1163*287e80b3SSadaf Ebrahimi ename = probes[j].address;
1164*287e80b3SSadaf Ebrahimi if (strcmp(ename, event))
1165*287e80b3SSadaf Ebrahimi continue;
1166*287e80b3SSadaf Ebrahimi if (probes[j].system) {
1167*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(probes[j].system, system) == 0);
1168*287e80b3SSadaf Ebrahimi }
1169*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(probes[j].address, address) == 0);
1170*287e80b3SSadaf Ebrahimi if (probes[j].format) {
1171*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(probes[j].format, format) == 0);
1172*287e80b3SSadaf Ebrahimi }
1173*287e80b3SSadaf Ebrahimi if (probes[j].prefix) {
1174*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(probes[j].prefix, prefix) == 0);
1175*287e80b3SSadaf Ebrahimi }
1176*287e80b3SSadaf Ebrahimi ret = tracefs_event_enable(instance, system, event);
1177*287e80b3SSadaf Ebrahimi if (in_system) {
1178*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1179*287e80b3SSadaf Ebrahimi } else {
1180*287e80b3SSadaf Ebrahimi CU_TEST(ret != 0);
1181*287e80b3SSadaf Ebrahimi }
1182*287e80b3SSadaf Ebrahimi ret = tracefs_event_disable(instance, system, event);
1183*287e80b3SSadaf Ebrahimi if (in_system) {
1184*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1185*287e80b3SSadaf Ebrahimi } else {
1186*287e80b3SSadaf Ebrahimi CU_TEST(ret != 0);
1187*287e80b3SSadaf Ebrahimi }
1188*287e80b3SSadaf Ebrahimi
1189*287e80b3SSadaf Ebrahimi tevent = tracefs_dynevent_get_event(tep, devents[i]);
1190*287e80b3SSadaf Ebrahimi if (in_system) {
1191*287e80b3SSadaf Ebrahimi CU_TEST(tevent != NULL);
1192*287e80b3SSadaf Ebrahimi if (tevent) {
1193*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(tevent->name, event) == 0);
1194*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(tevent->system, system) == 0);
1195*287e80b3SSadaf Ebrahimi }
1196*287e80b3SSadaf Ebrahimi } else {
1197*287e80b3SSadaf Ebrahimi CU_TEST(tevent == NULL);
1198*287e80b3SSadaf Ebrahimi }
1199*287e80b3SSadaf Ebrahimi
1200*287e80b3SSadaf Ebrahimi found++;
1201*287e80b3SSadaf Ebrahimi break;
1202*287e80b3SSadaf Ebrahimi }
1203*287e80b3SSadaf Ebrahimi free(system);
1204*287e80b3SSadaf Ebrahimi free(event);
1205*287e80b3SSadaf Ebrahimi free(prefix);
1206*287e80b3SSadaf Ebrahimi free(address);
1207*287e80b3SSadaf Ebrahimi free(format);
1208*287e80b3SSadaf Ebrahimi }
1209*287e80b3SSadaf Ebrahimi
1210*287e80b3SSadaf Ebrahimi CU_TEST(found == count);
1211*287e80b3SSadaf Ebrahimi if (found != count)
1212*287e80b3SSadaf Ebrahimi return false;
1213*287e80b3SSadaf Ebrahimi
1214*287e80b3SSadaf Ebrahimi return true;
1215*287e80b3SSadaf Ebrahimi }
1216*287e80b3SSadaf Ebrahimi
test_kprobes_instance(struct tracefs_instance * instance)1217*287e80b3SSadaf Ebrahimi static void test_kprobes_instance(struct tracefs_instance *instance)
1218*287e80b3SSadaf Ebrahimi {
1219*287e80b3SSadaf Ebrahimi struct probe_test ktests[] = {
1220*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_KPROBE, "p", NULL, "mkdir", "do_mkdirat", "path=+u0($arg2):ustring" },
1221*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_KPROBE, "p", NULL, "close", "close_fd", NULL },
1222*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_KPROBE, "p", "ptest", "open2", "do_sys_openat2",
1223*287e80b3SSadaf Ebrahimi "file=+u0($arg2):ustring flags=+0($arg3):x64" },
1224*287e80b3SSadaf Ebrahimi };
1225*287e80b3SSadaf Ebrahimi struct probe_test kretests[] = {
1226*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_KRETPROBE, NULL, NULL, "retopen", "do_sys_openat2", "ret=$retval" },
1227*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_KRETPROBE, NULL, NULL, NULL, "do_sys_open", "ret=$retval" },
1228*287e80b3SSadaf Ebrahimi };
1229*287e80b3SSadaf Ebrahimi int kretprobe_count = sizeof(kretests) / sizeof((kretests)[0]);
1230*287e80b3SSadaf Ebrahimi int kprobe_count = sizeof(ktests) / sizeof((ktests)[0]);
1231*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **dkretprobe;
1232*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **dkprobe;
1233*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **devents;
1234*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
1235*287e80b3SSadaf Ebrahimi char *tmp;
1236*287e80b3SSadaf Ebrahimi int ret;
1237*287e80b3SSadaf Ebrahimi int i;
1238*287e80b3SSadaf Ebrahimi
1239*287e80b3SSadaf Ebrahimi tep = tep_alloc();
1240*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
1241*287e80b3SSadaf Ebrahimi
1242*287e80b3SSadaf Ebrahimi dkprobe = calloc(kprobe_count + 1, sizeof(*dkprobe));
1243*287e80b3SSadaf Ebrahimi dkretprobe = calloc(kretprobe_count + 1, sizeof(*dkretprobe));
1244*287e80b3SSadaf Ebrahimi
1245*287e80b3SSadaf Ebrahimi /* Invalid parameters */
1246*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_kprobe_alloc("test", NULL, NULL, "test") == NULL);
1247*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_kretprobe_alloc("test", NULL, NULL, "test", 0) == NULL);
1248*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_create(NULL) != 0);
1249*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_info(NULL, &tmp, &tmp, &tmp, &tmp, &tmp) == TRACEFS_DYNEVENT_UNKNOWN);
1250*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_kprobe_raw("test", "test", NULL, "test") != 0);
1251*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_kretprobe_raw("test", "test", NULL, "test") != 0);
1252*287e80b3SSadaf Ebrahimi
1253*287e80b3SSadaf Ebrahimi /* kprobes APIs */
1254*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
1255*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1256*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1257*287e80b3SSadaf Ebrahimi
1258*287e80b3SSadaf Ebrahimi for (i = 0; i < kprobe_count; i++) {
1259*287e80b3SSadaf Ebrahimi dkprobe[i] = tracefs_kprobe_alloc(ktests[i].system, ktests[i].event,
1260*287e80b3SSadaf Ebrahimi ktests[i].address, ktests[i].format);
1261*287e80b3SSadaf Ebrahimi CU_TEST(dkprobe[i] != NULL);
1262*287e80b3SSadaf Ebrahimi }
1263*287e80b3SSadaf Ebrahimi dkprobe[i] = NULL;
1264*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1265*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance, tep));
1266*287e80b3SSadaf Ebrahimi
1267*287e80b3SSadaf Ebrahimi for (i = 0; i < kretprobe_count; i++) {
1268*287e80b3SSadaf Ebrahimi dkretprobe[i] = tracefs_kretprobe_alloc(kretests[i].system, kretests[i].event,
1269*287e80b3SSadaf Ebrahimi kretests[i].address, kretests[i].format, 0);
1270*287e80b3SSadaf Ebrahimi CU_TEST(dkretprobe[i] != NULL);
1271*287e80b3SSadaf Ebrahimi }
1272*287e80b3SSadaf Ebrahimi dkretprobe[i] = NULL;
1273*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1274*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
1275*287e80b3SSadaf Ebrahimi
1276*287e80b3SSadaf Ebrahimi for (i = 0; i < kprobe_count; i++) {
1277*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_create(dkprobe[i]) == 0);
1278*287e80b3SSadaf Ebrahimi }
1279*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
1280*287e80b3SSadaf Ebrahimi kprobe_count);
1281*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1282*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
1283*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1284*287e80b3SSadaf Ebrahimi devents = NULL;
1285*287e80b3SSadaf Ebrahimi
1286*287e80b3SSadaf Ebrahimi for (i = 0; i < kretprobe_count; i++) {
1287*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_create(dkretprobe[i]) == 0);
1288*287e80b3SSadaf Ebrahimi }
1289*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
1290*287e80b3SSadaf Ebrahimi kprobe_count + kretprobe_count);
1291*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1292*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
1293*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1294*287e80b3SSadaf Ebrahimi devents = NULL;
1295*287e80b3SSadaf Ebrahimi
1296*287e80b3SSadaf Ebrahimi for (i = 0; i < kretprobe_count; i++) {
1297*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_destroy(dkretprobe[i], false) == 0);
1298*287e80b3SSadaf Ebrahimi }
1299*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
1300*287e80b3SSadaf Ebrahimi kprobe_count);
1301*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1302*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
1303*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1304*287e80b3SSadaf Ebrahimi devents = NULL;
1305*287e80b3SSadaf Ebrahimi
1306*287e80b3SSadaf Ebrahimi for (i = 0; i < kprobe_count; i++) {
1307*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_destroy(dkprobe[i], false) == 0);
1308*287e80b3SSadaf Ebrahimi }
1309*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1310*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, dkprobe, false, instance, tep));
1311*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, dkretprobe, false, instance, tep));
1312*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1313*287e80b3SSadaf Ebrahimi devents = NULL;
1314*287e80b3SSadaf Ebrahimi
1315*287e80b3SSadaf Ebrahimi for (i = 0; i < kprobe_count; i++)
1316*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(dkprobe[i]);
1317*287e80b3SSadaf Ebrahimi for (i = 0; i < kretprobe_count; i++)
1318*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(dkretprobe[i]);
1319*287e80b3SSadaf Ebrahimi
1320*287e80b3SSadaf Ebrahimi /* kprobes raw APIs */
1321*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
1322*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1323*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1324*287e80b3SSadaf Ebrahimi
1325*287e80b3SSadaf Ebrahimi for (i = 0; i < kprobe_count; i++) {
1326*287e80b3SSadaf Ebrahimi ret = tracefs_kprobe_raw(ktests[i].system, ktests[i].event,
1327*287e80b3SSadaf Ebrahimi ktests[i].address, ktests[i].format);
1328*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1329*287e80b3SSadaf Ebrahimi }
1330*287e80b3SSadaf Ebrahimi
1331*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, kprobe_count);
1332*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1333*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1334*287e80b3SSadaf Ebrahimi devents = NULL;
1335*287e80b3SSadaf Ebrahimi
1336*287e80b3SSadaf Ebrahimi for (i = 0; i < kretprobe_count; i++) {
1337*287e80b3SSadaf Ebrahimi ret = tracefs_kretprobe_raw(kretests[i].system, kretests[i].event,
1338*287e80b3SSadaf Ebrahimi kretests[i].address, kretests[i].format);
1339*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1340*287e80b3SSadaf Ebrahimi }
1341*287e80b3SSadaf Ebrahimi
1342*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE, kprobe_count);
1343*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1344*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1345*287e80b3SSadaf Ebrahimi devents = NULL;
1346*287e80b3SSadaf Ebrahimi
1347*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KRETPROBE, kretprobe_count);
1348*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
1349*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1350*287e80b3SSadaf Ebrahimi devents = NULL;
1351*287e80b3SSadaf Ebrahimi
1352*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE,
1353*287e80b3SSadaf Ebrahimi kprobe_count + kretprobe_count);
1354*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(ktests, kprobe_count, devents, true, instance, tep));
1355*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(kretests, kretprobe_count, devents, true, instance, tep));
1356*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1357*287e80b3SSadaf Ebrahimi devents = NULL;
1358*287e80b3SSadaf Ebrahimi
1359*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
1360*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1361*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, 0);
1362*287e80b3SSadaf Ebrahimi free(dkretprobe);
1363*287e80b3SSadaf Ebrahimi free(dkprobe);
1364*287e80b3SSadaf Ebrahimi tep_free(tep);
1365*287e80b3SSadaf Ebrahimi }
1366*287e80b3SSadaf Ebrahimi
test_kprobes(void)1367*287e80b3SSadaf Ebrahimi static void test_kprobes(void)
1368*287e80b3SSadaf Ebrahimi {
1369*287e80b3SSadaf Ebrahimi test_kprobes_instance(test_instance);
1370*287e80b3SSadaf Ebrahimi }
1371*287e80b3SSadaf Ebrahimi
test_eprobes_instance(struct tracefs_instance * instance)1372*287e80b3SSadaf Ebrahimi static void test_eprobes_instance(struct tracefs_instance *instance)
1373*287e80b3SSadaf Ebrahimi {
1374*287e80b3SSadaf Ebrahimi struct probe_test etests[] = {
1375*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_EPROBE, "e", NULL, "sopen_in", "syscalls.sys_enter_openat",
1376*287e80b3SSadaf Ebrahimi "file=+0($filename):ustring" },
1377*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_EPROBE, "e", "etest", "sopen_out", "syscalls.sys_exit_openat",
1378*287e80b3SSadaf Ebrahimi "res=$ret:u64" },
1379*287e80b3SSadaf Ebrahimi };
1380*287e80b3SSadaf Ebrahimi int count = sizeof(etests) / sizeof((etests)[0]);
1381*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **deprobes;
1382*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **devents;
1383*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
1384*287e80b3SSadaf Ebrahimi char *tsys, *tevent;
1385*287e80b3SSadaf Ebrahimi char *tmp, *sav;
1386*287e80b3SSadaf Ebrahimi int ret;
1387*287e80b3SSadaf Ebrahimi int i;
1388*287e80b3SSadaf Ebrahimi
1389*287e80b3SSadaf Ebrahimi tep = tep_alloc();
1390*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
1391*287e80b3SSadaf Ebrahimi
1392*287e80b3SSadaf Ebrahimi deprobes = calloc(count + 1, sizeof(*deprobes));
1393*287e80b3SSadaf Ebrahimi
1394*287e80b3SSadaf Ebrahimi /* Invalid parameters */
1395*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_eprobe_alloc("test", NULL, "test", "test", "test") == NULL);
1396*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_eprobe_alloc("test", "test", NULL, "test", "test") == NULL);
1397*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_eprobe_alloc("test", "test", "test", NULL, "test") == NULL);
1398*287e80b3SSadaf Ebrahimi
1399*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_EPROBE, true);
1400*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1401*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, 0);
1402*287e80b3SSadaf Ebrahimi
1403*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1404*287e80b3SSadaf Ebrahimi tmp = strdup(etests[i].address);
1405*287e80b3SSadaf Ebrahimi tsys = strtok_r(tmp, "./", &sav);
1406*287e80b3SSadaf Ebrahimi tevent = strtok_r(NULL, "", &sav);
1407*287e80b3SSadaf Ebrahimi deprobes[i] = tracefs_eprobe_alloc(etests[i].system, etests[i].event,
1408*287e80b3SSadaf Ebrahimi tsys, tevent, etests[i].format);
1409*287e80b3SSadaf Ebrahimi free(tmp);
1410*287e80b3SSadaf Ebrahimi CU_TEST(deprobes[i] != NULL);
1411*287e80b3SSadaf Ebrahimi }
1412*287e80b3SSadaf Ebrahimi deprobes[i] = NULL;
1413*287e80b3SSadaf Ebrahimi
1414*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, 0);
1415*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(etests, count, deprobes, false, instance, tep));
1416*287e80b3SSadaf Ebrahimi
1417*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1418*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_create(deprobes[i]) == 0);
1419*287e80b3SSadaf Ebrahimi }
1420*287e80b3SSadaf Ebrahimi
1421*287e80b3SSadaf Ebrahimi devents = get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, count);
1422*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(etests, count, devents, true, instance, tep));
1423*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(devents);
1424*287e80b3SSadaf Ebrahimi devents = NULL;
1425*287e80b3SSadaf Ebrahimi
1426*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1427*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_destroy(deprobes[i], false) == 0);
1428*287e80b3SSadaf Ebrahimi }
1429*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, 0);
1430*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(etests, count, deprobes, false, instance, tep));
1431*287e80b3SSadaf Ebrahimi
1432*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++)
1433*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(deprobes[i]);
1434*287e80b3SSadaf Ebrahimi
1435*287e80b3SSadaf Ebrahimi free(deprobes);
1436*287e80b3SSadaf Ebrahimi tep_free(tep);
1437*287e80b3SSadaf Ebrahimi }
1438*287e80b3SSadaf Ebrahimi
test_eprobes(void)1439*287e80b3SSadaf Ebrahimi static void test_eprobes(void)
1440*287e80b3SSadaf Ebrahimi {
1441*287e80b3SSadaf Ebrahimi test_eprobes_instance(test_instance);
1442*287e80b3SSadaf Ebrahimi }
1443*287e80b3SSadaf Ebrahimi
1444*287e80b3SSadaf Ebrahimi #define FOFFSET 1000ll
test_uprobes_instance(struct tracefs_instance * instance)1445*287e80b3SSadaf Ebrahimi static void test_uprobes_instance(struct tracefs_instance *instance)
1446*287e80b3SSadaf Ebrahimi {
1447*287e80b3SSadaf Ebrahimi struct probe_test utests[] = {
1448*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_UPROBE, "p", "utest", "utest_u", NULL, "arg1=$stack2" },
1449*287e80b3SSadaf Ebrahimi { TRACEFS_DYNEVENT_URETPROBE, "r", "utest", "utest_r", NULL, "arg1=$retval" },
1450*287e80b3SSadaf Ebrahimi };
1451*287e80b3SSadaf Ebrahimi int count = sizeof(utests) / sizeof((utests)[0]);
1452*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **duprobes;
1453*287e80b3SSadaf Ebrahimi struct tracefs_dynevent **duvents;
1454*287e80b3SSadaf Ebrahimi char self[PATH_MAX] = { 0 };
1455*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
1456*287e80b3SSadaf Ebrahimi char *target = NULL;
1457*287e80b3SSadaf Ebrahimi int i;
1458*287e80b3SSadaf Ebrahimi
1459*287e80b3SSadaf Ebrahimi tep = tep_alloc();
1460*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
1461*287e80b3SSadaf Ebrahimi
1462*287e80b3SSadaf Ebrahimi duprobes = calloc(count + 1, sizeof(*duvents));
1463*287e80b3SSadaf Ebrahimi CU_TEST(duprobes != NULL);
1464*287e80b3SSadaf Ebrahimi CU_TEST(readlink("/proc/self/exe", self, sizeof(self)) > 0);
1465*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&target, "%s:0x%0*llx", self, (int)(sizeof(void *) * 2), FOFFSET) > 0);
1466*287e80b3SSadaf Ebrahimi
1467*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++)
1468*287e80b3SSadaf Ebrahimi utests[i].address = target;
1469*287e80b3SSadaf Ebrahimi
1470*287e80b3SSadaf Ebrahimi /* Invalid parameters */
1471*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_uprobe_alloc(NULL, NULL, self, 0, NULL) == NULL);
1472*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_uprobe_alloc(NULL, "test", NULL, 0, NULL) == NULL);
1473*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_uretprobe_alloc(NULL, NULL, self, 0, NULL) == NULL);
1474*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_uretprobe_alloc(NULL, "test", NULL, 0, NULL) == NULL);
1475*287e80b3SSadaf Ebrahimi
1476*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1477*287e80b3SSadaf Ebrahimi if (utests[i].type == TRACEFS_DYNEVENT_UPROBE)
1478*287e80b3SSadaf Ebrahimi duprobes[i] = tracefs_uprobe_alloc(utests[i].system, utests[i].event,
1479*287e80b3SSadaf Ebrahimi self, FOFFSET, utests[i].format);
1480*287e80b3SSadaf Ebrahimi else
1481*287e80b3SSadaf Ebrahimi duprobes[i] = tracefs_uretprobe_alloc(utests[i].system, utests[i].event,
1482*287e80b3SSadaf Ebrahimi self, FOFFSET, utests[i].format);
1483*287e80b3SSadaf Ebrahimi CU_TEST(duprobes[i] != NULL);
1484*287e80b3SSadaf Ebrahimi }
1485*287e80b3SSadaf Ebrahimi duprobes[i] = NULL;
1486*287e80b3SSadaf Ebrahimi
1487*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_UPROBE | TRACEFS_DYNEVENT_URETPROBE, 0);
1488*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(utests, count, duprobes, false, instance, tep));
1489*287e80b3SSadaf Ebrahimi
1490*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1491*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_create(duprobes[i]) == 0);
1492*287e80b3SSadaf Ebrahimi }
1493*287e80b3SSadaf Ebrahimi
1494*287e80b3SSadaf Ebrahimi duvents = get_dynevents_check(TRACEFS_DYNEVENT_UPROBE | TRACEFS_DYNEVENT_URETPROBE, count);
1495*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(utests, count, duvents, true, instance, tep));
1496*287e80b3SSadaf Ebrahimi tracefs_dynevent_list_free(duvents);
1497*287e80b3SSadaf Ebrahimi
1498*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++) {
1499*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dynevent_destroy(duprobes[i], false) == 0);
1500*287e80b3SSadaf Ebrahimi }
1501*287e80b3SSadaf Ebrahimi get_dynevents_check(TRACEFS_DYNEVENT_UPROBE | TRACEFS_DYNEVENT_URETPROBE, 0);
1502*287e80b3SSadaf Ebrahimi CU_TEST(check_probes(utests, count, duprobes, false, instance, tep));
1503*287e80b3SSadaf Ebrahimi
1504*287e80b3SSadaf Ebrahimi for (i = 0; i < count; i++)
1505*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(duprobes[i]);
1506*287e80b3SSadaf Ebrahimi
1507*287e80b3SSadaf Ebrahimi free(duprobes);
1508*287e80b3SSadaf Ebrahimi free(target);
1509*287e80b3SSadaf Ebrahimi tep_free(tep);
1510*287e80b3SSadaf Ebrahimi }
1511*287e80b3SSadaf Ebrahimi
test_uprobes(void)1512*287e80b3SSadaf Ebrahimi static void test_uprobes(void)
1513*287e80b3SSadaf Ebrahimi {
1514*287e80b3SSadaf Ebrahimi test_uprobes_instance(test_instance);
1515*287e80b3SSadaf Ebrahimi }
1516*287e80b3SSadaf Ebrahimi
test_instance_file(void)1517*287e80b3SSadaf Ebrahimi static void test_instance_file(void)
1518*287e80b3SSadaf Ebrahimi {
1519*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance = NULL;
1520*287e80b3SSadaf Ebrahimi struct tracefs_instance *second = NULL;
1521*287e80b3SSadaf Ebrahimi const char *name = get_rand_str();
1522*287e80b3SSadaf Ebrahimi const char *inst_name = NULL;
1523*287e80b3SSadaf Ebrahimi const char *tdir;
1524*287e80b3SSadaf Ebrahimi char *inst_file;
1525*287e80b3SSadaf Ebrahimi char *inst_dir;
1526*287e80b3SSadaf Ebrahimi struct stat st;
1527*287e80b3SSadaf Ebrahimi char *file1;
1528*287e80b3SSadaf Ebrahimi char *file2;
1529*287e80b3SSadaf Ebrahimi char *tracer;
1530*287e80b3SSadaf Ebrahimi char *fname;
1531*287e80b3SSadaf Ebrahimi int size;
1532*287e80b3SSadaf Ebrahimi int ret;
1533*287e80b3SSadaf Ebrahimi
1534*287e80b3SSadaf Ebrahimi tdir = tracefs_tracing_dir();
1535*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1536*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&inst_dir, "%s/instances/%s", tdir, name) > 0);
1537*287e80b3SSadaf Ebrahimi CU_TEST(stat(inst_dir, &st) != 0);
1538*287e80b3SSadaf Ebrahimi
1539*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_exists(name) == false);
1540*287e80b3SSadaf Ebrahimi instance = tracefs_instance_create(name);
1541*287e80b3SSadaf Ebrahimi CU_TEST(instance != NULL);
1542*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_is_new(instance));
1543*287e80b3SSadaf Ebrahimi second = tracefs_instance_create(name);
1544*287e80b3SSadaf Ebrahimi CU_TEST(second != NULL);
1545*287e80b3SSadaf Ebrahimi CU_TEST(!tracefs_instance_is_new(second));
1546*287e80b3SSadaf Ebrahimi tracefs_instance_free(second);
1547*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_exists(name) == true);
1548*287e80b3SSadaf Ebrahimi CU_TEST(stat(inst_dir, &st) == 0);
1549*287e80b3SSadaf Ebrahimi CU_TEST(S_ISDIR(st.st_mode));
1550*287e80b3SSadaf Ebrahimi inst_name = tracefs_instance_get_name(instance);
1551*287e80b3SSadaf Ebrahimi CU_TEST(inst_name != NULL);
1552*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(inst_name, name) == 0);
1553*287e80b3SSadaf Ebrahimi
1554*287e80b3SSadaf Ebrahimi fname = tracefs_instance_get_dir(NULL);
1555*287e80b3SSadaf Ebrahimi CU_TEST(fname != NULL);
1556*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(fname, tdir) == 0);
1557*287e80b3SSadaf Ebrahimi free(fname);
1558*287e80b3SSadaf Ebrahimi
1559*287e80b3SSadaf Ebrahimi fname = tracefs_instance_get_dir(instance);
1560*287e80b3SSadaf Ebrahimi CU_TEST(fname != NULL);
1561*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(fname, inst_dir) == 0);
1562*287e80b3SSadaf Ebrahimi free(fname);
1563*287e80b3SSadaf Ebrahimi
1564*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&fname, "%s/"ALL_TRACERS, tdir) > 0);
1565*287e80b3SSadaf Ebrahimi CU_TEST(fname != NULL);
1566*287e80b3SSadaf Ebrahimi inst_file = tracefs_instance_get_file(NULL, ALL_TRACERS);
1567*287e80b3SSadaf Ebrahimi CU_TEST(inst_file != NULL);
1568*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(fname, inst_file) == 0);
1569*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(inst_file);
1570*287e80b3SSadaf Ebrahimi free(fname);
1571*287e80b3SSadaf Ebrahimi
1572*287e80b3SSadaf Ebrahimi CU_TEST(asprintf(&fname, "%s/instances/%s/"ALL_TRACERS, tdir, name) > 0);
1573*287e80b3SSadaf Ebrahimi CU_TEST(fname != NULL);
1574*287e80b3SSadaf Ebrahimi CU_TEST(stat(fname, &st) == 0);
1575*287e80b3SSadaf Ebrahimi inst_file = tracefs_instance_get_file(instance, ALL_TRACERS);
1576*287e80b3SSadaf Ebrahimi CU_TEST(inst_file != NULL);
1577*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(fname, inst_file) == 0);
1578*287e80b3SSadaf Ebrahimi
1579*287e80b3SSadaf Ebrahimi test_instance_file_read(NULL, ALL_TRACERS);
1580*287e80b3SSadaf Ebrahimi test_instance_file_read(instance, ALL_TRACERS);
1581*287e80b3SSadaf Ebrahimi
1582*287e80b3SSadaf Ebrahimi file1 = tracefs_instance_file_read(instance, ALL_TRACERS, NULL);
1583*287e80b3SSadaf Ebrahimi CU_TEST(file1 != NULL);
1584*287e80b3SSadaf Ebrahimi tracer = strtok(file1, " ");
1585*287e80b3SSadaf Ebrahimi CU_TEST(tracer != NULL);
1586*287e80b3SSadaf Ebrahimi ret = tracefs_instance_file_write(instance, CUR_TRACER, tracer);
1587*287e80b3SSadaf Ebrahimi CU_TEST(ret == strlen(tracer));
1588*287e80b3SSadaf Ebrahimi file2 = tracefs_instance_file_read(instance, CUR_TRACER, &size);
1589*287e80b3SSadaf Ebrahimi CU_TEST(file2 != NULL);
1590*287e80b3SSadaf Ebrahimi CU_TEST(size >= strlen(tracer));
1591*287e80b3SSadaf Ebrahimi CU_TEST(strncmp(file2, tracer, strlen(tracer)) == 0);
1592*287e80b3SSadaf Ebrahimi free(file1);
1593*287e80b3SSadaf Ebrahimi free(file2);
1594*287e80b3SSadaf Ebrahimi
1595*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(inst_file);
1596*287e80b3SSadaf Ebrahimi free(fname);
1597*287e80b3SSadaf Ebrahimi
1598*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(NULL, (char *)name) == false);
1599*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(NULL, (char *)name) == false);
1600*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(instance, (char *)name) == false);
1601*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(instance, (char *)name) == false);
1602*287e80b3SSadaf Ebrahimi
1603*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(NULL, CUR_TRACER) == true);
1604*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(NULL, CUR_TRACER) == false);
1605*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(instance, CUR_TRACER) == true);
1606*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(instance, CUR_TRACER) == false);
1607*287e80b3SSadaf Ebrahimi
1608*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(NULL, PER_CPU) == false);
1609*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(NULL, PER_CPU) == true);
1610*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_file_exists(instance, PER_CPU) == false);
1611*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_dir_exists(instance, PER_CPU) == true);
1612*287e80b3SSadaf Ebrahimi
1613*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_destroy(NULL) != 0);
1614*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_destroy(instance) == 0);
1615*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_destroy(instance) != 0);
1616*287e80b3SSadaf Ebrahimi tracefs_instance_free(instance);
1617*287e80b3SSadaf Ebrahimi CU_TEST(stat(inst_dir, &st) != 0);
1618*287e80b3SSadaf Ebrahimi free(inst_dir);
1619*287e80b3SSadaf Ebrahimi }
1620*287e80b3SSadaf Ebrahimi
check_fd_name(int fd,const char * dir,const char * name)1621*287e80b3SSadaf Ebrahimi static bool check_fd_name(int fd, const char *dir, const char *name)
1622*287e80b3SSadaf Ebrahimi {
1623*287e80b3SSadaf Ebrahimi char link[PATH_MAX + 1];
1624*287e80b3SSadaf Ebrahimi char path[PATH_MAX + 1];
1625*287e80b3SSadaf Ebrahimi struct stat st;
1626*287e80b3SSadaf Ebrahimi char *file;
1627*287e80b3SSadaf Ebrahimi int ret;
1628*287e80b3SSadaf Ebrahimi
1629*287e80b3SSadaf Ebrahimi snprintf(link, PATH_MAX, "/proc/self/fd/%d", fd);
1630*287e80b3SSadaf Ebrahimi ret = lstat(link, &st);
1631*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1632*287e80b3SSadaf Ebrahimi if (ret < 0)
1633*287e80b3SSadaf Ebrahimi return false;
1634*287e80b3SSadaf Ebrahimi CU_TEST(S_ISLNK(st.st_mode));
1635*287e80b3SSadaf Ebrahimi if (!S_ISLNK(st.st_mode))
1636*287e80b3SSadaf Ebrahimi return false;
1637*287e80b3SSadaf Ebrahimi ret = readlink(link, path, PATH_MAX);
1638*287e80b3SSadaf Ebrahimi CU_TEST(ret > 0);
1639*287e80b3SSadaf Ebrahimi if (ret > PATH_MAX || ret < 0)
1640*287e80b3SSadaf Ebrahimi return false;
1641*287e80b3SSadaf Ebrahimi path[ret] = 0;
1642*287e80b3SSadaf Ebrahimi ret = strncmp(dir, path, strlen(dir));
1643*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1644*287e80b3SSadaf Ebrahimi if (ret)
1645*287e80b3SSadaf Ebrahimi return false;
1646*287e80b3SSadaf Ebrahimi file = basename(path);
1647*287e80b3SSadaf Ebrahimi CU_TEST(file != NULL);
1648*287e80b3SSadaf Ebrahimi if (!file)
1649*287e80b3SSadaf Ebrahimi return false;
1650*287e80b3SSadaf Ebrahimi ret = strcmp(file, name);
1651*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1652*287e80b3SSadaf Ebrahimi if (ret)
1653*287e80b3SSadaf Ebrahimi return false;
1654*287e80b3SSadaf Ebrahimi return true;
1655*287e80b3SSadaf Ebrahimi }
1656*287e80b3SSadaf Ebrahimi
1657*287e80b3SSadaf Ebrahimi #define FLAGS_STR "flags:"
check_fd_mode(int fd,int mode)1658*287e80b3SSadaf Ebrahimi static bool check_fd_mode(int fd, int mode)
1659*287e80b3SSadaf Ebrahimi {
1660*287e80b3SSadaf Ebrahimi char path[PATH_MAX + 1];
1661*287e80b3SSadaf Ebrahimi long fmode = -1;
1662*287e80b3SSadaf Ebrahimi char *line = NULL;
1663*287e80b3SSadaf Ebrahimi struct stat st;
1664*287e80b3SSadaf Ebrahimi size_t len = 0;
1665*287e80b3SSadaf Ebrahimi ssize_t size;
1666*287e80b3SSadaf Ebrahimi FILE *file;
1667*287e80b3SSadaf Ebrahimi int ret;
1668*287e80b3SSadaf Ebrahimi
1669*287e80b3SSadaf Ebrahimi snprintf(path, PATH_MAX, "/proc/self/fdinfo/%d", fd);
1670*287e80b3SSadaf Ebrahimi ret = stat(path, &st);
1671*287e80b3SSadaf Ebrahimi CU_TEST(ret == 0);
1672*287e80b3SSadaf Ebrahimi if (ret < 0)
1673*287e80b3SSadaf Ebrahimi return false;
1674*287e80b3SSadaf Ebrahimi file = fopen(path, "r");
1675*287e80b3SSadaf Ebrahimi if (!file)
1676*287e80b3SSadaf Ebrahimi return false;
1677*287e80b3SSadaf Ebrahimi while ((size = getline(&line, &len, file)) > 0) {
1678*287e80b3SSadaf Ebrahimi if (strncmp(line, FLAGS_STR, strlen(FLAGS_STR)))
1679*287e80b3SSadaf Ebrahimi continue;
1680*287e80b3SSadaf Ebrahimi fmode = strtol(line + strlen(FLAGS_STR), NULL, 8);
1681*287e80b3SSadaf Ebrahimi break;
1682*287e80b3SSadaf Ebrahimi }
1683*287e80b3SSadaf Ebrahimi free(line);
1684*287e80b3SSadaf Ebrahimi fclose(file);
1685*287e80b3SSadaf Ebrahimi if (fmode < 0 ||
1686*287e80b3SSadaf Ebrahimi (O_ACCMODE & fmode) != (O_ACCMODE & mode))
1687*287e80b3SSadaf Ebrahimi return false;
1688*287e80b3SSadaf Ebrahimi return true;
1689*287e80b3SSadaf Ebrahimi }
1690*287e80b3SSadaf Ebrahimi
test_instance_file_fd(struct tracefs_instance * instance)1691*287e80b3SSadaf Ebrahimi static void test_instance_file_fd(struct tracefs_instance *instance)
1692*287e80b3SSadaf Ebrahimi {
1693*287e80b3SSadaf Ebrahimi const char *name = get_rand_str();
1694*287e80b3SSadaf Ebrahimi const char *tdir = tracefs_instance_get_trace_dir(instance);
1695*287e80b3SSadaf Ebrahimi long long res = -1;
1696*287e80b3SSadaf Ebrahimi char rd[2];
1697*287e80b3SSadaf Ebrahimi int fd;
1698*287e80b3SSadaf Ebrahimi
1699*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1700*287e80b3SSadaf Ebrahimi fd = tracefs_instance_file_open(instance, name, -1);
1701*287e80b3SSadaf Ebrahimi CU_TEST(fd == -1);
1702*287e80b3SSadaf Ebrahimi fd = tracefs_instance_file_open(instance, TRACE_ON, O_RDONLY);
1703*287e80b3SSadaf Ebrahimi CU_TEST(fd >= 0);
1704*287e80b3SSadaf Ebrahimi
1705*287e80b3SSadaf Ebrahimi CU_TEST(check_fd_name(fd, tdir, TRACE_ON));
1706*287e80b3SSadaf Ebrahimi CU_TEST(check_fd_mode(fd, O_RDONLY));
1707*287e80b3SSadaf Ebrahimi
1708*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_file_read_number(instance, ALL_TRACERS, &res) != 0);
1709*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_file_read_number(instance, name, &res) != 0);
1710*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_file_read_number(instance, TRACE_ON, &res) == 0);
1711*287e80b3SSadaf Ebrahimi CU_TEST((res == 0 || res == 1));
1712*287e80b3SSadaf Ebrahimi CU_TEST(read(fd, &rd, 1) == 1);
1713*287e80b3SSadaf Ebrahimi rd[1] = 0;
1714*287e80b3SSadaf Ebrahimi CU_TEST(res == atoi(rd));
1715*287e80b3SSadaf Ebrahimi
1716*287e80b3SSadaf Ebrahimi close(fd);
1717*287e80b3SSadaf Ebrahimi }
1718*287e80b3SSadaf Ebrahimi
test_file_fd(void)1719*287e80b3SSadaf Ebrahimi static void test_file_fd(void)
1720*287e80b3SSadaf Ebrahimi {
1721*287e80b3SSadaf Ebrahimi test_instance_file_fd(test_instance);
1722*287e80b3SSadaf Ebrahimi }
1723*287e80b3SSadaf Ebrahimi
test_instance_tracing_onoff(struct tracefs_instance * instance)1724*287e80b3SSadaf Ebrahimi static void test_instance_tracing_onoff(struct tracefs_instance *instance)
1725*287e80b3SSadaf Ebrahimi {
1726*287e80b3SSadaf Ebrahimi const char *tdir = tracefs_instance_get_trace_dir(instance);
1727*287e80b3SSadaf Ebrahimi long long res = -1;
1728*287e80b3SSadaf Ebrahimi int fd;
1729*287e80b3SSadaf Ebrahimi
1730*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1731*287e80b3SSadaf Ebrahimi fd = tracefs_trace_on_get_fd(instance);
1732*287e80b3SSadaf Ebrahimi CU_TEST(fd >= 0);
1733*287e80b3SSadaf Ebrahimi CU_TEST(check_fd_name(fd, tdir, TRACE_ON));
1734*287e80b3SSadaf Ebrahimi CU_TEST(check_fd_mode(fd, O_RDWR));
1735*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instance_file_read_number(instance, TRACE_ON, &res) == 0);
1736*287e80b3SSadaf Ebrahimi if (res == 1) {
1737*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 1);
1738*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_off(instance) == 0);
1739*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 0);
1740*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_on(instance) == 0);
1741*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 1);
1742*287e80b3SSadaf Ebrahimi
1743*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_off_fd(fd) == 0);
1744*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 0);
1745*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_on_fd(fd) == 0);
1746*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 1);
1747*287e80b3SSadaf Ebrahimi } else {
1748*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 0);
1749*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_on(instance) == 0);
1750*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 1);
1751*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_off(instance) == 0);
1752*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 0);
1753*287e80b3SSadaf Ebrahimi
1754*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_on_fd(fd) == 0);
1755*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 1);
1756*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_off_fd(fd) == 0);
1757*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_trace_is_on(instance) == 0);
1758*287e80b3SSadaf Ebrahimi }
1759*287e80b3SSadaf Ebrahimi
1760*287e80b3SSadaf Ebrahimi if (fd >= 0)
1761*287e80b3SSadaf Ebrahimi close(fd);
1762*287e80b3SSadaf Ebrahimi }
1763*287e80b3SSadaf Ebrahimi
test_tracing_onoff(void)1764*287e80b3SSadaf Ebrahimi static void test_tracing_onoff(void)
1765*287e80b3SSadaf Ebrahimi {
1766*287e80b3SSadaf Ebrahimi test_instance_tracing_onoff(test_instance);
1767*287e80b3SSadaf Ebrahimi }
1768*287e80b3SSadaf Ebrahimi
check_option(struct tracefs_instance * instance,enum tracefs_option_id id,bool exist,int enabled)1769*287e80b3SSadaf Ebrahimi static bool check_option(struct tracefs_instance *instance,
1770*287e80b3SSadaf Ebrahimi enum tracefs_option_id id, bool exist, int enabled)
1771*287e80b3SSadaf Ebrahimi {
1772*287e80b3SSadaf Ebrahimi const char *name = tracefs_option_name(id);
1773*287e80b3SSadaf Ebrahimi char file[PATH_MAX];
1774*287e80b3SSadaf Ebrahimi char *path = NULL;
1775*287e80b3SSadaf Ebrahimi bool ret = false;
1776*287e80b3SSadaf Ebrahimi bool supported;
1777*287e80b3SSadaf Ebrahimi struct stat st;
1778*287e80b3SSadaf Ebrahimi char buf[10];
1779*287e80b3SSadaf Ebrahimi int fd = 0;
1780*287e80b3SSadaf Ebrahimi int r;
1781*287e80b3SSadaf Ebrahimi int rstat;
1782*287e80b3SSadaf Ebrahimi
1783*287e80b3SSadaf Ebrahimi CU_TEST(name != NULL);
1784*287e80b3SSadaf Ebrahimi supported = tracefs_option_is_supported(instance, id);
1785*287e80b3SSadaf Ebrahimi CU_TEST(supported == exist);
1786*287e80b3SSadaf Ebrahimi if (supported != exist)
1787*287e80b3SSadaf Ebrahimi goto out;
1788*287e80b3SSadaf Ebrahimi snprintf(file, PATH_MAX, "options/%s", name);
1789*287e80b3SSadaf Ebrahimi path = tracefs_instance_get_file(instance, file);
1790*287e80b3SSadaf Ebrahimi CU_TEST(path != NULL);
1791*287e80b3SSadaf Ebrahimi rstat = stat(path, &st);
1792*287e80b3SSadaf Ebrahimi if (exist) {
1793*287e80b3SSadaf Ebrahimi CU_TEST(rstat == 0);
1794*287e80b3SSadaf Ebrahimi if (rstat != 0)
1795*287e80b3SSadaf Ebrahimi goto out;
1796*287e80b3SSadaf Ebrahimi } else {
1797*287e80b3SSadaf Ebrahimi CU_TEST(stat(path, &st) == -1);
1798*287e80b3SSadaf Ebrahimi if (rstat != -1)
1799*287e80b3SSadaf Ebrahimi goto out;
1800*287e80b3SSadaf Ebrahimi }
1801*287e80b3SSadaf Ebrahimi
1802*287e80b3SSadaf Ebrahimi fd = open(path, O_RDONLY);
1803*287e80b3SSadaf Ebrahimi if (exist) {
1804*287e80b3SSadaf Ebrahimi CU_TEST(fd >= 0);
1805*287e80b3SSadaf Ebrahimi if (fd < 0)
1806*287e80b3SSadaf Ebrahimi goto out;
1807*287e80b3SSadaf Ebrahimi } else {
1808*287e80b3SSadaf Ebrahimi CU_TEST(fd < 0);
1809*287e80b3SSadaf Ebrahimi if (fd >= 0)
1810*287e80b3SSadaf Ebrahimi goto out;
1811*287e80b3SSadaf Ebrahimi }
1812*287e80b3SSadaf Ebrahimi
1813*287e80b3SSadaf Ebrahimi if (exist && enabled >= 0) {
1814*287e80b3SSadaf Ebrahimi int val = enabled ? '1' : '0';
1815*287e80b3SSadaf Ebrahimi
1816*287e80b3SSadaf Ebrahimi r = read(fd, buf, 10);
1817*287e80b3SSadaf Ebrahimi CU_TEST(r >= 1);
1818*287e80b3SSadaf Ebrahimi CU_TEST(buf[0] == val);
1819*287e80b3SSadaf Ebrahimi if (buf[0] != val)
1820*287e80b3SSadaf Ebrahimi goto out;
1821*287e80b3SSadaf Ebrahimi }
1822*287e80b3SSadaf Ebrahimi
1823*287e80b3SSadaf Ebrahimi ret = true;
1824*287e80b3SSadaf Ebrahimi out:
1825*287e80b3SSadaf Ebrahimi tracefs_put_tracing_file(path);
1826*287e80b3SSadaf Ebrahimi if (fd >= 0)
1827*287e80b3SSadaf Ebrahimi close(fd);
1828*287e80b3SSadaf Ebrahimi return ret;
1829*287e80b3SSadaf Ebrahimi }
1830*287e80b3SSadaf Ebrahimi
test_instance_tracing_options(struct tracefs_instance * instance)1831*287e80b3SSadaf Ebrahimi static void test_instance_tracing_options(struct tracefs_instance *instance)
1832*287e80b3SSadaf Ebrahimi {
1833*287e80b3SSadaf Ebrahimi const struct tracefs_options_mask *enabled;
1834*287e80b3SSadaf Ebrahimi const struct tracefs_options_mask *all_copy;
1835*287e80b3SSadaf Ebrahimi const struct tracefs_options_mask *all;
1836*287e80b3SSadaf Ebrahimi enum tracefs_option_id i = 1;
1837*287e80b3SSadaf Ebrahimi char file[PATH_MAX];
1838*287e80b3SSadaf Ebrahimi const char *name;
1839*287e80b3SSadaf Ebrahimi
1840*287e80b3SSadaf Ebrahimi all = tracefs_options_get_supported(instance);
1841*287e80b3SSadaf Ebrahimi all_copy = tracefs_options_get_supported(instance);
1842*287e80b3SSadaf Ebrahimi enabled = tracefs_options_get_enabled(instance);
1843*287e80b3SSadaf Ebrahimi CU_TEST(all != NULL);
1844*287e80b3SSadaf Ebrahimi
1845*287e80b3SSadaf Ebrahimi /* Invalid parameters test */
1846*287e80b3SSadaf Ebrahimi CU_TEST(!tracefs_option_is_supported(instance, TRACEFS_OPTION_INVALID));
1847*287e80b3SSadaf Ebrahimi CU_TEST(!tracefs_option_is_enabled(instance, TRACEFS_OPTION_INVALID));
1848*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_enable(instance, TRACEFS_OPTION_INVALID) == -1);
1849*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_disable(instance, TRACEFS_OPTION_INVALID) == -1);
1850*287e80b3SSadaf Ebrahimi name = tracefs_option_name(TRACEFS_OPTION_INVALID);
1851*287e80b3SSadaf Ebrahimi CU_TEST(!strcmp(name, "unknown"));
1852*287e80b3SSadaf Ebrahimi /* Test all valid options */
1853*287e80b3SSadaf Ebrahimi for (i = 1; i < TRACEFS_OPTION_MAX; i++) {
1854*287e80b3SSadaf Ebrahimi name = tracefs_option_name(i);
1855*287e80b3SSadaf Ebrahimi CU_TEST(name != NULL);
1856*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(name, "unknown"));
1857*287e80b3SSadaf Ebrahimi snprintf(file, PATH_MAX, "options/%s", name);
1858*287e80b3SSadaf Ebrahimi
1859*287e80b3SSadaf Ebrahimi if (tracefs_option_mask_is_set(all, i)) {
1860*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, -1));
1861*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_is_supported(instance, i));
1862*287e80b3SSadaf Ebrahimi } else {
1863*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, false, -1));
1864*287e80b3SSadaf Ebrahimi CU_TEST(!tracefs_option_is_supported(instance, i));
1865*287e80b3SSadaf Ebrahimi }
1866*287e80b3SSadaf Ebrahimi
1867*287e80b3SSadaf Ebrahimi if (tracefs_option_mask_is_set(enabled, i)) {
1868*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 1));
1869*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_is_supported(instance, i));
1870*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_is_enabled(instance, i));
1871*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_disable(instance, i) == 0);
1872*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 0));
1873*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_enable(instance, i) == 0);
1874*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 1));
1875*287e80b3SSadaf Ebrahimi } else if (tracefs_option_mask_is_set(all_copy, i)) {
1876*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 0));
1877*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_is_supported(instance, i));
1878*287e80b3SSadaf Ebrahimi CU_TEST(!tracefs_option_is_enabled(instance, i));
1879*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_enable(instance, i) == 0);
1880*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 1));
1881*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_option_disable(instance, i) == 0);
1882*287e80b3SSadaf Ebrahimi CU_TEST(check_option(instance, i, true, 0));
1883*287e80b3SSadaf Ebrahimi }
1884*287e80b3SSadaf Ebrahimi }
1885*287e80b3SSadaf Ebrahimi }
1886*287e80b3SSadaf Ebrahimi
test_tracing_options(void)1887*287e80b3SSadaf Ebrahimi static void test_tracing_options(void)
1888*287e80b3SSadaf Ebrahimi {
1889*287e80b3SSadaf Ebrahimi test_instance_tracing_options(test_instance);
1890*287e80b3SSadaf Ebrahimi }
1891*287e80b3SSadaf Ebrahimi
exclude_string(char ** strings,char * name)1892*287e80b3SSadaf Ebrahimi static void exclude_string(char **strings, char *name)
1893*287e80b3SSadaf Ebrahimi {
1894*287e80b3SSadaf Ebrahimi int i;
1895*287e80b3SSadaf Ebrahimi
1896*287e80b3SSadaf Ebrahimi for (i = 0; strings[i]; i++) {
1897*287e80b3SSadaf Ebrahimi if (strcmp(strings[i], name) == 0) {
1898*287e80b3SSadaf Ebrahimi free(strings[i]);
1899*287e80b3SSadaf Ebrahimi strings[i] = strdup("/");
1900*287e80b3SSadaf Ebrahimi return;
1901*287e80b3SSadaf Ebrahimi }
1902*287e80b3SSadaf Ebrahimi }
1903*287e80b3SSadaf Ebrahimi }
1904*287e80b3SSadaf Ebrahimi
test_check_files(const char * fdir,char ** files)1905*287e80b3SSadaf Ebrahimi static void test_check_files(const char *fdir, char **files)
1906*287e80b3SSadaf Ebrahimi {
1907*287e80b3SSadaf Ebrahimi struct dirent *dent;
1908*287e80b3SSadaf Ebrahimi DIR *dir;
1909*287e80b3SSadaf Ebrahimi int i;
1910*287e80b3SSadaf Ebrahimi
1911*287e80b3SSadaf Ebrahimi dir = opendir(fdir);
1912*287e80b3SSadaf Ebrahimi CU_TEST(dir != NULL);
1913*287e80b3SSadaf Ebrahimi
1914*287e80b3SSadaf Ebrahimi while ((dent = readdir(dir)))
1915*287e80b3SSadaf Ebrahimi exclude_string(files, dent->d_name);
1916*287e80b3SSadaf Ebrahimi
1917*287e80b3SSadaf Ebrahimi closedir(dir);
1918*287e80b3SSadaf Ebrahimi
1919*287e80b3SSadaf Ebrahimi for (i = 0; files[i]; i++)
1920*287e80b3SSadaf Ebrahimi CU_TEST(files[i][0] == '/');
1921*287e80b3SSadaf Ebrahimi }
1922*287e80b3SSadaf Ebrahimi
system_event(const char * tdir)1923*287e80b3SSadaf Ebrahimi static void system_event(const char *tdir)
1924*287e80b3SSadaf Ebrahimi {
1925*287e80b3SSadaf Ebrahimi
1926*287e80b3SSadaf Ebrahimi char **systems;
1927*287e80b3SSadaf Ebrahimi char **events;
1928*287e80b3SSadaf Ebrahimi char *sdir = NULL;
1929*287e80b3SSadaf Ebrahimi
1930*287e80b3SSadaf Ebrahimi systems = tracefs_event_systems(tdir);
1931*287e80b3SSadaf Ebrahimi CU_TEST(systems != NULL);
1932*287e80b3SSadaf Ebrahimi
1933*287e80b3SSadaf Ebrahimi events = tracefs_system_events(tdir, systems[0]);
1934*287e80b3SSadaf Ebrahimi CU_TEST(events != NULL);
1935*287e80b3SSadaf Ebrahimi
1936*287e80b3SSadaf Ebrahimi asprintf(&sdir, "%s/events/%s", tdir, systems[0]);
1937*287e80b3SSadaf Ebrahimi CU_TEST(sdir != NULL);
1938*287e80b3SSadaf Ebrahimi test_check_files(sdir, events);
1939*287e80b3SSadaf Ebrahimi free(sdir);
1940*287e80b3SSadaf Ebrahimi sdir = NULL;
1941*287e80b3SSadaf Ebrahimi
1942*287e80b3SSadaf Ebrahimi asprintf(&sdir, "%s/events", tdir);
1943*287e80b3SSadaf Ebrahimi CU_TEST(sdir != NULL);
1944*287e80b3SSadaf Ebrahimi test_check_files(sdir, systems);
1945*287e80b3SSadaf Ebrahimi
1946*287e80b3SSadaf Ebrahimi tracefs_list_free(systems);
1947*287e80b3SSadaf Ebrahimi tracefs_list_free(events);
1948*287e80b3SSadaf Ebrahimi
1949*287e80b3SSadaf Ebrahimi free(sdir);
1950*287e80b3SSadaf Ebrahimi }
1951*287e80b3SSadaf Ebrahimi
test_system_event(void)1952*287e80b3SSadaf Ebrahimi static void test_system_event(void)
1953*287e80b3SSadaf Ebrahimi {
1954*287e80b3SSadaf Ebrahimi const char *tdir;
1955*287e80b3SSadaf Ebrahimi
1956*287e80b3SSadaf Ebrahimi tdir = tracefs_tracing_dir();
1957*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1958*287e80b3SSadaf Ebrahimi system_event(tdir);
1959*287e80b3SSadaf Ebrahimi }
1960*287e80b3SSadaf Ebrahimi
test_instance_tracers(struct tracefs_instance * instance)1961*287e80b3SSadaf Ebrahimi static void test_instance_tracers(struct tracefs_instance *instance)
1962*287e80b3SSadaf Ebrahimi {
1963*287e80b3SSadaf Ebrahimi const char *tdir;
1964*287e80b3SSadaf Ebrahimi char **tracers;
1965*287e80b3SSadaf Ebrahimi char *tfile;
1966*287e80b3SSadaf Ebrahimi char *tracer;
1967*287e80b3SSadaf Ebrahimi int i;
1968*287e80b3SSadaf Ebrahimi
1969*287e80b3SSadaf Ebrahimi tdir = tracefs_instance_get_trace_dir(instance);
1970*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
1971*287e80b3SSadaf Ebrahimi
1972*287e80b3SSadaf Ebrahimi tracers = tracefs_tracers(tdir);
1973*287e80b3SSadaf Ebrahimi CU_TEST(tracers != NULL);
1974*287e80b3SSadaf Ebrahimi
1975*287e80b3SSadaf Ebrahimi for (i = 0; tracers[i]; i++)
1976*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_tracer_available(tdir, tracers[i]));
1977*287e80b3SSadaf Ebrahimi
1978*287e80b3SSadaf Ebrahimi tfile = tracefs_instance_file_read(NULL, ALL_TRACERS, NULL);
1979*287e80b3SSadaf Ebrahimi
1980*287e80b3SSadaf Ebrahimi tracer = strtok(tfile, " ");
1981*287e80b3SSadaf Ebrahimi while (tracer) {
1982*287e80b3SSadaf Ebrahimi exclude_string(tracers, tracer);
1983*287e80b3SSadaf Ebrahimi tracer = strtok(NULL, " ");
1984*287e80b3SSadaf Ebrahimi }
1985*287e80b3SSadaf Ebrahimi
1986*287e80b3SSadaf Ebrahimi for (i = 0; tracers[i]; i++)
1987*287e80b3SSadaf Ebrahimi CU_TEST(tracers[i][0] == '/');
1988*287e80b3SSadaf Ebrahimi
1989*287e80b3SSadaf Ebrahimi tracefs_list_free(tracers);
1990*287e80b3SSadaf Ebrahimi free(tfile);
1991*287e80b3SSadaf Ebrahimi }
1992*287e80b3SSadaf Ebrahimi
test_tracers(void)1993*287e80b3SSadaf Ebrahimi static void test_tracers(void)
1994*287e80b3SSadaf Ebrahimi {
1995*287e80b3SSadaf Ebrahimi test_instance_tracers(test_instance);
1996*287e80b3SSadaf Ebrahimi }
1997*287e80b3SSadaf Ebrahimi
test_check_events(struct tep_handle * tep,char * system,bool exist)1998*287e80b3SSadaf Ebrahimi static void test_check_events(struct tep_handle *tep, char *system, bool exist)
1999*287e80b3SSadaf Ebrahimi {
2000*287e80b3SSadaf Ebrahimi struct dirent *dent;
2001*287e80b3SSadaf Ebrahimi char file[PATH_MAX];
2002*287e80b3SSadaf Ebrahimi char buf[1024];
2003*287e80b3SSadaf Ebrahimi char *edir = NULL;
2004*287e80b3SSadaf Ebrahimi const char *tdir;
2005*287e80b3SSadaf Ebrahimi DIR *dir;
2006*287e80b3SSadaf Ebrahimi int fd;
2007*287e80b3SSadaf Ebrahimi
2008*287e80b3SSadaf Ebrahimi tdir = tracefs_tracing_dir();
2009*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
2010*287e80b3SSadaf Ebrahimi
2011*287e80b3SSadaf Ebrahimi asprintf(&edir, "%s/events/%s", tdir, system);
2012*287e80b3SSadaf Ebrahimi dir = opendir(edir);
2013*287e80b3SSadaf Ebrahimi CU_TEST(dir != NULL);
2014*287e80b3SSadaf Ebrahimi
2015*287e80b3SSadaf Ebrahimi while ((dent = readdir(dir))) {
2016*287e80b3SSadaf Ebrahimi if (dent->d_name[0] == '.')
2017*287e80b3SSadaf Ebrahimi continue;
2018*287e80b3SSadaf Ebrahimi sprintf(file, "%s/%s/id", edir, dent->d_name);
2019*287e80b3SSadaf Ebrahimi fd = open(file, O_RDONLY);
2020*287e80b3SSadaf Ebrahimi if (fd < 0)
2021*287e80b3SSadaf Ebrahimi continue;
2022*287e80b3SSadaf Ebrahimi CU_TEST(read(fd, buf, 1024) > 0);
2023*287e80b3SSadaf Ebrahimi if (exist) {
2024*287e80b3SSadaf Ebrahimi CU_TEST(tep_find_event(tep, atoi(buf)) != NULL);
2025*287e80b3SSadaf Ebrahimi } else {
2026*287e80b3SSadaf Ebrahimi CU_TEST(tep_find_event(tep, atoi(buf)) == NULL);
2027*287e80b3SSadaf Ebrahimi }
2028*287e80b3SSadaf Ebrahimi
2029*287e80b3SSadaf Ebrahimi close(fd);
2030*287e80b3SSadaf Ebrahimi }
2031*287e80b3SSadaf Ebrahimi
2032*287e80b3SSadaf Ebrahimi closedir(dir);
2033*287e80b3SSadaf Ebrahimi free(edir);
2034*287e80b3SSadaf Ebrahimi
2035*287e80b3SSadaf Ebrahimi }
2036*287e80b3SSadaf Ebrahimi
local_events(const char * tdir)2037*287e80b3SSadaf Ebrahimi static void local_events(const char *tdir)
2038*287e80b3SSadaf Ebrahimi {
2039*287e80b3SSadaf Ebrahimi struct tep_handle *tep;
2040*287e80b3SSadaf Ebrahimi char **systems;
2041*287e80b3SSadaf Ebrahimi char *lsystems[3];
2042*287e80b3SSadaf Ebrahimi int i;
2043*287e80b3SSadaf Ebrahimi
2044*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(tdir);
2045*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
2046*287e80b3SSadaf Ebrahimi
2047*287e80b3SSadaf Ebrahimi systems = tracefs_event_systems(tdir);
2048*287e80b3SSadaf Ebrahimi CU_TEST(systems != NULL);
2049*287e80b3SSadaf Ebrahimi
2050*287e80b3SSadaf Ebrahimi for (i = 0; systems[i]; i++)
2051*287e80b3SSadaf Ebrahimi test_check_events(tep, systems[i], true);
2052*287e80b3SSadaf Ebrahimi tep_free(tep);
2053*287e80b3SSadaf Ebrahimi
2054*287e80b3SSadaf Ebrahimi memset(lsystems, 0, sizeof(lsystems));
2055*287e80b3SSadaf Ebrahimi for (i = 0; systems[i]; i++) {
2056*287e80b3SSadaf Ebrahimi if (!lsystems[0])
2057*287e80b3SSadaf Ebrahimi lsystems[0] = systems[i];
2058*287e80b3SSadaf Ebrahimi else if (!lsystems[2])
2059*287e80b3SSadaf Ebrahimi lsystems[2] = systems[i];
2060*287e80b3SSadaf Ebrahimi else
2061*287e80b3SSadaf Ebrahimi break;
2062*287e80b3SSadaf Ebrahimi }
2063*287e80b3SSadaf Ebrahimi
2064*287e80b3SSadaf Ebrahimi if (lsystems[0] && lsystems[2]) {
2065*287e80b3SSadaf Ebrahimi tep = tracefs_local_events_system(tdir,
2066*287e80b3SSadaf Ebrahimi (const char * const *)lsystems);
2067*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
2068*287e80b3SSadaf Ebrahimi test_check_events(tep, lsystems[0], true);
2069*287e80b3SSadaf Ebrahimi test_check_events(tep, lsystems[2], false);
2070*287e80b3SSadaf Ebrahimi }
2071*287e80b3SSadaf Ebrahimi tep_free(tep);
2072*287e80b3SSadaf Ebrahimi
2073*287e80b3SSadaf Ebrahimi tep = tep_alloc();
2074*287e80b3SSadaf Ebrahimi CU_TEST(tep != NULL);
2075*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_fill_local_events(tdir, tep, NULL) == 0);
2076*287e80b3SSadaf Ebrahimi for (i = 0; systems[i]; i++)
2077*287e80b3SSadaf Ebrahimi test_check_events(tep, systems[i], true);
2078*287e80b3SSadaf Ebrahimi
2079*287e80b3SSadaf Ebrahimi tep_free(tep);
2080*287e80b3SSadaf Ebrahimi
2081*287e80b3SSadaf Ebrahimi tracefs_list_free(systems);
2082*287e80b3SSadaf Ebrahimi }
2083*287e80b3SSadaf Ebrahimi
test_local_events(void)2084*287e80b3SSadaf Ebrahimi static void test_local_events(void)
2085*287e80b3SSadaf Ebrahimi {
2086*287e80b3SSadaf Ebrahimi const char *tdir;
2087*287e80b3SSadaf Ebrahimi
2088*287e80b3SSadaf Ebrahimi tdir = tracefs_tracing_dir();
2089*287e80b3SSadaf Ebrahimi CU_TEST(tdir != NULL);
2090*287e80b3SSadaf Ebrahimi local_events(tdir);
2091*287e80b3SSadaf Ebrahimi }
2092*287e80b3SSadaf Ebrahimi
2093*287e80b3SSadaf Ebrahimi struct test_walk_instance {
2094*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance;
2095*287e80b3SSadaf Ebrahimi bool found;
2096*287e80b3SSadaf Ebrahimi };
2097*287e80b3SSadaf Ebrahimi #define WALK_COUNT 10
test_instances_walk_cb(const char * name,void * data)2098*287e80b3SSadaf Ebrahimi int test_instances_walk_cb(const char *name, void *data)
2099*287e80b3SSadaf Ebrahimi {
2100*287e80b3SSadaf Ebrahimi struct test_walk_instance *instances = (struct test_walk_instance *)data;
2101*287e80b3SSadaf Ebrahimi int i;
2102*287e80b3SSadaf Ebrahimi
2103*287e80b3SSadaf Ebrahimi CU_TEST(instances != NULL);
2104*287e80b3SSadaf Ebrahimi CU_TEST(name != NULL);
2105*287e80b3SSadaf Ebrahimi
2106*287e80b3SSadaf Ebrahimi for (i = 0; i < WALK_COUNT; i++) {
2107*287e80b3SSadaf Ebrahimi if (!strcmp(name,
2108*287e80b3SSadaf Ebrahimi tracefs_instance_get_name(instances[i].instance))) {
2109*287e80b3SSadaf Ebrahimi instances[i].found = true;
2110*287e80b3SSadaf Ebrahimi break;
2111*287e80b3SSadaf Ebrahimi }
2112*287e80b3SSadaf Ebrahimi }
2113*287e80b3SSadaf Ebrahimi
2114*287e80b3SSadaf Ebrahimi return 0;
2115*287e80b3SSadaf Ebrahimi }
2116*287e80b3SSadaf Ebrahimi
test_instances_walk(void)2117*287e80b3SSadaf Ebrahimi static void test_instances_walk(void)
2118*287e80b3SSadaf Ebrahimi {
2119*287e80b3SSadaf Ebrahimi struct test_walk_instance instances[WALK_COUNT];
2120*287e80b3SSadaf Ebrahimi int i;
2121*287e80b3SSadaf Ebrahimi
2122*287e80b3SSadaf Ebrahimi memset(instances, 0, WALK_COUNT * sizeof(struct test_walk_instance));
2123*287e80b3SSadaf Ebrahimi for (i = 0; i < WALK_COUNT; i++) {
2124*287e80b3SSadaf Ebrahimi instances[i].instance = tracefs_instance_create(get_rand_str());
2125*287e80b3SSadaf Ebrahimi CU_TEST(instances[i].instance != NULL);
2126*287e80b3SSadaf Ebrahimi }
2127*287e80b3SSadaf Ebrahimi
2128*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instances_walk(test_instances_walk_cb, instances) == 0);
2129*287e80b3SSadaf Ebrahimi for (i = 0; i < WALK_COUNT; i++) {
2130*287e80b3SSadaf Ebrahimi CU_TEST(instances[i].found);
2131*287e80b3SSadaf Ebrahimi tracefs_instance_destroy(instances[i].instance);
2132*287e80b3SSadaf Ebrahimi instances[i].found = false;
2133*287e80b3SSadaf Ebrahimi }
2134*287e80b3SSadaf Ebrahimi
2135*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_instances_walk(test_instances_walk_cb, instances) == 0);
2136*287e80b3SSadaf Ebrahimi for (i = 0; i < WALK_COUNT; i++) {
2137*287e80b3SSadaf Ebrahimi CU_TEST(!instances[i].found);
2138*287e80b3SSadaf Ebrahimi tracefs_instance_free(instances[i].instance);
2139*287e80b3SSadaf Ebrahimi }
2140*287e80b3SSadaf Ebrahimi }
2141*287e80b3SSadaf Ebrahimi
current_clock_check(struct tracefs_instance * instance,const char * clock)2142*287e80b3SSadaf Ebrahimi static void current_clock_check(struct tracefs_instance *instance, const char *clock)
2143*287e80b3SSadaf Ebrahimi {
2144*287e80b3SSadaf Ebrahimi int size = 0;
2145*287e80b3SSadaf Ebrahimi char *clocks;
2146*287e80b3SSadaf Ebrahimi char *str;
2147*287e80b3SSadaf Ebrahimi
2148*287e80b3SSadaf Ebrahimi clocks = tracefs_instance_file_read(instance, TRACE_CLOCK, &size);
2149*287e80b3SSadaf Ebrahimi CU_TEST_FATAL(clocks != NULL);
2150*287e80b3SSadaf Ebrahimi CU_TEST(size > strlen(clock));
2151*287e80b3SSadaf Ebrahimi str = strstr(clocks, clock);
2152*287e80b3SSadaf Ebrahimi CU_TEST(str != NULL);
2153*287e80b3SSadaf Ebrahimi CU_TEST(str != clocks);
2154*287e80b3SSadaf Ebrahimi CU_TEST(*(str - 1) == '[');
2155*287e80b3SSadaf Ebrahimi CU_TEST(*(str + strlen(clock)) == ']');
2156*287e80b3SSadaf Ebrahimi free(clocks);
2157*287e80b3SSadaf Ebrahimi }
2158*287e80b3SSadaf Ebrahimi
test_instance_get_clock(struct tracefs_instance * instance)2159*287e80b3SSadaf Ebrahimi static void test_instance_get_clock(struct tracefs_instance *instance)
2160*287e80b3SSadaf Ebrahimi {
2161*287e80b3SSadaf Ebrahimi const char *clock;
2162*287e80b3SSadaf Ebrahimi
2163*287e80b3SSadaf Ebrahimi clock = tracefs_get_clock(instance);
2164*287e80b3SSadaf Ebrahimi CU_TEST_FATAL(clock != NULL);
2165*287e80b3SSadaf Ebrahimi current_clock_check(instance, clock);
2166*287e80b3SSadaf Ebrahimi free((char *)clock);
2167*287e80b3SSadaf Ebrahimi }
2168*287e80b3SSadaf Ebrahimi
test_get_clock(void)2169*287e80b3SSadaf Ebrahimi static void test_get_clock(void)
2170*287e80b3SSadaf Ebrahimi {
2171*287e80b3SSadaf Ebrahimi test_instance_get_clock(test_instance);
2172*287e80b3SSadaf Ebrahimi }
2173*287e80b3SSadaf Ebrahimi
copy_trace_file(const char * from,char * to)2174*287e80b3SSadaf Ebrahimi static void copy_trace_file(const char *from, char *to)
2175*287e80b3SSadaf Ebrahimi {
2176*287e80b3SSadaf Ebrahimi int fd_from = -1;
2177*287e80b3SSadaf Ebrahimi int fd_to = -1;
2178*287e80b3SSadaf Ebrahimi char buf[512];
2179*287e80b3SSadaf Ebrahimi int ret;
2180*287e80b3SSadaf Ebrahimi
2181*287e80b3SSadaf Ebrahimi fd_from = open(from, O_RDONLY);
2182*287e80b3SSadaf Ebrahimi if (fd_from < 0)
2183*287e80b3SSadaf Ebrahimi goto out;
2184*287e80b3SSadaf Ebrahimi fd_to = open(to, O_WRONLY | O_TRUNC | O_CREAT, S_IRWXU | S_IRWXG);
2185*287e80b3SSadaf Ebrahimi if (fd_to < 0)
2186*287e80b3SSadaf Ebrahimi goto out;
2187*287e80b3SSadaf Ebrahimi
2188*287e80b3SSadaf Ebrahimi while ((ret = read(fd_from, buf, 512)) > 0) {
2189*287e80b3SSadaf Ebrahimi if (write(fd_to, buf, ret) == -1)
2190*287e80b3SSadaf Ebrahimi break;
2191*287e80b3SSadaf Ebrahimi }
2192*287e80b3SSadaf Ebrahimi
2193*287e80b3SSadaf Ebrahimi out:
2194*287e80b3SSadaf Ebrahimi if (fd_to >= 0)
2195*287e80b3SSadaf Ebrahimi close(fd_to);
2196*287e80b3SSadaf Ebrahimi if (fd_from >= 0)
2197*287e80b3SSadaf Ebrahimi close(fd_from);
2198*287e80b3SSadaf Ebrahimi }
2199*287e80b3SSadaf Ebrahimi
2200*287e80b3SSadaf Ebrahimi static int trace_dir_base;
2201*287e80b3SSadaf Ebrahimi static char *trace_tmp_dir;
copy_trace_walk(const char * fpath,const struct stat * sb,int typeflag,struct FTW * ftwbuf)2202*287e80b3SSadaf Ebrahimi static int copy_trace_walk(const char *fpath, const struct stat *sb,
2203*287e80b3SSadaf Ebrahimi int typeflag, struct FTW *ftwbuf)
2204*287e80b3SSadaf Ebrahimi {
2205*287e80b3SSadaf Ebrahimi char path[PATH_MAX];
2206*287e80b3SSadaf Ebrahimi
2207*287e80b3SSadaf Ebrahimi sprintf(path, "%s%s", trace_tmp_dir, fpath + trace_dir_base);
2208*287e80b3SSadaf Ebrahimi
2209*287e80b3SSadaf Ebrahimi switch (typeflag) {
2210*287e80b3SSadaf Ebrahimi case FTW_D:
2211*287e80b3SSadaf Ebrahimi mkdir(path, 0750);
2212*287e80b3SSadaf Ebrahimi break;
2213*287e80b3SSadaf Ebrahimi case FTW_F:
2214*287e80b3SSadaf Ebrahimi copy_trace_file(fpath, path);
2215*287e80b3SSadaf Ebrahimi break;
2216*287e80b3SSadaf Ebrahimi default:
2217*287e80b3SSadaf Ebrahimi break;
2218*287e80b3SSadaf Ebrahimi }
2219*287e80b3SSadaf Ebrahimi return 0;
2220*287e80b3SSadaf Ebrahimi }
2221*287e80b3SSadaf Ebrahimi
dup_trace_dir(char * to,char * dir)2222*287e80b3SSadaf Ebrahimi static void dup_trace_dir(char *to, char *dir)
2223*287e80b3SSadaf Ebrahimi {
2224*287e80b3SSadaf Ebrahimi const char *trace_dir = tracefs_tracing_dir();
2225*287e80b3SSadaf Ebrahimi char file_from[PATH_MAX];
2226*287e80b3SSadaf Ebrahimi char file_to[PATH_MAX];
2227*287e80b3SSadaf Ebrahimi
2228*287e80b3SSadaf Ebrahimi sprintf(file_from, "%s/%s", trace_dir, dir);
2229*287e80b3SSadaf Ebrahimi sprintf(file_to, "%s/%s", to, dir);
2230*287e80b3SSadaf Ebrahimi trace_tmp_dir = file_to;
2231*287e80b3SSadaf Ebrahimi trace_dir_base = strlen(file_from);
2232*287e80b3SSadaf Ebrahimi nftw(file_from, copy_trace_walk, 20, 0);
2233*287e80b3SSadaf Ebrahimi }
2234*287e80b3SSadaf Ebrahimi
dup_trace_file(char * to,char * file)2235*287e80b3SSadaf Ebrahimi static void dup_trace_file(char *to, char *file)
2236*287e80b3SSadaf Ebrahimi {
2237*287e80b3SSadaf Ebrahimi const char *trace_dir = tracefs_tracing_dir();
2238*287e80b3SSadaf Ebrahimi char file_from[PATH_MAX];
2239*287e80b3SSadaf Ebrahimi char file_to[PATH_MAX];
2240*287e80b3SSadaf Ebrahimi
2241*287e80b3SSadaf Ebrahimi sprintf(file_from, "%s/%s", trace_dir, file);
2242*287e80b3SSadaf Ebrahimi sprintf(file_to, "%s/%s", to, file);
2243*287e80b3SSadaf Ebrahimi copy_trace_file(file_from, file_to);
2244*287e80b3SSadaf Ebrahimi }
2245*287e80b3SSadaf Ebrahimi
copy_trace_dir(void)2246*287e80b3SSadaf Ebrahimi static char *copy_trace_dir(void)
2247*287e80b3SSadaf Ebrahimi {
2248*287e80b3SSadaf Ebrahimi char template[] = TEST_TRACE_DIR;
2249*287e80b3SSadaf Ebrahimi char *dname = mkdtemp(template);
2250*287e80b3SSadaf Ebrahimi
2251*287e80b3SSadaf Ebrahimi dup_trace_dir(dname, "events");
2252*287e80b3SSadaf Ebrahimi dup_trace_dir(dname, "options");
2253*287e80b3SSadaf Ebrahimi dup_trace_file(dname, TRACE_ON);
2254*287e80b3SSadaf Ebrahimi dup_trace_file(dname, CUR_TRACER);
2255*287e80b3SSadaf Ebrahimi dup_trace_file(dname, TRACE_CLOCK);
2256*287e80b3SSadaf Ebrahimi dup_trace_file(dname, ALL_TRACERS);
2257*287e80b3SSadaf Ebrahimi
2258*287e80b3SSadaf Ebrahimi return strdup(dname);
2259*287e80b3SSadaf Ebrahimi }
2260*287e80b3SSadaf Ebrahimi
del_trace_walk(const char * fpath,const struct stat * sb,int typeflag,struct FTW * ftwbuf)2261*287e80b3SSadaf Ebrahimi static int del_trace_walk(const char *fpath, const struct stat *sb,
2262*287e80b3SSadaf Ebrahimi int typeflag, struct FTW *ftwbuf)
2263*287e80b3SSadaf Ebrahimi {
2264*287e80b3SSadaf Ebrahimi remove(fpath);
2265*287e80b3SSadaf Ebrahimi return 0;
2266*287e80b3SSadaf Ebrahimi }
2267*287e80b3SSadaf Ebrahimi
del_trace_dir(char * dir)2268*287e80b3SSadaf Ebrahimi void del_trace_dir(char *dir)
2269*287e80b3SSadaf Ebrahimi {
2270*287e80b3SSadaf Ebrahimi nftw(dir, del_trace_walk, 20, FTW_DEPTH);
2271*287e80b3SSadaf Ebrahimi }
2272*287e80b3SSadaf Ebrahimi
test_custom_trace_dir(void)2273*287e80b3SSadaf Ebrahimi static void test_custom_trace_dir(void)
2274*287e80b3SSadaf Ebrahimi {
2275*287e80b3SSadaf Ebrahimi char *tdir = "/tmp/custom_tracefs";
2276*287e80b3SSadaf Ebrahimi struct tracefs_instance *instance;
2277*287e80b3SSadaf Ebrahimi char *dname = copy_trace_dir();
2278*287e80b3SSadaf Ebrahimi const char *trace_dir;
2279*287e80b3SSadaf Ebrahimi char *tfile;
2280*287e80b3SSadaf Ebrahimi
2281*287e80b3SSadaf Ebrahimi instance = tracefs_instance_alloc(dname, NULL);
2282*287e80b3SSadaf Ebrahimi CU_TEST(instance != NULL);
2283*287e80b3SSadaf Ebrahimi
2284*287e80b3SSadaf Ebrahimi system_event(dname);
2285*287e80b3SSadaf Ebrahimi local_events(dname);
2286*287e80b3SSadaf Ebrahimi test_instance_tracing_options(instance);
2287*287e80b3SSadaf Ebrahimi test_instance_get_clock(instance);
2288*287e80b3SSadaf Ebrahimi test_instance_file_fd(instance);
2289*287e80b3SSadaf Ebrahimi test_instance_tracers(instance);
2290*287e80b3SSadaf Ebrahimi
2291*287e80b3SSadaf Ebrahimi tracefs_instance_free(instance);
2292*287e80b3SSadaf Ebrahimi del_trace_dir(dname);
2293*287e80b3SSadaf Ebrahimi free(dname);
2294*287e80b3SSadaf Ebrahimi
2295*287e80b3SSadaf Ebrahimi trace_dir = tracefs_tracing_dir();
2296*287e80b3SSadaf Ebrahimi CU_TEST(trace_dir != NULL);
2297*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_set_tracing_dir(tdir) == 0);
2298*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(tdir, tracefs_tracing_dir()) == 0);
2299*287e80b3SSadaf Ebrahimi tfile = tracefs_get_tracing_file("trace");
2300*287e80b3SSadaf Ebrahimi CU_TEST(tfile != NULL);
2301*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(tdir, dirname(tfile)) == 0);
2302*287e80b3SSadaf Ebrahimi free(tfile);
2303*287e80b3SSadaf Ebrahimi
2304*287e80b3SSadaf Ebrahimi CU_TEST(tracefs_set_tracing_dir(NULL) == 0);
2305*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(trace_dir, tracefs_tracing_dir()) == 0);
2306*287e80b3SSadaf Ebrahimi tfile = tracefs_get_tracing_file("trace");
2307*287e80b3SSadaf Ebrahimi CU_TEST(tfile != NULL);
2308*287e80b3SSadaf Ebrahimi CU_TEST(strcmp(trace_dir, dirname(tfile)) == 0);
2309*287e80b3SSadaf Ebrahimi free(tfile);
2310*287e80b3SSadaf Ebrahimi }
2311*287e80b3SSadaf Ebrahimi
test_suite_destroy(void)2312*287e80b3SSadaf Ebrahimi static int test_suite_destroy(void)
2313*287e80b3SSadaf Ebrahimi {
2314*287e80b3SSadaf Ebrahimi tracefs_instance_destroy(test_instance);
2315*287e80b3SSadaf Ebrahimi tracefs_instance_free(test_instance);
2316*287e80b3SSadaf Ebrahimi tep_free(test_tep);
2317*287e80b3SSadaf Ebrahimi return 0;
2318*287e80b3SSadaf Ebrahimi }
2319*287e80b3SSadaf Ebrahimi
test_suite_init(void)2320*287e80b3SSadaf Ebrahimi static int test_suite_init(void)
2321*287e80b3SSadaf Ebrahimi {
2322*287e80b3SSadaf Ebrahimi const char *systems[] = {"ftrace", NULL};
2323*287e80b3SSadaf Ebrahimi
2324*287e80b3SSadaf Ebrahimi test_tep = tracefs_local_events_system(NULL, systems);
2325*287e80b3SSadaf Ebrahimi if (test_tep == NULL)
2326*287e80b3SSadaf Ebrahimi return 1;
2327*287e80b3SSadaf Ebrahimi test_instance = tracefs_instance_create(TEST_INSTANCE_NAME);
2328*287e80b3SSadaf Ebrahimi if (!test_instance)
2329*287e80b3SSadaf Ebrahimi return 1;
2330*287e80b3SSadaf Ebrahimi
2331*287e80b3SSadaf Ebrahimi return 0;
2332*287e80b3SSadaf Ebrahimi }
2333*287e80b3SSadaf Ebrahimi
test_tracefs_lib(void)2334*287e80b3SSadaf Ebrahimi void test_tracefs_lib(void)
2335*287e80b3SSadaf Ebrahimi {
2336*287e80b3SSadaf Ebrahimi CU_pSuite suite = NULL;
2337*287e80b3SSadaf Ebrahimi
2338*287e80b3SSadaf Ebrahimi suite = CU_add_suite(TRACEFS_SUITE, test_suite_init, test_suite_destroy);
2339*287e80b3SSadaf Ebrahimi if (suite == NULL) {
2340*287e80b3SSadaf Ebrahimi fprintf(stderr, "Suite \"%s\" cannot be ceated\n", TRACEFS_SUITE);
2341*287e80b3SSadaf Ebrahimi return;
2342*287e80b3SSadaf Ebrahimi }
2343*287e80b3SSadaf Ebrahimi
2344*287e80b3SSadaf Ebrahimi CU_add_test(suite, "Test tracefs/debugfs mounting", test_mounting);
2345*287e80b3SSadaf Ebrahimi CU_add_test(suite, "trace cpu read",
2346*287e80b3SSadaf Ebrahimi test_trace_cpu_read);
2347*287e80b3SSadaf Ebrahimi CU_add_test(suite, "trace cpu pipe",
2348*287e80b3SSadaf Ebrahimi test_trace_cpu_pipe);
2349*287e80b3SSadaf Ebrahimi CU_add_test(suite, "trace sql",
2350*287e80b3SSadaf Ebrahimi test_trace_sql);
2351*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracing file / directory APIs",
2352*287e80b3SSadaf Ebrahimi test_trace_file);
2353*287e80b3SSadaf Ebrahimi CU_add_test(suite, "instance file / directory APIs",
2354*287e80b3SSadaf Ebrahimi test_file_fd);
2355*287e80b3SSadaf Ebrahimi CU_add_test(suite, "instance file descriptor",
2356*287e80b3SSadaf Ebrahimi test_instance_file);
2357*287e80b3SSadaf Ebrahimi CU_add_test(suite, "systems and events APIs",
2358*287e80b3SSadaf Ebrahimi test_system_event);
2359*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracefs_iterate_raw_events API",
2360*287e80b3SSadaf Ebrahimi test_iter_raw_events);
2361*287e80b3SSadaf Ebrahimi
2362*287e80b3SSadaf Ebrahimi /* Follow events test must be after the iterate raw events above */
2363*287e80b3SSadaf Ebrahimi CU_add_test(suite, "Follow events", test_follow_events);
2364*287e80b3SSadaf Ebrahimi
2365*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracefs_tracers API",
2366*287e80b3SSadaf Ebrahimi test_tracers);
2367*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracefs_local events API",
2368*287e80b3SSadaf Ebrahimi test_local_events);
2369*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracefs_instances_walk API",
2370*287e80b3SSadaf Ebrahimi test_instances_walk);
2371*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracefs_get_clock API",
2372*287e80b3SSadaf Ebrahimi test_get_clock);
2373*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracing on / off",
2374*287e80b3SSadaf Ebrahimi test_tracing_onoff);
2375*287e80b3SSadaf Ebrahimi CU_add_test(suite, "tracing options",
2376*287e80b3SSadaf Ebrahimi test_tracing_options);
2377*287e80b3SSadaf Ebrahimi CU_add_test(suite, "custom system directory",
2378*287e80b3SSadaf Ebrahimi test_custom_trace_dir);
2379*287e80b3SSadaf Ebrahimi CU_add_test(suite, "ftrace marker",
2380*287e80b3SSadaf Ebrahimi test_ftrace_marker);
2381*287e80b3SSadaf Ebrahimi CU_add_test(suite, "kprobes", test_kprobes);
2382*287e80b3SSadaf Ebrahimi CU_add_test(suite, "synthetic events", test_synthetic);
2383*287e80b3SSadaf Ebrahimi CU_add_test(suite, "eprobes", test_eprobes);
2384*287e80b3SSadaf Ebrahimi CU_add_test(suite, "uprobes", test_uprobes);
2385*287e80b3SSadaf Ebrahimi }
2386