Rename files for condition event-rule to on-event
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Thu, 5 Nov 2020 02:46:11 +0000 (21:46 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 17 Mar 2021 05:54:26 +0000 (01:54 -0400)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I8bde2f15674be16c0a21c670affff4c4503ed846

22 files changed:
include/Makefile.am
include/lttng/condition/event-rule-internal.h [deleted file]
include/lttng/condition/event-rule.h [deleted file]
include/lttng/condition/on-event-internal.h [new file with mode: 0644]
include/lttng/condition/on-event.h [new file with mode: 0644]
include/lttng/lttng.h
src/bin/lttng-sessiond/action-executor.c
src/bin/lttng-sessiond/agent.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/condition-internal.c
src/bin/lttng-sessiond/event.c
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/notification-thread-events.c
src/bin/lttng-sessiond/ust-app.c
src/common/Makefile.am
src/common/conditions/condition.c
src/common/conditions/event-rule.c [deleted file]
src/common/conditions/on-event.c [new file with mode: 0644]
src/common/evaluation.c
src/common/trigger.c
tests/regression/tools/trigger/utils/notification-client.c
tests/unit/test_condition.c

index 8dae8097346b58268aa9d157a059ce84e2f3fe5e..751fa0ebd245080be46afa822a5056c6df777abb 100644 (file)
@@ -134,7 +134,7 @@ lttngactioninclude_HEADERS= \
 lttngconditioninclude_HEADERS= \
        lttng/condition/condition.h \
        lttng/condition/buffer-usage.h \
-       lttng/condition/event-rule.h \
+       lttng/condition/on-event.h \
        lttng/condition/session-consumed-size.h \
        lttng/condition/session-rotation.h \
        lttng/condition/evaluation.h
@@ -167,7 +167,7 @@ noinst_HEADERS = \
        lttng/action/stop-session-internal.h \
        lttng/condition/condition-internal.h \
        lttng/condition/buffer-usage-internal.h \
-       lttng/condition/event-rule-internal.h \
+       lttng/condition/on-event-internal.h \
        lttng/condition/session-consumed-size-internal.h \
        lttng/condition/evaluation-internal.h \
        lttng/condition/session-rotation-internal.h \
diff --git a/include/lttng/condition/event-rule-internal.h b/include/lttng/condition/event-rule-internal.h
deleted file mode 100644 (file)
index e22cb76..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
-#ifndef LTTNG_CONDITION_ON_EVENT_INTERNAL_H
-#define LTTNG_CONDITION_ON_EVENT_INTERNAL_H
-
-#include <lttng/condition/condition-internal.h>
-#include <common/buffer-view.h>
-#include <common/macros.h>
-#include <lttng/condition/evaluation-internal.h>
-#include <common/dynamic-array.h>
-#include <lttng/event-field-value.h>
-
-struct lttng_capture_descriptor {
-       struct lttng_event_expr *event_expression;
-       struct lttng_bytecode *bytecode;
-};
-
-struct lttng_condition_on_event {
-       struct lttng_condition parent;
-       struct lttng_event_rule *rule;
-
-       /* Array of `struct lttng_capture_descriptor *`. */
-       struct lttng_dynamic_pointer_array capture_descriptors;
-};
-
-struct lttng_evaluation_on_event {
-       struct lttng_evaluation parent;
-       char *name;
-
-       /* MessagePack-encoded captured event field values. */
-       struct lttng_dynamic_buffer capture_payload;
-
-       /*
-        * The content of this array event field value is the decoded
-        * version of `capture_payload` above.
-        *
-        * This is a cache: it's not serialized/deserialized in
-        * communications from/to the library and the session daemon.
-        */
-       struct lttng_event_field_value *captured_values;
-};
-
-struct lttng_evaluation_on_event_comm {
-       /* Includes the null terminator. */
-       uint32_t trigger_name_length;
-       /* Trigger name. */
-       char payload[];
-} LTTNG_PACKED;
-
-LTTNG_HIDDEN
-ssize_t lttng_condition_on_event_create_from_payload(
-               struct lttng_payload_view *view,
-               struct lttng_condition **condition);
-
-LTTNG_HIDDEN
-enum lttng_condition_status
-lttng_condition_on_event_borrow_rule_mutable(
-               const struct lttng_condition *condition,
-               struct lttng_event_rule **rule);
-
-LTTNG_HIDDEN
-struct lttng_evaluation *lttng_evaluation_on_event_create(
-               const struct lttng_condition_on_event *condition,
-               const char* trigger_name,
-               const char *capture_payload, size_t capture_payload_size,
-               bool decode_capture_payload);
-
-LTTNG_HIDDEN
-ssize_t lttng_evaluation_on_event_create_from_payload(
-               const struct lttng_condition_on_event *condition,
-               struct lttng_payload_view *view,
-               struct lttng_evaluation **_evaluation);
-
-LTTNG_HIDDEN
-enum lttng_error_code
-lttng_condition_on_event_generate_capture_descriptor_bytecode(
-               struct lttng_condition *condition);
-
-LTTNG_HIDDEN
-const struct lttng_bytecode *
-lttng_condition_on_event_get_capture_bytecode_at_index(
-               const struct lttng_condition *condition, unsigned int index);
-
-#endif /* LTTNG_CONDITION_ON_EVENT_INTERNAL_H */
diff --git a/include/lttng/condition/event-rule.h b/include/lttng/condition/event-rule.h
deleted file mode 100644 (file)
index 4505076..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
-#ifndef LTTNG_CONDITION_ON_EVENT_H
-#define LTTNG_CONDITION_ON_EVENT_H
-
-#include <lttng/event-rule/event-rule.h>
-#include <lttng/condition/condition.h>
-#include <lttng/condition/evaluation.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct lttng_event_expr;
-struct lttng_event_field_value;
-
-/**
- * On event conditions allows an action to be taken whenever an event matching
- * the on event is hit by the tracers.
- *
- * An on event condition can also specify a payload to be captured at runtime.
- * This is done via the capture descriptor.
- *
- * Note: the dynamic runtime capture of payload is only available for the
- *       trigger notification subsystem.
- */
-
-/*
- * Create a newly allocated on event condition.
- *
- * Returns a new condition on success, NULL on failure. This condition must be
- * destroyed using lttng_condition_destroy().
- */
-extern struct lttng_condition *lttng_condition_on_event_create(
-               struct lttng_event_rule *rule);
-
-/*
- * Get the rule property of a on event condition.
- *
- * The caller does not assume the ownership of the returned rule. The
- * rule shall only be used for the duration of the condition's
- * lifetime.
- *
- * Returns LTTNG_CONDITION_STATUS_OK and a pointer to the condition's rule
- * on success, LTTNG_CONDITION_STATUS_INVALID if an invalid
- * parameter is passed. */
-extern enum lttng_condition_status lttng_condition_on_event_get_rule(
-               const struct lttng_condition *condition,
-               const struct lttng_event_rule **rule);
-
-/**
- * lttng_evaluation_on_event_hit are specialised lttng_evaluations which
- * allow users to query a number of properties resulting from the evaluation
- * of a condition which evaluated to true.
- *
- * The evaluation of a on event hit yields two different results:
- *    TEMPORARY - The name of the triggers associated with the condition.
- *    TODO - The captured event payload if any
- */
-
-/*
- * Get the trigger name property of a on event hit evaluation.
- *
- * Returns LTTNG_EVALUATION_STATUS_OK on success and a trigger name
- * or LTTNG_EVALUATION_STATUS_INVALID if
- * an invalid parameter is passed.
- */
-extern enum lttng_evaluation_status
-lttng_evaluation_on_event_get_trigger_name(
-               const struct lttng_evaluation *evaluation,
-               const char **name);
-
-/*
- * Sets `*field_val` to the array event field value of the on event
- * condition evaluation `evaluation` which contains its captured values.
- *
- * Returns:
- *
- * `LTTNG_EVALUATION_STATUS_OK`:
- *     Success.
- *
- *     `*field_val` is an array event field value with a length of at
- *     least one.
- *
- * `LTTNG_EVALUATION_STATUS_INVALID`:
- *     * `evaluation` is `NULL`.
- *     * The type of the condition of `evaluation` is not
- *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
- *     * The condition of `evaluation` has no capture descriptors.
- *     * `field_val` is `NULL`.
- */
-extern enum lttng_evaluation_status
-lttng_evaluation_on_event_get_captured_values(
-               const struct lttng_evaluation *evaluation,
-               const struct lttng_event_field_value **field_val);
-
-/*
- * Appends (transfering the ownership) the capture descriptor `expr` to
- * the on event condition `condition`.
- *
- * Returns:
- *
- * `LTTNG_CONDITION_STATUS_OK`:
- *     Success.
- *
- * `LTTNG_CONDITION_STATUS_ERROR`:
- *     Memory error.
- *
- * `LTTNG_CONDITION_STATUS_INVALID`:
- *     * `condition` is `NULL`.
- *     * The type of `condition` is not
- *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
- *     * `expr` is `NULL`.
- *     * `expr` is not a locator expression, that is, its type is not
- *       one of:
- *
- *       * `LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD`
- *       * `LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD`
- *       * `LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD`
- *       * `LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT`
- *
- * `LTTNG_CONDITION_STATUS_UNSUPPORTED`:
- *     * The associated event-rule does not support runtime capture.
- */
-extern enum lttng_condition_status
-lttng_condition_on_event_append_capture_descriptor(
-               struct lttng_condition *condition,
-               struct lttng_event_expr *expr);
-
-/*
- * Sets `*count` to the number of capture descriptors in the on event
- * condition `condition`.
- *
- * Returns:
- *
- * `LTTNG_CONDITION_STATUS_OK`:
- *     Success.
- *
- * `LTTNG_CONDITION_STATUS_INVALID`:
- *     * `condition` is `NULL`.
- *     * The type of `condition` is not
- *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
- *     * `count` is `NULL`.
- */
-extern enum lttng_condition_status
-lttng_condition_on_event_get_capture_descriptor_count(
-               const struct lttng_condition *condition, unsigned int *count);
-
-/*
- * Returns the capture descriptor (borrowed) of the on event condition
- * `condition` at the index `index`, or `NULL` if:
- *
- * * `condition` is `NULL`.
- * * The type of `condition` is not
- *   `LTTNG_CONDITION_TYPE_ON_EVENT`.
- * * `index` is greater than or equal to the number of capture
- *   descriptors in `condition` (as returned by
- *   lttng_condition_on_event_get_capture_descriptor_count()).
- */
-extern const struct lttng_event_expr *
-lttng_condition_on_event_get_capture_descriptor_at_index(
-               const struct lttng_condition *condition, unsigned int index);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LTTNG_CONDITION_ON_EVENT_H */
diff --git a/include/lttng/condition/on-event-internal.h b/include/lttng/condition/on-event-internal.h
new file mode 100644 (file)
index 0000000..e22cb76
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_CONDITION_ON_EVENT_INTERNAL_H
+#define LTTNG_CONDITION_ON_EVENT_INTERNAL_H
+
+#include <lttng/condition/condition-internal.h>
+#include <common/buffer-view.h>
+#include <common/macros.h>
+#include <lttng/condition/evaluation-internal.h>
+#include <common/dynamic-array.h>
+#include <lttng/event-field-value.h>
+
+struct lttng_capture_descriptor {
+       struct lttng_event_expr *event_expression;
+       struct lttng_bytecode *bytecode;
+};
+
+struct lttng_condition_on_event {
+       struct lttng_condition parent;
+       struct lttng_event_rule *rule;
+
+       /* Array of `struct lttng_capture_descriptor *`. */
+       struct lttng_dynamic_pointer_array capture_descriptors;
+};
+
+struct lttng_evaluation_on_event {
+       struct lttng_evaluation parent;
+       char *name;
+
+       /* MessagePack-encoded captured event field values. */
+       struct lttng_dynamic_buffer capture_payload;
+
+       /*
+        * The content of this array event field value is the decoded
+        * version of `capture_payload` above.
+        *
+        * This is a cache: it's not serialized/deserialized in
+        * communications from/to the library and the session daemon.
+        */
+       struct lttng_event_field_value *captured_values;
+};
+
+struct lttng_evaluation_on_event_comm {
+       /* Includes the null terminator. */
+       uint32_t trigger_name_length;
+       /* Trigger name. */
+       char payload[];
+} LTTNG_PACKED;
+
+LTTNG_HIDDEN
+ssize_t lttng_condition_on_event_create_from_payload(
+               struct lttng_payload_view *view,
+               struct lttng_condition **condition);
+
+LTTNG_HIDDEN
+enum lttng_condition_status
+lttng_condition_on_event_borrow_rule_mutable(
+               const struct lttng_condition *condition,
+               struct lttng_event_rule **rule);
+
+LTTNG_HIDDEN
+struct lttng_evaluation *lttng_evaluation_on_event_create(
+               const struct lttng_condition_on_event *condition,
+               const char* trigger_name,
+               const char *capture_payload, size_t capture_payload_size,
+               bool decode_capture_payload);
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_on_event_create_from_payload(
+               const struct lttng_condition_on_event *condition,
+               struct lttng_payload_view *view,
+               struct lttng_evaluation **_evaluation);
+
+LTTNG_HIDDEN
+enum lttng_error_code
+lttng_condition_on_event_generate_capture_descriptor_bytecode(
+               struct lttng_condition *condition);
+
+LTTNG_HIDDEN
+const struct lttng_bytecode *
+lttng_condition_on_event_get_capture_bytecode_at_index(
+               const struct lttng_condition *condition, unsigned int index);
+
+#endif /* LTTNG_CONDITION_ON_EVENT_INTERNAL_H */
diff --git a/include/lttng/condition/on-event.h b/include/lttng/condition/on-event.h
new file mode 100644 (file)
index 0000000..4505076
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_CONDITION_ON_EVENT_H
+#define LTTNG_CONDITION_ON_EVENT_H
+
+#include <lttng/event-rule/event-rule.h>
+#include <lttng/condition/condition.h>
+#include <lttng/condition/evaluation.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct lttng_event_expr;
+struct lttng_event_field_value;
+
+/**
+ * On event conditions allows an action to be taken whenever an event matching
+ * the on event is hit by the tracers.
+ *
+ * An on event condition can also specify a payload to be captured at runtime.
+ * This is done via the capture descriptor.
+ *
+ * Note: the dynamic runtime capture of payload is only available for the
+ *       trigger notification subsystem.
+ */
+
+/*
+ * Create a newly allocated on event condition.
+ *
+ * Returns a new condition on success, NULL on failure. This condition must be
+ * destroyed using lttng_condition_destroy().
+ */
+extern struct lttng_condition *lttng_condition_on_event_create(
+               struct lttng_event_rule *rule);
+
+/*
+ * Get the rule property of a on event condition.
+ *
+ * The caller does not assume the ownership of the returned rule. The
+ * rule shall only be used for the duration of the condition's
+ * lifetime.
+ *
+ * Returns LTTNG_CONDITION_STATUS_OK and a pointer to the condition's rule
+ * on success, LTTNG_CONDITION_STATUS_INVALID if an invalid
+ * parameter is passed. */
+extern enum lttng_condition_status lttng_condition_on_event_get_rule(
+               const struct lttng_condition *condition,
+               const struct lttng_event_rule **rule);
+
+/**
+ * lttng_evaluation_on_event_hit are specialised lttng_evaluations which
+ * allow users to query a number of properties resulting from the evaluation
+ * of a condition which evaluated to true.
+ *
+ * The evaluation of a on event hit yields two different results:
+ *    TEMPORARY - The name of the triggers associated with the condition.
+ *    TODO - The captured event payload if any
+ */
+
+/*
+ * Get the trigger name property of a on event hit evaluation.
+ *
+ * Returns LTTNG_EVALUATION_STATUS_OK on success and a trigger name
+ * or LTTNG_EVALUATION_STATUS_INVALID if
+ * an invalid parameter is passed.
+ */
+extern enum lttng_evaluation_status
+lttng_evaluation_on_event_get_trigger_name(
+               const struct lttng_evaluation *evaluation,
+               const char **name);
+
+/*
+ * Sets `*field_val` to the array event field value of the on event
+ * condition evaluation `evaluation` which contains its captured values.
+ *
+ * Returns:
+ *
+ * `LTTNG_EVALUATION_STATUS_OK`:
+ *     Success.
+ *
+ *     `*field_val` is an array event field value with a length of at
+ *     least one.
+ *
+ * `LTTNG_EVALUATION_STATUS_INVALID`:
+ *     * `evaluation` is `NULL`.
+ *     * The type of the condition of `evaluation` is not
+ *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
+ *     * The condition of `evaluation` has no capture descriptors.
+ *     * `field_val` is `NULL`.
+ */
+extern enum lttng_evaluation_status
+lttng_evaluation_on_event_get_captured_values(
+               const struct lttng_evaluation *evaluation,
+               const struct lttng_event_field_value **field_val);
+
+/*
+ * Appends (transfering the ownership) the capture descriptor `expr` to
+ * the on event condition `condition`.
+ *
+ * Returns:
+ *
+ * `LTTNG_CONDITION_STATUS_OK`:
+ *     Success.
+ *
+ * `LTTNG_CONDITION_STATUS_ERROR`:
+ *     Memory error.
+ *
+ * `LTTNG_CONDITION_STATUS_INVALID`:
+ *     * `condition` is `NULL`.
+ *     * The type of `condition` is not
+ *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
+ *     * `expr` is `NULL`.
+ *     * `expr` is not a locator expression, that is, its type is not
+ *       one of:
+ *
+ *       * `LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD`
+ *       * `LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD`
+ *       * `LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD`
+ *       * `LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT`
+ *
+ * `LTTNG_CONDITION_STATUS_UNSUPPORTED`:
+ *     * The associated event-rule does not support runtime capture.
+ */
+extern enum lttng_condition_status
+lttng_condition_on_event_append_capture_descriptor(
+               struct lttng_condition *condition,
+               struct lttng_event_expr *expr);
+
+/*
+ * Sets `*count` to the number of capture descriptors in the on event
+ * condition `condition`.
+ *
+ * Returns:
+ *
+ * `LTTNG_CONDITION_STATUS_OK`:
+ *     Success.
+ *
+ * `LTTNG_CONDITION_STATUS_INVALID`:
+ *     * `condition` is `NULL`.
+ *     * The type of `condition` is not
+ *       `LTTNG_CONDITION_TYPE_ON_EVENT`.
+ *     * `count` is `NULL`.
+ */
+extern enum lttng_condition_status
+lttng_condition_on_event_get_capture_descriptor_count(
+               const struct lttng_condition *condition, unsigned int *count);
+
+/*
+ * Returns the capture descriptor (borrowed) of the on event condition
+ * `condition` at the index `index`, or `NULL` if:
+ *
+ * * `condition` is `NULL`.
+ * * The type of `condition` is not
+ *   `LTTNG_CONDITION_TYPE_ON_EVENT`.
+ * * `index` is greater than or equal to the number of capture
+ *   descriptors in `condition` (as returned by
+ *   lttng_condition_on_event_get_capture_descriptor_count()).
+ */
+extern const struct lttng_event_expr *
+lttng_condition_on_event_get_capture_descriptor_at_index(
+               const struct lttng_condition *condition, unsigned int index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LTTNG_CONDITION_ON_EVENT_H */
index 84032d1ec6f3da16976c46368101016fd9ff34c2..790943edf208850335b1bebe45ad4d7457d5cfc5 100644 (file)
@@ -29,7 +29,7 @@
 #include <lttng/condition/buffer-usage.h>
 #include <lttng/condition/condition.h>
 #include <lttng/condition/evaluation.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/condition/session-consumed-size.h>
 #include <lttng/condition/session-rotation.h>
 #include <lttng/constant.h>
index 69bf1f1d3ff7c4a5ebf607f8f93e36d7cffd58d6..7c2079ae97d40fa8f1bcb8de1b939de577f0a13e 100644 (file)
@@ -23,7 +23,7 @@
 #include <lttng/action/start-session.h>
 #include <lttng/action/stop-session.h>
 #include <lttng/condition/evaluation.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/lttng-error.h>
 #include <lttng/trigger/trigger-internal.h>
 #include <pthread.h>
index f9d98ab1ead6cd2ec20467ce8f6f026073b2d0f9..9832e5ef99b921c46577a6fdc83358712519e778 100644 (file)
@@ -15,7 +15,7 @@
 #include <lttng/event-rule/event-rule-internal.h>
 #include <lttng/event-rule/tracepoint.h>
 #include <lttng/condition/condition.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/domain-internal.h>
 
 #include <common/common.h>
index 6732a1c3c92c31289918c8188ba13eff0ec3a172..d3fc274c311a8ebb8bb0c70471f3cd98bfa5f6bd 100644 (file)
@@ -30,8 +30,8 @@
 #include <lttng/trigger/trigger-internal.h>
 #include <lttng/condition/condition.h>
 #include <lttng/condition/condition-internal.h>
-#include <lttng/condition/event-rule.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/event-rule/event-rule.h>
 #include <lttng/event-rule/event-rule-internal.h>
 #include <lttng/action/action.h>
index 0163a89774721d2e45536e20eb10274c960c938b..07b32f86d611367820e743ebea9a754b3ffe064c 100644 (file)
 #include <lttng/condition/buffer-usage-internal.h>
 #include <lttng/condition/session-consumed-size-internal.h>
 #include <lttng/condition/session-rotation-internal.h>
-#include <lttng/condition/event-rule-internal.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event-internal.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/event-rule/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
 #include "condition-internal.h"
 
 static
index 17f510154cc29c2a28a7a00c7bc6497f60702fb3..136617d7775d849b8b57c3be0026832ece3c30fb 100644 (file)
@@ -13,7 +13,7 @@
 #include <common/compat/errno.h>
 #include <lttng/lttng.h>
 #include <lttng/condition/condition.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/event-rule/event-rule.h>
 #include <lttng/event-rule/event-rule-internal.h>
 #include <common/bytecode/bytecode.h>
index 4e5216edcf3274acbc01937038b3fe8c52316fb7..bad864db05c4b56d35c0f6579c6764cfc5ffd605 100644 (file)
@@ -28,8 +28,8 @@
 
 #include <lttng/userspace-probe.h>
 #include <lttng/userspace-probe-internal.h>
-#include <lttng/condition/event-rule.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/event-rule/event-rule.h>
 #include <lttng/event-rule/event-rule-internal.h>
 #include <lttng/event-rule/userspace-probe-internal.h>
index aadc1b0a8b207edac646c8aa785ffc3b09f848f5..816456cd8263dd5d825c36bcc6cb09cb33cffa84 100644 (file)
@@ -28,7 +28,7 @@
 #include <lttng/condition/buffer-usage-internal.h>
 #include <lttng/condition/session-consumed-size-internal.h>
 #include <lttng/condition/session-rotation-internal.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/domain-internal.h>
 #include <lttng/notification/channel-internal.h>
 #include <lttng/trigger/trigger-internal.h>
index de22895022cb086e671a946d09ed2a49db71b651..81e3bd848a2b492695ef942df8928ee018f6987b 100644 (file)
@@ -26,8 +26,8 @@
 #include <lttng/event-rule/event-rule-internal.h>
 #include <lttng/event-rule/tracepoint.h>
 #include <lttng/condition/condition.h>
-#include <lttng/condition/event-rule-internal.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event-internal.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/trigger/trigger-internal.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 
index 154ab0faff216e5984e818e1240e7b5f92a0166d..9aca16b2ec9b3eed392c539d4d85e61e3ddcb9e8 100644 (file)
@@ -45,7 +45,7 @@ libcommon_la_SOURCES = \
        common.h \
        conditions/buffer-usage.c \
        conditions/condition.c \
-       conditions/event-rule.c \
+       conditions/on-event.c \
        conditions/session-consumed-size.c \
        conditions/session-rotation.c \
        context.c context.h \
index fa45ee22b573884106a18774d6cebd58b74c1d45..4948dbd3ffe5385aede0ff4d3b0b42842692fce2 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <lttng/condition/condition-internal.h>
 #include <lttng/condition/buffer-usage-internal.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/condition/session-consumed-size-internal.h>
 #include <lttng/condition/session-rotation-internal.h>
 #include <common/macros.h>
diff --git a/src/common/conditions/event-rule.c b/src/common/conditions/event-rule.c
deleted file mode 100644 (file)
index b121954..0000000
+++ /dev/null
@@ -1,1513 +0,0 @@
-/*
- * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
-#include <assert.h>
-#include <common/error.h>
-#include <common/event-expr-to-bytecode.h>
-#include <common/macros.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <lttng/condition/condition-internal.h>
-#include <lttng/event-rule/event-rule-internal.h>
-#include <lttng/condition/event-rule-internal.h>
-#include <lttng/condition/event-rule.h>
-#include <lttng/event-expr-internal.h>
-#include <lttng/event-expr.h>
-#include <lttng/event-field-value-internal.h>
-#include <lttng/event-rule/event-rule-internal.h>
-#include <lttng/lttng-error.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <vendor/msgpack/msgpack.h>
-
-#define IS_ON_EVENT_CONDITION(condition)      \
-       (lttng_condition_get_type(condition) == \
-                       LTTNG_CONDITION_TYPE_ON_EVENT)
-
-static bool is_on_event_evaluation(const struct lttng_evaluation *evaluation)
-{
-       enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
-
-       return type == LTTNG_CONDITION_TYPE_ON_EVENT;
-}
-
-static bool lttng_condition_on_event_validate(
-               const struct lttng_condition *condition);
-static int lttng_condition_on_event_serialize(
-               const struct lttng_condition *condition,
-               struct lttng_payload *payload);
-static bool lttng_condition_on_event_is_equal(
-               const struct lttng_condition *_a,
-               const struct lttng_condition *_b);
-static void lttng_condition_on_event_destroy(
-               struct lttng_condition *condition);
-
-static bool lttng_condition_on_event_validate(
-               const struct lttng_condition *condition)
-{
-       bool valid = false;
-       struct lttng_condition_on_event *event_rule;
-
-       if (!condition) {
-               goto end;
-       }
-
-       event_rule = container_of(
-                       condition, struct lttng_condition_on_event, parent);
-       if (!event_rule->rule) {
-               ERR("Invalid on event condition: a rule must be set");
-               goto end;
-       }
-
-       valid = lttng_event_rule_validate(event_rule->rule);
-end:
-       return valid;
-}
-
-static const char *msgpack_object_type_str(msgpack_object_type type)
-{
-       const char *name;
-
-       switch (type) {
-       case MSGPACK_OBJECT_NIL:
-               name = "MSGPACK_OBJECT_NIL";
-               break;
-       case MSGPACK_OBJECT_BOOLEAN:
-               name = "MSGPACK_OBJECT_BOOLEAN";
-               break;
-       case MSGPACK_OBJECT_POSITIVE_INTEGER:
-               name = "MSGPACK_OBJECT_POSITIVE_INTEGER";
-               break;
-       case MSGPACK_OBJECT_NEGATIVE_INTEGER:
-               name = "MSGPACK_OBJECT_NEGATIVE_INTEGER";
-               break;
-       case MSGPACK_OBJECT_FLOAT32:
-               name = "MSGPACK_OBJECT_FLOAT32";
-               break;
-       case MSGPACK_OBJECT_FLOAT:
-               /* Same value as MSGPACK_OBJECT_FLOAT64 */
-               name = "MSGPACK_OBJECT_FLOAT(64)";
-               break;
-       case MSGPACK_OBJECT_STR:
-               name = "MSGPACK_OBJECT_STR";
-               break;
-       case MSGPACK_OBJECT_ARRAY:
-               name = "MSGPACK_OBJECT_ARRAY";
-               break;
-       case MSGPACK_OBJECT_MAP:
-               name = "MSGPACK_OBJECT_MAP";
-               break;
-       case MSGPACK_OBJECT_BIN:
-               name = "MSGPACK_OBJECT_BIN";
-               break;
-       case MSGPACK_OBJECT_EXT:
-               name = "MSGPACK_OBJECT_EXT";
-               break;
-       default:
-               abort();
-       }
-
-       return name;
-}
-
-/*
- * Serializes the C string `str` into `buf`.
- *
- * Encoding is the length of `str` plus one (for the null character),
- * and then the string, including its null terminator.
- */
-static
-int serialize_cstr(const char *str, struct lttng_dynamic_buffer *buf)
-{
-       int ret;
-       const uint32_t len = strlen(str) + 1;
-
-       /* Serialize the length, including the null terminator. */
-       DBG("Serializing C string's length (including null terminator): "
-                       "%" PRIu32, len);
-       ret = lttng_dynamic_buffer_append(buf, &len, sizeof(len));
-       if (ret) {
-               goto end;
-       }
-
-       /* Serialize the string. */
-       DBG("Serializing C string: '%s'", str);
-       ret = lttng_dynamic_buffer_append(buf, str, len);
-       if (ret) {
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-/*
- * Serializes the event expression `expr` into `buf`.
- */
-static
-int serialize_event_expr(const struct lttng_event_expr *expr,
-               struct lttng_payload *payload)
-{
-       const uint8_t type = expr->type;
-       int ret;
-
-       /* Serialize the expression's type. */
-       DBG("Serializing event expression's type: %d", expr->type);
-       ret = lttng_dynamic_buffer_append(&payload->buffer, &type, sizeof(type));
-       if (ret) {
-               goto end;
-       }
-
-       /* Serialize the expression */
-       switch (expr->type) {
-       case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
-       case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
-       {
-               const struct lttng_event_expr_field *field_expr =
-                               container_of(expr,
-                                       const struct lttng_event_expr_field,
-                                       parent);
-
-               /* Serialize the field name. */
-               DBG("Serializing field event expression's field name: '%s'",
-                               field_expr->name);
-               ret = serialize_cstr(field_expr->name, &payload->buffer);
-               if (ret) {
-                       goto end;
-               }
-
-               break;
-       }
-       case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
-       {
-               const struct lttng_event_expr_app_specific_context_field *field_expr =
-                               container_of(expr,
-                                       const struct lttng_event_expr_app_specific_context_field,
-                                       parent);
-
-               /* Serialize the provider name. */
-               DBG("Serializing app-specific context field event expression's "
-                               "provider name: '%s'",
-                               field_expr->provider_name);
-               ret = serialize_cstr(field_expr->provider_name, &payload->buffer);
-               if (ret) {
-                       goto end;
-               }
-
-               /* Serialize the type name. */
-               DBG("Serializing app-specific context field event expression's "
-                               "type name: '%s'",
-                               field_expr->provider_name);
-               ret = serialize_cstr(field_expr->type_name, &payload->buffer);
-               if (ret) {
-                       goto end;
-               }
-
-               break;
-       }
-       case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
-       {
-               const struct lttng_event_expr_array_field_element *elem_expr =
-                               container_of(expr,
-                                       const struct lttng_event_expr_array_field_element,
-                                       parent);
-               const uint32_t index = elem_expr->index;
-
-               /* Serialize the index. */
-               DBG("Serializing array field element event expression's "
-                               "index: %u", elem_expr->index);
-               ret = lttng_dynamic_buffer_append(&payload->buffer, &index, sizeof(index));
-               if (ret) {
-                       goto end;
-               }
-
-               /* Serialize the parent array field expression. */
-               DBG("Serializing array field element event expression's "
-                               "parent array field event expression");
-               ret = serialize_event_expr(elem_expr->array_field_expr, payload);
-               if (ret) {
-                       goto end;
-               }
-
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return ret;
-}
-
-static
-struct lttng_capture_descriptor *
-lttng_condition_on_event_get_internal_capture_descriptor_at_index(
-               const struct lttng_condition *condition, unsigned int index)
-{
-       const struct lttng_condition_on_event *on_event_cond =
-                       container_of(condition,
-                               const struct lttng_condition_on_event,
-                               parent);
-       struct lttng_capture_descriptor *desc = NULL;
-       unsigned int count;
-       enum lttng_condition_status status;
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
-               goto end;
-       }
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition, &count);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto end;
-       }
-
-       if (index >= count) {
-               goto end;
-       }
-
-       desc = lttng_dynamic_pointer_array_get_pointer(
-                       &on_event_cond->capture_descriptors, index);
-end:
-       return desc;
-}
-
-static int lttng_condition_on_event_serialize(
-               const struct lttng_condition *condition,
-               struct lttng_payload *payload)
-{
-       int ret;
-       struct lttng_condition_on_event *on_event_condition;
-       enum lttng_condition_status status;
-       /* Used for iteration and communication (size matters). */
-       uint32_t i, capture_descr_count;
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
-               ret = -1;
-               goto end;
-       }
-
-       DBG("Serializing on event condition");
-       on_event_condition = container_of(
-                       condition, struct lttng_condition_on_event, parent);
-
-       DBG("Serializing on event condition's event rule");
-       ret = lttng_event_rule_serialize(on_event_condition->rule, payload);
-       if (ret) {
-               goto end;
-       }
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition, &capture_descr_count);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               ret = -1;
-               goto end;
-       };
-
-       DBG("Serializing on event condition's capture descriptor count: %" PRIu32,
-                       capture_descr_count);
-       ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count,
-                       sizeof(capture_descr_count));
-       if (ret) {
-               goto end;
-       }
-
-       for (i = 0; i < capture_descr_count; i++) {
-               const struct lttng_capture_descriptor *desc =
-                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
-                                               condition, i);
-
-               DBG("Serializing on event condition's capture descriptor %" PRIu32,
-                               i);
-               ret = serialize_event_expr(desc->event_expression, payload);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-static
-bool capture_descriptors_are_equal(
-               const struct lttng_condition *condition_a,
-               const struct lttng_condition *condition_b)
-{
-       bool is_equal = true;
-       unsigned int capture_descr_count_a;
-       unsigned int capture_descr_count_b;
-       size_t i;
-       enum lttng_condition_status status;
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition_a, &capture_descr_count_a);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto not_equal;
-       }
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition_b, &capture_descr_count_b);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto not_equal;
-       }
-
-       if (capture_descr_count_a != capture_descr_count_b) {
-               goto not_equal;
-       }
-
-       for (i = 0; i < capture_descr_count_a; i++) {
-               const struct lttng_event_expr *expr_a =
-                               lttng_condition_on_event_get_capture_descriptor_at_index(
-                                       condition_a,
-                                       i);
-               const struct lttng_event_expr *expr_b =
-                               lttng_condition_on_event_get_capture_descriptor_at_index(
-                                       condition_b,
-                                       i);
-
-               if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
-                       goto not_equal;
-               }
-       }
-
-       goto end;
-
-not_equal:
-       is_equal = false;
-
-end:
-       return is_equal;
-}
-
-static bool lttng_condition_on_event_is_equal(
-               const struct lttng_condition *_a,
-               const struct lttng_condition *_b)
-{
-       bool is_equal = false;
-       struct lttng_condition_on_event *a, *b;
-
-       a = container_of(_a, struct lttng_condition_on_event, parent);
-       b = container_of(_b, struct lttng_condition_on_event, parent);
-
-       /* Both event rules must be set or both must be unset. */
-       if ((a->rule && !b->rule) || (!a->rule && b->rule)) {
-               WARN("Comparing event_rule conditions with uninitialized rule");
-               goto end;
-       }
-
-       is_equal = lttng_event_rule_is_equal(a->rule, b->rule);
-       if (!is_equal) {
-               goto end;
-       }
-
-       is_equal = capture_descriptors_are_equal(_a, _b);
-
-end:
-       return is_equal;
-}
-
-static void lttng_condition_on_event_destroy(
-               struct lttng_condition *condition)
-{
-       struct lttng_condition_on_event *on_event_condition;
-
-       on_event_condition = container_of(
-                       condition, struct lttng_condition_on_event, parent);
-
-       lttng_event_rule_put(on_event_condition->rule);
-       lttng_dynamic_pointer_array_reset(&on_event_condition->capture_descriptors);
-       free(on_event_condition);
-}
-
-static
-void destroy_capture_descriptor(void *ptr)
-{
-       struct lttng_capture_descriptor *desc =
-                       (struct lttng_capture_descriptor *) ptr;
-
-       lttng_event_expr_destroy(desc->event_expression);
-       free(desc->bytecode);
-       free(desc);
-}
-
-struct lttng_condition *lttng_condition_on_event_create(
-               struct lttng_event_rule *rule)
-{
-       struct lttng_condition *parent = NULL;
-       struct lttng_condition_on_event *condition = NULL;
-
-       if (!rule) {
-               goto end;
-       }
-
-       condition = zmalloc(sizeof(struct lttng_condition_on_event));
-       if (!condition) {
-               return NULL;
-       }
-
-       lttng_condition_init(&condition->parent,
-                       LTTNG_CONDITION_TYPE_ON_EVENT);
-       condition->parent.validate = lttng_condition_on_event_validate,
-       condition->parent.serialize = lttng_condition_on_event_serialize,
-       condition->parent.equal = lttng_condition_on_event_is_equal,
-       condition->parent.destroy = lttng_condition_on_event_destroy,
-
-       lttng_event_rule_get(rule);
-       condition->rule = rule;
-       rule = NULL;
-
-       lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
-                       destroy_capture_descriptor);
-
-       parent = &condition->parent;
-end:
-       return parent;
-}
-
-static
-uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size,
-               size_t *offset)
-{
-       uint64_t ret;
-       const struct lttng_buffer_view uint_view =
-                       lttng_buffer_view_from_view(view, *offset, size);
-
-       if (!lttng_buffer_view_is_valid(&uint_view)) {
-               ret = UINT64_C(-1);
-               goto end;
-       }
-
-       switch (size) {
-       case 1:
-               ret = (uint64_t) *uint_view.data;
-               break;
-       case sizeof(uint32_t):
-       {
-               uint32_t u32;
-
-               memcpy(&u32, uint_view.data, sizeof(u32));
-               ret = (uint64_t) u32;
-               break;
-       }
-       case sizeof(ret):
-               memcpy(&ret, uint_view.data, sizeof(ret));
-               break;
-       default:
-               abort();
-       }
-
-       *offset += size;
-
-end:
-       return ret;
-}
-
-static
-const char *str_from_buffer(const struct lttng_buffer_view *view,
-               size_t *offset)
-{
-       uint64_t len;
-       const char *ret;
-
-       len = uint_from_buffer(view, sizeof(uint32_t), offset);
-       if (len == UINT64_C(-1)) {
-               goto error;
-       }
-
-       ret = &view->data[*offset];
-
-       if (!lttng_buffer_view_contains_string(view, ret, len)) {
-               goto error;
-       }
-
-       *offset += len;
-       goto end;
-
-error:
-       ret = NULL;
-
-end:
-       return ret;
-}
-
-static
-struct lttng_event_expr *event_expr_from_payload(
-               struct lttng_payload_view *view, size_t *offset)
-{
-       struct lttng_event_expr *expr = NULL;
-       const char *str;
-       uint64_t type;
-
-       type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
-       if (type == UINT64_C(-1)) {
-               goto error;
-       }
-
-       switch (type) {
-       case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
-               str = str_from_buffer(&view->buffer, offset);
-               if (!str) {
-                       goto error;
-               }
-
-               expr = lttng_event_expr_event_payload_field_create(str);
-               break;
-       case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
-               str = str_from_buffer(&view->buffer, offset);
-               if (!str) {
-                       goto error;
-               }
-
-               expr = lttng_event_expr_channel_context_field_create(str);
-               break;
-       case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
-       {
-               const char *provider_name;
-               const char *type_name;
-
-               provider_name = str_from_buffer(&view->buffer, offset);
-               if (!provider_name) {
-                       goto error;
-               }
-
-               type_name = str_from_buffer(&view->buffer, offset);
-               if (!type_name) {
-                       goto error;
-               }
-
-               expr = lttng_event_expr_app_specific_context_field_create(
-                               provider_name, type_name);
-               break;
-       }
-       case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
-       {
-               struct lttng_event_expr *array_field_expr;
-               const uint64_t index = uint_from_buffer(
-                               &view->buffer, sizeof(uint32_t), offset);
-
-               if (index == UINT64_C(-1)) {
-                       goto error;
-               }
-
-               /* Array field expression is the encoded after this. */
-               array_field_expr = event_expr_from_payload(view, offset);
-               if (!array_field_expr) {
-                       goto error;
-               }
-
-               /* Move ownership of `array_field_expr` to new expression. */
-               expr = lttng_event_expr_array_field_element_create(
-                               array_field_expr, (unsigned int) index);
-               if (!expr) {
-                       /* `array_field_expr` not moved: destroy it. */
-                       lttng_event_expr_destroy(array_field_expr);
-               }
-
-               break;
-       }
-       default:
-               abort();
-       }
-
-       goto end;
-
-error:
-       lttng_event_expr_destroy(expr);
-       expr = NULL;
-
-end:
-       return expr;
-}
-
-LTTNG_HIDDEN
-ssize_t lttng_condition_on_event_create_from_payload(
-               struct lttng_payload_view *view,
-               struct lttng_condition **_condition)
-{
-       ssize_t consumed_length;
-       size_t offset = 0;
-       ssize_t event_rule_length;
-       uint32_t i, capture_descr_count;
-       struct lttng_condition *condition = NULL;
-       struct lttng_event_rule *event_rule = NULL;
-
-       if (!view || !_condition) {
-               goto error;
-       }
-
-       /* Struct lttng_event_rule. */
-       {
-               struct lttng_payload_view event_rule_view =
-                               lttng_payload_view_from_view(view, offset, -1);
-
-               event_rule_length = lttng_event_rule_create_from_payload(
-                               &event_rule_view, &event_rule);
-       }
-
-       if (event_rule_length < 0 || !event_rule) {
-               goto error;
-       }
-
-       /* Create condition (no capture descriptors yet) at this point */
-       condition = lttng_condition_on_event_create(event_rule);
-       if (!condition) {
-               goto error;
-       }
-
-       /* Capture descriptor count. */
-       assert(event_rule_length >= 0);
-       offset += (size_t) event_rule_length;
-       capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
-       if (capture_descr_count == UINT32_C(-1)) {
-               goto error;
-       }
-
-       /* Capture descriptors. */
-       for (i = 0; i < capture_descr_count; i++) {
-               enum lttng_condition_status status;
-               struct lttng_event_expr *expr = event_expr_from_payload(
-                               view, &offset);
-
-               if (!expr) {
-                       goto error;
-               }
-
-               /* Move ownership of `expr` to `condition`. */
-               status = lttng_condition_on_event_append_capture_descriptor(
-                               condition, expr);
-               if (status != LTTNG_CONDITION_STATUS_OK) {
-                       /* `expr` not moved: destroy it. */
-                       lttng_event_expr_destroy(expr);
-                       goto error;
-               }
-       }
-
-       consumed_length = (ssize_t) offset;
-       *_condition = condition;
-       condition = NULL;
-       goto end;
-
-error:
-       consumed_length = -1;
-
-end:
-       lttng_event_rule_put(event_rule);
-       lttng_condition_put(condition);
-       return consumed_length;
-}
-
-LTTNG_HIDDEN
-enum lttng_condition_status lttng_condition_on_event_borrow_rule_mutable(
-               const struct lttng_condition *condition,
-               struct lttng_event_rule **rule)
-{
-       struct lttng_condition_on_event *event_rule;
-       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !rule) {
-               status = LTTNG_CONDITION_STATUS_INVALID;
-               goto end;
-       }
-
-       event_rule = container_of(
-                       condition, struct lttng_condition_on_event, parent);
-       if (!event_rule->rule) {
-               status = LTTNG_CONDITION_STATUS_UNSET;
-               goto end;
-       }
-
-       *rule = event_rule->rule;
-end:
-       return status;
-}
-
-enum lttng_condition_status lttng_condition_on_event_get_rule(
-               const struct lttng_condition *condition,
-               const struct lttng_event_rule **rule)
-{
-       struct lttng_event_rule *mutable_rule = NULL;
-       const enum lttng_condition_status status =
-                       lttng_condition_on_event_borrow_rule_mutable(
-                               condition, &mutable_rule);
-
-       *rule = mutable_rule;
-       return status;
-}
-
-enum lttng_condition_status
-lttng_condition_on_event_append_capture_descriptor(
-               struct lttng_condition *condition,
-               struct lttng_event_expr *expr)
-{
-       int ret;
-       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
-       struct lttng_condition_on_event *event_rule_cond =
-                       container_of(condition,
-                               struct lttng_condition_on_event, parent);
-       struct lttng_capture_descriptor *descriptor = NULL;
-       const struct lttng_event_rule *rule = NULL;
-
-       /* Only accept l-values. */
-       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !expr ||
-                       !lttng_event_expr_is_lvalue(expr)) {
-               status = LTTNG_CONDITION_STATUS_INVALID;
-               goto end;
-       }
-
-       status = lttng_condition_on_event_get_rule(condition, &rule);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto end;
-       }
-
-       switch(lttng_event_rule_get_type(rule)) {
-       case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
-       case LTTNG_EVENT_RULE_TYPE_SYSCALL:
-               /* Supported. */
-               status = LTTNG_CONDITION_STATUS_OK;
-               break;
-       case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
-               status = LTTNG_CONDITION_STATUS_INVALID;
-               break;
-       default:
-               status = LTTNG_CONDITION_STATUS_UNSUPPORTED;
-               break;
-       }
-
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto end;
-       }
-
-       descriptor = malloc(sizeof(*descriptor));
-       if (descriptor == NULL) {
-               status = LTTNG_CONDITION_STATUS_ERROR;
-               goto end;
-       }
-
-       descriptor->event_expression = expr;
-       descriptor->bytecode = NULL;
-
-       ret = lttng_dynamic_pointer_array_add_pointer(
-                       &event_rule_cond->capture_descriptors, descriptor);
-       if (ret) {
-               status = LTTNG_CONDITION_STATUS_ERROR;
-               goto end;
-       }
-
-       /* Ownership is transfered to the internal capture_descriptors array */
-       descriptor = NULL;
-end:
-       free(descriptor);
-       return status;
-}
-
-enum lttng_condition_status
-lttng_condition_on_event_get_capture_descriptor_count(
-               const struct lttng_condition *condition, unsigned int *count)
-{
-       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
-       const struct lttng_condition_on_event *on_event_condition =
-                       container_of(condition,
-                               const struct lttng_condition_on_event,
-                               parent);
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !count) {
-               status = LTTNG_CONDITION_STATUS_INVALID;
-               goto end;
-       }
-
-       *count = lttng_dynamic_pointer_array_get_count(
-                       &on_event_condition->capture_descriptors);
-
-end:
-       return status;
-}
-
-const struct lttng_event_expr *
-lttng_condition_on_event_get_capture_descriptor_at_index(
-               const struct lttng_condition *condition, unsigned int index)
-{
-       const struct lttng_event_expr *expr = NULL;
-       const struct lttng_capture_descriptor *desc = NULL;
-
-       desc = lttng_condition_on_event_get_internal_capture_descriptor_at_index(
-                       condition, index);
-       if (desc == NULL) {
-               goto end;
-       }
-       expr = desc->event_expression;
-
-end:
-       return expr;
-}
-
-LTTNG_HIDDEN
-ssize_t lttng_evaluation_on_event_create_from_payload(
-               const struct lttng_condition_on_event *condition,
-               struct lttng_payload_view *view,
-               struct lttng_evaluation **_evaluation)
-{
-       ssize_t ret, offset = 0;
-       const char *trigger_name;
-       struct lttng_evaluation *evaluation = NULL;
-       const struct lttng_evaluation_on_event_comm *header;
-       const struct lttng_payload_view header_view =
-                       lttng_payload_view_from_view(
-                                       view, 0, sizeof(*header));
-       uint32_t capture_payload_size;
-       const char *capture_payload = NULL;
-
-       if (!_evaluation) {
-               ret = -1;
-               goto error;
-       }
-
-       if (!lttng_payload_view_is_valid(&header_view)) {
-               ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
-               ret = -1;
-               goto error;
-       }
-
-       header = (typeof(header)) header_view.buffer.data;
-
-       /* Map the originating trigger's name. */
-       offset += sizeof(*header);
-       {
-               const struct lttng_payload_view current_view =
-                               lttng_payload_view_from_view(view, offset,
-                                               header->trigger_name_length);
-
-               if (!lttng_payload_view_is_valid(&current_view)) {
-                       ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
-                       ret = -1;
-                       goto error;
-               }
-
-               trigger_name = current_view.buffer.data;
-               if (!lttng_buffer_view_contains_string(&current_view.buffer,
-                                   trigger_name, header->trigger_name_length)) {
-                       ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
-                       ret = -1;
-                       goto error;
-               }
-       }
-
-       offset += header->trigger_name_length;
-       {
-               const struct lttng_payload_view current_view =
-                               lttng_payload_view_from_view(view, offset, -1);
-
-               if (current_view.buffer.size < sizeof(capture_payload_size)) {
-                       ret = -1;
-                       goto error;
-               }
-
-               memcpy(&capture_payload_size, current_view.buffer.data,
-                               sizeof(capture_payload_size));
-       }
-       offset += sizeof(capture_payload_size);
-
-       if (capture_payload_size > 0) {
-               const struct lttng_payload_view current_view =
-                               lttng_payload_view_from_view(view, offset, -1);
-
-               if (current_view.buffer.size < capture_payload_size) {
-                       ret = -1;
-                       goto error;
-               }
-
-               capture_payload = current_view.buffer.data;
-       }
-
-       evaluation = lttng_evaluation_on_event_create(condition, trigger_name,
-                       capture_payload, capture_payload_size, true);
-       if (!evaluation) {
-               ret = -1;
-               goto error;
-       }
-
-       offset += capture_payload_size;
-       *_evaluation = evaluation;
-       evaluation = NULL;
-       ret = offset;
-
-error:
-       lttng_evaluation_destroy(evaluation);
-       return ret;
-}
-
-static int lttng_evaluation_on_event_serialize(
-               const struct lttng_evaluation *evaluation,
-               struct lttng_payload *payload)
-{
-       int ret = 0;
-       struct lttng_evaluation_on_event *hit;
-       struct lttng_evaluation_on_event_comm comm;
-       uint32_t capture_payload_size;
-
-       hit = container_of(
-                       evaluation, struct lttng_evaluation_on_event, parent);
-
-       assert(hit->name);
-       comm.trigger_name_length = strlen(hit->name) + 1;
-
-       ret = lttng_dynamic_buffer_append(
-                       &payload->buffer, &comm, sizeof(comm));
-       if (ret) {
-               goto end;
-       }
-
-       ret = lttng_dynamic_buffer_append(
-                       &payload->buffer, hit->name, comm.trigger_name_length);
-       if (ret) {
-               goto end;
-       }
-
-       capture_payload_size = (uint32_t) hit->capture_payload.size;
-       ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_payload_size,
-                       sizeof(capture_payload_size));
-       if (ret) {
-               goto end;
-       }
-
-       ret = lttng_dynamic_buffer_append(&payload->buffer, hit->capture_payload.data,
-                       hit->capture_payload.size);
-       if (ret) {
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-static
-bool msgpack_str_is_equal(const struct msgpack_object *obj, const char *str)
-{
-       bool is_equal = true;
-
-       assert(obj->type == MSGPACK_OBJECT_STR);
-
-       if (obj->via.str.size != strlen(str)) {
-               is_equal = false;
-               goto end;
-       }
-
-       if (strncmp(obj->via.str.ptr, str, obj->via.str.size) != 0) {
-               is_equal = false;
-               goto end;
-       }
-
-end:
-       return is_equal;
-}
-
-static
-const msgpack_object *get_msgpack_map_obj(const struct msgpack_object *map_obj,
-               const char *name)
-{
-       const msgpack_object *ret = NULL;
-       size_t i;
-
-       assert(map_obj->type == MSGPACK_OBJECT_MAP);
-
-       for (i = 0; i < map_obj->via.map.size; i++) {
-               const struct msgpack_object_kv *kv = &map_obj->via.map.ptr[i];
-
-               assert(kv->key.type == MSGPACK_OBJECT_STR);
-
-               if (msgpack_str_is_equal(&kv->key, name)) {
-                       ret = &kv->val;
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-static void lttng_evaluation_on_event_destroy(
-               struct lttng_evaluation *evaluation)
-{
-       struct lttng_evaluation_on_event *hit;
-
-       hit = container_of(
-                       evaluation, struct lttng_evaluation_on_event, parent);
-       free(hit->name);
-       lttng_dynamic_buffer_reset(&hit->capture_payload);
-       lttng_event_field_value_destroy(hit->captured_values);
-       free(hit);
-}
-
-static
-int event_field_value_from_obj(const msgpack_object *obj,
-               struct lttng_event_field_value **field_val)
-{
-       int ret = 0;
-
-       assert(obj);
-       assert(field_val);
-
-       switch (obj->type) {
-       case MSGPACK_OBJECT_NIL:
-               /* Unavailable. */
-               *field_val = NULL;
-               goto end;
-       case MSGPACK_OBJECT_POSITIVE_INTEGER:
-               *field_val = lttng_event_field_value_uint_create(
-                               obj->via.u64);
-               break;
-       case MSGPACK_OBJECT_NEGATIVE_INTEGER:
-               *field_val = lttng_event_field_value_int_create(
-                               obj->via.i64);
-               break;
-       case MSGPACK_OBJECT_FLOAT32:
-       case MSGPACK_OBJECT_FLOAT64:
-               *field_val = lttng_event_field_value_real_create(
-                               obj->via.f64);
-               break;
-       case MSGPACK_OBJECT_STR:
-               *field_val = lttng_event_field_value_string_create_with_size(
-                               obj->via.str.ptr, obj->via.str.size);
-               break;
-       case MSGPACK_OBJECT_ARRAY:
-       {
-               size_t i;
-
-               *field_val = lttng_event_field_value_array_create();
-               if (!*field_val) {
-                       goto error;
-               }
-
-               for (i = 0; i < obj->via.array.size; i++) {
-                       const msgpack_object *elem_obj = &obj->via.array.ptr[i];
-                       struct lttng_event_field_value *elem_field_val;
-
-                       ret = event_field_value_from_obj(elem_obj,
-                                       &elem_field_val);
-                       if (ret) {
-                               goto error;
-                       }
-
-                       if (elem_field_val) {
-                               ret = lttng_event_field_value_array_append(
-                                               *field_val, elem_field_val);
-                       } else {
-                               ret = lttng_event_field_value_array_append_unavailable(
-                                               *field_val);
-                       }
-
-                       if (ret) {
-                               lttng_event_field_value_destroy(elem_field_val);
-                               goto error;
-                       }
-               }
-
-               break;
-       }
-       case MSGPACK_OBJECT_MAP:
-       {
-               /*
-                * As of this version, the only valid map object is
-                * for an enumeration value, for example:
-                *
-                *     type: enum
-                *     value: 177
-                *     labels:
-                *     - Labatt 50
-                *     - Molson Dry
-                *     - Carling Black Label
-                */
-               const msgpack_object *inner_obj;
-               size_t label_i;
-
-               inner_obj = get_msgpack_map_obj(obj, "type");
-               if (!inner_obj) {
-                       ERR("Missing `type` entry in map object");
-                       goto error;
-               }
-
-               if (inner_obj->type != MSGPACK_OBJECT_STR) {
-                       ERR("Map object's `type` entry is not a string: type = %s",
-                                       msgpack_object_type_str(inner_obj->type));
-                       goto error;
-               }
-
-               if (!msgpack_str_is_equal(inner_obj, "enum")) {
-                       ERR("Map object's `type` entry: expecting `enum`");
-                       goto error;
-               }
-
-               inner_obj = get_msgpack_map_obj(obj, "value");
-               if (!inner_obj) {
-                       ERR("Missing `value` entry in map object");
-                       goto error;
-               }
-
-               if (inner_obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
-                       *field_val = lttng_event_field_value_enum_uint_create(
-                                       inner_obj->via.u64);
-               } else if (inner_obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
-                       *field_val = lttng_event_field_value_enum_int_create(
-                                       inner_obj->via.i64);
-               } else {
-                       ERR("Map object's `value` entry is not an integer: type = %s",
-                                       msgpack_object_type_str(inner_obj->type));
-                       goto error;
-               }
-
-               if (!*field_val) {
-                       goto error;
-               }
-
-               inner_obj = get_msgpack_map_obj(obj, "labels");
-               if (!inner_obj) {
-                       /* No labels */
-                       goto end;
-               }
-
-               if (inner_obj->type != MSGPACK_OBJECT_ARRAY) {
-                       ERR("Map object's `labels` entry is not an array: type = %s",
-                                       msgpack_object_type_str(inner_obj->type));
-                       goto error;
-               }
-
-               for (label_i = 0; label_i < inner_obj->via.array.size;
-                               label_i++) {
-                       int iret;
-                       const msgpack_object *elem_obj =
-                                       &inner_obj->via.array.ptr[label_i];
-
-                       if (elem_obj->type != MSGPACK_OBJECT_STR) {
-                               ERR("Map object's `labels` entry's type is not a string: type = %s",
-                                               msgpack_object_type_str(elem_obj->type));
-                               goto error;
-                       }
-
-                       iret = lttng_event_field_value_enum_append_label_with_size(
-                                       *field_val, elem_obj->via.str.ptr,
-                                       elem_obj->via.str.size);
-                       if (iret) {
-                               goto error;
-                       }
-               }
-
-               break;
-       }
-       default:
-               ERR("Unexpected object type: type = %s",
-                               msgpack_object_type_str(obj->type));
-               goto error;
-       }
-
-       if (!*field_val) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       lttng_event_field_value_destroy(*field_val);
-       *field_val = NULL;
-       ret = -1;
-
-end:
-       return ret;
-}
-
-static
-struct lttng_event_field_value *event_field_value_from_capture_payload(
-               const struct lttng_condition_on_event *condition,
-               const char *capture_payload, size_t capture_payload_size)
-{
-       struct lttng_event_field_value *ret = NULL;
-       msgpack_unpacked unpacked;
-       msgpack_unpack_return unpack_return;
-       const msgpack_object *root_obj;
-       const msgpack_object_array *root_array_obj;
-       size_t i;
-       size_t count;
-
-       assert(condition);
-       assert(capture_payload);
-
-       /* Initialize value. */
-       msgpack_unpacked_init(&unpacked);
-
-       /* Decode. */
-       unpack_return = msgpack_unpack_next(&unpacked, capture_payload,
-                       capture_payload_size, NULL);
-       if (unpack_return != MSGPACK_UNPACK_SUCCESS) {
-               ERR("msgpack_unpack_next() failed to decode the "
-                               "MessagePack-encoded capture payload: "
-                               "size = %zu, ret = %d",
-                               capture_payload_size, unpack_return);
-               goto error;
-       }
-
-       /* Get root array. */
-       root_obj = &unpacked.data;
-
-       if (root_obj->type != MSGPACK_OBJECT_ARRAY) {
-               ERR("Expecting an array as the root object: type = %s",
-                               msgpack_object_type_str(root_obj->type));
-               goto error;
-       }
-
-       root_array_obj = &root_obj->via.array;
-
-       /* Create an empty root array event field value. */
-       ret = lttng_event_field_value_array_create();
-       if (!ret) {
-               goto error;
-       }
-
-       /*
-        * For each capture descriptor in the condition object:
-        *
-        * 1. Get its corresponding captured field value MessagePack
-        *    object.
-        *
-        * 2. Create a corresponding event field value.
-        *
-        * 3. Append it to `ret` (the root array event field value).
-        */
-       count = lttng_dynamic_pointer_array_get_count(
-                       &condition->capture_descriptors);
-       assert(count > 0);
-
-       for (i = 0; i < count; i++) {
-               const struct lttng_capture_descriptor *capture_descriptor =
-                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
-                                               &condition->parent, i);
-               const msgpack_object *elem_obj;
-               struct lttng_event_field_value *elem_field_val;
-               int iret;
-
-               assert(capture_descriptor);
-
-               elem_obj = &root_array_obj->ptr[i];
-               iret = event_field_value_from_obj(elem_obj,
-                               &elem_field_val);
-               if (iret) {
-                       goto error;
-               }
-
-               if (elem_field_val) {
-                       iret = lttng_event_field_value_array_append(ret,
-                                       elem_field_val);
-               } else {
-                       iret = lttng_event_field_value_array_append_unavailable(
-                                       ret);
-               }
-
-               if (iret) {
-                       lttng_event_field_value_destroy(elem_field_val);
-                       goto error;
-               }
-       }
-
-       goto end;
-
-error:
-       lttng_event_field_value_destroy(ret);
-       ret = NULL;
-
-end:
-       msgpack_unpacked_destroy(&unpacked);
-       return ret;
-}
-
-LTTNG_HIDDEN
-struct lttng_evaluation *lttng_evaluation_on_event_create(
-               const struct lttng_condition_on_event *condition,
-               const char *trigger_name,
-               const char *capture_payload, size_t capture_payload_size,
-               bool decode_capture_payload)
-{
-       struct lttng_evaluation_on_event *hit;
-       struct lttng_evaluation *evaluation = NULL;
-
-       hit = zmalloc(sizeof(struct lttng_evaluation_on_event));
-       if (!hit) {
-               goto error;
-       }
-
-       hit->name = strdup(trigger_name);
-       if (!hit->name) {
-               goto error;
-       }
-
-       lttng_dynamic_buffer_init(&hit->capture_payload);
-
-       if (capture_payload) {
-               const int ret = lttng_dynamic_buffer_append(
-                               &hit->capture_payload, capture_payload,
-                               capture_payload_size);
-               if (ret) {
-                       ERR("Failed to initialize capture payload of event rule evaluation");
-                       goto error;
-               }
-
-               if (decode_capture_payload) {
-                       hit->captured_values =
-                                       event_field_value_from_capture_payload(
-                                               condition,
-                                               capture_payload,
-                                               capture_payload_size);
-                       if (!hit->captured_values) {
-                               ERR("Failed to decode the capture payload: size = %zu",
-                                               capture_payload_size);
-                               goto error;
-                       }
-               }
-       }
-
-       hit->parent.type = LTTNG_CONDITION_TYPE_ON_EVENT;
-       hit->parent.serialize = lttng_evaluation_on_event_serialize;
-       hit->parent.destroy = lttng_evaluation_on_event_destroy;
-
-       evaluation = &hit->parent;
-       hit = NULL;
-
-error:
-       if (hit) {
-               lttng_evaluation_on_event_destroy(&hit->parent);
-       }
-
-       return evaluation;
-}
-
-enum lttng_evaluation_status lttng_evaluation_on_event_get_captured_values(
-               const struct lttng_evaluation *evaluation,
-               const struct lttng_event_field_value **field_val)
-{
-       struct lttng_evaluation_on_event *hit;
-       enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
-
-       if (!evaluation || !is_on_event_evaluation(evaluation) ||
-                       !field_val) {
-               status = LTTNG_EVALUATION_STATUS_INVALID;
-               goto end;
-       }
-
-       hit = container_of(evaluation, struct lttng_evaluation_on_event,
-                       parent);
-       if (!hit->captured_values) {
-               status = LTTNG_EVALUATION_STATUS_INVALID;
-               goto end;
-       }
-
-       *field_val = hit->captured_values;
-
-end:
-       return status;
-}
-
-enum lttng_evaluation_status lttng_evaluation_on_event_get_trigger_name(
-               const struct lttng_evaluation *evaluation, const char **name)
-{
-       struct lttng_evaluation_on_event *hit;
-       enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
-
-       if (!evaluation || !is_on_event_evaluation(evaluation) || !name) {
-               status = LTTNG_EVALUATION_STATUS_INVALID;
-               goto end;
-       }
-
-       hit = container_of(
-                       evaluation, struct lttng_evaluation_on_event, parent);
-       *name = hit->name;
-end:
-       return status;
-}
-
-LTTNG_HIDDEN
-enum lttng_error_code
-lttng_condition_on_event_generate_capture_descriptor_bytecode(
-               struct lttng_condition *condition)
-{
-       enum lttng_error_code ret;
-       enum lttng_condition_status status;
-       unsigned int capture_count, i;
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
-               ret = LTTNG_ERR_FATAL;
-               goto end;
-       }
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition, &capture_count);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               ret = LTTNG_ERR_FATAL;
-               goto end;
-       }
-
-       for (i = 0; i < capture_count; i++) {
-               struct lttng_capture_descriptor *local_capture_desc =
-                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
-                                               condition, i);
-
-               if (local_capture_desc == NULL) {
-                       ret = LTTNG_ERR_FATAL;
-                       goto end;
-               }
-
-               /* Generate the bytecode. */
-               status = lttng_event_expr_to_bytecode(
-                               local_capture_desc->event_expression,
-                               &local_capture_desc->bytecode);
-               if (status < 0 || local_capture_desc->bytecode == NULL) {
-                       ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
-                       goto end;
-               }
-       }
-
-       /* Everything went better than expected */
-       ret = LTTNG_OK;
-
-end:
-       return ret;
-}
-
-LTTNG_HIDDEN
-const struct lttng_bytecode *
-lttng_condition_on_event_get_capture_bytecode_at_index(
-               const struct lttng_condition *condition, unsigned int index)
-{
-       const struct lttng_condition_on_event *event_rule_cond =
-                       container_of(condition,
-                               const struct lttng_condition_on_event,
-                               parent);
-       struct lttng_capture_descriptor *desc = NULL;
-       struct lttng_bytecode *bytecode = NULL;
-       unsigned int count;
-       enum lttng_condition_status status;
-
-       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
-               goto end;
-       }
-
-       status = lttng_condition_on_event_get_capture_descriptor_count(
-                       condition, &count);
-       if (status != LTTNG_CONDITION_STATUS_OK) {
-               goto end;
-       }
-
-       if (index >= count) {
-               goto end;
-       }
-
-       desc = lttng_dynamic_pointer_array_get_pointer(
-                       &event_rule_cond->capture_descriptors, index);
-       if (desc == NULL) {
-               goto end;
-       }
-
-       bytecode = desc->bytecode;
-end:
-       return bytecode;
-}
diff --git a/src/common/conditions/on-event.c b/src/common/conditions/on-event.c
new file mode 100644 (file)
index 0000000..a10df86
--- /dev/null
@@ -0,0 +1,1512 @@
+/*
+ * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <assert.h>
+#include <common/error.h>
+#include <common/event-expr-to-bytecode.h>
+#include <common/macros.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <lttng/condition/condition-internal.h>
+#include <lttng/condition/on-event-internal.h>
+#include <lttng/condition/on-event.h>
+#include <lttng/event-expr-internal.h>
+#include <lttng/event-expr.h>
+#include <lttng/event-field-value-internal.h>
+#include <lttng/event-rule/event-rule-internal.h>
+#include <lttng/lttng-error.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <vendor/msgpack/msgpack.h>
+
+#define IS_ON_EVENT_CONDITION(condition)      \
+       (lttng_condition_get_type(condition) == \
+                       LTTNG_CONDITION_TYPE_ON_EVENT)
+
+static bool is_on_event_evaluation(const struct lttng_evaluation *evaluation)
+{
+       enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
+
+       return type == LTTNG_CONDITION_TYPE_ON_EVENT;
+}
+
+static bool lttng_condition_on_event_validate(
+               const struct lttng_condition *condition);
+static int lttng_condition_on_event_serialize(
+               const struct lttng_condition *condition,
+               struct lttng_payload *payload);
+static bool lttng_condition_on_event_is_equal(
+               const struct lttng_condition *_a,
+               const struct lttng_condition *_b);
+static void lttng_condition_on_event_destroy(
+               struct lttng_condition *condition);
+
+static bool lttng_condition_on_event_validate(
+               const struct lttng_condition *condition)
+{
+       bool valid = false;
+       struct lttng_condition_on_event *event_rule;
+
+       if (!condition) {
+               goto end;
+       }
+
+       event_rule = container_of(
+                       condition, struct lttng_condition_on_event, parent);
+       if (!event_rule->rule) {
+               ERR("Invalid on event condition: a rule must be set");
+               goto end;
+       }
+
+       valid = lttng_event_rule_validate(event_rule->rule);
+end:
+       return valid;
+}
+
+static const char *msgpack_object_type_str(msgpack_object_type type)
+{
+       const char *name;
+
+       switch (type) {
+       case MSGPACK_OBJECT_NIL:
+               name = "MSGPACK_OBJECT_NIL";
+               break;
+       case MSGPACK_OBJECT_BOOLEAN:
+               name = "MSGPACK_OBJECT_BOOLEAN";
+               break;
+       case MSGPACK_OBJECT_POSITIVE_INTEGER:
+               name = "MSGPACK_OBJECT_POSITIVE_INTEGER";
+               break;
+       case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+               name = "MSGPACK_OBJECT_NEGATIVE_INTEGER";
+               break;
+       case MSGPACK_OBJECT_FLOAT32:
+               name = "MSGPACK_OBJECT_FLOAT32";
+               break;
+       case MSGPACK_OBJECT_FLOAT:
+               /* Same value as MSGPACK_OBJECT_FLOAT64 */
+               name = "MSGPACK_OBJECT_FLOAT(64)";
+               break;
+       case MSGPACK_OBJECT_STR:
+               name = "MSGPACK_OBJECT_STR";
+               break;
+       case MSGPACK_OBJECT_ARRAY:
+               name = "MSGPACK_OBJECT_ARRAY";
+               break;
+       case MSGPACK_OBJECT_MAP:
+               name = "MSGPACK_OBJECT_MAP";
+               break;
+       case MSGPACK_OBJECT_BIN:
+               name = "MSGPACK_OBJECT_BIN";
+               break;
+       case MSGPACK_OBJECT_EXT:
+               name = "MSGPACK_OBJECT_EXT";
+               break;
+       default:
+               abort();
+       }
+
+       return name;
+}
+
+/*
+ * Serializes the C string `str` into `buf`.
+ *
+ * Encoding is the length of `str` plus one (for the null character),
+ * and then the string, including its null terminator.
+ */
+static
+int serialize_cstr(const char *str, struct lttng_dynamic_buffer *buf)
+{
+       int ret;
+       const uint32_t len = strlen(str) + 1;
+
+       /* Serialize the length, including the null terminator. */
+       DBG("Serializing C string's length (including null terminator): "
+                       "%" PRIu32, len);
+       ret = lttng_dynamic_buffer_append(buf, &len, sizeof(len));
+       if (ret) {
+               goto end;
+       }
+
+       /* Serialize the string. */
+       DBG("Serializing C string: '%s'", str);
+       ret = lttng_dynamic_buffer_append(buf, str, len);
+       if (ret) {
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * Serializes the event expression `expr` into `buf`.
+ */
+static
+int serialize_event_expr(const struct lttng_event_expr *expr,
+               struct lttng_payload *payload)
+{
+       const uint8_t type = expr->type;
+       int ret;
+
+       /* Serialize the expression's type. */
+       DBG("Serializing event expression's type: %d", expr->type);
+       ret = lttng_dynamic_buffer_append(&payload->buffer, &type, sizeof(type));
+       if (ret) {
+               goto end;
+       }
+
+       /* Serialize the expression */
+       switch (expr->type) {
+       case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
+       case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
+       {
+               const struct lttng_event_expr_field *field_expr =
+                               container_of(expr,
+                                       const struct lttng_event_expr_field,
+                                       parent);
+
+               /* Serialize the field name. */
+               DBG("Serializing field event expression's field name: '%s'",
+                               field_expr->name);
+               ret = serialize_cstr(field_expr->name, &payload->buffer);
+               if (ret) {
+                       goto end;
+               }
+
+               break;
+       }
+       case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
+       {
+               const struct lttng_event_expr_app_specific_context_field *field_expr =
+                               container_of(expr,
+                                       const struct lttng_event_expr_app_specific_context_field,
+                                       parent);
+
+               /* Serialize the provider name. */
+               DBG("Serializing app-specific context field event expression's "
+                               "provider name: '%s'",
+                               field_expr->provider_name);
+               ret = serialize_cstr(field_expr->provider_name, &payload->buffer);
+               if (ret) {
+                       goto end;
+               }
+
+               /* Serialize the type name. */
+               DBG("Serializing app-specific context field event expression's "
+                               "type name: '%s'",
+                               field_expr->provider_name);
+               ret = serialize_cstr(field_expr->type_name, &payload->buffer);
+               if (ret) {
+                       goto end;
+               }
+
+               break;
+       }
+       case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
+       {
+               const struct lttng_event_expr_array_field_element *elem_expr =
+                               container_of(expr,
+                                       const struct lttng_event_expr_array_field_element,
+                                       parent);
+               const uint32_t index = elem_expr->index;
+
+               /* Serialize the index. */
+               DBG("Serializing array field element event expression's "
+                               "index: %u", elem_expr->index);
+               ret = lttng_dynamic_buffer_append(&payload->buffer, &index, sizeof(index));
+               if (ret) {
+                       goto end;
+               }
+
+               /* Serialize the parent array field expression. */
+               DBG("Serializing array field element event expression's "
+                               "parent array field event expression");
+               ret = serialize_event_expr(elem_expr->array_field_expr, payload);
+               if (ret) {
+                       goto end;
+               }
+
+               break;
+       }
+       default:
+               break;
+       }
+
+end:
+       return ret;
+}
+
+static
+struct lttng_capture_descriptor *
+lttng_condition_on_event_get_internal_capture_descriptor_at_index(
+               const struct lttng_condition *condition, unsigned int index)
+{
+       const struct lttng_condition_on_event *on_event_cond =
+                       container_of(condition,
+                               const struct lttng_condition_on_event,
+                               parent);
+       struct lttng_capture_descriptor *desc = NULL;
+       unsigned int count;
+       enum lttng_condition_status status;
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
+               goto end;
+       }
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition, &count);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto end;
+       }
+
+       if (index >= count) {
+               goto end;
+       }
+
+       desc = lttng_dynamic_pointer_array_get_pointer(
+                       &on_event_cond->capture_descriptors, index);
+end:
+       return desc;
+}
+
+static int lttng_condition_on_event_serialize(
+               const struct lttng_condition *condition,
+               struct lttng_payload *payload)
+{
+       int ret;
+       struct lttng_condition_on_event *on_event_condition;
+       enum lttng_condition_status status;
+       /* Used for iteration and communication (size matters). */
+       uint32_t i, capture_descr_count;
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
+               ret = -1;
+               goto end;
+       }
+
+       DBG("Serializing on event condition");
+       on_event_condition = container_of(
+                       condition, struct lttng_condition_on_event, parent);
+
+       DBG("Serializing on event condition's event rule");
+       ret = lttng_event_rule_serialize(on_event_condition->rule, payload);
+       if (ret) {
+               goto end;
+       }
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition, &capture_descr_count);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               ret = -1;
+               goto end;
+       };
+
+       DBG("Serializing on event condition's capture descriptor count: %" PRIu32,
+                       capture_descr_count);
+       ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count,
+                       sizeof(capture_descr_count));
+       if (ret) {
+               goto end;
+       }
+
+       for (i = 0; i < capture_descr_count; i++) {
+               const struct lttng_capture_descriptor *desc =
+                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
+                                               condition, i);
+
+               DBG("Serializing on event condition's capture descriptor %" PRIu32,
+                               i);
+               ret = serialize_event_expr(desc->event_expression, payload);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+static
+bool capture_descriptors_are_equal(
+               const struct lttng_condition *condition_a,
+               const struct lttng_condition *condition_b)
+{
+       bool is_equal = true;
+       unsigned int capture_descr_count_a;
+       unsigned int capture_descr_count_b;
+       size_t i;
+       enum lttng_condition_status status;
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition_a, &capture_descr_count_a);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto not_equal;
+       }
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition_b, &capture_descr_count_b);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto not_equal;
+       }
+
+       if (capture_descr_count_a != capture_descr_count_b) {
+               goto not_equal;
+       }
+
+       for (i = 0; i < capture_descr_count_a; i++) {
+               const struct lttng_event_expr *expr_a =
+                               lttng_condition_on_event_get_capture_descriptor_at_index(
+                                       condition_a,
+                                       i);
+               const struct lttng_event_expr *expr_b =
+                               lttng_condition_on_event_get_capture_descriptor_at_index(
+                                       condition_b,
+                                       i);
+
+               if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
+                       goto not_equal;
+               }
+       }
+
+       goto end;
+
+not_equal:
+       is_equal = false;
+
+end:
+       return is_equal;
+}
+
+static bool lttng_condition_on_event_is_equal(
+               const struct lttng_condition *_a,
+               const struct lttng_condition *_b)
+{
+       bool is_equal = false;
+       struct lttng_condition_on_event *a, *b;
+
+       a = container_of(_a, struct lttng_condition_on_event, parent);
+       b = container_of(_b, struct lttng_condition_on_event, parent);
+
+       /* Both event rules must be set or both must be unset. */
+       if ((a->rule && !b->rule) || (!a->rule && b->rule)) {
+               WARN("Comparing event_rule conditions with uninitialized rule");
+               goto end;
+       }
+
+       is_equal = lttng_event_rule_is_equal(a->rule, b->rule);
+       if (!is_equal) {
+               goto end;
+       }
+
+       is_equal = capture_descriptors_are_equal(_a, _b);
+
+end:
+       return is_equal;
+}
+
+static void lttng_condition_on_event_destroy(
+               struct lttng_condition *condition)
+{
+       struct lttng_condition_on_event *on_event_condition;
+
+       on_event_condition = container_of(
+                       condition, struct lttng_condition_on_event, parent);
+
+       lttng_event_rule_put(on_event_condition->rule);
+       lttng_dynamic_pointer_array_reset(&on_event_condition->capture_descriptors);
+       free(on_event_condition);
+}
+
+static
+void destroy_capture_descriptor(void *ptr)
+{
+       struct lttng_capture_descriptor *desc =
+                       (struct lttng_capture_descriptor *) ptr;
+
+       lttng_event_expr_destroy(desc->event_expression);
+       free(desc->bytecode);
+       free(desc);
+}
+
+struct lttng_condition *lttng_condition_on_event_create(
+               struct lttng_event_rule *rule)
+{
+       struct lttng_condition *parent = NULL;
+       struct lttng_condition_on_event *condition = NULL;
+
+       if (!rule) {
+               goto end;
+       }
+
+       condition = zmalloc(sizeof(struct lttng_condition_on_event));
+       if (!condition) {
+               return NULL;
+       }
+
+       lttng_condition_init(&condition->parent,
+                       LTTNG_CONDITION_TYPE_ON_EVENT);
+       condition->parent.validate = lttng_condition_on_event_validate,
+       condition->parent.serialize = lttng_condition_on_event_serialize,
+       condition->parent.equal = lttng_condition_on_event_is_equal,
+       condition->parent.destroy = lttng_condition_on_event_destroy,
+
+       lttng_event_rule_get(rule);
+       condition->rule = rule;
+       rule = NULL;
+
+       lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
+                       destroy_capture_descriptor);
+
+       parent = &condition->parent;
+end:
+       return parent;
+}
+
+static
+uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size,
+               size_t *offset)
+{
+       uint64_t ret;
+       const struct lttng_buffer_view uint_view =
+                       lttng_buffer_view_from_view(view, *offset, size);
+
+       if (!lttng_buffer_view_is_valid(&uint_view)) {
+               ret = UINT64_C(-1);
+               goto end;
+       }
+
+       switch (size) {
+       case 1:
+               ret = (uint64_t) *uint_view.data;
+               break;
+       case sizeof(uint32_t):
+       {
+               uint32_t u32;
+
+               memcpy(&u32, uint_view.data, sizeof(u32));
+               ret = (uint64_t) u32;
+               break;
+       }
+       case sizeof(ret):
+               memcpy(&ret, uint_view.data, sizeof(ret));
+               break;
+       default:
+               abort();
+       }
+
+       *offset += size;
+
+end:
+       return ret;
+}
+
+static
+const char *str_from_buffer(const struct lttng_buffer_view *view,
+               size_t *offset)
+{
+       uint64_t len;
+       const char *ret;
+
+       len = uint_from_buffer(view, sizeof(uint32_t), offset);
+       if (len == UINT64_C(-1)) {
+               goto error;
+       }
+
+       ret = &view->data[*offset];
+
+       if (!lttng_buffer_view_contains_string(view, ret, len)) {
+               goto error;
+       }
+
+       *offset += len;
+       goto end;
+
+error:
+       ret = NULL;
+
+end:
+       return ret;
+}
+
+static
+struct lttng_event_expr *event_expr_from_payload(
+               struct lttng_payload_view *view, size_t *offset)
+{
+       struct lttng_event_expr *expr = NULL;
+       const char *str;
+       uint64_t type;
+
+       type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
+       if (type == UINT64_C(-1)) {
+               goto error;
+       }
+
+       switch (type) {
+       case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
+               str = str_from_buffer(&view->buffer, offset);
+               if (!str) {
+                       goto error;
+               }
+
+               expr = lttng_event_expr_event_payload_field_create(str);
+               break;
+       case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
+               str = str_from_buffer(&view->buffer, offset);
+               if (!str) {
+                       goto error;
+               }
+
+               expr = lttng_event_expr_channel_context_field_create(str);
+               break;
+       case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
+       {
+               const char *provider_name;
+               const char *type_name;
+
+               provider_name = str_from_buffer(&view->buffer, offset);
+               if (!provider_name) {
+                       goto error;
+               }
+
+               type_name = str_from_buffer(&view->buffer, offset);
+               if (!type_name) {
+                       goto error;
+               }
+
+               expr = lttng_event_expr_app_specific_context_field_create(
+                               provider_name, type_name);
+               break;
+       }
+       case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
+       {
+               struct lttng_event_expr *array_field_expr;
+               const uint64_t index = uint_from_buffer(
+                               &view->buffer, sizeof(uint32_t), offset);
+
+               if (index == UINT64_C(-1)) {
+                       goto error;
+               }
+
+               /* Array field expression is the encoded after this. */
+               array_field_expr = event_expr_from_payload(view, offset);
+               if (!array_field_expr) {
+                       goto error;
+               }
+
+               /* Move ownership of `array_field_expr` to new expression. */
+               expr = lttng_event_expr_array_field_element_create(
+                               array_field_expr, (unsigned int) index);
+               if (!expr) {
+                       /* `array_field_expr` not moved: destroy it. */
+                       lttng_event_expr_destroy(array_field_expr);
+               }
+
+               break;
+       }
+       default:
+               abort();
+       }
+
+       goto end;
+
+error:
+       lttng_event_expr_destroy(expr);
+       expr = NULL;
+
+end:
+       return expr;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_condition_on_event_create_from_payload(
+               struct lttng_payload_view *view,
+               struct lttng_condition **_condition)
+{
+       ssize_t consumed_length;
+       size_t offset = 0;
+       ssize_t event_rule_length;
+       uint32_t i, capture_descr_count;
+       struct lttng_condition *condition = NULL;
+       struct lttng_event_rule *event_rule = NULL;
+
+       if (!view || !_condition) {
+               goto error;
+       }
+
+       /* Struct lttng_event_rule. */
+       {
+               struct lttng_payload_view event_rule_view =
+                               lttng_payload_view_from_view(view, offset, -1);
+
+               event_rule_length = lttng_event_rule_create_from_payload(
+                               &event_rule_view, &event_rule);
+       }
+
+       if (event_rule_length < 0 || !event_rule) {
+               goto error;
+       }
+
+       /* Create condition (no capture descriptors yet) at this point */
+       condition = lttng_condition_on_event_create(event_rule);
+       if (!condition) {
+               goto error;
+       }
+
+       /* Capture descriptor count. */
+       assert(event_rule_length >= 0);
+       offset += (size_t) event_rule_length;
+       capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
+       if (capture_descr_count == UINT32_C(-1)) {
+               goto error;
+       }
+
+       /* Capture descriptors. */
+       for (i = 0; i < capture_descr_count; i++) {
+               enum lttng_condition_status status;
+               struct lttng_event_expr *expr = event_expr_from_payload(
+                               view, &offset);
+
+               if (!expr) {
+                       goto error;
+               }
+
+               /* Move ownership of `expr` to `condition`. */
+               status = lttng_condition_on_event_append_capture_descriptor(
+                               condition, expr);
+               if (status != LTTNG_CONDITION_STATUS_OK) {
+                       /* `expr` not moved: destroy it. */
+                       lttng_event_expr_destroy(expr);
+                       goto error;
+               }
+       }
+
+       consumed_length = (ssize_t) offset;
+       *_condition = condition;
+       condition = NULL;
+       goto end;
+
+error:
+       consumed_length = -1;
+
+end:
+       lttng_event_rule_put(event_rule);
+       lttng_condition_put(condition);
+       return consumed_length;
+}
+
+LTTNG_HIDDEN
+enum lttng_condition_status lttng_condition_on_event_borrow_rule_mutable(
+               const struct lttng_condition *condition,
+               struct lttng_event_rule **rule)
+{
+       struct lttng_condition_on_event *event_rule;
+       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !rule) {
+               status = LTTNG_CONDITION_STATUS_INVALID;
+               goto end;
+       }
+
+       event_rule = container_of(
+                       condition, struct lttng_condition_on_event, parent);
+       if (!event_rule->rule) {
+               status = LTTNG_CONDITION_STATUS_UNSET;
+               goto end;
+       }
+
+       *rule = event_rule->rule;
+end:
+       return status;
+}
+
+enum lttng_condition_status lttng_condition_on_event_get_rule(
+               const struct lttng_condition *condition,
+               const struct lttng_event_rule **rule)
+{
+       struct lttng_event_rule *mutable_rule = NULL;
+       const enum lttng_condition_status status =
+                       lttng_condition_on_event_borrow_rule_mutable(
+                               condition, &mutable_rule);
+
+       *rule = mutable_rule;
+       return status;
+}
+
+enum lttng_condition_status
+lttng_condition_on_event_append_capture_descriptor(
+               struct lttng_condition *condition,
+               struct lttng_event_expr *expr)
+{
+       int ret;
+       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
+       struct lttng_condition_on_event *event_rule_cond =
+                       container_of(condition,
+                               struct lttng_condition_on_event, parent);
+       struct lttng_capture_descriptor *descriptor = NULL;
+       const struct lttng_event_rule *rule = NULL;
+
+       /* Only accept l-values. */
+       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !expr ||
+                       !lttng_event_expr_is_lvalue(expr)) {
+               status = LTTNG_CONDITION_STATUS_INVALID;
+               goto end;
+       }
+
+       status = lttng_condition_on_event_get_rule(condition, &rule);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto end;
+       }
+
+       switch(lttng_event_rule_get_type(rule)) {
+       case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
+       case LTTNG_EVENT_RULE_TYPE_SYSCALL:
+               /* Supported. */
+               status = LTTNG_CONDITION_STATUS_OK;
+               break;
+       case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
+               status = LTTNG_CONDITION_STATUS_INVALID;
+               break;
+       default:
+               status = LTTNG_CONDITION_STATUS_UNSUPPORTED;
+               break;
+       }
+
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto end;
+       }
+
+       descriptor = malloc(sizeof(*descriptor));
+       if (descriptor == NULL) {
+               status = LTTNG_CONDITION_STATUS_ERROR;
+               goto end;
+       }
+
+       descriptor->event_expression = expr;
+       descriptor->bytecode = NULL;
+
+       ret = lttng_dynamic_pointer_array_add_pointer(
+                       &event_rule_cond->capture_descriptors, descriptor);
+       if (ret) {
+               status = LTTNG_CONDITION_STATUS_ERROR;
+               goto end;
+       }
+
+       /* Ownership is transfered to the internal capture_descriptors array */
+       descriptor = NULL;
+end:
+       free(descriptor);
+       return status;
+}
+
+enum lttng_condition_status
+lttng_condition_on_event_get_capture_descriptor_count(
+               const struct lttng_condition *condition, unsigned int *count)
+{
+       enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
+       const struct lttng_condition_on_event *on_event_condition =
+                       container_of(condition,
+                               const struct lttng_condition_on_event,
+                               parent);
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition) || !count) {
+               status = LTTNG_CONDITION_STATUS_INVALID;
+               goto end;
+       }
+
+       *count = lttng_dynamic_pointer_array_get_count(
+                       &on_event_condition->capture_descriptors);
+
+end:
+       return status;
+}
+
+const struct lttng_event_expr *
+lttng_condition_on_event_get_capture_descriptor_at_index(
+               const struct lttng_condition *condition, unsigned int index)
+{
+       const struct lttng_event_expr *expr = NULL;
+       const struct lttng_capture_descriptor *desc = NULL;
+
+       desc = lttng_condition_on_event_get_internal_capture_descriptor_at_index(
+                       condition, index);
+       if (desc == NULL) {
+               goto end;
+       }
+       expr = desc->event_expression;
+
+end:
+       return expr;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_on_event_create_from_payload(
+               const struct lttng_condition_on_event *condition,
+               struct lttng_payload_view *view,
+               struct lttng_evaluation **_evaluation)
+{
+       ssize_t ret, offset = 0;
+       const char *trigger_name;
+       struct lttng_evaluation *evaluation = NULL;
+       const struct lttng_evaluation_on_event_comm *header;
+       const struct lttng_payload_view header_view =
+                       lttng_payload_view_from_view(
+                                       view, 0, sizeof(*header));
+       uint32_t capture_payload_size;
+       const char *capture_payload = NULL;
+
+       if (!_evaluation) {
+               ret = -1;
+               goto error;
+       }
+
+       if (!lttng_payload_view_is_valid(&header_view)) {
+               ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
+               ret = -1;
+               goto error;
+       }
+
+       header = (typeof(header)) header_view.buffer.data;
+
+       /* Map the originating trigger's name. */
+       offset += sizeof(*header);
+       {
+               const struct lttng_payload_view current_view =
+                               lttng_payload_view_from_view(view, offset,
+                                               header->trigger_name_length);
+
+               if (!lttng_payload_view_is_valid(&current_view)) {
+                       ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
+                       ret = -1;
+                       goto error;
+               }
+
+               trigger_name = current_view.buffer.data;
+               if (!lttng_buffer_view_contains_string(&current_view.buffer,
+                                   trigger_name, header->trigger_name_length)) {
+                       ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
+                       ret = -1;
+                       goto error;
+               }
+       }
+
+       offset += header->trigger_name_length;
+       {
+               const struct lttng_payload_view current_view =
+                               lttng_payload_view_from_view(view, offset, -1);
+
+               if (current_view.buffer.size < sizeof(capture_payload_size)) {
+                       ret = -1;
+                       goto error;
+               }
+
+               memcpy(&capture_payload_size, current_view.buffer.data,
+                               sizeof(capture_payload_size));
+       }
+       offset += sizeof(capture_payload_size);
+
+       if (capture_payload_size > 0) {
+               const struct lttng_payload_view current_view =
+                               lttng_payload_view_from_view(view, offset, -1);
+
+               if (current_view.buffer.size < capture_payload_size) {
+                       ret = -1;
+                       goto error;
+               }
+
+               capture_payload = current_view.buffer.data;
+       }
+
+       evaluation = lttng_evaluation_on_event_create(condition, trigger_name,
+                       capture_payload, capture_payload_size, true);
+       if (!evaluation) {
+               ret = -1;
+               goto error;
+       }
+
+       offset += capture_payload_size;
+       *_evaluation = evaluation;
+       evaluation = NULL;
+       ret = offset;
+
+error:
+       lttng_evaluation_destroy(evaluation);
+       return ret;
+}
+
+static int lttng_evaluation_on_event_serialize(
+               const struct lttng_evaluation *evaluation,
+               struct lttng_payload *payload)
+{
+       int ret = 0;
+       struct lttng_evaluation_on_event *hit;
+       struct lttng_evaluation_on_event_comm comm;
+       uint32_t capture_payload_size;
+
+       hit = container_of(
+                       evaluation, struct lttng_evaluation_on_event, parent);
+
+       assert(hit->name);
+       comm.trigger_name_length = strlen(hit->name) + 1;
+
+       ret = lttng_dynamic_buffer_append(
+                       &payload->buffer, &comm, sizeof(comm));
+       if (ret) {
+               goto end;
+       }
+
+       ret = lttng_dynamic_buffer_append(
+                       &payload->buffer, hit->name, comm.trigger_name_length);
+       if (ret) {
+               goto end;
+       }
+
+       capture_payload_size = (uint32_t) hit->capture_payload.size;
+       ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_payload_size,
+                       sizeof(capture_payload_size));
+       if (ret) {
+               goto end;
+       }
+
+       ret = lttng_dynamic_buffer_append(&payload->buffer, hit->capture_payload.data,
+                       hit->capture_payload.size);
+       if (ret) {
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+bool msgpack_str_is_equal(const struct msgpack_object *obj, const char *str)
+{
+       bool is_equal = true;
+
+       assert(obj->type == MSGPACK_OBJECT_STR);
+
+       if (obj->via.str.size != strlen(str)) {
+               is_equal = false;
+               goto end;
+       }
+
+       if (strncmp(obj->via.str.ptr, str, obj->via.str.size) != 0) {
+               is_equal = false;
+               goto end;
+       }
+
+end:
+       return is_equal;
+}
+
+static
+const msgpack_object *get_msgpack_map_obj(const struct msgpack_object *map_obj,
+               const char *name)
+{
+       const msgpack_object *ret = NULL;
+       size_t i;
+
+       assert(map_obj->type == MSGPACK_OBJECT_MAP);
+
+       for (i = 0; i < map_obj->via.map.size; i++) {
+               const struct msgpack_object_kv *kv = &map_obj->via.map.ptr[i];
+
+               assert(kv->key.type == MSGPACK_OBJECT_STR);
+
+               if (msgpack_str_is_equal(&kv->key, name)) {
+                       ret = &kv->val;
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+static void lttng_evaluation_on_event_destroy(
+               struct lttng_evaluation *evaluation)
+{
+       struct lttng_evaluation_on_event *hit;
+
+       hit = container_of(
+                       evaluation, struct lttng_evaluation_on_event, parent);
+       free(hit->name);
+       lttng_dynamic_buffer_reset(&hit->capture_payload);
+       lttng_event_field_value_destroy(hit->captured_values);
+       free(hit);
+}
+
+static
+int event_field_value_from_obj(const msgpack_object *obj,
+               struct lttng_event_field_value **field_val)
+{
+       int ret = 0;
+
+       assert(obj);
+       assert(field_val);
+
+       switch (obj->type) {
+       case MSGPACK_OBJECT_NIL:
+               /* Unavailable. */
+               *field_val = NULL;
+               goto end;
+       case MSGPACK_OBJECT_POSITIVE_INTEGER:
+               *field_val = lttng_event_field_value_uint_create(
+                               obj->via.u64);
+               break;
+       case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+               *field_val = lttng_event_field_value_int_create(
+                               obj->via.i64);
+               break;
+       case MSGPACK_OBJECT_FLOAT32:
+       case MSGPACK_OBJECT_FLOAT64:
+               *field_val = lttng_event_field_value_real_create(
+                               obj->via.f64);
+               break;
+       case MSGPACK_OBJECT_STR:
+               *field_val = lttng_event_field_value_string_create_with_size(
+                               obj->via.str.ptr, obj->via.str.size);
+               break;
+       case MSGPACK_OBJECT_ARRAY:
+       {
+               size_t i;
+
+               *field_val = lttng_event_field_value_array_create();
+               if (!*field_val) {
+                       goto error;
+               }
+
+               for (i = 0; i < obj->via.array.size; i++) {
+                       const msgpack_object *elem_obj = &obj->via.array.ptr[i];
+                       struct lttng_event_field_value *elem_field_val;
+
+                       ret = event_field_value_from_obj(elem_obj,
+                                       &elem_field_val);
+                       if (ret) {
+                               goto error;
+                       }
+
+                       if (elem_field_val) {
+                               ret = lttng_event_field_value_array_append(
+                                               *field_val, elem_field_val);
+                       } else {
+                               ret = lttng_event_field_value_array_append_unavailable(
+                                               *field_val);
+                       }
+
+                       if (ret) {
+                               lttng_event_field_value_destroy(elem_field_val);
+                               goto error;
+                       }
+               }
+
+               break;
+       }
+       case MSGPACK_OBJECT_MAP:
+       {
+               /*
+                * As of this version, the only valid map object is
+                * for an enumeration value, for example:
+                *
+                *     type: enum
+                *     value: 177
+                *     labels:
+                *     - Labatt 50
+                *     - Molson Dry
+                *     - Carling Black Label
+                */
+               const msgpack_object *inner_obj;
+               size_t label_i;
+
+               inner_obj = get_msgpack_map_obj(obj, "type");
+               if (!inner_obj) {
+                       ERR("Missing `type` entry in map object");
+                       goto error;
+               }
+
+               if (inner_obj->type != MSGPACK_OBJECT_STR) {
+                       ERR("Map object's `type` entry is not a string: type = %s",
+                                       msgpack_object_type_str(inner_obj->type));
+                       goto error;
+               }
+
+               if (!msgpack_str_is_equal(inner_obj, "enum")) {
+                       ERR("Map object's `type` entry: expecting `enum`");
+                       goto error;
+               }
+
+               inner_obj = get_msgpack_map_obj(obj, "value");
+               if (!inner_obj) {
+                       ERR("Missing `value` entry in map object");
+                       goto error;
+               }
+
+               if (inner_obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
+                       *field_val = lttng_event_field_value_enum_uint_create(
+                                       inner_obj->via.u64);
+               } else if (inner_obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
+                       *field_val = lttng_event_field_value_enum_int_create(
+                                       inner_obj->via.i64);
+               } else {
+                       ERR("Map object's `value` entry is not an integer: type = %s",
+                                       msgpack_object_type_str(inner_obj->type));
+                       goto error;
+               }
+
+               if (!*field_val) {
+                       goto error;
+               }
+
+               inner_obj = get_msgpack_map_obj(obj, "labels");
+               if (!inner_obj) {
+                       /* No labels */
+                       goto end;
+               }
+
+               if (inner_obj->type != MSGPACK_OBJECT_ARRAY) {
+                       ERR("Map object's `labels` entry is not an array: type = %s",
+                                       msgpack_object_type_str(inner_obj->type));
+                       goto error;
+               }
+
+               for (label_i = 0; label_i < inner_obj->via.array.size;
+                               label_i++) {
+                       int iret;
+                       const msgpack_object *elem_obj =
+                                       &inner_obj->via.array.ptr[label_i];
+
+                       if (elem_obj->type != MSGPACK_OBJECT_STR) {
+                               ERR("Map object's `labels` entry's type is not a string: type = %s",
+                                               msgpack_object_type_str(elem_obj->type));
+                               goto error;
+                       }
+
+                       iret = lttng_event_field_value_enum_append_label_with_size(
+                                       *field_val, elem_obj->via.str.ptr,
+                                       elem_obj->via.str.size);
+                       if (iret) {
+                               goto error;
+                       }
+               }
+
+               break;
+       }
+       default:
+               ERR("Unexpected object type: type = %s",
+                               msgpack_object_type_str(obj->type));
+               goto error;
+       }
+
+       if (!*field_val) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       lttng_event_field_value_destroy(*field_val);
+       *field_val = NULL;
+       ret = -1;
+
+end:
+       return ret;
+}
+
+static
+struct lttng_event_field_value *event_field_value_from_capture_payload(
+               const struct lttng_condition_on_event *condition,
+               const char *capture_payload, size_t capture_payload_size)
+{
+       struct lttng_event_field_value *ret = NULL;
+       msgpack_unpacked unpacked;
+       msgpack_unpack_return unpack_return;
+       const msgpack_object *root_obj;
+       const msgpack_object_array *root_array_obj;
+       size_t i;
+       size_t count;
+
+       assert(condition);
+       assert(capture_payload);
+
+       /* Initialize value. */
+       msgpack_unpacked_init(&unpacked);
+
+       /* Decode. */
+       unpack_return = msgpack_unpack_next(&unpacked, capture_payload,
+                       capture_payload_size, NULL);
+       if (unpack_return != MSGPACK_UNPACK_SUCCESS) {
+               ERR("msgpack_unpack_next() failed to decode the "
+                               "MessagePack-encoded capture payload: "
+                               "size = %zu, ret = %d",
+                               capture_payload_size, unpack_return);
+               goto error;
+       }
+
+       /* Get root array. */
+       root_obj = &unpacked.data;
+
+       if (root_obj->type != MSGPACK_OBJECT_ARRAY) {
+               ERR("Expecting an array as the root object: type = %s",
+                               msgpack_object_type_str(root_obj->type));
+               goto error;
+       }
+
+       root_array_obj = &root_obj->via.array;
+
+       /* Create an empty root array event field value. */
+       ret = lttng_event_field_value_array_create();
+       if (!ret) {
+               goto error;
+       }
+
+       /*
+        * For each capture descriptor in the condition object:
+        *
+        * 1. Get its corresponding captured field value MessagePack
+        *    object.
+        *
+        * 2. Create a corresponding event field value.
+        *
+        * 3. Append it to `ret` (the root array event field value).
+        */
+       count = lttng_dynamic_pointer_array_get_count(
+                       &condition->capture_descriptors);
+       assert(count > 0);
+
+       for (i = 0; i < count; i++) {
+               const struct lttng_capture_descriptor *capture_descriptor =
+                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
+                                               &condition->parent, i);
+               const msgpack_object *elem_obj;
+               struct lttng_event_field_value *elem_field_val;
+               int iret;
+
+               assert(capture_descriptor);
+
+               elem_obj = &root_array_obj->ptr[i];
+               iret = event_field_value_from_obj(elem_obj,
+                               &elem_field_val);
+               if (iret) {
+                       goto error;
+               }
+
+               if (elem_field_val) {
+                       iret = lttng_event_field_value_array_append(ret,
+                                       elem_field_val);
+               } else {
+                       iret = lttng_event_field_value_array_append_unavailable(
+                                       ret);
+               }
+
+               if (iret) {
+                       lttng_event_field_value_destroy(elem_field_val);
+                       goto error;
+               }
+       }
+
+       goto end;
+
+error:
+       lttng_event_field_value_destroy(ret);
+       ret = NULL;
+
+end:
+       msgpack_unpacked_destroy(&unpacked);
+       return ret;
+}
+
+LTTNG_HIDDEN
+struct lttng_evaluation *lttng_evaluation_on_event_create(
+               const struct lttng_condition_on_event *condition,
+               const char *trigger_name,
+               const char *capture_payload, size_t capture_payload_size,
+               bool decode_capture_payload)
+{
+       struct lttng_evaluation_on_event *hit;
+       struct lttng_evaluation *evaluation = NULL;
+
+       hit = zmalloc(sizeof(struct lttng_evaluation_on_event));
+       if (!hit) {
+               goto error;
+       }
+
+       hit->name = strdup(trigger_name);
+       if (!hit->name) {
+               goto error;
+       }
+
+       lttng_dynamic_buffer_init(&hit->capture_payload);
+
+       if (capture_payload) {
+               const int ret = lttng_dynamic_buffer_append(
+                               &hit->capture_payload, capture_payload,
+                               capture_payload_size);
+               if (ret) {
+                       ERR("Failed to initialize capture payload of event rule evaluation");
+                       goto error;
+               }
+
+               if (decode_capture_payload) {
+                       hit->captured_values =
+                                       event_field_value_from_capture_payload(
+                                               condition,
+                                               capture_payload,
+                                               capture_payload_size);
+                       if (!hit->captured_values) {
+                               ERR("Failed to decode the capture payload: size = %zu",
+                                               capture_payload_size);
+                               goto error;
+                       }
+               }
+       }
+
+       hit->parent.type = LTTNG_CONDITION_TYPE_ON_EVENT;
+       hit->parent.serialize = lttng_evaluation_on_event_serialize;
+       hit->parent.destroy = lttng_evaluation_on_event_destroy;
+
+       evaluation = &hit->parent;
+       hit = NULL;
+
+error:
+       if (hit) {
+               lttng_evaluation_on_event_destroy(&hit->parent);
+       }
+
+       return evaluation;
+}
+
+enum lttng_evaluation_status lttng_evaluation_on_event_get_captured_values(
+               const struct lttng_evaluation *evaluation,
+               const struct lttng_event_field_value **field_val)
+{
+       struct lttng_evaluation_on_event *hit;
+       enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
+
+       if (!evaluation || !is_on_event_evaluation(evaluation) ||
+                       !field_val) {
+               status = LTTNG_EVALUATION_STATUS_INVALID;
+               goto end;
+       }
+
+       hit = container_of(evaluation, struct lttng_evaluation_on_event,
+                       parent);
+       if (!hit->captured_values) {
+               status = LTTNG_EVALUATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *field_val = hit->captured_values;
+
+end:
+       return status;
+}
+
+enum lttng_evaluation_status lttng_evaluation_on_event_get_trigger_name(
+               const struct lttng_evaluation *evaluation, const char **name)
+{
+       struct lttng_evaluation_on_event *hit;
+       enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
+
+       if (!evaluation || !is_on_event_evaluation(evaluation) || !name) {
+               status = LTTNG_EVALUATION_STATUS_INVALID;
+               goto end;
+       }
+
+       hit = container_of(
+                       evaluation, struct lttng_evaluation_on_event, parent);
+       *name = hit->name;
+end:
+       return status;
+}
+
+LTTNG_HIDDEN
+enum lttng_error_code
+lttng_condition_on_event_generate_capture_descriptor_bytecode(
+               struct lttng_condition *condition)
+{
+       enum lttng_error_code ret;
+       enum lttng_condition_status status;
+       unsigned int capture_count, i;
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
+               ret = LTTNG_ERR_FATAL;
+               goto end;
+       }
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition, &capture_count);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               ret = LTTNG_ERR_FATAL;
+               goto end;
+       }
+
+       for (i = 0; i < capture_count; i++) {
+               struct lttng_capture_descriptor *local_capture_desc =
+                               lttng_condition_on_event_get_internal_capture_descriptor_at_index(
+                                               condition, i);
+
+               if (local_capture_desc == NULL) {
+                       ret = LTTNG_ERR_FATAL;
+                       goto end;
+               }
+
+               /* Generate the bytecode. */
+               status = lttng_event_expr_to_bytecode(
+                               local_capture_desc->event_expression,
+                               &local_capture_desc->bytecode);
+               if (status < 0 || local_capture_desc->bytecode == NULL) {
+                       ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
+                       goto end;
+               }
+       }
+
+       /* Everything went better than expected */
+       ret = LTTNG_OK;
+
+end:
+       return ret;
+}
+
+LTTNG_HIDDEN
+const struct lttng_bytecode *
+lttng_condition_on_event_get_capture_bytecode_at_index(
+               const struct lttng_condition *condition, unsigned int index)
+{
+       const struct lttng_condition_on_event *event_rule_cond =
+                       container_of(condition,
+                               const struct lttng_condition_on_event,
+                               parent);
+       struct lttng_capture_descriptor *desc = NULL;
+       struct lttng_bytecode *bytecode = NULL;
+       unsigned int count;
+       enum lttng_condition_status status;
+
+       if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
+               goto end;
+       }
+
+       status = lttng_condition_on_event_get_capture_descriptor_count(
+                       condition, &count);
+       if (status != LTTNG_CONDITION_STATUS_OK) {
+               goto end;
+       }
+
+       if (index >= count) {
+               goto end;
+       }
+
+       desc = lttng_dynamic_pointer_array_get_pointer(
+                       &event_rule_cond->capture_descriptors, index);
+       if (desc == NULL) {
+               goto end;
+       }
+
+       bytecode = desc->bytecode;
+end:
+       return bytecode;
+}
index 872875a9f9a90f12aa5c821ef10b9477b6acc5ad..2b06be614a73ddc788987b7ce711bf19e8cef6df 100644 (file)
@@ -10,7 +10,7 @@
 #include <lttng/condition/buffer-usage-internal.h>
 #include <lttng/condition/session-consumed-size-internal.h>
 #include <lttng/condition/session-rotation-internal.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
 #include <common/macros.h>
 #include <common/error.h>
 #include <stdbool.h>
index 0fdcf40499966e3a87be9f6b7f690db1774d4e41..ca082d139ac888b76ed229ab9869fc694c833fa8 100644 (file)
@@ -7,9 +7,9 @@
 
 #include <lttng/trigger/trigger-internal.h>
 #include <lttng/condition/condition-internal.h>
-#include <lttng/condition/event-rule-internal.h>
-#include <lttng/condition/event-rule.h>
-#include <lttng/condition/event-rule-internal.h>
+#include <lttng/condition/on-event-internal.h>
+#include <lttng/condition/on-event.h>
+#include <lttng/condition/on-event-internal.h>
 #include <lttng/condition/buffer-usage.h>
 #include <lttng/event-rule/event-rule-internal.h>
 #include <lttng/event-expr-internal.h>
index 0722945f7dc8165b07fc8dce6db4ba7cc832695c..2c7c896d846a213038589f3580b6b6bb557d459d 100644 (file)
@@ -14,7 +14,7 @@
 #include <sys/time.h>
 #include <time.h>
 
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/lttng.h>
 
 #include "utils.h"
index 4f48187431537191872e66337112613bd8d00e40..c5a94bb6519781da908e3d3475c5c570a77afcd6 100644 (file)
@@ -20,7 +20,7 @@
 #include <lttng/event.h>
 #include <lttng/event-rule/tracepoint.h>
 #include <lttng/condition/condition-internal.h>
-#include <lttng/condition/event-rule.h>
+#include <lttng/condition/on-event.h>
 #include <lttng/domain.h>
 #include <common/dynamic-buffer.h>
 #include <common/buffer-view.h>
This page took 0.117705 seconds and 4 git commands to generate.