condition: implement lttng_condition_event_rule_generate_capture_descriptor_bytecode
[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>
683d081a 13#include <lttng/condition/condition-internal.h>
834966af 14#include <lttng/event-rule/event-rule-internal.h>
683d081a
JR
15#include <lttng/condition/event-rule-internal.h>
16#include <lttng/condition/event-rule.h>
38114013
PP
17#include <lttng/event-expr-internal.h>
18#include <lttng/event-expr.h>
834966af 19#include <lttng/lttng-error.h>
683d081a 20#include <stdbool.h>
38114013 21#include <stdint.h>
116a02e3 22#include <vendor/msgpack/msgpack.h>
683d081a
JR
23
24#define IS_EVENT_RULE_CONDITION(condition) \
25 (lttng_condition_get_type(condition) == \
26 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT)
27
28static bool is_event_rule_evaluation(const struct lttng_evaluation *evaluation)
29{
30 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
31
32 return type == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT;
33}
34
35static bool lttng_condition_event_rule_validate(
36 const struct lttng_condition *condition);
37static int lttng_condition_event_rule_serialize(
38 const struct lttng_condition *condition,
39 struct lttng_payload *payload);
40static bool lttng_condition_event_rule_is_equal(
41 const struct lttng_condition *_a,
42 const struct lttng_condition *_b);
43static void lttng_condition_event_rule_destroy(
44 struct lttng_condition *condition);
45
46static bool lttng_condition_event_rule_validate(
47 const struct lttng_condition *condition)
48{
49 bool valid = false;
50 struct lttng_condition_event_rule *event_rule;
51
52 if (!condition) {
53 goto end;
54 }
55
56 event_rule = container_of(
57 condition, struct lttng_condition_event_rule, parent);
58 if (!event_rule->rule) {
59 ERR("Invalid event rule condition: a rule must be set.");
60 goto end;
61 }
62
63 valid = lttng_event_rule_validate(event_rule->rule);
64end:
65 return valid;
66}
67
38114013
PP
68/*
69 * Serializes the C string `str` into `buf`.
70 *
71 * Encoding is the length of `str` plus one (for the null character),
72 * and then the string, including its null terminator.
73 */
74static
75int serialize_cstr(const char *str, struct lttng_dynamic_buffer *buf)
76{
77 int ret;
78 const uint32_t len = strlen(str) + 1;
79
80 /* Serialize the length, including the null terminator. */
81 DBG("Serializing C string's length (including null terminator): "
82 "%" PRIu32, len);
83 ret = lttng_dynamic_buffer_append(buf, &len, sizeof(len));
84 if (ret) {
85 goto end;
86 }
87
88 /* Serialize the string. */
89 DBG("Serializing C string: '%s'", str);
90 ret = lttng_dynamic_buffer_append(buf, str, len);
91 if (ret) {
92 goto end;
93 }
94
95end:
96 return ret;
97}
98
99/*
100 * Serializes the event expression `expr` into `buf`.
101 */
102static
103int serialize_event_expr(const struct lttng_event_expr *expr,
104 struct lttng_payload *payload)
105{
106 const uint8_t type = expr->type;
107 int ret;
108
109 /* Serialize the expression's type. */
110 DBG("Serializing event expression's type: %d", expr->type);
111 ret = lttng_dynamic_buffer_append(&payload->buffer, &type, sizeof(type));
112 if (ret) {
113 goto end;
114 }
115
116 /* Serialize the expression */
117 switch (expr->type) {
118 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
119 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
120 {
121 const struct lttng_event_expr_field *field_expr =
122 container_of(expr,
123 const struct lttng_event_expr_field,
124 parent);
125
126 /* Serialize the field name. */
127 DBG("Serializing field event expression's field name: '%s'",
128 field_expr->name);
129 ret = serialize_cstr(field_expr->name, &payload->buffer);
130 if (ret) {
131 goto end;
132 }
133
134 break;
135 }
136 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
137 {
138 const struct lttng_event_expr_app_specific_context_field *field_expr =
139 container_of(expr,
140 const struct lttng_event_expr_app_specific_context_field,
141 parent);
142
143 /* Serialize the provider name. */
144 DBG("Serializing app-specific context field event expression's "
145 "provider name: '%s'",
146 field_expr->provider_name);
147 ret = serialize_cstr(field_expr->provider_name, &payload->buffer);
148 if (ret) {
149 goto end;
150 }
151
152 /* Serialize the type name. */
153 DBG("Serializing app-specific context field event expression's "
154 "type name: '%s'",
155 field_expr->provider_name);
156 ret = serialize_cstr(field_expr->type_name, &payload->buffer);
157 if (ret) {
158 goto end;
159 }
160
161 break;
162 }
163 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
164 {
165 const struct lttng_event_expr_array_field_element *elem_expr =
166 container_of(expr,
167 const struct lttng_event_expr_array_field_element,
168 parent);
169 const uint32_t index = elem_expr->index;
170
171 /* Serialize the index. */
172 DBG("Serializing array field element event expression's "
173 "index: %u", elem_expr->index);
174 ret = lttng_dynamic_buffer_append(&payload->buffer, &index, sizeof(index));
175 if (ret) {
176 goto end;
177 }
178
179 /* Serialize the parent array field expression. */
180 DBG("Serializing array field element event expression's "
181 "parent array field event expression.");
182 ret = serialize_event_expr(elem_expr->array_field_expr, payload);
183 if (ret) {
184 goto end;
185 }
186
187 break;
188 }
189 default:
190 break;
191 }
192
193end:
194 return ret;
195}
196
6fb7c690
JR
197static
198struct lttng_capture_descriptor *
199lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
200 const struct lttng_condition *condition, unsigned int index)
201{
202 const struct lttng_condition_event_rule *event_rule_cond =
203 container_of(condition,
204 const struct lttng_condition_event_rule,
205 parent);
206 struct lttng_capture_descriptor *desc = NULL;
207 unsigned int count;
208 enum lttng_condition_status status;
209
210 if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
211 goto end;
212 }
213
214 status = lttng_condition_event_rule_get_capture_descriptor_count(
215 condition, &count);
216 if (status != LTTNG_CONDITION_STATUS_OK) {
217 goto end;
218 }
219
220 if (index >= count) {
221 goto end;
222 }
223
224 desc = lttng_dynamic_pointer_array_get_pointer(
225 &event_rule_cond->capture_descriptors, index);
226end:
227 return desc;
228}
229
683d081a
JR
230static int lttng_condition_event_rule_serialize(
231 const struct lttng_condition *condition,
232 struct lttng_payload *payload)
233{
234 int ret;
683d081a 235 struct lttng_condition_event_rule *event_rule;
0912b5ea 236 enum lttng_condition_status status;
38114013
PP
237 /* Used for iteration and communication (size matters). */
238 uint32_t i, capture_descr_count;
683d081a
JR
239
240 if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
241 ret = -1;
242 goto end;
243 }
244
245 DBG("Serializing event rule condition");
246 event_rule = container_of(
247 condition, struct lttng_condition_event_rule, parent);
248
38114013
PP
249 DBG("Serializing event rule condition's event rule");
250 ret = lttng_event_rule_serialize(event_rule->rule, payload);
683d081a
JR
251 if (ret) {
252 goto end;
253 }
254
0912b5ea
JR
255 status = lttng_condition_event_rule_get_capture_descriptor_count(
256 condition, &capture_descr_count);
257 if (status != LTTNG_CONDITION_STATUS_OK) {
258 ret = -1;
259 goto end;
260 };
261
38114013
PP
262 DBG("Serializing event rule condition's capture descriptor count: %" PRIu32,
263 capture_descr_count);
264 ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count,
265 sizeof(capture_descr_count));
683d081a
JR
266 if (ret) {
267 goto end;
268 }
269
38114013 270 for (i = 0; i < capture_descr_count; i++) {
6fb7c690
JR
271 const struct lttng_capture_descriptor *desc =
272 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
0912b5ea 273 condition, i);
38114013
PP
274
275 DBG("Serializing event rule condition's capture descriptor %" PRIu32,
276 i);
6fb7c690 277 ret = serialize_event_expr(desc->event_expression, payload);
38114013
PP
278 if (ret) {
279 goto end;
280 }
281 }
683d081a
JR
282
283end:
284 return ret;
285}
286
38114013
PP
287static
288bool capture_descriptors_are_equal(
0912b5ea
JR
289 const struct lttng_condition *condition_a,
290 const struct lttng_condition *condition_b)
38114013
PP
291{
292 bool is_equal = true;
0912b5ea
JR
293 unsigned int capture_descr_count_a;
294 unsigned int capture_descr_count_b;
38114013 295 size_t i;
0912b5ea 296 enum lttng_condition_status status;
38114013 297
0912b5ea
JR
298 status = lttng_condition_event_rule_get_capture_descriptor_count(
299 condition_a, &capture_descr_count_a);
300 if (status != LTTNG_CONDITION_STATUS_OK) {
301 goto not_equal;
302 }
303
304 status = lttng_condition_event_rule_get_capture_descriptor_count(
305 condition_b, &capture_descr_count_b);
306 if (status != LTTNG_CONDITION_STATUS_OK) {
307 goto not_equal;
308 }
38114013
PP
309
310 if (capture_descr_count_a != capture_descr_count_b) {
311 goto not_equal;
312 }
313
314 for (i = 0; i < capture_descr_count_a; i++) {
315 const struct lttng_event_expr *expr_a =
0912b5ea
JR
316 lttng_condition_event_rule_get_capture_descriptor_at_index(
317 condition_a,
38114013
PP
318 i);
319 const struct lttng_event_expr *expr_b =
0912b5ea
JR
320 lttng_condition_event_rule_get_capture_descriptor_at_index(
321 condition_b,
38114013
PP
322 i);
323
324 if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
325 goto not_equal;
326 }
327 }
328
329 goto end;
330
331not_equal:
332 is_equal = false;
333
334end:
335 return is_equal;
336}
337
683d081a
JR
338static bool lttng_condition_event_rule_is_equal(
339 const struct lttng_condition *_a,
340 const struct lttng_condition *_b)
341{
342 bool is_equal = false;
343 struct lttng_condition_event_rule *a, *b;
344
345 a = container_of(_a, struct lttng_condition_event_rule, parent);
346 b = container_of(_b, struct lttng_condition_event_rule, parent);
347
348 /* Both event rules must be set or both must be unset. */
349 if ((a->rule && !b->rule) || (!a->rule && b->rule)) {
350 WARN("Comparing event_rule conditions with uninitialized rule");
351 goto end;
352 }
353
354 is_equal = lttng_event_rule_is_equal(a->rule, b->rule);
38114013
PP
355 if (!is_equal) {
356 goto end;
357 }
358
0912b5ea 359 is_equal = capture_descriptors_are_equal(_a, _b);
38114013 360
683d081a
JR
361end:
362 return is_equal;
363}
364
365static void lttng_condition_event_rule_destroy(
366 struct lttng_condition *condition)
367{
368 struct lttng_condition_event_rule *event_rule;
369
370 event_rule = container_of(
371 condition, struct lttng_condition_event_rule, parent);
372
373 lttng_event_rule_put(event_rule->rule);
38114013 374 lttng_dynamic_pointer_array_reset(&event_rule->capture_descriptors);
683d081a
JR
375 free(event_rule);
376}
377
38114013 378static
0912b5ea 379void destroy_capture_descriptor(void *ptr)
38114013 380{
0912b5ea
JR
381 struct lttng_capture_descriptor *desc =
382 (struct lttng_capture_descriptor *) ptr;
383
384 lttng_event_expr_destroy(desc->event_expression);
385 free(desc->bytecode);
386 free(desc);
38114013
PP
387}
388
683d081a
JR
389struct lttng_condition *lttng_condition_event_rule_create(
390 struct lttng_event_rule *rule)
391{
392 struct lttng_condition *parent = NULL;
393 struct lttng_condition_event_rule *condition = NULL;
394
395 if (!rule) {
396 goto end;
397 }
398
399 condition = zmalloc(sizeof(struct lttng_condition_event_rule));
400 if (!condition) {
401 return NULL;
402 }
403
404 lttng_condition_init(&condition->parent,
405 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT);
406 condition->parent.validate = lttng_condition_event_rule_validate,
407 condition->parent.serialize = lttng_condition_event_rule_serialize,
408 condition->parent.equal = lttng_condition_event_rule_is_equal,
409 condition->parent.destroy = lttng_condition_event_rule_destroy,
410
411 lttng_event_rule_get(rule);
412 condition->rule = rule;
413 rule = NULL;
414
38114013 415 lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
0912b5ea 416 destroy_capture_descriptor);
38114013 417
683d081a
JR
418 parent = &condition->parent;
419end:
420 return parent;
421}
422
38114013
PP
423static
424uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size,
425 size_t *offset)
426{
427 uint64_t ret;
428 const struct lttng_buffer_view uint_view =
429 lttng_buffer_view_from_view(view, *offset, size);
430
431 if (!lttng_buffer_view_is_valid(&uint_view)) {
432 ret = UINT64_C(-1);
433 goto end;
434 }
435
436 switch (size) {
437 case 1:
438 ret = (uint64_t) *uint_view.data;
439 break;
440 case sizeof(uint32_t):
441 {
442 uint32_t u32;
443
444 memcpy(&u32, uint_view.data, sizeof(u32));
445 ret = (uint64_t) u32;
446 break;
447 }
448 case sizeof(ret):
449 memcpy(&ret, uint_view.data, sizeof(ret));
450 break;
451 default:
452 abort();
453 }
454
455 *offset += size;
456
457end:
458 return ret;
459}
460
461static
462const char *str_from_buffer(const struct lttng_buffer_view *view,
463 size_t *offset)
464{
465 uint64_t len;
466 const char *ret;
467
468 len = uint_from_buffer(view, sizeof(uint32_t), offset);
469 if (len == UINT64_C(-1)) {
470 goto error;
471 }
472
473 ret = &view->data[*offset];
474
475 if (!lttng_buffer_view_contains_string(view, ret, len)) {
476 goto error;
477 }
478
479 *offset += len;
480 goto end;
481
482error:
483 ret = NULL;
484
485end:
486 return ret;
487}
488
489static
490struct lttng_event_expr *event_expr_from_payload(
491 struct lttng_payload_view *view, size_t *offset)
492{
493 struct lttng_event_expr *expr = NULL;
494 const char *str;
495 uint64_t type;
496
497 type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
498 if (type == UINT64_C(-1)) {
499 goto error;
500 }
501
502 switch (type) {
503 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
504 str = str_from_buffer(&view->buffer, offset);
505 if (!str) {
506 goto error;
507 }
508
509 expr = lttng_event_expr_event_payload_field_create(str);
510 break;
511 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
512 str = str_from_buffer(&view->buffer, offset);
513 if (!str) {
514 goto error;
515 }
516
517 expr = lttng_event_expr_channel_context_field_create(str);
518 break;
519 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
520 {
521 const char *provider_name;
522 const char *type_name;
523
524 provider_name = str_from_buffer(&view->buffer, offset);
525 if (!provider_name) {
526 goto error;
527 }
528
529 type_name = str_from_buffer(&view->buffer, offset);
530 if (!type_name) {
531 goto error;
532 }
533
534 expr = lttng_event_expr_app_specific_context_field_create(
535 provider_name, type_name);
536 break;
537 }
538 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
539 {
540 struct lttng_event_expr *array_field_expr;
541 const uint64_t index = uint_from_buffer(
542 &view->buffer, sizeof(uint32_t), offset);
543
544 if (index == UINT64_C(-1)) {
545 goto error;
546 }
547
548 /* Array field expression is the encoded after this. */
549 array_field_expr = event_expr_from_payload(view, offset);
550 if (!array_field_expr) {
551 goto error;
552 }
553
554 /* Move ownership of `array_field_expr` to new expression. */
555 expr = lttng_event_expr_array_field_element_create(
556 array_field_expr, (unsigned int) index);
557 if (!expr) {
558 /* `array_field_expr` not moved: destroy it. */
559 lttng_event_expr_destroy(array_field_expr);
560 }
561
562 break;
563 }
564 default:
565 abort();
566 }
567
568 goto end;
569
570error:
571 lttng_event_expr_destroy(expr);
572 expr = NULL;
573
574end:
575 return expr;
576}
577
683d081a
JR
578LTTNG_HIDDEN
579ssize_t lttng_condition_event_rule_create_from_payload(
580 struct lttng_payload_view *view,
581 struct lttng_condition **_condition)
582{
38114013
PP
583 ssize_t consumed_length;
584 size_t offset = 0;
585 ssize_t event_rule_length;
586 uint32_t i, capture_descr_count;
683d081a
JR
587 struct lttng_condition *condition = NULL;
588 struct lttng_event_rule *event_rule = NULL;
683d081a
JR
589
590 if (!view || !_condition) {
591 goto error;
592 }
593
38114013 594 /* Struct lttng_event_rule. */
683d081a
JR
595 {
596 struct lttng_payload_view event_rule_view =
597 lttng_payload_view_from_view(view, offset, -1);
598
599 event_rule_length = lttng_event_rule_create_from_payload(
600 &event_rule_view, &event_rule);
601 }
602
603 if (event_rule_length < 0 || !event_rule) {
604 goto error;
605 }
606
38114013
PP
607 /* Create condition (no capture descriptors yet) at this point. */
608 condition = lttng_condition_event_rule_create(event_rule);
609 if (!condition) {
683d081a
JR
610 goto error;
611 }
612
683d081a 613
38114013
PP
614 /* Capture descriptor count. */
615 assert(event_rule_length >= 0);
616 offset += (size_t) event_rule_length;
617 capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
618 if (capture_descr_count == UINT32_C(-1)) {
683d081a
JR
619 goto error;
620 }
621
38114013
PP
622 /* Capture descriptors. */
623 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 624 enum lttng_condition_status status;
38114013
PP
625 struct lttng_event_expr *expr = event_expr_from_payload(
626 view, &offset);
38114013
PP
627
628 if (!expr) {
629 goto error;
630 }
631
632 /* Move ownership of `expr` to `condition`. */
633 status = lttng_condition_event_rule_append_capture_descriptor(
634 condition, expr);
635 if (status != LTTNG_CONDITION_STATUS_OK) {
636 /* `expr` not moved: destroy it. */
637 lttng_event_expr_destroy(expr);
638 goto error;
639 }
640 }
641
642 consumed_length = (ssize_t) offset;
683d081a
JR
643 *_condition = condition;
644 condition = NULL;
645 goto end;
646
647error:
38114013 648 consumed_length = -1;
683d081a
JR
649
650end:
651 lttng_event_rule_put(event_rule);
652 lttng_condition_put(condition);
38114013 653 return consumed_length;
683d081a
JR
654}
655
656LTTNG_HIDDEN
657enum lttng_condition_status lttng_condition_event_rule_borrow_rule_mutable(
658 const struct lttng_condition *condition,
659 struct lttng_event_rule **rule)
660{
661 struct lttng_condition_event_rule *event_rule;
662 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
663
664 if (!condition || !IS_EVENT_RULE_CONDITION(condition) || !rule) {
665 status = LTTNG_CONDITION_STATUS_INVALID;
666 goto end;
667 }
668
669 event_rule = container_of(
670 condition, struct lttng_condition_event_rule, parent);
671 if (!event_rule->rule) {
672 status = LTTNG_CONDITION_STATUS_UNSET;
673 goto end;
674 }
675
676 *rule = event_rule->rule;
677end:
678 return status;
679}
680
681enum lttng_condition_status lttng_condition_event_rule_get_rule(
682 const struct lttng_condition *condition,
683 const struct lttng_event_rule **rule)
684{
685 struct lttng_event_rule *mutable_rule = NULL;
686 const enum lttng_condition_status status =
687 lttng_condition_event_rule_borrow_rule_mutable(
688 condition, &mutable_rule);
689
690 *rule = mutable_rule;
691 return status;
692}
693
38114013
PP
694enum lttng_condition_status
695lttng_condition_event_rule_append_capture_descriptor(
696 struct lttng_condition *condition,
697 struct lttng_event_expr *expr)
698{
699 int ret;
700 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
701 struct lttng_condition_event_rule *event_rule_cond =
702 container_of(condition,
703 struct lttng_condition_event_rule, parent);
0912b5ea 704 struct lttng_capture_descriptor *descriptor = NULL;
38114013
PP
705
706 /* Only accept l-values. */
707 if (!condition || !IS_EVENT_RULE_CONDITION(condition) || !expr ||
708 !lttng_event_expr_is_lvalue(expr)) {
709 status = LTTNG_CONDITION_STATUS_INVALID;
710 goto end;
711 }
712
0912b5ea
JR
713 descriptor = malloc(sizeof(*descriptor));
714 if (descriptor == NULL) {
715 status = LTTNG_CONDITION_STATUS_ERROR;
716 goto end;
717 }
718
719 descriptor->event_expression = expr;
720 descriptor->bytecode = NULL;
721
38114013 722 ret = lttng_dynamic_pointer_array_add_pointer(
0912b5ea 723 &event_rule_cond->capture_descriptors, descriptor);
38114013
PP
724 if (ret) {
725 status = LTTNG_CONDITION_STATUS_ERROR;
726 goto end;
727 }
728
0912b5ea
JR
729 /* Ownership is transfered to the internal capture_descriptors array */
730 descriptor = NULL;
38114013 731end:
0912b5ea 732 free(descriptor);
38114013
PP
733 return status;
734}
735
736enum lttng_condition_status
737lttng_condition_event_rule_get_capture_descriptor_count(
738 const struct lttng_condition *condition, unsigned int *count)
739{
740 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
741 const struct lttng_condition_event_rule *event_rule_cond =
742 container_of(condition,
743 const struct lttng_condition_event_rule,
744 parent);
745
746 if (!condition || !IS_EVENT_RULE_CONDITION(condition) || !count) {
747 status = LTTNG_CONDITION_STATUS_INVALID;
748 goto end;
749 }
750
751 *count = lttng_dynamic_pointer_array_get_count(
752 &event_rule_cond->capture_descriptors);
753
754end:
755 return status;
756}
757
758const struct lttng_event_expr *
759lttng_condition_event_rule_get_capture_descriptor_at_index(
760 const struct lttng_condition *condition, unsigned int index)
761{
38114013 762 const struct lttng_event_expr *expr = NULL;
6fb7c690 763 const struct lttng_capture_descriptor *desc = NULL;
0912b5ea 764
6fb7c690
JR
765 desc = lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
766 condition, index);
767 if (desc == NULL) {
38114013
PP
768 goto end;
769 }
0912b5ea 770 expr = desc->event_expression;
38114013
PP
771
772end:
773 return expr;
774}
775
683d081a
JR
776LTTNG_HIDDEN
777ssize_t lttng_evaluation_event_rule_create_from_payload(
778 struct lttng_payload_view *view,
779 struct lttng_evaluation **_evaluation)
780{
781 ssize_t ret, offset = 0;
782 const char *trigger_name;
783 struct lttng_evaluation *evaluation = NULL;
784 const struct lttng_evaluation_event_rule_comm *header;
785 const struct lttng_payload_view header_view =
786 lttng_payload_view_from_view(
787 view, 0, sizeof(*header));
788
789 if (!_evaluation) {
790 ret = -1;
791 goto error;
792 }
793
794 if (!lttng_payload_view_is_valid(&header_view)) {
795 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
796 ret = -1;
797 goto error;
798 }
799
800 header = (typeof(header)) header_view.buffer.data;
801
802 /* Map the originating trigger's name. */
803 offset += sizeof(*header);
804 {
805 struct lttng_payload_view current_view =
806 lttng_payload_view_from_view(view, offset,
807 header->trigger_name_length);
808
809 if (!lttng_payload_view_is_valid(&current_view)) {
810 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
811 ret = -1;
812 goto error;
813 }
814
815 trigger_name = current_view.buffer.data;
816 if (!lttng_buffer_view_contains_string(&current_view.buffer,
817 trigger_name, header->trigger_name_length)) {
818 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
819 ret = -1;
820 goto error;
821 }
822 }
823
824 offset += header->trigger_name_length;
825
826 evaluation = lttng_evaluation_event_rule_create(trigger_name);
827 if (!evaluation) {
828 ret = -1;
829 goto error;
830 }
831
832 *_evaluation = evaluation;
833 evaluation = NULL;
834 ret = offset;
835
836error:
837 lttng_evaluation_destroy(evaluation);
838 return ret;
839}
840
841static int lttng_evaluation_event_rule_serialize(
842 const struct lttng_evaluation *evaluation,
843 struct lttng_payload *payload)
844{
845 int ret = 0;
846 struct lttng_evaluation_event_rule *hit;
847 struct lttng_evaluation_event_rule_comm comm;
848
849 hit = container_of(
850 evaluation, struct lttng_evaluation_event_rule, parent);
851
852 assert(hit->name);
853 comm.trigger_name_length = strlen(hit->name) + 1;
854
855 ret = lttng_dynamic_buffer_append(
856 &payload->buffer, &comm, sizeof(comm));
857 if (ret) {
858 goto end;
859 }
860
861 ret = lttng_dynamic_buffer_append(
862 &payload->buffer, hit->name, comm.trigger_name_length);
863end:
864 return ret;
865}
866
867static void lttng_evaluation_event_rule_destroy(
868 struct lttng_evaluation *evaluation)
869{
870 struct lttng_evaluation_event_rule *hit;
871
872 hit = container_of(
873 evaluation, struct lttng_evaluation_event_rule, parent);
874 free(hit->name);
875 free(hit);
876}
877
878LTTNG_HIDDEN
879struct lttng_evaluation *lttng_evaluation_event_rule_create(
880 const char *trigger_name)
881{
882 struct lttng_evaluation_event_rule *hit;
883 struct lttng_evaluation *evaluation = NULL;
884
885 hit = zmalloc(sizeof(struct lttng_evaluation_event_rule));
886 if (!hit) {
887 goto end;
888 }
889
890 hit->name = strdup(trigger_name);
891 if (!hit->name) {
892 goto end;
893 }
894
895 hit->parent.type = LTTNG_CONDITION_TYPE_EVENT_RULE_HIT;
896 hit->parent.serialize = lttng_evaluation_event_rule_serialize;
897 hit->parent.destroy = lttng_evaluation_event_rule_destroy;
898
899 evaluation = &hit->parent;
900 hit = NULL;
901
902end:
903 if (hit) {
904 lttng_evaluation_event_rule_destroy(&hit->parent);
905 }
906
907 return evaluation;
908}
909
910enum lttng_evaluation_status lttng_evaluation_event_rule_get_trigger_name(
911 const struct lttng_evaluation *evaluation, const char **name)
912{
913 struct lttng_evaluation_event_rule *hit;
914 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
915
916 if (!evaluation || !is_event_rule_evaluation(evaluation) || !name) {
917 status = LTTNG_EVALUATION_STATUS_INVALID;
918 goto end;
919 }
920
921 hit = container_of(
922 evaluation, struct lttng_evaluation_event_rule, parent);
923 *name = hit->name;
924end:
925 return status;
926}
834966af
JR
927
928LTTNG_HIDDEN
929enum lttng_error_code
930lttng_condition_event_rule_generate_capture_descriptor_bytecode(
931 struct lttng_condition *condition)
932{
933 enum lttng_error_code ret;
934 enum lttng_condition_status status;
935 unsigned int capture_count, i;
936
937 if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
938 ret = LTTNG_ERR_FATAL;
939 goto end;
940 }
941
942 status = lttng_condition_event_rule_get_capture_descriptor_count(
943 condition, &capture_count);
944 if (status != LTTNG_CONDITION_STATUS_OK) {
945 ret = LTTNG_ERR_FATAL;
946 goto end;
947 }
948
949 for (i = 0; i < capture_count; i++) {
950 struct lttng_capture_descriptor *local_capture_desc =
951 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
952 condition, i);
953
954 if (local_capture_desc == NULL) {
955 ret = LTTNG_ERR_FATAL;
956 goto end;
957 }
958
959 /* Generate the bytecode. */
960 status = lttng_event_expr_to_bytecode(
961 local_capture_desc->event_expression,
962 &local_capture_desc->bytecode);
963 if (status < 0 || local_capture_desc->bytecode == NULL) {
964 ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
965 goto end;
966 }
967 }
968
969 /* Everything went better than expected */
970 ret = LTTNG_OK;
971
972end:
973 return ret;
974}
This page took 0.062068 seconds and 4 git commands to generate.