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