X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Flist_triggers.c;h=69d1e0f0afdd2ceacb2ef3dca130a306339bc14d;hb=ea76a8bbde6896bddfa656627e8f12e0b9f55a5e;hp=929d9a46b442e01b26679906972253c0d9d50a85;hpb=45ce77e1f8f35eb126de67b85f645180115168fa;p=lttng-tools.git diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index 929d9a46b..69d1e0f0a 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -10,6 +10,7 @@ #include "../command.h" #include "common/argpar/argpar.h" +#include "common/argpar-utils/argpar-utils.h" #include "common/dynamic-array.h" #include "common/mi-lttng.h" /* For lttng_condition_type_str(). */ @@ -29,6 +30,8 @@ static const char help_msg[] = ; #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)( @@ -638,6 +641,79 @@ void print_one_event_expr(const struct lttng_event_expr *event_expr) } } +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) { @@ -676,9 +752,7 @@ static void print_action_errors(const struct lttng_trigger *trigger, 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; @@ -710,53 +784,7 @@ static void print_action_errors(const struct lttng_trigger *trigger, 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(""); @@ -945,9 +973,7 @@ end: 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; @@ -974,53 +1000,45 @@ void print_trigger_errors(const struct lttng_trigger *trigger) 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(""); @@ -1078,6 +1096,8 @@ void print_one_trigger(const struct lttng_trigger *trigger) 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) { @@ -1127,11 +1147,9 @@ int compare_triggers_by_name(const void *a, const void *b) return strcmp(name_a, name_b); } -int cmd_list_triggers(int argc, const char **argv) +static int print_sorted_triggers(const struct lttng_triggers *triggers) { int ret; - struct argpar_parse_ret argpar_parse_ret = {}; - struct lttng_triggers *triggers = NULL; int i; struct lttng_dynamic_pointer_array sorted_triggers; enum lttng_trigger_status trigger_status; @@ -1139,51 +1157,6 @@ int cmd_list_triggers(int argc, const char **argv) lttng_dynamic_pointer_array_init(&sorted_triggers, NULL); - argpar_parse_ret = argpar_parse( - argc - 1, argv + 1, list_trigger_options, true); - if (!argpar_parse_ret.items) { - ERR("%s", argpar_parse_ret.error); - goto error; - } - - for (i = 0; i < argpar_parse_ret.items->n_items; i++) { - const struct argpar_item *item = - argpar_parse_ret.items->items[i]; - - if (item->type == ARGPAR_ITEM_TYPE_OPT) { - const struct argpar_item_opt *item_opt = - (const struct argpar_item_opt *) item; - - switch (item_opt->descr->id) { - case OPT_HELP: - SHOW_HELP(); - ret = 0; - goto end; - - case OPT_LIST_OPTIONS: - list_cmd_options_argpar(stdout, - list_trigger_options); - ret = 0; - goto end; - - default: - abort(); - } - - } else { - const struct argpar_item_non_opt *item_non_opt = - (const struct argpar_item_non_opt *) item; - - ERR("Unexpected argument: %s", item_non_opt->arg); - } - } - - ret = lttng_list_triggers(&triggers); - if (ret != LTTNG_OK) { - ERR("Error listing triggers: %s.", lttng_strerror(-ret)); - goto error; - } - trigger_status = lttng_triggers_get_count(triggers, &num_triggers); if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { ERR("Failed to get trigger count."); @@ -1209,7 +1182,6 @@ int cmd_list_triggers(int argc, const char **argv) add_ret = lttng_dynamic_pointer_array_add_pointer( &sorted_triggers, (void *) trigger); - if (add_ret) { ERR("Failed to allocate array of struct lttng_trigger *."); goto error; @@ -1220,9 +1192,10 @@ int cmd_list_triggers(int argc, const char **argv) sizeof(struct lttng_trigger *), compare_triggers_by_name); - for (i = 0; i < num_triggers; i++) { - const struct lttng_trigger *trigger_to_print = - (const struct lttng_trigger *) + for (i = 0; i < lttng_dynamic_pointer_array_get_count(&sorted_triggers); + i++) { + const struct lttng_trigger *trigger_to_print = (const struct lttng_trigger + *) lttng_dynamic_pointer_array_get_pointer( &sorted_triggers, i); @@ -1231,14 +1204,257 @@ int cmd_list_triggers(int argc, const char **argv) ret = 0; goto end; - error: ret = 1; end: - argpar_parse_ret_fini(&argpar_parse_ret); - lttng_triggers_destroy(triggers); lttng_dynamic_pointer_array_reset(&sorted_triggers); + return ret; +} + +static enum lttng_error_code mi_error_query_trigger_callback( + const struct lttng_trigger *trigger, + struct lttng_error_query_results **results) +{ + enum lttng_error_code ret_code; + struct lttng_error_query *query = + lttng_error_query_trigger_create(trigger); + + assert(results); + assert(query); + + ret_code = lttng_error_query_execute( + query, lttng_session_daemon_command_endpoint, results); + if (ret_code != LTTNG_OK) { + enum lttng_trigger_status trigger_status; + const char *trigger_name; + uid_t trigger_uid; + + trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + trigger_status = lttng_trigger_get_owner_uid( + trigger, &trigger_uid); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s", + trigger_name, (int) trigger_uid, + lttng_strerror(-ret_code)); + } + + lttng_error_query_destroy(query); + return ret_code; +} + +static enum lttng_error_code mi_error_query_action_callback( + const struct lttng_trigger *trigger, + const struct lttng_action_path *action_path, + struct lttng_error_query_results **results) +{ + enum lttng_error_code ret_code; + struct lttng_error_query *query = + lttng_error_query_action_create(trigger, action_path); + + assert(results); + assert(query); + + ret_code = lttng_error_query_execute( + query, lttng_session_daemon_command_endpoint, results); + if (ret_code != LTTNG_OK) { + enum lttng_trigger_status trigger_status; + const char *trigger_name; + uid_t trigger_uid; + + trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + trigger_status = lttng_trigger_get_owner_uid( + trigger, &trigger_uid); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + ERR("Failed to query errors of an action for trigger '%s' (owner uid: %d): %s", + trigger_name, (int) trigger_uid, + lttng_strerror(-ret_code)); + } + + lttng_error_query_destroy(query); + return ret_code; +} + +static enum lttng_error_code mi_error_query_condition_callback( + const struct lttng_trigger *trigger, + struct lttng_error_query_results **results) +{ + enum lttng_error_code ret_code; + struct lttng_error_query *query = + lttng_error_query_condition_create(trigger); + + assert(results); + assert(query); + ret_code = lttng_error_query_execute( + query, lttng_session_daemon_command_endpoint, results); + if (ret_code != LTTNG_OK) { + enum lttng_trigger_status trigger_status; + const char *trigger_name; + uid_t trigger_uid; + + trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + trigger_status = lttng_trigger_get_owner_uid( + trigger, &trigger_uid); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + ERR("Failed to query errors of of condition for condition of trigger '%s' (owner uid: %d): %s", + trigger_name, (int) trigger_uid, + lttng_strerror(-ret_code)); + } + + lttng_error_query_destroy(query); + return ret_code; +} + +int cmd_list_triggers(int argc, const char **argv) +{ + int ret; + struct argpar_iter *argpar_iter = NULL; + const struct argpar_item *argpar_item = NULL; + struct lttng_triggers *triggers = NULL; + struct mi_writer *mi_writer = NULL; + + argc--; + argv++; + + argpar_iter = argpar_iter_create(argc, argv, list_trigger_options); + if (!argpar_iter) { + ERR("Failed to allocate an argpar iter."); + goto error; + } + + while (true) { + enum parse_next_item_status status; + + status = parse_next_item(argpar_iter, &argpar_item, argv, + true, NULL); + if (status == PARSE_NEXT_ITEM_STATUS_ERROR) { + goto error; + } else if (status == PARSE_NEXT_ITEM_STATUS_END) { + break; + } + + assert(status == PARSE_NEXT_ITEM_STATUS_OK); + + if (argpar_item_type(argpar_item) == ARGPAR_ITEM_TYPE_OPT) { + const struct argpar_opt_descr *descr = + argpar_item_opt_descr(argpar_item); + + switch (descr->id) { + case OPT_HELP: + SHOW_HELP(); + ret = 0; + goto end; + + case OPT_LIST_OPTIONS: + list_cmd_options_argpar( + stdout, list_trigger_options); + ret = 0; + goto end; + + default: + abort(); + } + + } else { + ERR("Unexpected argument: %s", + argpar_item_non_opt_arg(argpar_item)); + } + } + + ret = lttng_list_triggers(&triggers); + if (ret != LTTNG_OK) { + ERR("Error listing triggers: %s.", lttng_strerror(-ret)); + goto error; + } + + if (lttng_opt_mi) { + mi_writer = mi_lttng_writer_create( + fileno(stdout), lttng_opt_mi); + if (!mi_writer) { + ret = CMD_ERROR; + goto end; + } + + /* Open command element. */ + ret = mi_lttng_writer_command_open(mi_writer, + mi_lttng_element_command_list_trigger); + if (ret) { + ret = CMD_ERROR; + goto end; + } + + /* Open output element. */ + ret = mi_lttng_writer_open_element( + mi_writer, mi_lttng_element_command_output); + if (ret) { + ret = CMD_ERROR; + goto end; + } + } + + if (lttng_opt_mi) { + const struct mi_lttng_error_query_callbacks callbacks = { + .trigger_cb = mi_error_query_trigger_callback, + .action_cb = mi_error_query_action_callback, + .condition_cb = mi_error_query_condition_callback, + }; + + ret = lttng_triggers_mi_serialize( + triggers, mi_writer, &callbacks); + if (ret != LTTNG_OK) { + ERR("Error printing MI triggers: %s.", + lttng_strerror(-ret)); + goto error; + } + } else { + ret = print_sorted_triggers(triggers); + if (ret) { + ERR("Error printing triggers"); + goto error; + } + } + + /* Mi closing. */ + if (lttng_opt_mi) { + /* Close output element. */ + ret = mi_lttng_writer_close_element(mi_writer); + if (ret) { + ret = CMD_ERROR; + goto end; + } + + /* Command element close. */ + ret = mi_lttng_writer_command_close(mi_writer); + if (ret) { + ret = CMD_ERROR; + goto end; + } + } + + ret = 0; + goto end; + +error: + ret = 1; + +end: + argpar_item_destroy(argpar_item); + argpar_iter_destroy(argpar_iter); + lttng_triggers_destroy(triggers); + /* Mi clean-up. */ + if (mi_writer && mi_lttng_writer_destroy(mi_writer)) { + /* Preserve original error code. */ + ret = ret ? ret : CMD_ERROR; + } return ret; }