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