1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef _USER_EVENTS_SELFTESTS_H
4 #define _USER_EVENTS_SELFTESTS_H
5
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <sys/mount.h>
9 #include <unistd.h>
10 #include <errno.h>
11
12 #include "../kselftest.h"
13
tracefs_unmount(void)14 static inline void tracefs_unmount(void)
15 {
16 umount("/sys/kernel/tracing");
17 }
18
tracefs_enabled(char ** message,bool * fail,bool * umount)19 static inline bool tracefs_enabled(char **message, bool *fail, bool *umount)
20 {
21 struct stat buf;
22 int ret;
23
24 *message = "";
25 *fail = false;
26 *umount = false;
27
28 /* Ensure tracefs is installed */
29 ret = stat("/sys/kernel/tracing", &buf);
30
31 if (ret == -1) {
32 *message = "Tracefs is not installed";
33 return false;
34 }
35
36 /* Ensure mounted tracefs */
37 ret = stat("/sys/kernel/tracing/README", &buf);
38
39 if (ret == -1 && errno == ENOENT) {
40 if (mount(NULL, "/sys/kernel/tracing", "tracefs", 0, NULL) != 0) {
41 *message = "Cannot mount tracefs";
42 *fail = true;
43 return false;
44 }
45
46 *umount = true;
47
48 ret = stat("/sys/kernel/tracing/README", &buf);
49 }
50
51 if (ret == -1) {
52 *message = "Cannot access tracefs";
53 *fail = true;
54 return false;
55 }
56
57 return true;
58 }
59
user_events_enabled(char ** message,bool * fail,bool * umount)60 static inline bool user_events_enabled(char **message, bool *fail, bool *umount)
61 {
62 struct stat buf;
63 int ret;
64
65 *message = "";
66 *fail = false;
67 *umount = false;
68
69 if (getuid() != 0) {
70 *message = "Must be run as root";
71 *fail = true;
72 return false;
73 }
74
75 if (!tracefs_enabled(message, fail, umount))
76 return false;
77
78 /* Ensure user_events is installed */
79 ret = stat("/sys/kernel/tracing/user_events_data", &buf);
80
81 if (ret == -1) {
82 switch (errno) {
83 case ENOENT:
84 *message = "user_events is not installed";
85 return false;
86
87 default:
88 *message = "Cannot access user_events_data";
89 *fail = true;
90 return false;
91 }
92 }
93
94 return true;
95 }
96
97 #define USER_EVENT_FIXTURE_SETUP(statement, umount) do { \
98 char *message; \
99 bool fail; \
100 if (!user_events_enabled(&message, &fail, &(umount))) { \
101 if (fail) { \
102 TH_LOG("Setup failed due to: %s", message); \
103 ASSERT_FALSE(fail); \
104 } \
105 SKIP(statement, "Skipping due to: %s", message); \
106 } \
107 } while (0)
108
109 #define USER_EVENT_FIXTURE_TEARDOWN(umount) do { \
110 if ((umount)) \
111 tracefs_unmount(); \
112 } while (0)
113
114 #endif /* _USER_EVENTS_SELFTESTS_H */
115