8959652ddda3da8ba23364b73cc3e8b1d0bbc338
[lttng-tools.git] / src / common / conditions / event-rule.c
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>
10 #include <common/event-expr-to-bytecode.h>
11 #include <common/macros.h>
12 #include <inttypes.h>
13 #include <lttng/condition/condition-internal.h>
14 #include <lttng/event-rule/event-rule-internal.h>
15 #include <lttng/condition/event-rule-internal.h>
16 #include <lttng/condition/event-rule.h>
17 #include <lttng/event-expr-internal.h>
18 #include <lttng/event-expr.h>
19 #include <lttng/lttng-error.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <vendor/msgpack/msgpack.h>
23
24 #define IS_EVENT_RULE_CONDITION(condition) \
25 (lttng_condition_get_type(condition) == \
26 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT)
27
28 static 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
35 static bool lttng_condition_event_rule_validate(
36 const struct lttng_condition *condition);
37 static int lttng_condition_event_rule_serialize(
38 const struct lttng_condition *condition,
39 struct lttng_payload *payload);
40 static bool lttng_condition_event_rule_is_equal(
41 const struct lttng_condition *_a,
42 const struct lttng_condition *_b);
43 static void lttng_condition_event_rule_destroy(
44 struct lttng_condition *condition);
45
46 static 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);
64 end:
65 return valid;
66 }
67
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 */
74 static
75 int 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
95 end:
96 return ret;
97 }
98
99 /*
100 * Serializes the event expression `expr` into `buf`.
101 */
102 static
103 int 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
193 end:
194 return ret;
195 }
196
197 static
198 struct lttng_capture_descriptor *
199 lttng_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);
226 end:
227 return desc;
228 }
229
230 static int lttng_condition_event_rule_serialize(
231 const struct lttng_condition *condition,
232 struct lttng_payload *payload)
233 {
234 int ret;
235 struct lttng_condition_event_rule *event_rule;
236 enum lttng_condition_status status;
237 /* Used for iteration and communication (size matters). */
238 uint32_t i, capture_descr_count;
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
249 DBG("Serializing event rule condition's event rule");
250 ret = lttng_event_rule_serialize(event_rule->rule, payload);
251 if (ret) {
252 goto end;
253 }
254
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
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));
266 if (ret) {
267 goto end;
268 }
269
270 for (i = 0; i < capture_descr_count; i++) {
271 const struct lttng_capture_descriptor *desc =
272 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
273 condition, i);
274
275 DBG("Serializing event rule condition's capture descriptor %" PRIu32,
276 i);
277 ret = serialize_event_expr(desc->event_expression, payload);
278 if (ret) {
279 goto end;
280 }
281 }
282
283 end:
284 return ret;
285 }
286
287 static
288 bool capture_descriptors_are_equal(
289 const struct lttng_condition *condition_a,
290 const struct lttng_condition *condition_b)
291 {
292 bool is_equal = true;
293 unsigned int capture_descr_count_a;
294 unsigned int capture_descr_count_b;
295 size_t i;
296 enum lttng_condition_status status;
297
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 }
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 =
316 lttng_condition_event_rule_get_capture_descriptor_at_index(
317 condition_a,
318 i);
319 const struct lttng_event_expr *expr_b =
320 lttng_condition_event_rule_get_capture_descriptor_at_index(
321 condition_b,
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
331 not_equal:
332 is_equal = false;
333
334 end:
335 return is_equal;
336 }
337
338 static 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);
355 if (!is_equal) {
356 goto end;
357 }
358
359 is_equal = capture_descriptors_are_equal(_a, _b);
360
361 end:
362 return is_equal;
363 }
364
365 static 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);
374 lttng_dynamic_pointer_array_reset(&event_rule->capture_descriptors);
375 free(event_rule);
376 }
377
378 static
379 void destroy_capture_descriptor(void *ptr)
380 {
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);
387 }
388
389 struct 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
415 lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
416 destroy_capture_descriptor);
417
418 parent = &condition->parent;
419 end:
420 return parent;
421 }
422
423 static
424 uint64_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
457 end:
458 return ret;
459 }
460
461 static
462 const 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
482 error:
483 ret = NULL;
484
485 end:
486 return ret;
487 }
488
489 static
490 struct 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
570 error:
571 lttng_event_expr_destroy(expr);
572 expr = NULL;
573
574 end:
575 return expr;
576 }
577
578 LTTNG_HIDDEN
579 ssize_t lttng_condition_event_rule_create_from_payload(
580 struct lttng_payload_view *view,
581 struct lttng_condition **_condition)
582 {
583 ssize_t consumed_length;
584 size_t offset = 0;
585 ssize_t event_rule_length;
586 uint32_t i, capture_descr_count;
587 struct lttng_condition *condition = NULL;
588 struct lttng_event_rule *event_rule = NULL;
589
590 if (!view || !_condition) {
591 goto error;
592 }
593
594 /* Struct lttng_event_rule. */
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
607 /* Create condition (no capture descriptors yet) at this point. */
608 condition = lttng_condition_event_rule_create(event_rule);
609 if (!condition) {
610 goto error;
611 }
612
613
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)) {
619 goto error;
620 }
621
622 /* Capture descriptors. */
623 for (i = 0; i < capture_descr_count; i++) {
624 enum lttng_condition_status status;
625 struct lttng_event_expr *expr = event_expr_from_payload(
626 view, &offset);
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;
643 *_condition = condition;
644 condition = NULL;
645 goto end;
646
647 error:
648 consumed_length = -1;
649
650 end:
651 lttng_event_rule_put(event_rule);
652 lttng_condition_put(condition);
653 return consumed_length;
654 }
655
656 LTTNG_HIDDEN
657 enum 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;
677 end:
678 return status;
679 }
680
681 enum 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
694 enum lttng_condition_status
695 lttng_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);
704 struct lttng_capture_descriptor *descriptor = NULL;
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
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
722 ret = lttng_dynamic_pointer_array_add_pointer(
723 &event_rule_cond->capture_descriptors, descriptor);
724 if (ret) {
725 status = LTTNG_CONDITION_STATUS_ERROR;
726 goto end;
727 }
728
729 /* Ownership is transfered to the internal capture_descriptors array */
730 descriptor = NULL;
731 end:
732 free(descriptor);
733 return status;
734 }
735
736 enum lttng_condition_status
737 lttng_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
754 end:
755 return status;
756 }
757
758 const struct lttng_event_expr *
759 lttng_condition_event_rule_get_capture_descriptor_at_index(
760 const struct lttng_condition *condition, unsigned int index)
761 {
762 const struct lttng_event_expr *expr = NULL;
763 const struct lttng_capture_descriptor *desc = NULL;
764
765 desc = lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
766 condition, index);
767 if (desc == NULL) {
768 goto end;
769 }
770 expr = desc->event_expression;
771
772 end:
773 return expr;
774 }
775
776 LTTNG_HIDDEN
777 ssize_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
836 error:
837 lttng_evaluation_destroy(evaluation);
838 return ret;
839 }
840
841 static 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);
863 end:
864 return ret;
865 }
866
867 static 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
878 LTTNG_HIDDEN
879 struct 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
902 end:
903 if (hit) {
904 lttng_evaluation_event_rule_destroy(&hit->parent);
905 }
906
907 return evaluation;
908 }
909
910 enum 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;
924 end:
925 return status;
926 }
927
928 LTTNG_HIDDEN
929 enum lttng_error_code
930 lttng_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
972 end:
973 return ret;
974 }
This page took 0.075012 seconds and 3 git commands to generate.