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 
14 static inline bool tracefs_enabled(char **message, bool *fail)
15 {
16 	struct stat buf;
17 	int ret;
18 
19 	*message = "";
20 	*fail = false;
21 
22 	/* Ensure tracefs is installed */
23 	ret = stat("/sys/kernel/tracing", &buf);
24 
25 	if (ret == -1) {
26 		*message = "Tracefs is not installed";
27 		return false;
28 	}
29 
30 	/* Ensure mounted tracefs */
31 	ret = stat("/sys/kernel/tracing/README", &buf);
32 
33 	if (ret == -1 && errno == ENOENT) {
34 		if (mount(NULL, "/sys/kernel/tracing", "tracefs", 0, NULL) != 0) {
35 			*message = "Cannot mount tracefs";
36 			*fail = true;
37 			return false;
38 		}
39 
40 		ret = stat("/sys/kernel/tracing/README", &buf);
41 	}
42 
43 	if (ret == -1) {
44 		*message = "Cannot access tracefs";
45 		*fail = true;
46 		return false;
47 	}
48 
49 	return true;
50 }
51 
52 static inline bool user_events_enabled(char **message, bool *fail)
53 {
54 	struct stat buf;
55 	int ret;
56 
57 	*message = "";
58 	*fail = false;
59 
60 	if (getuid() != 0) {
61 		*message = "Must be run as root";
62 		*fail = true;
63 		return false;
64 	}
65 
66 	if (!tracefs_enabled(message, fail))
67 		return false;
68 
69 	/* Ensure user_events is installed */
70 	ret = stat("/sys/kernel/tracing/user_events_data", &buf);
71 
72 	if (ret == -1) {
73 		switch (errno) {
74 		case ENOENT:
75 			*message = "user_events is not installed";
76 			return false;
77 
78 		default:
79 			*message = "Cannot access user_events_data";
80 			*fail = true;
81 			return false;
82 		}
83 	}
84 
85 	return true;
86 }
87 
88 #define USER_EVENT_FIXTURE_SETUP(statement) do { \
89 	char *message; \
90 	bool fail; \
91 	if (!user_events_enabled(&message, &fail)) { \
92 		if (fail) { \
93 			TH_LOG("Setup failed due to: %s", message); \
94 			ASSERT_FALSE(fail); \
95 		} \
96 		SKIP(statement, "Skipping due to: %s", message); \
97 	} \
98 } while (0)
99 
100 #endif /* _USER_EVENTS_SELFTESTS_H */
101