X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Factions%2Flist.c;h=86eabda8a73c9dd450a5fced59d235451e3768b1;hb=ca806b0b247f89c62ac628a7779ae84049a8c2d7;hp=4c325df84d68447cb34dfcf32d8eb08941db3c1a;hpb=ad63a966ae7a204528fa77599f92100d7341be7a;p=lttng-tools.git diff --git a/src/common/actions/list.c b/src/common/actions/list.c index 4c325df84..86eabda8a 100644 --- a/src/common/actions/list.c +++ b/src/common/actions/list.c @@ -5,18 +5,18 @@ * */ -#include #include -#include -#include #include #include +#include +#include +#include #include #include #include -#define IS_GROUP_ACTION(action) \ - (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_GROUP) +#define IS_LIST_ACTION(action) \ + (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_LIST) struct lttng_action_list { struct lttng_action parent; @@ -44,7 +44,7 @@ static void destroy_lttng_action_list_element(void *ptr) static struct lttng_action_list *action_list_from_action( const struct lttng_action *action) { - assert(action); + LTTNG_ASSERT(action); return container_of(action, struct lttng_action_list, parent); } @@ -52,7 +52,7 @@ static struct lttng_action_list *action_list_from_action( static const struct lttng_action_list *action_list_from_action_const( const struct lttng_action *action) { - assert(action); + LTTNG_ASSERT(action); return container_of(action, struct lttng_action_list, parent); } @@ -63,7 +63,7 @@ static bool lttng_action_list_validate(struct lttng_action *action) struct lttng_action_list *action_list; bool valid; - assert(IS_GROUP_ACTION(action)); + LTTNG_ASSERT(IS_LIST_ACTION(action)); action_list = action_list_from_action(action); @@ -74,7 +74,7 @@ static bool lttng_action_list_validate(struct lttng_action *action) lttng_dynamic_pointer_array_get_pointer( &action_list->actions, i); - assert(child); + LTTNG_ASSERT(child); if (!lttng_action_validate(child)) { valid = false; @@ -115,8 +115,8 @@ static bool lttng_action_list_is_equal( const struct lttng_action *child_b = lttng_action_list_get_at_index(_b, i); - assert(child_a); - assert(child_b); + LTTNG_ASSERT(child_a); + LTTNG_ASSERT(child_b); if (!lttng_action_is_equal(child_a, child_b)) { goto end; @@ -136,9 +136,9 @@ static int lttng_action_list_serialize( int ret; unsigned int i, count; - assert(action); - assert(payload); - assert(IS_GROUP_ACTION(action)); + LTTNG_ASSERT(action); + LTTNG_ASSERT(payload); + LTTNG_ASSERT(IS_LIST_ACTION(action)); action_list = action_list_from_action(action); @@ -160,7 +160,7 @@ static int lttng_action_list_serialize( lttng_dynamic_pointer_array_get_pointer( &action_list->actions, i); - assert(child); + LTTNG_ASSERT(child); ret = lttng_action_serialize(child, payload); if (ret) { @@ -196,13 +196,13 @@ ssize_t lttng_action_list_create_from_payload( { ssize_t consumed_len; const struct lttng_action_list_comm *comm; - struct lttng_action *group; + struct lttng_action *list; struct lttng_action *child_action = NULL; enum lttng_action_status status; size_t i; - group = lttng_action_list_create(); - if (!group) { + list = lttng_action_list_create(); + if (!list) { consumed_len = -1; goto end; } @@ -229,7 +229,7 @@ ssize_t lttng_action_list_create_from_payload( goto end; } - status = lttng_action_list_add_action(group, child_action); + status = lttng_action_list_add_action(list, child_action); if (status != LTTNG_ACTION_STATUS_OK) { consumed_len = -1; goto end; @@ -242,11 +242,11 @@ ssize_t lttng_action_list_create_from_payload( consumed_len += consumed_len_child; } - *p_action = group; - group = NULL; + *p_action = list; + list = NULL; end: - lttng_action_list_destroy(group); + lttng_action_list_destroy(list); return consumed_len; } @@ -256,8 +256,8 @@ static enum lttng_action_status lttng_action_list_add_error_query_results( { unsigned int i, count; enum lttng_action_status action_status; - const struct lttng_action_list *group = - container_of(action, typeof(*group), parent); + const struct lttng_action_list *list = + container_of(action, typeof(*list), parent); action_status = lttng_action_list_get_count(action, &count); if (action_status != LTTNG_ACTION_STATUS_OK) { @@ -278,6 +278,85 @@ end: return action_status; } +enum lttng_error_code lttng_action_list_mi_serialize( + const struct lttng_trigger *trigger, + const struct lttng_action *action, + struct mi_writer *writer, + const struct mi_lttng_error_query_callbacks + *error_query_callbacks, + struct lttng_dynamic_array *action_path_indexes) +{ + int ret; + struct lttng_action_list *action_list; + unsigned int i, count; + enum lttng_error_code ret_code; + + LTTNG_ASSERT(action); + LTTNG_ASSERT(IS_LIST_ACTION(action)); + LTTNG_ASSERT(writer); + + /* Open action list. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_action_list); + if (ret) { + goto mi_error; + } + + /* Serialize every action of the list. */ + action_list = action_list_from_action(action); + count = lttng_dynamic_pointer_array_get_count(&action_list->actions); + for (i = 0; i < count; i++) { + const struct lttng_action *child = + lttng_action_list_get_at_index(action, i); + const uint64_t index = (uint64_t) i; + + LTTNG_ASSERT(child); + + /* + * Add the index to the action path. + * + * This index is replaced on every iteration to walk the action + * tree in-order and to re-use the dynamic array instead of + * copying it at every level. + */ + ret = lttng_dynamic_array_add_element( + action_path_indexes, &index); + if (ret) { + ret_code = LTTNG_ERR_NOMEM; + goto end; + } + + ret_code = lttng_action_mi_serialize(trigger, child, writer, + error_query_callbacks, action_path_indexes); + if (ret_code != LTTNG_OK) { + goto end; + } + + ret = lttng_dynamic_array_remove_element(action_path_indexes, + lttng_dynamic_array_get_count( + action_path_indexes) - + 1); + if (ret) { + ret_code = LTTNG_ERR_UNK; + goto end; + } + } + + /* Close action_list element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + struct lttng_action *lttng_action_list_create(void) { struct lttng_action_list *action_list; @@ -291,12 +370,14 @@ struct lttng_action *lttng_action_list_create(void) action = &action_list->parent; - lttng_action_init(action, LTTNG_ACTION_TYPE_GROUP, - lttng_action_list_validate, - lttng_action_list_serialize, + /* + * The mi for the list is handled at the lttng_action_mi level to ease + * action path management for error query. + */ + lttng_action_init(action, LTTNG_ACTION_TYPE_LIST, + lttng_action_list_validate, lttng_action_list_serialize, lttng_action_list_is_equal, lttng_action_list_destroy, - NULL, - lttng_action_list_add_error_query_results); + NULL, lttng_action_list_add_error_query_results, NULL); lttng_dynamic_pointer_array_init(&action_list->actions, destroy_lttng_action_list_element); @@ -306,27 +387,27 @@ end: } enum lttng_action_status lttng_action_list_add_action( - struct lttng_action *group, struct lttng_action *action) + struct lttng_action *list, struct lttng_action *action) { struct lttng_action_list *action_list; enum lttng_action_status status; int ret; - if (!group || !IS_GROUP_ACTION(group) || !action) { + if (!list || !IS_LIST_ACTION(list) || !action) { status = LTTNG_ACTION_STATUS_INVALID; goto end; } /* - * Don't allow adding groups in groups for now, since we're afraid of + * Don't allow adding lists in lists for now, since we're afraid of * cycles. */ - if (IS_GROUP_ACTION(action)) { + if (IS_LIST_ACTION(action)) { status = LTTNG_ACTION_STATUS_INVALID; goto end; } - action_list = action_list_from_action(group); + action_list = action_list_from_action(list); ret = lttng_dynamic_pointer_array_add_pointer(&action_list->actions, action); @@ -343,38 +424,37 @@ end: } enum lttng_action_status lttng_action_list_get_count( - const struct lttng_action *group, unsigned int *count) + const struct lttng_action *list, unsigned int *count) { const struct lttng_action_list *action_list; enum lttng_action_status status = LTTNG_ACTION_STATUS_OK; - if (!group || !IS_GROUP_ACTION(group)) { + if (!list || !IS_LIST_ACTION(list)) { status = LTTNG_ACTION_STATUS_INVALID; *count = 0; goto end; } - action_list = action_list_from_action_const(group); + action_list = action_list_from_action_const(list); *count = lttng_dynamic_pointer_array_get_count(&action_list->actions); end: return status; } const struct lttng_action *lttng_action_list_get_at_index( - const struct lttng_action *group, unsigned int index) + const struct lttng_action *list, unsigned int index) { - return lttng_action_list_borrow_mutable_at_index(group, index); + return lttng_action_list_borrow_mutable_at_index(list, index); } -LTTNG_HIDDEN struct lttng_action *lttng_action_list_borrow_mutable_at_index( - const struct lttng_action *group, unsigned int index) + const struct lttng_action *list, unsigned int index) { unsigned int count; const struct lttng_action_list *action_list; struct lttng_action *action = NULL; - if (lttng_action_list_get_count(group, &count) != + if (lttng_action_list_get_count(list, &count) != LTTNG_ACTION_STATUS_OK) { goto end; } @@ -383,7 +463,7 @@ struct lttng_action *lttng_action_list_borrow_mutable_at_index( goto end; } - action_list = action_list_from_action_const(group); + action_list = action_list_from_action_const(list); action = lttng_dynamic_pointer_array_get_pointer(&action_list->actions, index); end: