|
16 | 16 |
|
17 | 17 | #include "../kselftest_harness.h"
|
18 | 18 |
|
19 |
| -const char *dyn_file = "/sys/kernel/tracing/dynamic_events"; |
20 |
| -const char *clear = "!u:__test_event"; |
| 19 | +const char *abi_file = "/sys/kernel/tracing/user_events_data"; |
| 20 | +const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable"; |
21 | 21 |
|
22 |
| -static int Append(const char *value) |
| 22 | +static bool wait_for_delete(void) |
23 | 23 | {
|
24 |
| - int fd = open(dyn_file, O_RDWR | O_APPEND); |
25 |
| - int ret = write(fd, value, strlen(value)); |
| 24 | + int i; |
| 25 | + |
| 26 | + for (i = 0; i < 1000; ++i) { |
| 27 | + int fd = open(enable_file, O_RDONLY); |
| 28 | + |
| 29 | + if (fd == -1) |
| 30 | + return true; |
| 31 | + |
| 32 | + close(fd); |
| 33 | + usleep(1000); |
| 34 | + } |
| 35 | + |
| 36 | + return false; |
| 37 | +} |
| 38 | + |
| 39 | +static int reg_event(int fd, int *check, int bit, const char *value) |
| 40 | +{ |
| 41 | + struct user_reg reg = {0}; |
| 42 | + |
| 43 | + reg.size = sizeof(reg); |
| 44 | + reg.name_args = (__u64)value; |
| 45 | + reg.enable_bit = bit; |
| 46 | + reg.enable_addr = (__u64)check; |
| 47 | + reg.enable_size = sizeof(*check); |
| 48 | + |
| 49 | + if (ioctl(fd, DIAG_IOCSREG, ®) == -1) |
| 50 | + return -1; |
| 51 | + |
| 52 | + return 0; |
| 53 | +} |
| 54 | + |
| 55 | +static int unreg_event(int fd, int *check, int bit) |
| 56 | +{ |
| 57 | + struct user_unreg unreg = {0}; |
| 58 | + |
| 59 | + unreg.size = sizeof(unreg); |
| 60 | + unreg.disable_bit = bit; |
| 61 | + unreg.disable_addr = (__u64)check; |
| 62 | + |
| 63 | + return ioctl(fd, DIAG_IOCSUNREG, &unreg); |
| 64 | +} |
| 65 | + |
| 66 | +static int parse(int *check, const char *value) |
| 67 | +{ |
| 68 | + int fd = open(abi_file, O_RDWR); |
| 69 | + int ret; |
| 70 | + |
| 71 | + if (fd == -1) |
| 72 | + return -1; |
| 73 | + |
| 74 | + /* Until we have persist flags via dynamic events, use the base name */ |
| 75 | + if (value[0] != 'u' || value[1] != ':') { |
| 76 | + close(fd); |
| 77 | + return -1; |
| 78 | + } |
| 79 | + |
| 80 | + ret = reg_event(fd, check, 31, value + 2); |
| 81 | + |
| 82 | + if (ret != -1) { |
| 83 | + if (unreg_event(fd, check, 31) == -1) |
| 84 | + printf("WARN: Couldn't unreg event\n"); |
| 85 | + } |
26 | 86 |
|
27 | 87 | close(fd);
|
| 88 | + |
28 | 89 | return ret;
|
29 | 90 | }
|
30 | 91 |
|
31 |
| -#define CLEAR() \ |
| 92 | +static int check_match(int *check, const char *first, const char *second, bool *match) |
| 93 | +{ |
| 94 | + int fd = open(abi_file, O_RDWR); |
| 95 | + int ret = -1; |
| 96 | + |
| 97 | + if (fd == -1) |
| 98 | + return -1; |
| 99 | + |
| 100 | + if (reg_event(fd, check, 31, first) == -1) |
| 101 | + goto cleanup; |
| 102 | + |
| 103 | + if (reg_event(fd, check, 30, second) == -1) { |
| 104 | + if (errno == EADDRINUSE) { |
| 105 | + /* Name is in use, with different fields */ |
| 106 | + *match = false; |
| 107 | + ret = 0; |
| 108 | + } |
| 109 | + |
| 110 | + goto cleanup; |
| 111 | + } |
| 112 | + |
| 113 | + *match = true; |
| 114 | + ret = 0; |
| 115 | +cleanup: |
| 116 | + unreg_event(fd, check, 31); |
| 117 | + unreg_event(fd, check, 30); |
| 118 | + |
| 119 | + close(fd); |
| 120 | + |
| 121 | + wait_for_delete(); |
| 122 | + |
| 123 | + return ret; |
| 124 | +} |
| 125 | + |
| 126 | +#define TEST_MATCH(x, y) \ |
32 | 127 | do { \
|
33 |
| - int ret = Append(clear); \ |
34 |
| - if (ret == -1) \ |
35 |
| - ASSERT_EQ(ENOENT, errno); \ |
| 128 | + bool match; \ |
| 129 | + ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \ |
| 130 | + ASSERT_EQ(true, match); \ |
36 | 131 | } while (0)
|
37 | 132 |
|
38 |
| -#define TEST_PARSE(x) \ |
| 133 | +#define TEST_NMATCH(x, y) \ |
39 | 134 | do { \
|
40 |
| - ASSERT_NE(-1, Append(x)); \ |
41 |
| - CLEAR(); \ |
| 135 | + bool match; \ |
| 136 | + ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \ |
| 137 | + ASSERT_EQ(false, match); \ |
42 | 138 | } while (0)
|
43 | 139 |
|
44 |
| -#define TEST_NPARSE(x) ASSERT_EQ(-1, Append(x)) |
| 140 | +#define TEST_PARSE(x) ASSERT_NE(-1, parse(&self->check, x)) |
| 141 | + |
| 142 | +#define TEST_NPARSE(x) ASSERT_EQ(-1, parse(&self->check, x)) |
45 | 143 |
|
46 | 144 | FIXTURE(user) {
|
| 145 | + int check; |
47 | 146 | };
|
48 | 147 |
|
49 | 148 | FIXTURE_SETUP(user) {
|
50 |
| - CLEAR(); |
51 | 149 | }
|
52 | 150 |
|
53 | 151 | FIXTURE_TEARDOWN(user) {
|
54 |
| - CLEAR(); |
| 152 | + wait_for_delete(); |
55 | 153 | }
|
56 | 154 |
|
57 | 155 | TEST_F(user, basic_types) {
|
@@ -95,33 +193,30 @@ TEST_F(user, size_types) {
|
95 | 193 | TEST_NPARSE("u:__test_event char a 20");
|
96 | 194 | }
|
97 | 195 |
|
98 |
| -TEST_F(user, flags) { |
99 |
| - /* Should work */ |
100 |
| - TEST_PARSE("u:__test_event:BPF_ITER u32 a"); |
101 |
| - /* Forward compat */ |
102 |
| - TEST_PARSE("u:__test_event:BPF_ITER,FLAG_FUTURE u32 a"); |
103 |
| -} |
104 |
| - |
105 | 196 | TEST_F(user, matching) {
|
106 |
| - /* Register */ |
107 |
| - ASSERT_NE(-1, Append("u:__test_event struct custom a 20")); |
108 |
| - /* Should not match */ |
109 |
| - TEST_NPARSE("!u:__test_event struct custom b"); |
110 |
| - /* Should match */ |
111 |
| - TEST_PARSE("!u:__test_event struct custom a"); |
112 |
| - /* Multi field reg */ |
113 |
| - ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b")); |
114 |
| - /* Non matching cases */ |
115 |
| - TEST_NPARSE("!u:__test_event u32 a"); |
116 |
| - TEST_NPARSE("!u:__test_event u32 b"); |
117 |
| - TEST_NPARSE("!u:__test_event u32 a; u32 "); |
118 |
| - TEST_NPARSE("!u:__test_event u32 a; u32 a"); |
119 |
| - /* Matching case */ |
120 |
| - TEST_PARSE("!u:__test_event u32 a; u32 b"); |
121 |
| - /* Register */ |
122 |
| - ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b")); |
123 |
| - /* Ensure trailing semi-colon case */ |
124 |
| - TEST_PARSE("!u:__test_event u32 a; u32 b;"); |
| 197 | + /* Single name matches */ |
| 198 | + TEST_MATCH("__test_event u32 a", |
| 199 | + "__test_event u32 a"); |
| 200 | + |
| 201 | + /* Multiple names match */ |
| 202 | + TEST_MATCH("__test_event u32 a; u32 b", |
| 203 | + "__test_event u32 a; u32 b"); |
| 204 | + |
| 205 | + /* Multiple names match with dangling ; */ |
| 206 | + TEST_MATCH("__test_event u32 a; u32 b", |
| 207 | + "__test_event u32 a; u32 b;"); |
| 208 | + |
| 209 | + /* Single name doesn't match */ |
| 210 | + TEST_NMATCH("__test_event u32 a", |
| 211 | + "__test_event u32 b"); |
| 212 | + |
| 213 | + /* Multiple names don't match */ |
| 214 | + TEST_NMATCH("__test_event u32 a; u32 b", |
| 215 | + "__test_event u32 b; u32 a"); |
| 216 | + |
| 217 | + /* Types don't match */ |
| 218 | + TEST_NMATCH("__test_event u64 a; u64 b", |
| 219 | + "__test_event u32 a; u32 b"); |
125 | 220 | }
|
126 | 221 |
|
127 | 222 | int main(int argc, char **argv)
|
|
0 commit comments