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