fix: relayd: unaligned access in trace_chunk_registry_ht_key_hash
[lttng-tools.git] / src / common / event-rule / event-rule.cpp
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
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
17 #include <lttng/event-rule/event-rule-internal.hpp>
18 #include <lttng/event-rule/jul-logging-internal.hpp>
19 #include <lttng/event-rule/kernel-kprobe-internal.hpp>
20 #include <lttng/event-rule/kernel-syscall-internal.hpp>
21 #include <lttng/event-rule/kernel-tracepoint-internal.hpp>
22 #include <lttng/event-rule/kernel-uprobe-internal.hpp>
23 #include <lttng/event-rule/log4j-logging-internal.hpp>
24 #include <lttng/event-rule/python-logging-internal.hpp>
25 #include <lttng/event-rule/user-tracepoint-internal.hpp>
26
27 #include <stdbool.h>
28
29 enum lttng_event_rule_type lttng_event_rule_get_type(const struct lttng_event_rule *event_rule)
30 {
31 return event_rule ? event_rule->type : LTTNG_EVENT_RULE_TYPE_UNKNOWN;
32 }
33
34 enum lttng_domain_type lttng_event_rule_get_domain_type(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)) {
39 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
40 domain_type = LTTNG_DOMAIN_UST;
41 break;
42 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
43 domain_type = LTTNG_DOMAIN_JUL;
44 break;
45 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
46 domain_type = LTTNG_DOMAIN_LOG4J;
47 break;
48 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
49 domain_type = LTTNG_DOMAIN_PYTHON;
50 break;
51 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
52 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
53 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
54 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
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
65 static void lttng_event_rule_release(struct urcu_ref *ref)
66 {
67 struct lttng_event_rule *event_rule =
68 lttng::utils::container_of(ref, &lttng_event_rule::ref);
69
70 LTTNG_ASSERT(event_rule->destroy);
71 event_rule->destroy(event_rule);
72 }
73
74 void lttng_event_rule_destroy(struct lttng_event_rule *event_rule)
75 {
76 lttng_event_rule_put(event_rule);
77 }
78
79 bool 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);
95 end:
96 return valid;
97 }
98
99 int 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 }
122 end:
123 return ret;
124 }
125
126 bool lttng_event_rule_is_equal(const struct lttng_event_rule *a, const struct lttng_event_rule *b)
127 {
128 bool is_equal = false;
129
130 if (!a || !b) {
131 goto end;
132 }
133
134 if (a->type != b->type) {
135 goto end;
136 }
137
138 if (a == b) {
139 is_equal = true;
140 goto end;
141 }
142
143 is_equal = a->equal ? a->equal(a, b) : true;
144 end:
145 return is_equal;
146 }
147
148 ssize_t lttng_event_rule_create_from_payload(struct lttng_payload_view *view,
149 struct lttng_event_rule **event_rule)
150 {
151 ssize_t ret, consumed = 0;
152 event_rule_create_from_payload_cb create_from_payload = nullptr;
153 const struct lttng_event_rule_comm *event_rule_comm;
154 const struct lttng_payload_view event_rule_comm_view =
155 lttng_payload_view_from_view(view, 0, sizeof(*event_rule_comm));
156
157 if (!view || !event_rule) {
158 ret = -1;
159 goto end;
160 }
161
162 if (!lttng_payload_view_is_valid(&event_rule_comm_view)) {
163 ret = -1;
164 goto end;
165 }
166
167 DBG("Deserializing event_rule from payload");
168 event_rule_comm = (const struct lttng_event_rule_comm *) event_rule_comm_view.buffer.data;
169 consumed += sizeof(*event_rule_comm);
170
171 switch ((enum lttng_event_rule_type) event_rule_comm->event_rule_type) {
172 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
173 create_from_payload = lttng_event_rule_kernel_kprobe_create_from_payload;
174 break;
175 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
176 create_from_payload = lttng_event_rule_kernel_uprobe_create_from_payload;
177 break;
178 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
179 create_from_payload = lttng_event_rule_kernel_syscall_create_from_payload;
180 break;
181 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
182 create_from_payload = lttng_event_rule_kernel_tracepoint_create_from_payload;
183 break;
184 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
185 create_from_payload = lttng_event_rule_user_tracepoint_create_from_payload;
186 break;
187 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
188 create_from_payload = lttng_event_rule_jul_logging_create_from_payload;
189 break;
190 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
191 create_from_payload = lttng_event_rule_log4j_logging_create_from_payload;
192 break;
193 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
194 create_from_payload = lttng_event_rule_python_logging_create_from_payload;
195 break;
196 default:
197 ERR("Attempted to create event rule of unknown type (%i)",
198 (int) event_rule_comm->event_rule_type);
199 ret = -1;
200 goto end;
201 }
202
203 LTTNG_ASSERT(create_from_payload);
204
205 {
206 struct lttng_payload_view child_view =
207 lttng_payload_view_from_view(view, consumed, -1);
208
209 ret = create_from_payload(&child_view, event_rule);
210 if (ret < 0) {
211 goto end;
212 }
213
214 consumed += ret;
215 }
216
217 if (!lttng_event_rule_validate(*event_rule)) {
218 ret = -1;
219 goto end;
220 }
221
222 ret = consumed;
223 end:
224 return ret;
225 }
226
227 void lttng_event_rule_init(struct lttng_event_rule *event_rule, enum lttng_event_rule_type type)
228 {
229 urcu_ref_init(&event_rule->ref);
230 event_rule->type = type;
231 }
232
233 bool lttng_event_rule_get(struct lttng_event_rule *event_rule)
234 {
235 return urcu_ref_get_unless_zero(&event_rule->ref);
236 }
237
238 void lttng_event_rule_put(struct lttng_event_rule *event_rule)
239 {
240 if (!event_rule) {
241 return;
242 }
243
244 LTTNG_ASSERT(event_rule->ref.refcount);
245 urcu_ref_put(&event_rule->ref, lttng_event_rule_release);
246 }
247
248 enum lttng_error_code
249 lttng_event_rule_generate_filter_bytecode(struct lttng_event_rule *rule,
250 const struct lttng_credentials *creds)
251 {
252 LTTNG_ASSERT(rule->generate_filter_bytecode);
253 return rule->generate_filter_bytecode(rule, creds);
254 }
255
256 const char *lttng_event_rule_get_filter(const struct lttng_event_rule *rule)
257 {
258 LTTNG_ASSERT(rule->get_filter);
259 return rule->get_filter(rule);
260 }
261
262 const struct lttng_bytecode *
263 lttng_event_rule_get_filter_bytecode(const struct lttng_event_rule *rule)
264 {
265 LTTNG_ASSERT(rule->get_filter_bytecode);
266 return rule->get_filter_bytecode(rule);
267 }
268
269 enum lttng_event_rule_generate_exclusions_status
270 lttng_event_rule_generate_exclusions(const struct lttng_event_rule *rule,
271 struct lttng_event_exclusion **exclusions)
272 {
273 LTTNG_ASSERT(rule->generate_exclusions);
274 return rule->generate_exclusions(rule, exclusions);
275 }
276
277 struct lttng_event *lttng_event_rule_generate_lttng_event(const struct lttng_event_rule *rule)
278 {
279 LTTNG_ASSERT(rule->generate_lttng_event);
280 return rule->generate_lttng_event(rule);
281 }
282
283 bool lttng_event_rule_targets_agent_domain(const struct lttng_event_rule *rule)
284 {
285 bool targets_agent_domain = false;
286 enum lttng_domain_type type = lttng_event_rule_get_domain_type(rule);
287
288 switch (type) {
289 case LTTNG_DOMAIN_JUL:
290 case LTTNG_DOMAIN_LOG4J:
291 case LTTNG_DOMAIN_PYTHON:
292 targets_agent_domain = true;
293 break;
294 case LTTNG_DOMAIN_UST:
295 case LTTNG_DOMAIN_KERNEL:
296 targets_agent_domain = false;
297 break;
298 default:
299 abort();
300 };
301
302 return targets_agent_domain;
303 }
304
305 const char *lttng_event_rule_type_str(enum lttng_event_rule_type type)
306 {
307 switch (type) {
308 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
309 return "unknown";
310 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
311 return "kernel syscall";
312 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
313 return "kernel kprobe";
314 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
315 return "kernel uprobe";
316 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
317 return "kernel tracepoint";
318 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
319 return "user tracepoint";
320 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
321 return "jul logging";
322 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
323 return "log4j logging";
324 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
325 return "python logging";
326
327 default:
328 abort();
329 }
330 }
331
332 unsigned long lttng_event_rule_hash(const struct lttng_event_rule *rule)
333 {
334 LTTNG_ASSERT(rule->hash);
335 return rule->hash(rule);
336 }
337
338 enum lttng_error_code lttng_event_rule_mi_serialize(const struct lttng_event_rule *rule,
339 struct mi_writer *writer)
340 {
341 int ret;
342 enum lttng_error_code ret_code;
343
344 LTTNG_ASSERT(rule);
345 LTTNG_ASSERT(writer);
346 LTTNG_ASSERT(rule->mi_serialize);
347
348 /* Open event rule element. */
349 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule);
350 if (ret) {
351 goto mi_error;
352 }
353
354 /* Serialize underlying event rule. */
355 ret_code = rule->mi_serialize(rule, writer);
356 if (ret_code != LTTNG_OK) {
357 goto end;
358 }
359
360 /* Close event rule element. */
361 ret = mi_lttng_writer_close_element(writer);
362 if (ret) {
363 goto mi_error;
364 }
365
366 ret_code = LTTNG_OK;
367 goto end;
368
369 mi_error:
370 ret_code = LTTNG_ERR_MI_IO_FAIL;
371 end:
372 return ret_code;
373 }
This page took 0.035858 seconds and 4 git commands to generate.