X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Flist_triggers.c;h=59db1c5d4b8b499fbd81a5fe10c9ccf9c374da7b;hp=a456afc89c620232d92568eafd737c637a4f1e81;hb=523c4f8cdeb927b789710e3dafcb3f249751ccfd;hpb=6a751b953a43c566b74818ec6325db0978e16c66 diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index a456afc89..59db1c5d4 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -1146,11 +1146,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; @@ -1158,6 +1156,166 @@ int cmd_list_triggers(int argc, const char **argv) lttng_dynamic_pointer_array_init(&sorted_triggers, NULL); + trigger_status = lttng_triggers_get_count(triggers, &num_triggers); + if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { + ERR("Failed to get trigger count."); + goto error; + } + + for (i = 0; i < num_triggers; i++) { + int add_ret; + const char *unused_name; + const struct lttng_trigger *trigger = + lttng_triggers_get_at_index(triggers, i); + + trigger_status = lttng_trigger_get_name(trigger, &unused_name); + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + case LTTNG_TRIGGER_STATUS_UNSET: + /* Don't list anonymous triggers. */ + continue; + default: + abort(); + } + + 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; + } + } + + qsort(sorted_triggers.array.buffer.data, num_triggers, + 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 *) + lttng_dynamic_pointer_array_get_pointer( + &sorted_triggers, i); + + print_one_trigger(trigger_to_print); + } + + ret = 0; + goto end; +error: + ret = 1; + +end: + 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)); + } + + 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)); + } + 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)); + } + + return ret_code; +} +int cmd_list_triggers(int argc, const char **argv) +{ + int ret; + struct argpar_parse_ret argpar_parse_ret = {}; + struct lttng_triggers *triggers = NULL; + int i; + struct mi_writer *mi_writer = NULL; + argpar_parse_ret = argpar_parse( argc - 1, argv + 1, list_trigger_options, true); if (!argpar_parse_ret.items) { @@ -1180,8 +1338,8 @@ int cmd_list_triggers(int argc, const char **argv) goto end; case OPT_LIST_OPTIONS: - list_cmd_options_argpar(stdout, - list_trigger_options); + list_cmd_options_argpar( + stdout, list_trigger_options); ret = 0; goto end; @@ -1203,49 +1361,68 @@ int cmd_list_triggers(int argc, const char **argv) goto error; } - trigger_status = lttng_triggers_get_count(triggers, &num_triggers); - if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { - ERR("Failed to get trigger count."); - goto error; - } - - for (i = 0; i < num_triggers; i++) { - int add_ret; - const char *unused_name; - const struct lttng_trigger *trigger = - lttng_triggers_get_at_index(triggers, i); + if (lttng_opt_mi) { + mi_writer = mi_lttng_writer_create( + fileno(stdout), lttng_opt_mi); + if (!mi_writer) { + ret = CMD_ERROR; + goto end; + } - trigger_status = lttng_trigger_get_name(trigger, &unused_name); - switch (trigger_status) { - case LTTNG_TRIGGER_STATUS_OK: - break; - case LTTNG_TRIGGER_STATUS_UNSET: - /* Don't list anonymous triggers. */ - continue; - default: - abort(); + /* Open command element. */ + ret = mi_lttng_writer_command_open(mi_writer, + mi_lttng_element_command_list_trigger); + if (ret) { + ret = CMD_ERROR; + goto end; } - add_ret = lttng_dynamic_pointer_array_add_pointer( - &sorted_triggers, (void *) trigger); + /* Open output element. */ + ret = mi_lttng_writer_open_element( + mi_writer, mi_lttng_element_command_output); + if (ret) { + ret = CMD_ERROR; + goto end; + } + } - if (add_ret) { - ERR("Failed to allocate array of struct lttng_trigger *."); + 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; } } - qsort(sorted_triggers.array.buffer.data, num_triggers, - 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 *) - lttng_dynamic_pointer_array_get_pointer( - &sorted_triggers, i); + /* Mi closing. */ + if (lttng_opt_mi) { + /* Close output element. */ + ret = mi_lttng_writer_close_element(mi_writer); + if (ret) { + ret = CMD_ERROR; + goto end; + } - print_one_trigger(trigger_to_print); + /* Command element close. */ + ret = mi_lttng_writer_command_close(mi_writer); + if (ret) { + ret = CMD_ERROR; + goto end; + } } ret = 0; @@ -1257,7 +1434,10 @@ error: end: argpar_parse_ret_fini(&argpar_parse_ret); lttng_triggers_destroy(triggers); - lttng_dynamic_pointer_array_reset(&sorted_triggers); - + /* Mi clean-up. */ + if (mi_writer && mi_lttng_writer_destroy(mi_writer)) { + /* Preserve original error code. */ + ret = ret ? ret : CMD_ERROR; + } return ret; }