(lttng_condition_get_type(condition) == \
LTTNG_CONDITION_TYPE_ON_EVENT)
+typedef LTTNG_OPTIONAL(uint64_t) optional_uint64;
+
static bool is_on_event_evaluation(const struct lttng_evaluation *evaluation)
{
enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
enum lttng_condition_status status;
/* Used for iteration and communication (size matters). */
uint32_t i, capture_descr_count;
+ LTTNG_OPTIONAL_COMM(typeof(on_event_condition->error_count.value)) error_count_comm;
if (!condition || !IS_ON_EVENT_CONDITION(condition)) {
ret = -1;
goto end;
}
+ error_count_comm = (typeof(error_count_comm)) {
+ .is_set = on_event_condition->error_count.is_set,
+ .value = on_event_condition->error_count.value,
+ };
+
+ {
+ char error_count_value_str[MAX_INT_DEC_LEN(on_event_condition->error_count.value)];
+ const int fmt_ret = snprintf(error_count_value_str,
+ sizeof(error_count_value_str), "%" PRIu64,
+ on_event_condition->error_count.value);
+
+ assert(fmt_ret > 0);
+ DBG("Serializing event rule condition's error count: value = %s",
+ on_event_condition->error_count.is_set ?
+ error_count_value_str :
+ "(unset)");
+ }
+
+ ret = lttng_dynamic_buffer_append(&payload->buffer, &error_count_comm,
+ sizeof(error_count_comm));
+ if (ret) {
+ goto end;
+ }
+
status = lttng_condition_on_event_get_capture_descriptor_count(
condition, &capture_descr_count);
if (status != LTTNG_CONDITION_STATUS_OK) {
return ret;
}
+static
+int optional_uint_from_buffer(
+ const struct lttng_buffer_view *view,
+ size_t inner_value_size,
+ size_t *offset,
+ optional_uint64 *value)
+{
+ int ret;
+
+ /*
+ * Those cases are identical except for the optional's inner type width.
+ */
+ switch (inner_value_size) {
+ case sizeof(uint8_t):
+ {
+ LTTNG_OPTIONAL_COMM(uint8_t) *value_comm;
+ const struct lttng_buffer_view optional_uint_view =
+ lttng_buffer_view_from_view(view, *offset,
+ sizeof(*value_comm));
+
+ if (!lttng_buffer_view_is_valid(&optional_uint_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ value_comm = (typeof(value_comm)) optional_uint_view.data;
+ *value = (typeof(*value)) {
+ .is_set = value_comm->is_set,
+ .value = (uint64_t) value_comm->value,
+ };
+
+ *offset += sizeof(*value_comm);
+ break;
+ }
+ case sizeof(uint16_t):
+ {
+ LTTNG_OPTIONAL_COMM(uint16_t) *value_comm;
+ const struct lttng_buffer_view optional_uint_view =
+ lttng_buffer_view_from_view(view, *offset,
+ sizeof(*value_comm));
+
+ if (!lttng_buffer_view_is_valid(&optional_uint_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ value_comm = (typeof(value_comm)) optional_uint_view.data;
+ *value = (typeof(*value)) {
+ .is_set = value_comm->is_set,
+ .value = (uint64_t) value_comm->value,
+ };
+
+ *offset += sizeof(*value_comm);
+ break;
+ }
+ case sizeof(uint32_t):
+ {
+ LTTNG_OPTIONAL_COMM(uint32_t) *value_comm;
+ const struct lttng_buffer_view optional_uint_view =
+ lttng_buffer_view_from_view(view, *offset,
+ sizeof(*value_comm));
+
+ if (!lttng_buffer_view_is_valid(&optional_uint_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ value_comm = (typeof(value_comm)) optional_uint_view.data;
+ *value = (typeof(*value)) {
+ .is_set = value_comm->is_set,
+ .value = (uint64_t) value_comm->value,
+ };
+
+ *offset += sizeof(*value_comm);
+ break;
+ }
+ case sizeof(uint64_t):
+ {
+ LTTNG_OPTIONAL_COMM(uint64_t) *value_comm;
+ const struct lttng_buffer_view optional_uint_view =
+ lttng_buffer_view_from_view(view, *offset,
+ sizeof(*value_comm));
+
+ if (!lttng_buffer_view_is_valid(&optional_uint_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ value_comm = (typeof(value_comm)) optional_uint_view.data;
+ *value = (typeof(*value)) {
+ .is_set = value_comm->is_set,
+ .value = (uint64_t) value_comm->value,
+ };
+
+ *offset += sizeof(*value_comm);
+ break;
+ }
+ default:
+ abort();
+ }
+
+ ret = 0;
+end:
+ return ret;
+}
+
static
const char *str_from_buffer(const struct lttng_buffer_view *view,
size_t *offset)
struct lttng_payload_view *view,
struct lttng_condition **_condition)
{
+ int optional_ret;
ssize_t consumed_length;
size_t offset = 0;
ssize_t event_rule_length;
uint32_t i, capture_descr_count;
+ optional_uint64 error_count;
struct lttng_condition *condition = NULL;
struct lttng_event_rule *event_rule = NULL;
goto error;
}
+ offset += event_rule_length;
+
+ /* Error count. */
+ optional_ret = optional_uint_from_buffer(&view->buffer,
+ sizeof(error_count.value), &offset,
+ &error_count);
+ if (optional_ret) {
+ goto error;
+ }
+
/* Create condition (no capture descriptors yet) at this point */
condition = lttng_condition_on_event_create(event_rule);
if (!condition) {
goto error;
}
+ if (error_count.is_set) {
+ lttng_condition_on_event_set_error_count(
+ condition, error_count.value);
+ }
+
/* 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;
return status;
}
+LTTNG_HIDDEN
+void lttng_condition_on_event_set_error_counter_index(
+ struct lttng_condition *condition, uint64_t error_counter_index)
+{
+ struct lttng_condition_on_event *on_event_cond =
+ container_of(condition,
+ struct lttng_condition_on_event, parent);
+
+ LTTNG_OPTIONAL_SET(&on_event_cond->error_counter_index, error_counter_index);
+}
+
+LTTNG_HIDDEN
+uint64_t lttng_condition_on_event_get_error_counter_index(
+ const struct lttng_condition *condition)
+{
+ const struct lttng_condition_on_event *on_event_cond =
+ container_of(condition,
+ const struct lttng_condition_on_event, parent);
+
+ return LTTNG_OPTIONAL_GET(on_event_cond->error_counter_index);
+}
+
+LTTNG_HIDDEN
+void lttng_condition_on_event_set_error_count(struct lttng_condition *condition,
+ uint64_t error_count)
+{
+ struct lttng_condition_on_event *on_event_cond =
+ container_of(condition,
+ struct lttng_condition_on_event, parent);
+
+ LTTNG_OPTIONAL_SET(&on_event_cond->error_count, error_count);
+}
+
+uint64_t lttng_condition_on_event_get_error_count(
+ const struct lttng_condition *condition)
+{
+ const struct lttng_condition_on_event *on_event_cond =
+ container_of(condition,
+ const struct lttng_condition_on_event, parent);
+
+ return LTTNG_OPTIONAL_GET(on_event_cond->error_count);
+}
+
enum lttng_condition_status
lttng_condition_on_event_append_capture_descriptor(
struct lttng_condition *condition,
{
int ret;
enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
- struct lttng_condition_on_event *event_rule_cond =
+ struct lttng_condition_on_event *on_event_cond =
container_of(condition,
struct lttng_condition_on_event, parent);
struct lttng_capture_descriptor *descriptor = NULL;
descriptor->bytecode = NULL;
ret = lttng_dynamic_pointer_array_add_pointer(
- &event_rule_cond->capture_descriptors, descriptor);
+ &on_event_cond->capture_descriptors, descriptor);
if (ret) {
status = LTTNG_CONDITION_STATUS_ERROR;
goto end;
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 =
+ const struct lttng_condition_on_event *on_event_cond =
container_of(condition,
const struct lttng_condition_on_event,
parent);
}
desc = lttng_dynamic_pointer_array_get_pointer(
- &event_rule_cond->capture_descriptors, index);
+ &on_event_cond->capture_descriptors, index);
if (desc == NULL) {
goto end;
}
#include <lttng/event-rule/tracepoint.h>
#include <lttng/condition/condition-internal.h>
#include <lttng/condition/on-event.h>
+#include <lttng/condition/on-event-internal.h>
#include <lttng/domain.h>
#include <lttng/log-level-rule.h>
#include <common/dynamic-buffer.h>
int lttng_opt_verbose;
int lttng_opt_mi;
-#define NUM_TESTS 13
+#define NUM_TESTS 14
static
void test_condition_event_rule(void)
const char *pattern="my_event_*";
const char *filter="msg_id == 23 && size >= 2048";
const char *exclusions[] = { "my_event_test1", "my_event_test2", "my_event_test3" };
+ uint64_t _error_count = 420, error_count;
struct lttng_log_level_rule *log_level_rule_at_least_as_severe = NULL;
struct lttng_payload buffer;
condition = lttng_condition_on_event_create(tracepoint);
ok(condition, "Created condition");
+ /* Set the error count information. */
+ lttng_condition_on_event_set_error_count(condition, _error_count);
+
condition_status = lttng_condition_on_event_get_rule(
condition, &tracepoint_tmp);
ok(condition_status == LTTNG_CONDITION_STATUS_OK,
ok(lttng_condition_is_equal(condition, condition_from_buffer),
"Serialized and de-serialized conditions are equal");
+ /*
+ * Error count info is not considered in is_equal; test it separately.
+ */
+ error_count = lttng_condition_on_event_get_error_count(condition_from_buffer);
+ ok(error_count == _error_count, "Error count is the same. Got %" PRIu64 " Expected %" PRIu64, error_count, _error_count);
+
lttng_payload_reset(&buffer);
lttng_event_rule_destroy(tracepoint);
lttng_condition_destroy(condition);