Fix: waiter: futex wait: handle spurious futex wakeups
[lttng-tools.git] / src / common / event-rule / event-rule.cpp
CommitLineData
7a3dcaf6
JR
1/*
2 * Copyright (C) 2019 Jonathan Rajotte
3 * <jonathan.rajotte-julien@efficios.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only
6 *
7 */
8
c9e313bc
SM
9#include <common/error.hpp>
10#include <common/hashtable/hashtable.hpp>
11#include <common/hashtable/utils.hpp>
12#include <common/macros.hpp>
13#include <common/mi-lttng.hpp>
14#include <common/payload-view.hpp>
15#include <common/payload.hpp>
16#include <lttng/event-rule/event-rule-internal.hpp>
17#include <lttng/event-rule/jul-logging-internal.hpp>
18#include <lttng/event-rule/kernel-kprobe-internal.hpp>
19#include <lttng/event-rule/kernel-syscall-internal.hpp>
20#include <lttng/event-rule/kernel-tracepoint-internal.hpp>
21#include <lttng/event-rule/kernel-uprobe-internal.hpp>
22#include <lttng/event-rule/log4j-logging-internal.hpp>
23#include <lttng/event-rule/python-logging-internal.hpp>
24#include <lttng/event-rule/user-tracepoint-internal.hpp>
7a3dcaf6
JR
25#include <stdbool.h>
26
27enum lttng_event_rule_type lttng_event_rule_get_type(
28 const struct lttng_event_rule *event_rule)
29{
30 return event_rule ? event_rule->type : LTTNG_EVENT_RULE_TYPE_UNKNOWN;
31}
32
7a3dcaf6
JR
33enum lttng_domain_type lttng_event_rule_get_domain_type(
34 const struct lttng_event_rule *event_rule)
35{
36 enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE;
37
38 switch (lttng_event_rule_get_type(event_rule)) {
0a23a07d
JR
39 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
40 domain_type = LTTNG_DOMAIN_UST;
41 break;
b47b01d8
JR
42 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
43 domain_type = LTTNG_DOMAIN_JUL;
44 break;
138d6838
JR
45 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
46 domain_type = LTTNG_DOMAIN_LOG4J;
47 break;
6530ec7d
JR
48 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
49 domain_type = LTTNG_DOMAIN_PYTHON;
50 break;
4f7da553 51 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
85522de5 52 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
46fd07ac 53 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
af0818ef 54 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
7a3dcaf6
JR
55 domain_type = LTTNG_DOMAIN_KERNEL;
56 break;
57 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
58 domain_type = LTTNG_DOMAIN_NONE;
59 break;
60 }
61
62 return domain_type;
63}
64
65static void lttng_event_rule_release(struct urcu_ref *ref)
66{
67 struct lttng_event_rule *event_rule =
0114db0e 68 lttng::utils::container_of(ref, &lttng_event_rule::ref);
7a3dcaf6 69
a0377dfe 70 LTTNG_ASSERT(event_rule->destroy);
7a3dcaf6
JR
71 event_rule->destroy(event_rule);
72}
73
74void lttng_event_rule_destroy(struct lttng_event_rule *event_rule)
75{
76 lttng_event_rule_put(event_rule);
77}
78
7a3dcaf6
JR
79bool lttng_event_rule_validate(const struct lttng_event_rule *event_rule)
80{
81 bool valid;
82
83 if (!event_rule) {
84 valid = false;
85 goto end;
86 }
87
88 if (!event_rule->validate) {
89 /* Sub-class guarantees that it can never be invalid. */
90 valid = true;
91 goto end;
92 }
93
94 valid = event_rule->validate(event_rule);
95end:
96 return valid;
97}
98
7a3dcaf6
JR
99int lttng_event_rule_serialize(const struct lttng_event_rule *event_rule,
100 struct lttng_payload *payload)
101{
102 int ret;
103 struct lttng_event_rule_comm event_rule_comm = {};
104
105 if (!event_rule) {
106 ret = -1;
107 goto end;
108 }
109
110 event_rule_comm.event_rule_type = (int8_t) event_rule->type;
111
112 ret = lttng_dynamic_buffer_append(
113 &payload->buffer, &event_rule_comm, sizeof(event_rule_comm));
114 if (ret) {
115 goto end;
116 }
117
118 ret = event_rule->serialize(event_rule, payload);
119 if (ret) {
120 goto end;
121 }
122end:
123 return ret;
124}
125
7a3dcaf6
JR
126bool lttng_event_rule_is_equal(const struct lttng_event_rule *a,
127 const struct lttng_event_rule *b)
128{
129 bool is_equal = false;
130
131 if (!a || !b) {
132 goto end;
133 }
134
135 if (a->type != b->type) {
136 goto end;
137 }
138
139 if (a == b) {
140 is_equal = true;
141 goto end;
142 }
143
144 is_equal = a->equal ? a->equal(a, b) : true;
145end:
146 return is_equal;
147}
148
7a3dcaf6
JR
149ssize_t lttng_event_rule_create_from_payload(
150 struct lttng_payload_view *view,
151 struct lttng_event_rule **event_rule)
152{
153 ssize_t ret, consumed = 0;
7a3dcaf6 154 event_rule_create_from_payload_cb create_from_payload = NULL;
3e6e0df2
JG
155 const struct lttng_event_rule_comm *event_rule_comm;
156 const struct lttng_payload_view event_rule_comm_view =
157 lttng_payload_view_from_view(
158 view, 0, sizeof(*event_rule_comm));
7a3dcaf6
JR
159
160 if (!view || !event_rule) {
161 ret = -1;
162 goto end;
163 }
164
3e6e0df2
JG
165 if (!lttng_payload_view_is_valid(&event_rule_comm_view)) {
166 ret = -1;
167 goto end;
168 }
169
683d081a 170 DBG("Deserializing event_rule from payload");
3e6e0df2 171 event_rule_comm = (const struct lttng_event_rule_comm *) event_rule_comm_view.buffer.data;
7a3dcaf6
JR
172 consumed += sizeof(*event_rule_comm);
173
174 switch ((enum lttng_event_rule_type) event_rule_comm->event_rule_type) {
85522de5
JR
175 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
176 create_from_payload = lttng_event_rule_kernel_kprobe_create_from_payload;
7a3dcaf6 177 break;
46fd07ac
JR
178 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
179 create_from_payload = lttng_event_rule_kernel_uprobe_create_from_payload;
7a3dcaf6 180 break;
4f7da553 181 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
e6a39346 182 create_from_payload =
4f7da553 183 lttng_event_rule_kernel_syscall_create_from_payload;
7a3dcaf6 184 break;
af0818ef
JR
185 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
186 create_from_payload =
187 lttng_event_rule_kernel_tracepoint_create_from_payload;
188 break;
0a23a07d
JR
189 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
190 create_from_payload =
191 lttng_event_rule_user_tracepoint_create_from_payload;
192 break;
b47b01d8
JR
193 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
194 create_from_payload =
195 lttng_event_rule_jul_logging_create_from_payload;
196 break;
138d6838
JR
197 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
198 create_from_payload =
199 lttng_event_rule_log4j_logging_create_from_payload;
200 break;
6530ec7d
JR
201 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
202 create_from_payload =
203 lttng_event_rule_python_logging_create_from_payload;
204 break;
7a3dcaf6
JR
205 default:
206 ERR("Attempted to create event rule of unknown type (%i)",
207 (int) event_rule_comm->event_rule_type);
208 ret = -1;
209 goto end;
210 }
211
a0377dfe 212 LTTNG_ASSERT(create_from_payload);
7a3dcaf6
JR
213
214 {
215 struct lttng_payload_view child_view =
216 lttng_payload_view_from_view(
217 view, consumed, -1);
218
219 ret = create_from_payload(&child_view, event_rule);
220 if (ret < 0) {
221 goto end;
222 }
223
224 consumed += ret;
225 }
226
227 if (!lttng_event_rule_validate(*event_rule)) {
228 ret = -1;
229 goto end;
230 }
231
232 ret = consumed;
233end:
234 return ret;
235}
236
7a3dcaf6
JR
237void lttng_event_rule_init(struct lttng_event_rule *event_rule,
238 enum lttng_event_rule_type type)
239{
240 urcu_ref_init(&event_rule->ref);
241 event_rule->type = type;
242}
243
7a3dcaf6
JR
244bool lttng_event_rule_get(struct lttng_event_rule *event_rule)
245{
246 return urcu_ref_get_unless_zero(&event_rule->ref);
247}
248
7a3dcaf6
JR
249void lttng_event_rule_put(struct lttng_event_rule *event_rule)
250{
251 if (!event_rule) {
252 return;
253 }
254
a0377dfe 255 LTTNG_ASSERT(event_rule->ref.refcount);
7a3dcaf6
JR
256 urcu_ref_put(&event_rule->ref, lttng_event_rule_release);
257}
258
7a3dcaf6 259enum lttng_error_code lttng_event_rule_generate_filter_bytecode(
58daac01
JR
260 struct lttng_event_rule *rule,
261 const struct lttng_credentials *creds)
7a3dcaf6 262{
a0377dfe 263 LTTNG_ASSERT(rule->generate_filter_bytecode);
58daac01 264 return rule->generate_filter_bytecode(rule, creds);
7a3dcaf6
JR
265}
266
7a3dcaf6
JR
267const char *lttng_event_rule_get_filter(const struct lttng_event_rule *rule)
268{
a0377dfe 269 LTTNG_ASSERT(rule->get_filter);
7a3dcaf6
JR
270 return rule->get_filter(rule);
271}
272
2b00d462 273const struct lttng_bytecode *lttng_event_rule_get_filter_bytecode(
7a3dcaf6
JR
274 const struct lttng_event_rule *rule)
275{
a0377dfe 276 LTTNG_ASSERT(rule->get_filter_bytecode);
7a3dcaf6
JR
277 return rule->get_filter_bytecode(rule);
278}
279
993578ff
JR
280enum lttng_event_rule_generate_exclusions_status
281lttng_event_rule_generate_exclusions(const struct lttng_event_rule *rule,
282 struct lttng_event_exclusion **exclusions)
7a3dcaf6 283{
a0377dfe 284 LTTNG_ASSERT(rule->generate_exclusions);
993578ff 285 return rule->generate_exclusions(rule, exclusions);
7a3dcaf6
JR
286}
287
44760c20
JR
288struct lttng_event *lttng_event_rule_generate_lttng_event(
289 const struct lttng_event_rule *rule)
290{
a0377dfe 291 LTTNG_ASSERT(rule->generate_lttng_event);
44760c20
JR
292 return rule->generate_lttng_event(rule);
293}
294
44760c20
JR
295bool lttng_event_rule_targets_agent_domain(const struct lttng_event_rule *rule)
296{
297 bool targets_agent_domain = false;
298 enum lttng_domain_type type = lttng_event_rule_get_domain_type(rule);
299
300 switch (type) {
301 case LTTNG_DOMAIN_JUL:
302 case LTTNG_DOMAIN_LOG4J:
303 case LTTNG_DOMAIN_PYTHON:
304 targets_agent_domain = true;
305 break;
306 case LTTNG_DOMAIN_UST:
307 case LTTNG_DOMAIN_KERNEL:
308 targets_agent_domain = false;
309 break;
310 default:
311 abort();
312 };
313
314 return targets_agent_domain;
315}
316
7a3dcaf6
JR
317const char *lttng_event_rule_type_str(enum lttng_event_rule_type type)
318{
319 switch (type) {
320 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
321 return "unknown";
4f7da553
JR
322 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
323 return "kernel syscall";
85522de5
JR
324 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
325 return "kernel kprobe";
46fd07ac
JR
326 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
327 return "kernel uprobe";
af0818ef
JR
328 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
329 return "kernel tracepoint";
0a23a07d
JR
330 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
331 return "user tracepoint";
b47b01d8
JR
332 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
333 return "jul logging";
138d6838
JR
334 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
335 return "log4j logging";
6530ec7d
JR
336 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
337 return "python logging";
338
7a3dcaf6
JR
339 default:
340 abort();
341 }
342}
959e3c66 343
959e3c66
JR
344unsigned long lttng_event_rule_hash(const struct lttng_event_rule *rule)
345{
a0377dfe 346 LTTNG_ASSERT(rule->hash);
959e3c66
JR
347 return rule->hash(rule);
348}
6a751b95 349
6a751b95
JR
350enum lttng_error_code lttng_event_rule_mi_serialize(
351 const struct lttng_event_rule *rule, struct mi_writer *writer)
352{
353 int ret;
354 enum lttng_error_code ret_code;
355
a0377dfe
FD
356 LTTNG_ASSERT(rule);
357 LTTNG_ASSERT(writer);
358 LTTNG_ASSERT(rule->mi_serialize);
6a751b95
JR
359
360 /* Open event rule element. */
361 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule);
362 if (ret) {
363 goto mi_error;
364 }
365
366 /* Serialize underlying event rule. */
367 ret_code = rule->mi_serialize(rule, writer);
368 if (ret_code != LTTNG_OK) {
369 goto end;
370 }
371
372 /* Close event rule element. */
373 ret = mi_lttng_writer_close_element(writer);
374 if (ret) {
375 goto mi_error;
376 }
377
378 ret_code = LTTNG_OK;
379 goto end;
380
381mi_error:
382 ret_code = LTTNG_ERR_MI_IO_FAIL;
383end:
384 return ret_code;
385}
This page took 0.056289 seconds and 4 git commands to generate.