From 2658b8b58e4cb6fb40bcdb4e2adcbb2132d6b798 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 25 May 2021 19:17:07 -0400 Subject: [PATCH] lttng-ctl: use lttng_action_path to specify error query actions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau Change-Id: I30a93465231ec963d087b25678b6703a0425ceef --- include/lttng/error-query.h | 9 +- src/bin/lttng/commands/list_triggers.c | 29 ++-- src/common/actions/path.c | 10 +- src/common/error-query.c | 197 ++++++++++--------------- 4 files changed, 110 insertions(+), 135 deletions(-) diff --git a/include/lttng/error-query.h b/include/lttng/error-query.h index 382f2cad5..8a5945ae9 100644 --- a/include/lttng/error-query.h +++ b/include/lttng/error-query.h @@ -61,10 +61,15 @@ enum lttng_error_query_results_status { extern struct lttng_error_query *lttng_error_query_trigger_create( const struct lttng_trigger *trigger); -/* Create an error query targetting an action object. */ +/* + * Create an error query targetting an action object. + * + * `action_path` is copied internally. The root of the `action_path` is the + * action of `trigger`. + */ extern struct lttng_error_query *lttng_error_query_action_create( const struct lttng_trigger *trigger, - const struct lttng_action *action); + const struct lttng_action_path *action_path); /* Destroy an error query. */ extern void lttng_error_query_destroy(struct lttng_error_query *query); diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index 5a40fdc18..a58ef2837 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -539,9 +539,10 @@ static void print_condition_event_rule_matches( } } -static -void print_action_errors(const struct lttng_trigger *trigger, - const struct lttng_action *action) +static void print_action_errors(const struct lttng_trigger *trigger, + const struct lttng_action *action, + 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; @@ -550,9 +551,13 @@ void print_action_errors(const struct lttng_trigger *trigger, const char *trigger_name; uid_t trigger_uid; enum lttng_trigger_status trigger_status; - struct lttng_error_query *query = - lttng_error_query_action_create(trigger, action); + struct lttng_error_query *query; + struct lttng_action_path *action_path = lttng_action_path_create( + action_path_indexes, action_path_length); + + assert(action_path); + query = lttng_error_query_action_create(trigger, action_path); assert(query); trigger_status = lttng_trigger_get_name(trigger, &trigger_name); @@ -625,11 +630,14 @@ end: MSG(""); lttng_error_query_destroy(query); lttng_error_query_results_destroy(results); + lttng_action_path_destroy(action_path); } static void print_one_action(const struct lttng_trigger *trigger, - const struct lttng_action *action) + const struct lttng_action *action, + const uint64_t *action_path_indexes, + size_t action_path_length) { enum lttng_action_type action_type; enum lttng_action_status action_status; @@ -795,7 +803,8 @@ void print_one_action(const struct lttng_trigger *trigger, } MSG(""); - print_action_errors(trigger, action); + print_action_errors(trigger, action, action_path_indexes, + action_path_length); end: return; @@ -949,16 +958,18 @@ void print_one_trigger(const struct lttng_trigger *trigger) assert(action_status == LTTNG_ACTION_STATUS_OK); for (i = 0; i < count; i++) { + const uint64_t action_path_index = i; const struct lttng_action *subaction = lttng_action_list_get_at_index( action, i); _MSG(" "); - print_one_action(trigger, subaction); + print_one_action(trigger, subaction, &action_path_index, + 1); } } else { _MSG(" action:"); - print_one_action(trigger, action); + print_one_action(trigger, action, NULL, 0); } print_trigger_errors(trigger); diff --git a/src/common/actions/path.c b/src/common/actions/path.c index dbae34b9e..7f4955475 100644 --- a/src/common/actions/path.c +++ b/src/common/actions/path.c @@ -29,10 +29,6 @@ struct lttng_action_path *lttng_action_path_create( } lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL); - ret = lttng_dynamic_array_set_count(&path->indexes, index_count); - if (ret) { - goto error; - } for (i = 0; i < index_count; i++) { ret = lttng_dynamic_array_add_element( @@ -112,11 +108,6 @@ int lttng_action_path_copy(const struct lttng_action_path *src, lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL); src_count = lttng_dynamic_array_get_count(&src->indexes); - ret = lttng_dynamic_array_set_count(&dst->indexes, src_count); - if (ret) { - goto error; - } - for (i = 0; i < src_count; i++) { const void *index = lttng_dynamic_array_get_element( &src->indexes, i); @@ -173,6 +164,7 @@ ssize_t lttng_action_path_create_from_payload( } ret = consumed_size; + *_action_path = action_path; end: return ret; } diff --git a/src/common/error-query.c b/src/common/error-query.c index c4a28e9c4..0be04fa13 100644 --- a/src/common/error-query.c +++ b/src/common/error-query.c @@ -36,23 +36,11 @@ struct lttng_error_query_trigger { struct lttng_trigger *trigger; }; -struct lttng_error_query_action_comm { - LTTNG_OPTIONAL_COMM(uint32_t) action_index; - /* Trigger payload. */ - char payload[]; -}; - struct lttng_error_query_action { struct lttng_error_query parent; /* Mutable only because of the reference count. */ struct lttng_trigger *trigger; - /* - * Index of the target action. Since action lists can't be nested, - * the targetted action is the top-level list if the action_index is - * unset. Otherwise, the index refers to the index within the top-level - * list. - */ - LTTNG_OPTIONAL(unsigned int) action_index; + struct lttng_action_path action_path; }; struct lttng_error_query_result { @@ -123,66 +111,67 @@ end: return query ? &query->parent : NULL; } -extern struct lttng_error_query *lttng_error_query_action_create( - const struct lttng_trigger *trigger, - const struct lttng_action *action) +static +struct lttng_action *get_trigger_action_from_path( + struct lttng_trigger *trigger, + const struct lttng_action_path *action_path) { - struct lttng_error_query_action *query = NULL; - typeof(query->action_index) action_index = {}; - struct lttng_trigger *trigger_copy = NULL; + size_t index_count, i; + enum lttng_action_path_status path_status; + struct lttng_action *current_action = NULL; - if (!trigger || !action) { + path_status = lttng_action_path_get_index_count( + action_path, &index_count); + if (path_status != LTTNG_ACTION_PATH_STATUS_OK) { goto end; } - trigger_copy = lttng_trigger_copy(trigger); - if (!trigger_copy) { - goto end; + current_action = lttng_trigger_get_action(trigger); + for (i = 0; i < index_count; i++) { + uint64_t path_index; + + path_status = lttng_action_path_get_index_at_index( + action_path, i, &path_index); + current_action = lttng_action_list_borrow_mutable_at_index( + current_action, path_index); + if (!current_action) { + /* Invalid action path. */ + goto end; + } } +end: + return current_action; +} + +static +bool is_valid_action_path(const struct lttng_trigger *trigger, + const struct lttng_action_path *action_path) +{ /* - * If an action is not the top-level action of the trigger, our only - * hope of finding its position is if the top-level action is an - * action list. - * - * Note that action comparisons are performed by pointer since multiple - * otherwise identical actions can be found in an action list (two - * notify actions, for example). + * While 'trigger's constness is casted-away, the trigger and resulting + * action are not modified; we merely check for the action's existence. */ - if (action != trigger->action && - lttng_action_get_type(trigger->action) == - LTTNG_ACTION_TYPE_LIST) { - unsigned int i, action_list_count; - enum lttng_action_status action_status; - - action_status = lttng_action_list_get_count( - trigger->action, &action_list_count); - if (action_status != LTTNG_ACTION_STATUS_OK) { - goto error; - } + return !!get_trigger_action_from_path( + (struct lttng_trigger *) trigger, action_path); +} - for (i = 0; i < action_list_count; i++) { - const struct lttng_action *candidate_action = - lttng_action_list_get_at_index( - trigger->action, i); +struct lttng_error_query *lttng_error_query_action_create( + const struct lttng_trigger *trigger, + const struct lttng_action_path *action_path) +{ + struct lttng_error_query_action *query = NULL; + struct lttng_trigger *trigger_copy = NULL; + int ret_copy; - assert(candidate_action); - if (candidate_action == action) { - LTTNG_OPTIONAL_SET(&action_index, i); - break; - } - } + if (!trigger || !action_path || + !is_valid_action_path(trigger, action_path)) { + goto end; + } - if (!action_index.is_set) { - /* Not found; invalid action. */ - goto error; - } - } else { - /* - * Trigger action is not a list and not equal to the target - * action; invalid action provided. - */ - goto error; + trigger_copy = lttng_trigger_copy(trigger); + if (!trigger_copy) { + goto end; } query = zmalloc(sizeof(*query)); @@ -191,12 +180,19 @@ extern struct lttng_error_query *lttng_error_query_action_create( goto error; } + ret_copy = lttng_action_path_copy(action_path, &query->action_path); + if (ret_copy) { + goto error; + } + query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION; query->trigger = trigger_copy; trigger_copy = NULL; - query->action_index = action_index; + goto end; + error: lttng_trigger_put(trigger_copy); + lttng_error_query_destroy(query ? &query->parent : NULL); end: return query ? &query->parent : NULL; } @@ -616,26 +612,22 @@ int lttng_error_query_action_serialize(const struct lttng_error_query *query, int ret; const struct lttng_error_query_action *query_action = container_of(query, typeof(*query_action), parent); - struct lttng_error_query_action_comm header = { - .action_index.is_set = query_action->action_index.is_set, - .action_index.value = query_action->action_index.value, - }; if (!lttng_trigger_validate(query_action->trigger)) { ret = -1; goto end; } - ret = lttng_dynamic_buffer_append( - &payload->buffer, &header, sizeof(header)); + ret = lttng_trigger_serialize(query_action->trigger, payload); if (ret) { goto end; } - ret = lttng_trigger_serialize(query_action->trigger, payload); + ret = lttng_action_path_serialize(&query_action->action_path, payload); if (ret) { goto end; } + end: return ret; } @@ -672,28 +664,11 @@ struct lttng_action *lttng_error_query_action_borrow_action_target( const struct lttng_error_query *query, struct lttng_trigger *trigger) { - struct lttng_action *target_action = NULL; const struct lttng_error_query_action *query_action = container_of(query, typeof(*query_action), parent); - struct lttng_action *trigger_action = - lttng_trigger_get_action(trigger); - - if (!query_action->action_index.is_set) { - target_action = trigger_action; - } else { - if (lttng_action_get_type(trigger_action) != - LTTNG_ACTION_TYPE_LIST) { - ERR("Invalid action error query target index: trigger action is not a list"); - goto end; - } - - target_action = lttng_action_list_borrow_mutable_at_index( - trigger_action, - LTTNG_OPTIONAL_GET(query_action->action_index)); - } -end: - return target_action; + return get_trigger_action_from_path( + trigger, &query_action->action_path); } LTTNG_HIDDEN @@ -785,26 +760,10 @@ ssize_t lttng_error_query_create_from_payload(struct lttng_payload_view *view, } case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION: { - const struct lttng_action *target_action; - ssize_t trigger_used_size; - struct lttng_error_query_action_comm *action_header; - - { - struct lttng_payload_view action_header_view = - lttng_payload_view_from_view(view, - used_size, - sizeof(*action_header)); - - if (!lttng_payload_view_is_valid(&action_header_view)) { - used_size = -1; - goto end; - } - - action_header = (typeof(action_header)) action_header_view.buffer.data; - used_size += sizeof(*action_header); - } + struct lttng_action_path *action_path = NULL; { + ssize_t trigger_used_size; struct lttng_payload_view trigger_view = lttng_payload_view_from_view( view, used_size, -1); @@ -824,22 +783,30 @@ ssize_t lttng_error_query_create_from_payload(struct lttng_payload_view *view, used_size += trigger_used_size; } - if (!action_header->action_index.is_set) { - target_action = trigger->action; - } else { - if (lttng_action_get_type(trigger->action) != - LTTNG_ACTION_TYPE_LIST) { + { + ssize_t action_path_used_size; + struct lttng_payload_view action_path_view = + lttng_payload_view_from_view( + view, used_size, -1); + + if (!lttng_payload_view_is_valid(&action_path_view)) { + used_size = -1; + goto end; + } + + action_path_used_size = lttng_action_path_create_from_payload( + &action_path_view, &action_path); + if (action_path_used_size < 0) { used_size = -1; goto end; } - target_action = lttng_action_list_get_at_index( - trigger->action, - action_header->action_index.value); + used_size += action_path_used_size; } *query = lttng_error_query_action_create( - trigger, target_action); + trigger, action_path); + lttng_action_path_destroy(action_path); if (!*query) { used_size = -1; goto end; -- 2.34.1