enum lttng_error_query_target_type {
LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER,
+ LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION,
LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION,
};
const struct lttng_trigger *lttng_error_query_trigger_borrow_target(
const struct lttng_error_query *query);
+LTTNG_HIDDEN
+const struct lttng_trigger *lttng_error_query_condition_borrow_target(
+ const struct lttng_error_query *query);
+
LTTNG_HIDDEN
const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
const struct lttng_error_query *query);
extern struct lttng_error_query *lttng_error_query_trigger_create(
const struct lttng_trigger *trigger);
+/* Create an error query targetting a trigger's condition object. */
+extern struct lttng_error_query *lttng_error_query_condition_create(
+ const struct lttng_trigger *trigger);
+
/*
* Create an error query targetting an action object.
*
const struct lttng_trigger *trigger,
struct lttng_error_query_results *results);
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_condition_add_error_results(
+ const struct lttng_trigger *trigger,
+ struct lttng_error_query_results *results);
+
LTTNG_HIDDEN
enum lttng_trigger_status lttng_trigger_add_action_error_query_results(
struct lttng_trigger *trigger,
{
enum lttng_error_code ret_code;
const struct lttng_trigger *query_target_trigger;
- struct lttng_action *query_target_action = NULL;
+ const struct lttng_action *query_target_action = NULL;
struct lttng_trigger *matching_trigger = NULL;
const char *trigger_name;
uid_t trigger_owner;
case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
query_target_trigger = lttng_error_query_trigger_borrow_target(query);
break;
+ case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
+ query_target_trigger =
+ lttng_error_query_condition_borrow_target(query);
+ break;
case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
query_target_trigger = lttng_error_query_action_borrow_trigger_target(
query);
}
break;
+ case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
+ {
+ trigger_status = lttng_trigger_condition_add_error_results(
+ matching_trigger, results);
+
+ switch (trigger_status) {
+ case LTTNG_TRIGGER_STATUS_OK:
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+
+ break;
+ }
case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
{
const enum lttng_action_status action_status =
enum lttng_trigger_status lttng_trigger_add_error_results(
const struct lttng_trigger *trigger,
struct lttng_error_query_results *results)
+{
+ return LTTNG_TRIGGER_STATUS_OK;
+}
+
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_condition_add_error_results(
+ const struct lttng_trigger *trigger,
+ struct lttng_error_query_results *results)
{
enum lttng_trigger_status status;
uint64_t discarded_tracer_messages_count;
&trigger_owner);
assert(status == LTTNG_TRIGGER_STATUS_OK);
- /* Only add discarded tracer messages count for applicable triggers. */
+ /*
+ * Only add discarded tracer messages count for applicable conditions.
+ * As of 2.13, only "event rule matches" conditions can generate
+ * reportable errors hence why this function is very specific to this
+ * condition type.
+ */
if (!lttng_trigger_needs_tracer_notifier(trigger)) {
status = LTTNG_TRIGGER_STATUS_OK;
goto end;
;
#endif
+#define INDENTATION_LEVEL_STR " "
+
typedef enum lttng_event_rule_status (*event_rule_logging_get_name_pattern)(
const struct lttng_event_rule *rule, const char **pattern);
typedef enum lttng_event_rule_status (*event_rule_logging_get_filter)(
}
}
+static
+void print_indentation(unsigned int indentation_level)
+{
+ unsigned int i;
+
+ for (i = 0; i < indentation_level; i++) {
+ _MSG(INDENTATION_LEVEL_STR);
+ }
+}
+
+static
+void print_error_query_results(struct lttng_error_query_results *results,
+ unsigned int base_indentation_level)
+{
+ unsigned int i, count, printed_errors_count = 0;
+ enum lttng_error_query_results_status results_status;
+
+ results_status = lttng_error_query_results_get_count(results, &count);
+ assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
+
+ assert(results);
+
+ print_indentation(base_indentation_level);
+ _MSG("errors:");
+
+ for (i = 0; i < count; i++) {
+ const struct lttng_error_query_result *result;
+ enum lttng_error_query_result_status result_status;
+ const char *result_name;
+ const char *result_description;
+ uint64_t result_value;
+
+ results_status = lttng_error_query_results_get_result(
+ results, &result, i);
+ assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
+
+ result_status = lttng_error_query_result_get_name(
+ result, &result_name);
+ assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
+ result_status = lttng_error_query_result_get_description(
+ result, &result_description);
+ assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
+
+
+ if (lttng_error_query_result_get_type(result) ==
+ LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
+ result_status = lttng_error_query_result_counter_get_value(
+ result, &result_value);
+ assert(result_status ==
+ LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
+ if (result_value == 0) {
+ continue;
+ }
+
+ MSG("");
+ print_indentation(base_indentation_level + 1);
+
+ _MSG("%s: %" PRIu64, result_name, result_value);
+ printed_errors_count++;
+ } else {
+ MSG("");
+ print_indentation(base_indentation_level + 1);
+ _MSG("Unknown error query result type for result '%s' (%s)",
+ result_name, result_description);
+ continue;
+ }
+ }
+
+ if (printed_errors_count == 0) {
+ _MSG(" none");
+ }
+}
+
static void print_condition_event_rule_matches(
const struct lttng_condition *condition)
{
const uint64_t *action_path_indexes,
size_t action_path_length)
{
- unsigned int i, count, printed_errors_count = 0;
enum lttng_error_code error_query_ret;
- enum lttng_error_query_results_status results_status;
struct lttng_error_query_results *results = NULL;
const char *trigger_name;
uid_t trigger_uid;
goto end;
}
- results_status = lttng_error_query_results_get_count(results, &count);
- assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
-
- _MSG(" errors:");
-
- for (i = 0; i < count; i++) {
- const struct lttng_error_query_result *result;
- enum lttng_error_query_result_status result_status;
- const char *result_name;
- const char *result_description;
- uint64_t result_value;
-
- results_status = lttng_error_query_results_get_result(
- results, &result, i);
- assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
-
- result_status = lttng_error_query_result_get_name(
- result, &result_name);
- assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
- result_status = lttng_error_query_result_get_description(
- result, &result_description);
- assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
-
- if (lttng_error_query_result_get_type(result) ==
- LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
- result_status = lttng_error_query_result_counter_get_value(
- result, &result_value);
- assert(result_status ==
- LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
- if (result_value == 0) {
- continue;
- }
-
- MSG("");
- _MSG(" %s: %" PRIu64, result_name,
- result_value);
- printed_errors_count++;
- } else {
- _MSG(" Unknown error query result type for result '%s' (%s)",
- result_name, result_description);
- continue;
- }
- }
-
- if (printed_errors_count == 0) {
- _MSG(" none");
- }
+ print_error_query_results(results, 3);
end:
MSG("");
static
void print_trigger_errors(const struct lttng_trigger *trigger)
{
- unsigned int i, count, printed_errors_count = 0;
enum lttng_error_code error_query_ret;
- enum lttng_error_query_results_status results_status;
struct lttng_error_query_results *results = NULL;
enum lttng_trigger_status trigger_status;
const char *trigger_name;
goto end;
}
- results_status = lttng_error_query_results_get_count(results, &count);
- assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
-
- _MSG(" errors:");
+ print_error_query_results(results, 1);
- for (i = 0; i < count; i++) {
- const struct lttng_error_query_result *result;
- enum lttng_error_query_result_status result_status;
- const char *result_name;
- const char *result_description;
- uint64_t result_value;
+end:
+ MSG("");
+ lttng_error_query_destroy(query);
+ lttng_error_query_results_destroy(results);
+}
- results_status = lttng_error_query_results_get_result(
- results, &result, i);
- assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
+static
+void print_condition_errors(const struct lttng_trigger *trigger)
+{
+ enum lttng_error_code error_query_ret;
+ struct lttng_error_query_results *results = NULL;
+ enum lttng_trigger_status trigger_status;
+ const char *trigger_name;
+ uid_t trigger_uid;
+ struct lttng_error_query *query =
+ lttng_error_query_condition_create(trigger);
- result_status = lttng_error_query_result_get_name(
- result, &result_name);
- assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
- result_status = lttng_error_query_result_get_description(
- result, &result_description);
- assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
+ assert(query);
+ /*
+ * Anonymous triggers are not listed; this would be an internal error.
+ */
+ trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
+ assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
- if (lttng_error_query_result_get_type(result) ==
- LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
- result_status = lttng_error_query_result_counter_get_value(
- result, &result_value);
- assert(result_status ==
- LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
- if (result_value == 0) {
- continue;
- }
+ trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
+ assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
- MSG("");
- _MSG(" %s: %" PRIu64, result_name,
- result_value);
- printed_errors_count++;
- } else {
- _MSG(" Unknown error query result type for result '%s' (%s)",
- result_name, result_description);
- continue;
- }
+ error_query_ret = lttng_error_query_execute(
+ query, lttng_session_daemon_command_endpoint, &results);
+ if (error_query_ret != LTTNG_OK) {
+ ERR("Failed to query errors of condition of trigger '%s' (owner uid: %d): %s",
+ trigger_name, (int) trigger_uid,
+ lttng_strerror(-error_query_ret));
+ goto end;
}
- if (printed_errors_count == 0) {
- _MSG(" none");
- }
+ print_error_query_results(results, 2);
end:
MSG("");
abort();
}
+ print_condition_errors(trigger);
+
action = lttng_trigger_get_const_action(trigger);
action_type = lttng_action_get_type(action);
if (action_type == LTTNG_ACTION_TYPE_LIST) {
struct lttng_trigger *trigger;
};
+struct lttng_error_query_condition {
+ struct lttng_error_query parent;
+ /* Mutable only because of the reference count. */
+ struct lttng_trigger *trigger;
+};
+
struct lttng_error_query_action {
struct lttng_error_query parent;
/* Mutable only because of the reference count. */
return query ? &query->parent : NULL;
}
+struct lttng_error_query *lttng_error_query_condition_create(
+ const struct lttng_trigger *trigger)
+{
+ struct lttng_error_query_condition *query = NULL;
+ struct lttng_trigger *trigger_copy = NULL;
+
+ if (!trigger) {
+ goto end;
+ }
+
+ trigger_copy = lttng_trigger_copy(trigger);
+ if (!trigger_copy) {
+ goto end;
+ }
+
+ query = zmalloc(sizeof(*query));
+ if (!query) {
+ PERROR("Failed to allocate condition error query");
+ goto error;
+ }
+
+ query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION;
+ query->trigger = trigger_copy;
+ trigger_copy = NULL;
+
+error:
+ lttng_trigger_put(trigger_copy);
+end:
+ return query ? &query->parent : NULL;
+}
+
static
struct lttng_action *get_trigger_action_from_path(
struct lttng_trigger *trigger,
return ret;
}
+static
+int lttng_error_query_condition_serialize(const struct lttng_error_query *query,
+ struct lttng_payload *payload)
+{
+ int ret;
+ const struct lttng_error_query_condition *query_trigger =
+ container_of(query, typeof(*query_trigger), parent);
+
+ if (!lttng_trigger_validate(query_trigger->trigger)) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = lttng_trigger_serialize(query_trigger->trigger, payload);
+ if (ret) {
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
static
int lttng_error_query_action_serialize(const struct lttng_error_query *query,
struct lttng_payload *payload)
return query_trigger->trigger;
}
+LTTNG_HIDDEN
+const struct lttng_trigger *lttng_error_query_condition_borrow_target(
+ const struct lttng_error_query *query)
+{
+ const struct lttng_error_query_condition *query_trigger =
+ container_of(query, typeof(*query_trigger), parent);
+
+ return query_trigger->trigger;
+}
+
LTTNG_HIDDEN
const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
const struct lttng_error_query *query)
goto end;
}
+ break;
+ case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
+ ret = lttng_error_query_condition_serialize(query, payload);
+ if (ret) {
+ goto end;
+ }
+
break;
case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
ret = lttng_error_query_action_serialize(query, payload);
break;
}
+ case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
+ {
+ ssize_t trigger_used_size;
+ struct lttng_payload_view trigger_view =
+ lttng_payload_view_from_view(
+ view, used_size, -1);
+
+ if (!lttng_payload_view_is_valid(&trigger_view)) {
+ used_size = -1;
+ goto end;
+ }
+
+ trigger_used_size = lttng_trigger_create_from_payload(
+ &trigger_view, &trigger);
+ if (trigger_used_size < 0) {
+ used_size = -1;
+ goto end;
+ }
+
+ used_size += trigger_used_size;
+
+ *query = lttng_error_query_condition_create(trigger);
+ if (!*query) {
+ used_size = -1;
+ goto end;
+ }
+
+ break;
+ }
case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
{
struct lttng_action_path *action_path = NULL;
"$FULL_LTTNG_BIN" list-triggers > "$list_triggers_stdout"
- cat "$list_triggers_stdout" | grep -a7 "$trigger_name" | tail -1 | grep --quiet "errors: none"
+ cat "$list_triggers_stdout" | grep -A7 "$trigger_name" | grep -A2 "event rule matches" | tail -1 | grep --quiet "errors: none"
ret=$?
if [ "$ret" -eq "0" ]; then
notif_nb="0"
else
- notif_nb=$(cat "$list_triggers_stdout" | grep -a8 "$trigger_name" | tail -1 | grep "discarded tracer messages" | cut -d' ' -f8)
+ notif_nb=$(cat "$list_triggers_stdout" | grep -A7 "$trigger_name" | grep "discarded tracer messages" | cut -d' ' -f10)
fi
rm -f "$list_triggers_stdout"
owner uid: ${uid}
condition: event rule matches
rule: test-name (type: user tracepoint)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: aaa (type: user tracepoint, filter: p == 2)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: gerboise (type: user tracepoint, log level at least INFO)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: * (type: user tracepoint)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: hello* (type: user tracepoint, exclusions: hello2,hello3,hello4)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: lemming (type: user tracepoint, log level is WARNING)
+ errors: none
actions:
notify
errors: none
rule: capture-payload-field (type: user tracepoint)
captures:
- a
+ errors: none
actions:
notify
errors: none
captures:
- a[2]
- \$ctx.tourlou[18]
+ errors: none
actions:
notify
errors: none
rule: capture-chan-ctx (type: user tracepoint)
captures:
- \$ctx.vpid
+ errors: none
actions:
notify
errors: none
rule: capture-app-ctx (type: user tracepoint)
captures:
- \$app.iga:active_clients
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: lemming (type: user tracepoint)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: my_channel_enable (type: kernel:kprobe, location: lttng_channel_enable)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: my_channel_enable (type: kernel:kprobe, location: ${base_symbol}+${offset_hex})
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: my_channel_enable (type: kernel:kprobe, location: 0x${channel_enable_addr})
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: ma-probe-elf (type: kernel:uprobe, location type: ELF, location: ${uprobe_elf_binary}:${elf_function_name})
+ errors: none
actions:
notify
errors: none
owner uid: 0
condition: event rule matches
rule: ma-probe-sdt (type: kernel:uprobe, location type: SDT, location: ${uprobe_sdt_binary}:${sdt_provider_name}:${sdt_probe_name})
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: open (type: kernel:syscall:entry+exit)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: open (type: kernel:syscall:entry)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: open (type: kernel:syscall:exit)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: open (type: kernel:syscall:entry+exit)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: ptrace (type: kernel:syscall:entry+exit, filter: a > 2)
+ errors: none
actions:
notify
errors: none
condition: session consumed size
session name: the-session-name
threshold: 1234 bytes
+ errors: none
actions:
notify
errors: none
channel name: the-channel-name
domain: ust
threshold (bytes): 1234
+ errors: none
actions:
notify
errors: none
channel name: the-channel-name
domain: ust
threshold (ratio): 0.25
+ errors: none
actions:
notify
errors: none
channel name: the-channel-name
domain: ust
threshold (bytes): 2345
+ errors: none
actions:
notify
errors: none
channel name: the-channel-name
domain: ust
threshold (ratio): 0.40
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: session rotation completed
session name: the-session-name
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: session rotation ongoing
session name: the-session-name
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, path: /some/path
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, path: /some/other/path
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, url: net://1.2.3.4
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, url: net://1.2.3.4:1234:1235
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, control url: tcp://1.2.3.4:1111, data url: tcp://1.2.3.4:1112
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, path: /some/path, max size: 1234
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, path: /some/path, name: meh
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, rate policy: every 10 occurrences
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
snapshot session \`ze-session\`, rate policy: once after 10 occurrences
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
notify, rate policy: once after 5 occurrences
errors: none
owner uid: ${uid}
condition: event rule matches
rule: some-event (type: user tracepoint)
+ errors: none
actions:
notify, rate policy: every 10 occurrences
errors: none
owner uid: ${uid}
condition: event rule matches
rule: aaa (type: user tracepoint, filter: p == 2)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: * (type: user tracepoint)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: * (type: user tracepoint)
+ errors: none
actions:
notify
errors: none
owner uid: ${uid}
condition: event rule matches
rule: * (type: python:logging)
+ errors: none
actions:
notify
errors: none