Rename lttng_condition_event_rule to lttng_condition_on_event
[lttng-tools.git] / src / common / conditions / event-rule.c
CommitLineData
683d081a
JR
1/*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <assert.h>
9#include <common/error.h>
834966af 10#include <common/event-expr-to-bytecode.h>
683d081a 11#include <common/macros.h>
38114013 12#include <inttypes.h>
7c920b63 13#include <limits.h>
683d081a 14#include <lttng/condition/condition-internal.h>
834966af 15#include <lttng/event-rule/event-rule-internal.h>
683d081a
JR
16#include <lttng/condition/event-rule-internal.h>
17#include <lttng/condition/event-rule.h>
38114013
PP
18#include <lttng/event-expr-internal.h>
19#include <lttng/event-expr.h>
7c920b63
PP
20#include <lttng/event-field-value-internal.h>
21#include <lttng/event-rule/event-rule-internal.h>
834966af 22#include <lttng/lttng-error.h>
683d081a 23#include <stdbool.h>
38114013 24#include <stdint.h>
116a02e3 25#include <vendor/msgpack/msgpack.h>
683d081a 26
d602bd6a 27#define IS_ON_EVENT_CONDITION(condition) \
683d081a 28 (lttng_condition_get_type(condition) == \
d602bd6a 29 LTTNG_CONDITION_TYPE_ON_EVENT)
683d081a 30
d602bd6a 31static bool is_on_event_evaluation(const struct lttng_evaluation *evaluation)
683d081a
JR
32{
33 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
34
d602bd6a 35 return type == LTTNG_CONDITION_TYPE_ON_EVENT;
683d081a
JR
36}
37
d602bd6a 38static bool lttng_condition_on_event_validate(
683d081a 39 const struct lttng_condition *condition);
d602bd6a 40static int lttng_condition_on_event_serialize(
683d081a
JR
41 const struct lttng_condition *condition,
42 struct lttng_payload *payload);
d602bd6a 43static bool lttng_condition_on_event_is_equal(
683d081a
JR
44 const struct lttng_condition *_a,
45 const struct lttng_condition *_b);
d602bd6a 46static void lttng_condition_on_event_destroy(
683d081a
JR
47 struct lttng_condition *condition);
48
d602bd6a 49static bool lttng_condition_on_event_validate(
683d081a
JR
50 const struct lttng_condition *condition)
51{
52 bool valid = false;
d602bd6a 53 struct lttng_condition_on_event *event_rule;
683d081a
JR
54
55 if (!condition) {
56 goto end;
57 }
58
59 event_rule = container_of(
d602bd6a 60 condition, struct lttng_condition_on_event, parent);
683d081a 61 if (!event_rule->rule) {
d602bd6a 62 ERR("Invalid on event condition: a rule must be set");
683d081a
JR
63 goto end;
64 }
65
66 valid = lttng_event_rule_validate(event_rule->rule);
67end:
68 return valid;
69}
70
7c920b63
PP
71static const char *msgpack_object_type_str(msgpack_object_type type)
72{
73 const char *name;
74
75 switch (type) {
76 case MSGPACK_OBJECT_NIL:
77 name = "MSGPACK_OBJECT_NIL";
78 break;
79 case MSGPACK_OBJECT_BOOLEAN:
80 name = "MSGPACK_OBJECT_BOOLEAN";
81 break;
82 case MSGPACK_OBJECT_POSITIVE_INTEGER:
83 name = "MSGPACK_OBJECT_POSITIVE_INTEGER";
84 break;
85 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
86 name = "MSGPACK_OBJECT_NEGATIVE_INTEGER";
87 break;
88 case MSGPACK_OBJECT_FLOAT32:
89 name = "MSGPACK_OBJECT_FLOAT32";
90 break;
91 case MSGPACK_OBJECT_FLOAT:
92 /* Same value as MSGPACK_OBJECT_FLOAT64 */
93 name = "MSGPACK_OBJECT_FLOAT(64)";
94 break;
95 case MSGPACK_OBJECT_STR:
96 name = "MSGPACK_OBJECT_STR";
97 break;
98 case MSGPACK_OBJECT_ARRAY:
99 name = "MSGPACK_OBJECT_ARRAY";
100 break;
101 case MSGPACK_OBJECT_MAP:
102 name = "MSGPACK_OBJECT_MAP";
103 break;
104 case MSGPACK_OBJECT_BIN:
105 name = "MSGPACK_OBJECT_BIN";
106 break;
107 case MSGPACK_OBJECT_EXT:
108 name = "MSGPACK_OBJECT_EXT";
109 break;
110 default:
111 abort();
112 }
113
114 return name;
115}
116
38114013
PP
117/*
118 * Serializes the C string `str` into `buf`.
119 *
120 * Encoding is the length of `str` plus one (for the null character),
121 * and then the string, including its null terminator.
122 */
123static
124int serialize_cstr(const char *str, struct lttng_dynamic_buffer *buf)
125{
126 int ret;
127 const uint32_t len = strlen(str) + 1;
128
129 /* Serialize the length, including the null terminator. */
130 DBG("Serializing C string's length (including null terminator): "
131 "%" PRIu32, len);
132 ret = lttng_dynamic_buffer_append(buf, &len, sizeof(len));
133 if (ret) {
134 goto end;
135 }
136
137 /* Serialize the string. */
138 DBG("Serializing C string: '%s'", str);
139 ret = lttng_dynamic_buffer_append(buf, str, len);
140 if (ret) {
141 goto end;
142 }
143
144end:
145 return ret;
146}
147
148/*
149 * Serializes the event expression `expr` into `buf`.
150 */
151static
152int serialize_event_expr(const struct lttng_event_expr *expr,
153 struct lttng_payload *payload)
154{
155 const uint8_t type = expr->type;
156 int ret;
157
158 /* Serialize the expression's type. */
159 DBG("Serializing event expression's type: %d", expr->type);
160 ret = lttng_dynamic_buffer_append(&payload->buffer, &type, sizeof(type));
161 if (ret) {
162 goto end;
163 }
164
165 /* Serialize the expression */
166 switch (expr->type) {
167 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
168 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
169 {
170 const struct lttng_event_expr_field *field_expr =
171 container_of(expr,
172 const struct lttng_event_expr_field,
173 parent);
174
175 /* Serialize the field name. */
176 DBG("Serializing field event expression's field name: '%s'",
177 field_expr->name);
178 ret = serialize_cstr(field_expr->name, &payload->buffer);
179 if (ret) {
180 goto end;
181 }
182
183 break;
184 }
185 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
186 {
187 const struct lttng_event_expr_app_specific_context_field *field_expr =
188 container_of(expr,
189 const struct lttng_event_expr_app_specific_context_field,
190 parent);
191
192 /* Serialize the provider name. */
193 DBG("Serializing app-specific context field event expression's "
194 "provider name: '%s'",
195 field_expr->provider_name);
196 ret = serialize_cstr(field_expr->provider_name, &payload->buffer);
197 if (ret) {
198 goto end;
199 }
200
201 /* Serialize the type name. */
202 DBG("Serializing app-specific context field event expression's "
203 "type name: '%s'",
204 field_expr->provider_name);
205 ret = serialize_cstr(field_expr->type_name, &payload->buffer);
206 if (ret) {
207 goto end;
208 }
209
210 break;
211 }
212 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
213 {
214 const struct lttng_event_expr_array_field_element *elem_expr =
215 container_of(expr,
216 const struct lttng_event_expr_array_field_element,
217 parent);
218 const uint32_t index = elem_expr->index;
219
220 /* Serialize the index. */
221 DBG("Serializing array field element event expression's "
222 "index: %u", elem_expr->index);
223 ret = lttng_dynamic_buffer_append(&payload->buffer, &index, sizeof(index));
224 if (ret) {
225 goto end;
226 }
227
228 /* Serialize the parent array field expression. */
229 DBG("Serializing array field element event expression's "
7c920b63 230 "parent array field event expression");
38114013
PP
231 ret = serialize_event_expr(elem_expr->array_field_expr, payload);
232 if (ret) {
233 goto end;
234 }
235
236 break;
237 }
238 default:
239 break;
240 }
241
242end:
243 return ret;
244}
245
6fb7c690
JR
246static
247struct lttng_capture_descriptor *
d602bd6a 248lttng_condition_on_event_get_internal_capture_descriptor_at_index(
6fb7c690
JR
249 const struct lttng_condition *condition, unsigned int index)
250{
d602bd6a 251 const struct lttng_condition_on_event *on_event_cond =
6fb7c690 252 container_of(condition,
d602bd6a 253 const struct lttng_condition_on_event,
6fb7c690
JR
254 parent);
255 struct lttng_capture_descriptor *desc = NULL;
256 unsigned int count;
257 enum lttng_condition_status status;
258
d602bd6a 259 if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
6fb7c690
JR
260 goto end;
261 }
262
d602bd6a 263 status = lttng_condition_on_event_get_capture_descriptor_count(
6fb7c690
JR
264 condition, &count);
265 if (status != LTTNG_CONDITION_STATUS_OK) {
266 goto end;
267 }
268
269 if (index >= count) {
270 goto end;
271 }
272
273 desc = lttng_dynamic_pointer_array_get_pointer(
d602bd6a 274 &on_event_cond->capture_descriptors, index);
6fb7c690
JR
275end:
276 return desc;
277}
278
d602bd6a 279static int lttng_condition_on_event_serialize(
683d081a
JR
280 const struct lttng_condition *condition,
281 struct lttng_payload *payload)
282{
283 int ret;
d602bd6a 284 struct lttng_condition_on_event *on_event_condition;
0912b5ea 285 enum lttng_condition_status status;
38114013
PP
286 /* Used for iteration and communication (size matters). */
287 uint32_t i, capture_descr_count;
683d081a 288
d602bd6a 289 if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
683d081a
JR
290 ret = -1;
291 goto end;
292 }
293
d602bd6a
JR
294 DBG("Serializing on event condition");
295 on_event_condition = container_of(
296 condition, struct lttng_condition_on_event, parent);
683d081a 297
d602bd6a
JR
298 DBG("Serializing on event condition's event rule");
299 ret = lttng_event_rule_serialize(on_event_condition->rule, payload);
683d081a
JR
300 if (ret) {
301 goto end;
302 }
303
d602bd6a 304 status = lttng_condition_on_event_get_capture_descriptor_count(
0912b5ea
JR
305 condition, &capture_descr_count);
306 if (status != LTTNG_CONDITION_STATUS_OK) {
307 ret = -1;
308 goto end;
309 };
310
d602bd6a 311 DBG("Serializing on event condition's capture descriptor count: %" PRIu32,
38114013
PP
312 capture_descr_count);
313 ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count,
314 sizeof(capture_descr_count));
683d081a
JR
315 if (ret) {
316 goto end;
317 }
318
38114013 319 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 320 const struct lttng_capture_descriptor *desc =
d602bd6a 321 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
0912b5ea 322 condition, i);
38114013 323
d602bd6a 324 DBG("Serializing on event condition's capture descriptor %" PRIu32,
38114013 325 i);
6fb7c690 326 ret = serialize_event_expr(desc->event_expression, payload);
38114013
PP
327 if (ret) {
328 goto end;
329 }
330 }
683d081a
JR
331
332end:
333 return ret;
334}
335
38114013
PP
336static
337bool capture_descriptors_are_equal(
0912b5ea
JR
338 const struct lttng_condition *condition_a,
339 const struct lttng_condition *condition_b)
38114013
PP
340{
341 bool is_equal = true;
0912b5ea
JR
342 unsigned int capture_descr_count_a;
343 unsigned int capture_descr_count_b;
38114013 344 size_t i;
0912b5ea 345 enum lttng_condition_status status;
38114013 346
d602bd6a 347 status = lttng_condition_on_event_get_capture_descriptor_count(
0912b5ea
JR
348 condition_a, &capture_descr_count_a);
349 if (status != LTTNG_CONDITION_STATUS_OK) {
350 goto not_equal;
351 }
352
d602bd6a 353 status = lttng_condition_on_event_get_capture_descriptor_count(
0912b5ea
JR
354 condition_b, &capture_descr_count_b);
355 if (status != LTTNG_CONDITION_STATUS_OK) {
356 goto not_equal;
357 }
38114013
PP
358
359 if (capture_descr_count_a != capture_descr_count_b) {
360 goto not_equal;
361 }
362
363 for (i = 0; i < capture_descr_count_a; i++) {
364 const struct lttng_event_expr *expr_a =
d602bd6a 365 lttng_condition_on_event_get_capture_descriptor_at_index(
0912b5ea 366 condition_a,
38114013
PP
367 i);
368 const struct lttng_event_expr *expr_b =
d602bd6a 369 lttng_condition_on_event_get_capture_descriptor_at_index(
0912b5ea 370 condition_b,
38114013
PP
371 i);
372
373 if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
374 goto not_equal;
375 }
376 }
377
378 goto end;
379
380not_equal:
381 is_equal = false;
382
383end:
384 return is_equal;
385}
386
d602bd6a 387static bool lttng_condition_on_event_is_equal(
683d081a
JR
388 const struct lttng_condition *_a,
389 const struct lttng_condition *_b)
390{
391 bool is_equal = false;
d602bd6a 392 struct lttng_condition_on_event *a, *b;
683d081a 393
d602bd6a
JR
394 a = container_of(_a, struct lttng_condition_on_event, parent);
395 b = container_of(_b, struct lttng_condition_on_event, parent);
683d081a
JR
396
397 /* Both event rules must be set or both must be unset. */
398 if ((a->rule && !b->rule) || (!a->rule && b->rule)) {
399 WARN("Comparing event_rule conditions with uninitialized rule");
400 goto end;
401 }
402
403 is_equal = lttng_event_rule_is_equal(a->rule, b->rule);
38114013
PP
404 if (!is_equal) {
405 goto end;
406 }
407
0912b5ea 408 is_equal = capture_descriptors_are_equal(_a, _b);
38114013 409
683d081a
JR
410end:
411 return is_equal;
412}
413
d602bd6a 414static void lttng_condition_on_event_destroy(
683d081a
JR
415 struct lttng_condition *condition)
416{
d602bd6a 417 struct lttng_condition_on_event *on_event_condition;
683d081a 418
d602bd6a
JR
419 on_event_condition = container_of(
420 condition, struct lttng_condition_on_event, parent);
683d081a 421
d602bd6a
JR
422 lttng_event_rule_put(on_event_condition->rule);
423 lttng_dynamic_pointer_array_reset(&on_event_condition->capture_descriptors);
424 free(on_event_condition);
683d081a
JR
425}
426
38114013 427static
0912b5ea 428void destroy_capture_descriptor(void *ptr)
38114013 429{
0912b5ea
JR
430 struct lttng_capture_descriptor *desc =
431 (struct lttng_capture_descriptor *) ptr;
432
433 lttng_event_expr_destroy(desc->event_expression);
434 free(desc->bytecode);
435 free(desc);
38114013
PP
436}
437
d602bd6a 438struct lttng_condition *lttng_condition_on_event_create(
683d081a
JR
439 struct lttng_event_rule *rule)
440{
441 struct lttng_condition *parent = NULL;
d602bd6a 442 struct lttng_condition_on_event *condition = NULL;
683d081a
JR
443
444 if (!rule) {
445 goto end;
446 }
447
d602bd6a 448 condition = zmalloc(sizeof(struct lttng_condition_on_event));
683d081a
JR
449 if (!condition) {
450 return NULL;
451 }
452
453 lttng_condition_init(&condition->parent,
d602bd6a
JR
454 LTTNG_CONDITION_TYPE_ON_EVENT);
455 condition->parent.validate = lttng_condition_on_event_validate,
456 condition->parent.serialize = lttng_condition_on_event_serialize,
457 condition->parent.equal = lttng_condition_on_event_is_equal,
458 condition->parent.destroy = lttng_condition_on_event_destroy,
683d081a
JR
459
460 lttng_event_rule_get(rule);
461 condition->rule = rule;
462 rule = NULL;
463
38114013 464 lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
0912b5ea 465 destroy_capture_descriptor);
38114013 466
683d081a
JR
467 parent = &condition->parent;
468end:
469 return parent;
470}
471
38114013
PP
472static
473uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size,
474 size_t *offset)
475{
476 uint64_t ret;
477 const struct lttng_buffer_view uint_view =
478 lttng_buffer_view_from_view(view, *offset, size);
479
480 if (!lttng_buffer_view_is_valid(&uint_view)) {
481 ret = UINT64_C(-1);
482 goto end;
483 }
484
485 switch (size) {
486 case 1:
487 ret = (uint64_t) *uint_view.data;
488 break;
489 case sizeof(uint32_t):
490 {
491 uint32_t u32;
492
493 memcpy(&u32, uint_view.data, sizeof(u32));
494 ret = (uint64_t) u32;
495 break;
496 }
497 case sizeof(ret):
498 memcpy(&ret, uint_view.data, sizeof(ret));
499 break;
500 default:
501 abort();
502 }
503
504 *offset += size;
505
506end:
507 return ret;
508}
509
510static
511const char *str_from_buffer(const struct lttng_buffer_view *view,
512 size_t *offset)
513{
514 uint64_t len;
515 const char *ret;
516
517 len = uint_from_buffer(view, sizeof(uint32_t), offset);
518 if (len == UINT64_C(-1)) {
519 goto error;
520 }
521
522 ret = &view->data[*offset];
523
524 if (!lttng_buffer_view_contains_string(view, ret, len)) {
525 goto error;
526 }
527
528 *offset += len;
529 goto end;
530
531error:
532 ret = NULL;
533
534end:
535 return ret;
536}
537
538static
539struct lttng_event_expr *event_expr_from_payload(
540 struct lttng_payload_view *view, size_t *offset)
541{
542 struct lttng_event_expr *expr = NULL;
543 const char *str;
544 uint64_t type;
545
546 type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
547 if (type == UINT64_C(-1)) {
548 goto error;
549 }
550
551 switch (type) {
552 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
553 str = str_from_buffer(&view->buffer, offset);
554 if (!str) {
555 goto error;
556 }
557
558 expr = lttng_event_expr_event_payload_field_create(str);
559 break;
560 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
561 str = str_from_buffer(&view->buffer, offset);
562 if (!str) {
563 goto error;
564 }
565
566 expr = lttng_event_expr_channel_context_field_create(str);
567 break;
568 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
569 {
570 const char *provider_name;
571 const char *type_name;
572
573 provider_name = str_from_buffer(&view->buffer, offset);
574 if (!provider_name) {
575 goto error;
576 }
577
578 type_name = str_from_buffer(&view->buffer, offset);
579 if (!type_name) {
580 goto error;
581 }
582
583 expr = lttng_event_expr_app_specific_context_field_create(
584 provider_name, type_name);
585 break;
586 }
587 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
588 {
589 struct lttng_event_expr *array_field_expr;
590 const uint64_t index = uint_from_buffer(
591 &view->buffer, sizeof(uint32_t), offset);
592
593 if (index == UINT64_C(-1)) {
594 goto error;
595 }
596
597 /* Array field expression is the encoded after this. */
598 array_field_expr = event_expr_from_payload(view, offset);
599 if (!array_field_expr) {
600 goto error;
601 }
602
603 /* Move ownership of `array_field_expr` to new expression. */
604 expr = lttng_event_expr_array_field_element_create(
605 array_field_expr, (unsigned int) index);
606 if (!expr) {
607 /* `array_field_expr` not moved: destroy it. */
608 lttng_event_expr_destroy(array_field_expr);
609 }
610
611 break;
612 }
613 default:
614 abort();
615 }
616
617 goto end;
618
619error:
620 lttng_event_expr_destroy(expr);
621 expr = NULL;
622
623end:
624 return expr;
625}
626
683d081a 627LTTNG_HIDDEN
d602bd6a 628ssize_t lttng_condition_on_event_create_from_payload(
683d081a
JR
629 struct lttng_payload_view *view,
630 struct lttng_condition **_condition)
631{
38114013
PP
632 ssize_t consumed_length;
633 size_t offset = 0;
634 ssize_t event_rule_length;
635 uint32_t i, capture_descr_count;
683d081a
JR
636 struct lttng_condition *condition = NULL;
637 struct lttng_event_rule *event_rule = NULL;
683d081a
JR
638
639 if (!view || !_condition) {
640 goto error;
641 }
642
38114013 643 /* Struct lttng_event_rule. */
683d081a
JR
644 {
645 struct lttng_payload_view event_rule_view =
646 lttng_payload_view_from_view(view, offset, -1);
647
648 event_rule_length = lttng_event_rule_create_from_payload(
649 &event_rule_view, &event_rule);
650 }
651
652 if (event_rule_length < 0 || !event_rule) {
653 goto error;
654 }
655
d602bd6a
JR
656 /* Create condition (no capture descriptors yet) at this point */
657 condition = lttng_condition_on_event_create(event_rule);
38114013 658 if (!condition) {
683d081a
JR
659 goto error;
660 }
661
38114013
PP
662 /* Capture descriptor count. */
663 assert(event_rule_length >= 0);
664 offset += (size_t) event_rule_length;
665 capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
666 if (capture_descr_count == UINT32_C(-1)) {
683d081a
JR
667 goto error;
668 }
669
38114013
PP
670 /* Capture descriptors. */
671 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 672 enum lttng_condition_status status;
38114013
PP
673 struct lttng_event_expr *expr = event_expr_from_payload(
674 view, &offset);
38114013
PP
675
676 if (!expr) {
677 goto error;
678 }
679
680 /* Move ownership of `expr` to `condition`. */
d602bd6a 681 status = lttng_condition_on_event_append_capture_descriptor(
38114013
PP
682 condition, expr);
683 if (status != LTTNG_CONDITION_STATUS_OK) {
684 /* `expr` not moved: destroy it. */
685 lttng_event_expr_destroy(expr);
686 goto error;
687 }
688 }
689
690 consumed_length = (ssize_t) offset;
683d081a
JR
691 *_condition = condition;
692 condition = NULL;
693 goto end;
694
695error:
38114013 696 consumed_length = -1;
683d081a
JR
697
698end:
699 lttng_event_rule_put(event_rule);
700 lttng_condition_put(condition);
38114013 701 return consumed_length;
683d081a
JR
702}
703
704LTTNG_HIDDEN
d602bd6a 705enum lttng_condition_status lttng_condition_on_event_borrow_rule_mutable(
683d081a
JR
706 const struct lttng_condition *condition,
707 struct lttng_event_rule **rule)
708{
d602bd6a 709 struct lttng_condition_on_event *event_rule;
683d081a
JR
710 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
711
d602bd6a 712 if (!condition || !IS_ON_EVENT_CONDITION(condition) || !rule) {
683d081a
JR
713 status = LTTNG_CONDITION_STATUS_INVALID;
714 goto end;
715 }
716
717 event_rule = container_of(
d602bd6a 718 condition, struct lttng_condition_on_event, parent);
683d081a
JR
719 if (!event_rule->rule) {
720 status = LTTNG_CONDITION_STATUS_UNSET;
721 goto end;
722 }
723
724 *rule = event_rule->rule;
725end:
726 return status;
727}
728
d602bd6a 729enum lttng_condition_status lttng_condition_on_event_get_rule(
683d081a
JR
730 const struct lttng_condition *condition,
731 const struct lttng_event_rule **rule)
732{
733 struct lttng_event_rule *mutable_rule = NULL;
734 const enum lttng_condition_status status =
d602bd6a 735 lttng_condition_on_event_borrow_rule_mutable(
683d081a
JR
736 condition, &mutable_rule);
737
738 *rule = mutable_rule;
739 return status;
740}
741
38114013 742enum lttng_condition_status
d602bd6a 743lttng_condition_on_event_append_capture_descriptor(
38114013
PP
744 struct lttng_condition *condition,
745 struct lttng_event_expr *expr)
746{
747 int ret;
748 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
d602bd6a 749 struct lttng_condition_on_event *event_rule_cond =
38114013 750 container_of(condition,
d602bd6a 751 struct lttng_condition_on_event, parent);
0912b5ea 752 struct lttng_capture_descriptor *descriptor = NULL;
81d566c9 753 const struct lttng_event_rule *rule = NULL;
38114013
PP
754
755 /* Only accept l-values. */
d602bd6a 756 if (!condition || !IS_ON_EVENT_CONDITION(condition) || !expr ||
38114013
PP
757 !lttng_event_expr_is_lvalue(expr)) {
758 status = LTTNG_CONDITION_STATUS_INVALID;
81d566c9
JR
759 goto end;
760 }
761
d602bd6a 762 status = lttng_condition_on_event_get_rule(condition, &rule);
81d566c9
JR
763 if (status != LTTNG_CONDITION_STATUS_OK) {
764 goto end;
765 }
766
767 switch(lttng_event_rule_get_type(rule)) {
768 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
769 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
770 /* Supported. */
771 status = LTTNG_CONDITION_STATUS_OK;
772 break;
773 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
774 status = LTTNG_CONDITION_STATUS_INVALID;
775 break;
776 default:
777 status = LTTNG_CONDITION_STATUS_UNSUPPORTED;
778 break;
779 }
780
781 if (status != LTTNG_CONDITION_STATUS_OK) {
38114013
PP
782 goto end;
783 }
784
0912b5ea
JR
785 descriptor = malloc(sizeof(*descriptor));
786 if (descriptor == NULL) {
787 status = LTTNG_CONDITION_STATUS_ERROR;
788 goto end;
789 }
790
791 descriptor->event_expression = expr;
792 descriptor->bytecode = NULL;
793
38114013 794 ret = lttng_dynamic_pointer_array_add_pointer(
0912b5ea 795 &event_rule_cond->capture_descriptors, descriptor);
38114013
PP
796 if (ret) {
797 status = LTTNG_CONDITION_STATUS_ERROR;
798 goto end;
799 }
800
0912b5ea
JR
801 /* Ownership is transfered to the internal capture_descriptors array */
802 descriptor = NULL;
38114013 803end:
0912b5ea 804 free(descriptor);
38114013
PP
805 return status;
806}
807
808enum lttng_condition_status
d602bd6a 809lttng_condition_on_event_get_capture_descriptor_count(
38114013
PP
810 const struct lttng_condition *condition, unsigned int *count)
811{
812 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
d602bd6a 813 const struct lttng_condition_on_event *on_event_condition =
38114013 814 container_of(condition,
d602bd6a 815 const struct lttng_condition_on_event,
38114013
PP
816 parent);
817
d602bd6a 818 if (!condition || !IS_ON_EVENT_CONDITION(condition) || !count) {
38114013
PP
819 status = LTTNG_CONDITION_STATUS_INVALID;
820 goto end;
821 }
822
823 *count = lttng_dynamic_pointer_array_get_count(
d602bd6a 824 &on_event_condition->capture_descriptors);
38114013
PP
825
826end:
827 return status;
828}
829
830const struct lttng_event_expr *
d602bd6a 831lttng_condition_on_event_get_capture_descriptor_at_index(
38114013
PP
832 const struct lttng_condition *condition, unsigned int index)
833{
38114013 834 const struct lttng_event_expr *expr = NULL;
6fb7c690 835 const struct lttng_capture_descriptor *desc = NULL;
0912b5ea 836
d602bd6a 837 desc = lttng_condition_on_event_get_internal_capture_descriptor_at_index(
6fb7c690
JR
838 condition, index);
839 if (desc == NULL) {
38114013
PP
840 goto end;
841 }
0912b5ea 842 expr = desc->event_expression;
38114013
PP
843
844end:
845 return expr;
846}
847
683d081a 848LTTNG_HIDDEN
d602bd6a
JR
849ssize_t lttng_evaluation_on_event_create_from_payload(
850 const struct lttng_condition_on_event *condition,
683d081a
JR
851 struct lttng_payload_view *view,
852 struct lttng_evaluation **_evaluation)
853{
854 ssize_t ret, offset = 0;
855 const char *trigger_name;
856 struct lttng_evaluation *evaluation = NULL;
d602bd6a 857 const struct lttng_evaluation_on_event_comm *header;
683d081a
JR
858 const struct lttng_payload_view header_view =
859 lttng_payload_view_from_view(
860 view, 0, sizeof(*header));
7c920b63
PP
861 uint32_t capture_payload_size;
862 const char *capture_payload = NULL;
683d081a
JR
863
864 if (!_evaluation) {
865 ret = -1;
866 goto error;
867 }
868
869 if (!lttng_payload_view_is_valid(&header_view)) {
870 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
871 ret = -1;
872 goto error;
873 }
874
875 header = (typeof(header)) header_view.buffer.data;
876
877 /* Map the originating trigger's name. */
878 offset += sizeof(*header);
879 {
7c920b63 880 const struct lttng_payload_view current_view =
683d081a
JR
881 lttng_payload_view_from_view(view, offset,
882 header->trigger_name_length);
883
884 if (!lttng_payload_view_is_valid(&current_view)) {
885 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
886 ret = -1;
887 goto error;
888 }
889
890 trigger_name = current_view.buffer.data;
891 if (!lttng_buffer_view_contains_string(&current_view.buffer,
892 trigger_name, header->trigger_name_length)) {
893 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
894 ret = -1;
895 goto error;
896 }
897 }
898
899 offset += header->trigger_name_length;
7c920b63
PP
900 {
901 const struct lttng_payload_view current_view =
902 lttng_payload_view_from_view(view, offset, -1);
903
904 if (current_view.buffer.size < sizeof(capture_payload_size)) {
905 ret = -1;
906 goto error;
907 }
683d081a 908
7c920b63
PP
909 memcpy(&capture_payload_size, current_view.buffer.data,
910 sizeof(capture_payload_size));
911 }
912 offset += sizeof(capture_payload_size);
913
914 if (capture_payload_size > 0) {
915 const struct lttng_payload_view current_view =
916 lttng_payload_view_from_view(view, offset, -1);
917
918 if (current_view.buffer.size < capture_payload_size) {
919 ret = -1;
920 goto error;
921 }
922
923 capture_payload = current_view.buffer.data;
924 }
925
d602bd6a 926 evaluation = lttng_evaluation_on_event_create(condition, trigger_name,
7c920b63 927 capture_payload, capture_payload_size, true);
683d081a
JR
928 if (!evaluation) {
929 ret = -1;
930 goto error;
931 }
932
7c920b63 933 offset += capture_payload_size;
683d081a
JR
934 *_evaluation = evaluation;
935 evaluation = NULL;
936 ret = offset;
937
938error:
939 lttng_evaluation_destroy(evaluation);
940 return ret;
941}
942
d602bd6a 943static int lttng_evaluation_on_event_serialize(
683d081a
JR
944 const struct lttng_evaluation *evaluation,
945 struct lttng_payload *payload)
946{
947 int ret = 0;
d602bd6a
JR
948 struct lttng_evaluation_on_event *hit;
949 struct lttng_evaluation_on_event_comm comm;
7c920b63 950 uint32_t capture_payload_size;
683d081a
JR
951
952 hit = container_of(
d602bd6a 953 evaluation, struct lttng_evaluation_on_event, parent);
683d081a
JR
954
955 assert(hit->name);
956 comm.trigger_name_length = strlen(hit->name) + 1;
957
958 ret = lttng_dynamic_buffer_append(
959 &payload->buffer, &comm, sizeof(comm));
960 if (ret) {
961 goto end;
962 }
963
964 ret = lttng_dynamic_buffer_append(
965 &payload->buffer, hit->name, comm.trigger_name_length);
7c920b63
PP
966 if (ret) {
967 goto end;
968 }
969
970 capture_payload_size = (uint32_t) hit->capture_payload.size;
971 ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_payload_size,
972 sizeof(capture_payload_size));
973 if (ret) {
974 goto end;
975 }
976
977 ret = lttng_dynamic_buffer_append(&payload->buffer, hit->capture_payload.data,
978 hit->capture_payload.size);
979 if (ret) {
980 goto end;
981 }
982
983end:
984 return ret;
985}
986
987static
988bool msgpack_str_is_equal(const struct msgpack_object *obj, const char *str)
989{
990 bool is_equal = true;
991
992 assert(obj->type == MSGPACK_OBJECT_STR);
993
994 if (obj->via.str.size != strlen(str)) {
995 is_equal = false;
996 goto end;
997 }
998
999 if (strncmp(obj->via.str.ptr, str, obj->via.str.size) != 0) {
1000 is_equal = false;
1001 goto end;
1002 }
1003
1004end:
1005 return is_equal;
1006}
1007
1008static
1009const msgpack_object *get_msgpack_map_obj(const struct msgpack_object *map_obj,
1010 const char *name)
1011{
1012 const msgpack_object *ret = NULL;
1013 size_t i;
1014
1015 assert(map_obj->type == MSGPACK_OBJECT_MAP);
1016
1017 for (i = 0; i < map_obj->via.map.size; i++) {
1018 const struct msgpack_object_kv *kv = &map_obj->via.map.ptr[i];
1019
1020 assert(kv->key.type == MSGPACK_OBJECT_STR);
1021
1022 if (msgpack_str_is_equal(&kv->key, name)) {
1023 ret = &kv->val;
1024 goto end;
1025 }
1026 }
1027
683d081a
JR
1028end:
1029 return ret;
1030}
1031
d602bd6a 1032static void lttng_evaluation_on_event_destroy(
683d081a
JR
1033 struct lttng_evaluation *evaluation)
1034{
d602bd6a 1035 struct lttng_evaluation_on_event *hit;
683d081a
JR
1036
1037 hit = container_of(
d602bd6a 1038 evaluation, struct lttng_evaluation_on_event, parent);
683d081a 1039 free(hit->name);
7c920b63
PP
1040 lttng_dynamic_buffer_reset(&hit->capture_payload);
1041 lttng_event_field_value_destroy(hit->captured_values);
683d081a
JR
1042 free(hit);
1043}
1044
7c920b63
PP
1045static
1046int event_field_value_from_obj(const msgpack_object *obj,
1047 struct lttng_event_field_value **field_val)
1048{
1049 int ret = 0;
1050
1051 assert(obj);
1052 assert(field_val);
1053
1054 switch (obj->type) {
1055 case MSGPACK_OBJECT_NIL:
1056 /* Unavailable. */
1057 *field_val = NULL;
1058 goto end;
1059 case MSGPACK_OBJECT_POSITIVE_INTEGER:
1060 *field_val = lttng_event_field_value_uint_create(
1061 obj->via.u64);
1062 break;
1063 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
1064 *field_val = lttng_event_field_value_int_create(
1065 obj->via.i64);
1066 break;
1067 case MSGPACK_OBJECT_FLOAT32:
1068 case MSGPACK_OBJECT_FLOAT64:
1069 *field_val = lttng_event_field_value_real_create(
1070 obj->via.f64);
1071 break;
1072 case MSGPACK_OBJECT_STR:
1073 *field_val = lttng_event_field_value_string_create_with_size(
1074 obj->via.str.ptr, obj->via.str.size);
1075 break;
1076 case MSGPACK_OBJECT_ARRAY:
1077 {
1078 size_t i;
1079
1080 *field_val = lttng_event_field_value_array_create();
1081 if (!*field_val) {
1082 goto error;
1083 }
1084
1085 for (i = 0; i < obj->via.array.size; i++) {
1086 const msgpack_object *elem_obj = &obj->via.array.ptr[i];
1087 struct lttng_event_field_value *elem_field_val;
1088
1089 ret = event_field_value_from_obj(elem_obj,
1090 &elem_field_val);
1091 if (ret) {
1092 goto error;
1093 }
1094
1095 if (elem_field_val) {
1096 ret = lttng_event_field_value_array_append(
1097 *field_val, elem_field_val);
1098 } else {
1099 ret = lttng_event_field_value_array_append_unavailable(
1100 *field_val);
1101 }
1102
1103 if (ret) {
1104 lttng_event_field_value_destroy(elem_field_val);
1105 goto error;
1106 }
1107 }
1108
1109 break;
1110 }
1111 case MSGPACK_OBJECT_MAP:
1112 {
1113 /*
1114 * As of this version, the only valid map object is
1115 * for an enumeration value, for example:
1116 *
1117 * type: enum
1118 * value: 177
1119 * labels:
1120 * - Labatt 50
1121 * - Molson Dry
1122 * - Carling Black Label
1123 */
1124 const msgpack_object *inner_obj;
1125 size_t label_i;
1126
1127 inner_obj = get_msgpack_map_obj(obj, "type");
1128 if (!inner_obj) {
1129 ERR("Missing `type` entry in map object");
1130 goto error;
1131 }
1132
1133 if (inner_obj->type != MSGPACK_OBJECT_STR) {
1134 ERR("Map object's `type` entry is not a string: type = %s",
1135 msgpack_object_type_str(inner_obj->type));
1136 goto error;
1137 }
1138
1139 if (!msgpack_str_is_equal(inner_obj, "enum")) {
1140 ERR("Map object's `type` entry: expecting `enum`");
1141 goto error;
1142 }
1143
1144 inner_obj = get_msgpack_map_obj(obj, "value");
1145 if (!inner_obj) {
1146 ERR("Missing `value` entry in map object");
1147 goto error;
1148 }
1149
1150 if (inner_obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
1151 *field_val = lttng_event_field_value_enum_uint_create(
1152 inner_obj->via.u64);
1153 } else if (inner_obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
1154 *field_val = lttng_event_field_value_enum_int_create(
1155 inner_obj->via.i64);
1156 } else {
1157 ERR("Map object's `value` entry is not an integer: type = %s",
1158 msgpack_object_type_str(inner_obj->type));
1159 goto error;
1160 }
1161
1162 if (!*field_val) {
1163 goto error;
1164 }
1165
1166 inner_obj = get_msgpack_map_obj(obj, "labels");
1167 if (!inner_obj) {
1168 /* No labels */
1169 goto end;
1170 }
1171
1172 if (inner_obj->type != MSGPACK_OBJECT_ARRAY) {
1173 ERR("Map object's `labels` entry is not an array: type = %s",
1174 msgpack_object_type_str(inner_obj->type));
1175 goto error;
1176 }
1177
1178 for (label_i = 0; label_i < inner_obj->via.array.size;
1179 label_i++) {
1180 int iret;
1181 const msgpack_object *elem_obj =
1182 &inner_obj->via.array.ptr[label_i];
1183
1184 if (elem_obj->type != MSGPACK_OBJECT_STR) {
1185 ERR("Map object's `labels` entry's type is not a string: type = %s",
1186 msgpack_object_type_str(elem_obj->type));
1187 goto error;
1188 }
1189
1190 iret = lttng_event_field_value_enum_append_label_with_size(
1191 *field_val, elem_obj->via.str.ptr,
1192 elem_obj->via.str.size);
1193 if (iret) {
1194 goto error;
1195 }
1196 }
1197
1198 break;
1199 }
1200 default:
1201 ERR("Unexpected object type: type = %s",
1202 msgpack_object_type_str(obj->type));
1203 goto error;
1204 }
1205
1206 if (!*field_val) {
1207 goto error;
1208 }
1209
1210 goto end;
1211
1212error:
1213 lttng_event_field_value_destroy(*field_val);
1214 *field_val = NULL;
1215 ret = -1;
1216
1217end:
1218 return ret;
1219}
1220
1221static
1222struct lttng_event_field_value *event_field_value_from_capture_payload(
d602bd6a 1223 const struct lttng_condition_on_event *condition,
7c920b63
PP
1224 const char *capture_payload, size_t capture_payload_size)
1225{
1226 struct lttng_event_field_value *ret = NULL;
1227 msgpack_unpacked unpacked;
1228 msgpack_unpack_return unpack_return;
1229 const msgpack_object *root_obj;
1230 const msgpack_object_array *root_array_obj;
1231 size_t i;
1232 size_t count;
1233
1234 assert(condition);
1235 assert(capture_payload);
1236
1237 /* Initialize value. */
1238 msgpack_unpacked_init(&unpacked);
1239
1240 /* Decode. */
1241 unpack_return = msgpack_unpack_next(&unpacked, capture_payload,
1242 capture_payload_size, NULL);
1243 if (unpack_return != MSGPACK_UNPACK_SUCCESS) {
1244 ERR("msgpack_unpack_next() failed to decode the "
1245 "MessagePack-encoded capture payload: "
1246 "size = %zu, ret = %d",
1247 capture_payload_size, unpack_return);
1248 goto error;
1249 }
1250
1251 /* Get root array. */
1252 root_obj = &unpacked.data;
1253
1254 if (root_obj->type != MSGPACK_OBJECT_ARRAY) {
1255 ERR("Expecting an array as the root object: type = %s",
1256 msgpack_object_type_str(root_obj->type));
1257 goto error;
1258 }
1259
1260 root_array_obj = &root_obj->via.array;
1261
1262 /* Create an empty root array event field value. */
1263 ret = lttng_event_field_value_array_create();
1264 if (!ret) {
1265 goto error;
1266 }
1267
1268 /*
1269 * For each capture descriptor in the condition object:
1270 *
1271 * 1. Get its corresponding captured field value MessagePack
1272 * object.
1273 *
1274 * 2. Create a corresponding event field value.
1275 *
1276 * 3. Append it to `ret` (the root array event field value).
1277 */
1278 count = lttng_dynamic_pointer_array_get_count(
1279 &condition->capture_descriptors);
1280 assert(count > 0);
1281
1282 for (i = 0; i < count; i++) {
1283 const struct lttng_capture_descriptor *capture_descriptor =
d602bd6a 1284 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
7c920b63
PP
1285 &condition->parent, i);
1286 const msgpack_object *elem_obj;
1287 struct lttng_event_field_value *elem_field_val;
1288 int iret;
1289
1290 assert(capture_descriptor);
1291
1292 elem_obj = &root_array_obj->ptr[i];
1293 iret = event_field_value_from_obj(elem_obj,
1294 &elem_field_val);
1295 if (iret) {
1296 goto error;
1297 }
1298
1299 if (elem_field_val) {
1300 iret = lttng_event_field_value_array_append(ret,
1301 elem_field_val);
1302 } else {
1303 iret = lttng_event_field_value_array_append_unavailable(
1304 ret);
1305 }
1306
1307 if (iret) {
1308 lttng_event_field_value_destroy(elem_field_val);
1309 goto error;
1310 }
1311 }
1312
1313 goto end;
1314
1315error:
1316 lttng_event_field_value_destroy(ret);
1317 ret = NULL;
1318
1319end:
1320 msgpack_unpacked_destroy(&unpacked);
1321 return ret;
1322}
1323
683d081a 1324LTTNG_HIDDEN
d602bd6a
JR
1325struct lttng_evaluation *lttng_evaluation_on_event_create(
1326 const struct lttng_condition_on_event *condition,
7c920b63
PP
1327 const char *trigger_name,
1328 const char *capture_payload, size_t capture_payload_size,
1329 bool decode_capture_payload)
683d081a 1330{
d602bd6a 1331 struct lttng_evaluation_on_event *hit;
683d081a
JR
1332 struct lttng_evaluation *evaluation = NULL;
1333
d602bd6a 1334 hit = zmalloc(sizeof(struct lttng_evaluation_on_event));
683d081a 1335 if (!hit) {
7c920b63 1336 goto error;
683d081a
JR
1337 }
1338
1339 hit->name = strdup(trigger_name);
1340 if (!hit->name) {
7c920b63
PP
1341 goto error;
1342 }
1343
1344 lttng_dynamic_buffer_init(&hit->capture_payload);
1345
1346 if (capture_payload) {
1347 const int ret = lttng_dynamic_buffer_append(
1348 &hit->capture_payload, capture_payload,
1349 capture_payload_size);
1350 if (ret) {
1351 ERR("Failed to initialize capture payload of event rule evaluation");
1352 goto error;
1353 }
1354
1355 if (decode_capture_payload) {
1356 hit->captured_values =
1357 event_field_value_from_capture_payload(
1358 condition,
1359 capture_payload,
1360 capture_payload_size);
1361 if (!hit->captured_values) {
1362 ERR("Failed to decode the capture payload: size = %zu",
1363 capture_payload_size);
1364 goto error;
1365 }
1366 }
683d081a
JR
1367 }
1368
d602bd6a
JR
1369 hit->parent.type = LTTNG_CONDITION_TYPE_ON_EVENT;
1370 hit->parent.serialize = lttng_evaluation_on_event_serialize;
1371 hit->parent.destroy = lttng_evaluation_on_event_destroy;
683d081a
JR
1372
1373 evaluation = &hit->parent;
1374 hit = NULL;
1375
7c920b63 1376error:
683d081a 1377 if (hit) {
d602bd6a 1378 lttng_evaluation_on_event_destroy(&hit->parent);
683d081a
JR
1379 }
1380
1381 return evaluation;
1382}
1383
d602bd6a 1384enum lttng_evaluation_status lttng_evaluation_on_event_get_captured_values(
7c920b63
PP
1385 const struct lttng_evaluation *evaluation,
1386 const struct lttng_event_field_value **field_val)
1387{
d602bd6a 1388 struct lttng_evaluation_on_event *hit;
7c920b63
PP
1389 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
1390
d602bd6a 1391 if (!evaluation || !is_on_event_evaluation(evaluation) ||
7c920b63
PP
1392 !field_val) {
1393 status = LTTNG_EVALUATION_STATUS_INVALID;
1394 goto end;
1395 }
1396
d602bd6a 1397 hit = container_of(evaluation, struct lttng_evaluation_on_event,
7c920b63
PP
1398 parent);
1399 if (!hit->captured_values) {
1400 status = LTTNG_EVALUATION_STATUS_INVALID;
1401 goto end;
1402 }
1403
1404 *field_val = hit->captured_values;
1405
1406end:
1407 return status;
1408}
1409
d602bd6a 1410enum lttng_evaluation_status lttng_evaluation_on_event_get_trigger_name(
683d081a
JR
1411 const struct lttng_evaluation *evaluation, const char **name)
1412{
d602bd6a 1413 struct lttng_evaluation_on_event *hit;
683d081a
JR
1414 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
1415
d602bd6a 1416 if (!evaluation || !is_on_event_evaluation(evaluation) || !name) {
683d081a
JR
1417 status = LTTNG_EVALUATION_STATUS_INVALID;
1418 goto end;
1419 }
1420
1421 hit = container_of(
d602bd6a 1422 evaluation, struct lttng_evaluation_on_event, parent);
683d081a
JR
1423 *name = hit->name;
1424end:
1425 return status;
1426}
834966af
JR
1427
1428LTTNG_HIDDEN
1429enum lttng_error_code
d602bd6a 1430lttng_condition_on_event_generate_capture_descriptor_bytecode(
834966af
JR
1431 struct lttng_condition *condition)
1432{
1433 enum lttng_error_code ret;
1434 enum lttng_condition_status status;
1435 unsigned int capture_count, i;
1436
d602bd6a 1437 if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
834966af
JR
1438 ret = LTTNG_ERR_FATAL;
1439 goto end;
1440 }
1441
d602bd6a 1442 status = lttng_condition_on_event_get_capture_descriptor_count(
834966af
JR
1443 condition, &capture_count);
1444 if (status != LTTNG_CONDITION_STATUS_OK) {
1445 ret = LTTNG_ERR_FATAL;
1446 goto end;
1447 }
1448
1449 for (i = 0; i < capture_count; i++) {
1450 struct lttng_capture_descriptor *local_capture_desc =
d602bd6a 1451 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
834966af
JR
1452 condition, i);
1453
1454 if (local_capture_desc == NULL) {
1455 ret = LTTNG_ERR_FATAL;
1456 goto end;
1457 }
1458
1459 /* Generate the bytecode. */
1460 status = lttng_event_expr_to_bytecode(
1461 local_capture_desc->event_expression,
1462 &local_capture_desc->bytecode);
1463 if (status < 0 || local_capture_desc->bytecode == NULL) {
1464 ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
1465 goto end;
1466 }
1467 }
1468
1469 /* Everything went better than expected */
1470 ret = LTTNG_OK;
1471
1472end:
1473 return ret;
1474}
51dbe985
JR
1475
1476LTTNG_HIDDEN
1477const struct lttng_bytecode *
d602bd6a 1478lttng_condition_on_event_get_capture_bytecode_at_index(
51dbe985
JR
1479 const struct lttng_condition *condition, unsigned int index)
1480{
d602bd6a 1481 const struct lttng_condition_on_event *event_rule_cond =
51dbe985 1482 container_of(condition,
d602bd6a 1483 const struct lttng_condition_on_event,
51dbe985
JR
1484 parent);
1485 struct lttng_capture_descriptor *desc = NULL;
1486 struct lttng_bytecode *bytecode = NULL;
1487 unsigned int count;
1488 enum lttng_condition_status status;
1489
d602bd6a 1490 if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
51dbe985
JR
1491 goto end;
1492 }
1493
d602bd6a 1494 status = lttng_condition_on_event_get_capture_descriptor_count(
51dbe985
JR
1495 condition, &count);
1496 if (status != LTTNG_CONDITION_STATUS_OK) {
1497 goto end;
1498 }
1499
1500 if (index >= count) {
1501 goto end;
1502 }
1503
1504 desc = lttng_dynamic_pointer_array_get_pointer(
1505 &event_rule_cond->capture_descriptors, index);
1506 if (desc == NULL) {
1507 goto end;
1508 }
1509
1510 bytecode = desc->bytecode;
1511end:
1512 return bytecode;
1513}
This page took 0.091371 seconds and 4 git commands to generate.