X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Factions%2Flist.c;h=3713cbd76da49f69c319f86a46def560f284616c;hb=6a751b953a43c566b74818ec6325db0978e16c66;hp=4c325df84d68447cb34dfcf32d8eb08941db3c1a;hpb=ad63a966ae7a204528fa77599f92100d7341be7a;p=lttng-tools.git diff --git a/src/common/actions/list.c b/src/common/actions/list.c index 4c325df84..3713cbd76 100644 --- a/src/common/actions/list.c +++ b/src/common/actions/list.c @@ -7,16 +7,17 @@ #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; @@ -63,7 +64,7 @@ static bool lttng_action_list_validate(struct lttng_action *action) struct lttng_action_list *action_list; bool valid; - assert(IS_GROUP_ACTION(action)); + assert(IS_LIST_ACTION(action)); action_list = action_list_from_action(action); @@ -138,7 +139,7 @@ static int lttng_action_list_serialize( assert(action); assert(payload); - assert(IS_GROUP_ACTION(action)); + assert(IS_LIST_ACTION(action)); action_list = action_list_from_action(action); @@ -196,13 +197,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 +230,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 +243,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 +257,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 +279,86 @@ end: return action_status; } +LTTNG_HIDDEN +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; + + assert(action); + assert(IS_LIST_ACTION(action)); + 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; + + 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 +372,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 +389,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 +426,38 @@ 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 +466,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: