X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=3b776c57634fcfa5f05688a2c7b2c8233fb505b7;hb=d37406195ec30adfb1bd903e3ee8dfdda79700ef;hp=8d36e7192c8deb32a46ca471c5d58dafd5e19d63;hpb=39b95a70bbb440eb42a548df21742f6ddebe0e2d;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 8d36e7192..3b776c576 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -6,66 +6,69 @@ * */ + #define _LGPL_SOURCE #include #include +#include +#include #include #include -#include -#include -#include +#include #include -#include -#include -#include #include -#include +#include #include -#include -#include +#include #include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include #include +#include +#include +#include #include -#include +#include +#include +#include "agent-thread.h" +#include "agent.h" +#include "buffer-registry.h" #include "channel.h" +#include "cmd.h" #include "consumer.h" +#include "event-notifier-error-accounting.h" #include "event.h" #include "health-sessiond.h" -#include "kernel.h" #include "kernel-consumer.h" +#include "kernel.h" #include "lttng-sessiond.h" -#include "utils.h" #include "lttng-syscall.h" -#include "agent.h" -#include "buffer-registry.h" -#include "notification-thread.h" #include "notification-thread-commands.h" +#include "notification-thread.h" #include "rotate.h" #include "rotation-thread.h" +#include "session.h" #include "timer.h" -#include "agent-thread.h" #include "tracker.h" - -#include "cmd.h" +#include "utils.h" /* Sleep for 100ms between each check for the shm path's deletion. */ #define SESSION_DESTROY_SHM_PATH_CHECK_DELAY_US 100000 @@ -115,7 +118,7 @@ static int cmd_enable_event_internal(struct ltt_session *session, const struct lttng_domain *domain, char *channel_name, struct lttng_event *event, char *filter_expression, - struct lttng_filter_bytecode *filter, + struct lttng_bytecode *filter, struct lttng_event_exclusion *exclusion, int wpipe); @@ -359,7 +362,7 @@ static ssize_t list_lttng_channels(enum lttng_domain_type domain, * Map enum lttng_ust_output to enum lttng_event_output. */ switch (uchan->attr.output) { - case LTTNG_UST_MMAP: + case LTTNG_UST_ABI_MMAP: channels[i].attr.output = LTTNG_EVENT_MMAP; break; default: @@ -579,26 +582,26 @@ static int list_lttng_ust_global_events(char *channel_name, event.enabled = uevent->enabled; switch (uevent->attr.instrumentation) { - case LTTNG_UST_TRACEPOINT: + case LTTNG_UST_ABI_TRACEPOINT: event.type = LTTNG_EVENT_TRACEPOINT; break; - case LTTNG_UST_PROBE: + case LTTNG_UST_ABI_PROBE: event.type = LTTNG_EVENT_PROBE; break; - case LTTNG_UST_FUNCTION: + case LTTNG_UST_ABI_FUNCTION: event.type = LTTNG_EVENT_FUNCTION; break; } event.loglevel = uevent->attr.loglevel; switch (uevent->attr.loglevel_type) { - case LTTNG_UST_LOGLEVEL_ALL: + case LTTNG_UST_ABI_LOGLEVEL_ALL: event.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; break; - case LTTNG_UST_LOGLEVEL_RANGE: + case LTTNG_UST_ABI_LOGLEVEL_RANGE: event.loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE; break; - case LTTNG_UST_LOGLEVEL_SINGLE: + case LTTNG_UST_ABI_LOGLEVEL_SINGLE: event.loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE; break; } @@ -678,34 +681,34 @@ static int list_lttng_kernel_events(char *channel_name, event.filter = (unsigned char) !!kevent->filter_expression; switch (kevent->event->instrumentation) { - case LTTNG_KERNEL_TRACEPOINT: + case LTTNG_KERNEL_ABI_TRACEPOINT: event.type = LTTNG_EVENT_TRACEPOINT; break; - case LTTNG_KERNEL_KRETPROBE: + case LTTNG_KERNEL_ABI_KRETPROBE: event.type = LTTNG_EVENT_FUNCTION; memcpy(&event.attr.probe, &kevent->event->u.kprobe, - sizeof(struct lttng_kernel_kprobe)); + sizeof(struct lttng_kernel_abi_kprobe)); break; - case LTTNG_KERNEL_KPROBE: + case LTTNG_KERNEL_ABI_KPROBE: event.type = LTTNG_EVENT_PROBE; memcpy(&event.attr.probe, &kevent->event->u.kprobe, - sizeof(struct lttng_kernel_kprobe)); + sizeof(struct lttng_kernel_abi_kprobe)); break; - case LTTNG_KERNEL_UPROBE: + case LTTNG_KERNEL_ABI_UPROBE: event.type = LTTNG_EVENT_USERSPACE_PROBE; break; - case LTTNG_KERNEL_FUNCTION: + case LTTNG_KERNEL_ABI_FUNCTION: event.type = LTTNG_EVENT_FUNCTION; memcpy(&event.attr.ftrace, &kevent->event->u.ftrace, - sizeof(struct lttng_kernel_function)); + sizeof(struct lttng_kernel_abi_function)); break; - case LTTNG_KERNEL_NOOP: + case LTTNG_KERNEL_ABI_NOOP: event.type = LTTNG_EVENT_NOOP; break; - case LTTNG_KERNEL_SYSCALL: + case LTTNG_KERNEL_ABI_SYSCALL: event.type = LTTNG_EVENT_SYSCALL; break; - case LTTNG_KERNEL_ALL: + case LTTNG_KERNEL_ABI_ALL: /* fall-through. */ default: assert(0); @@ -2083,7 +2086,7 @@ static int _cmd_enable_event(struct ltt_session *session, const struct lttng_domain *domain, char *channel_name, struct lttng_event *event, char *filter_expression, - struct lttng_filter_bytecode *filter, + struct lttng_bytecode *filter, struct lttng_event_exclusion *exclusion, int wpipe, bool internal_event) { @@ -2166,7 +2169,7 @@ static int _cmd_enable_event(struct ltt_session *session, case LTTNG_EVENT_ALL: { char *filter_expression_a = NULL; - struct lttng_filter_bytecode *filter_a = NULL; + struct lttng_bytecode *filter_a = NULL; /* * We need to duplicate filter_expression and filter, @@ -2401,11 +2404,11 @@ static int _cmd_enable_event(struct ltt_session *session, { char *filter_expression_copy = NULL; - struct lttng_filter_bytecode *filter_copy = NULL; + struct lttng_bytecode *filter_copy = NULL; if (filter) { const size_t filter_size = sizeof( - struct lttng_filter_bytecode) + struct lttng_bytecode) + filter->len; filter_copy = zmalloc(filter_size); @@ -2481,7 +2484,7 @@ int cmd_enable_event(struct ltt_session *session, const struct lttng_domain *domain, char *channel_name, struct lttng_event *event, char *filter_expression, - struct lttng_filter_bytecode *filter, + struct lttng_bytecode *filter, struct lttng_event_exclusion *exclusion, int wpipe) { @@ -2498,7 +2501,7 @@ static int cmd_enable_event_internal(struct ltt_session *session, const struct lttng_domain *domain, char *channel_name, struct lttng_event *event, char *filter_expression, - struct lttng_filter_bytecode *filter, + struct lttng_bytecode *filter, struct lttng_event_exclusion *exclusion, int wpipe) { @@ -3238,6 +3241,7 @@ void cmd_destroy_session_reply(const struct ltt_session *session, payload_size_before_location = payload.size; comm_ret = lttng_trace_archive_location_serialize(location, &payload); + lttng_trace_archive_location_put(location); if (comm_ret < 0) { ERR("Failed to serialize the location of the trace archive produced during the destruction of session \"%s\"", session->name); @@ -4203,7 +4207,7 @@ end: * then regenerate the metadata. Live and per-pid sessions are not * supported and return an error. * - * Return 0 on success or else a LTTNG_ERR code. + * Return LTTNG_OK on success or else a LTTNG_ERR code. */ int cmd_regenerate_metadata(struct ltt_session *session) { @@ -4244,7 +4248,7 @@ end: * * Ask the tracer to regenerate a new statedump. * - * Return 0 on success or else a LTTNG_ERR code. + * Return LTTNG_OK on success or else a LTTNG_ERR code. */ int cmd_regenerate_statedump(struct ltt_session *session) { @@ -4293,38 +4297,107 @@ end: return ret; } -static enum lttng_error_code trigger_modifies_event_notifier( - const struct lttng_trigger *trigger, bool *adds_event_notifier) +static +enum lttng_error_code synchronize_tracer_notifier_register( + struct notification_thread_handle *notification_thread, + struct lttng_trigger *trigger, const struct lttng_credentials *cmd_creds) { - enum lttng_error_code ret_code = LTTNG_OK; - const struct lttng_condition *condition = NULL; + enum lttng_error_code ret_code; + const struct lttng_condition *condition = + lttng_trigger_get_const_condition(trigger); + const char *trigger_name; + uid_t trigger_owner; + enum lttng_trigger_status trigger_status; + const enum lttng_domain_type trigger_domain = + lttng_trigger_get_underlying_domain_type_restriction( + trigger); - condition = lttng_trigger_get_const_condition(trigger); - if (!condition) { - ret_code = LTTNG_ERR_INVALID_TRIGGER; - goto end; + trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + assert(condition); + assert(lttng_condition_get_type(condition) == + LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES); + + trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? + trigger_name : "(anonymous)"; + + session_lock_list(); + switch (trigger_domain) { + case LTTNG_DOMAIN_KERNEL: + { + ret_code = kernel_register_event_notifier(trigger, cmd_creds); + if (ret_code != LTTNG_OK) { + enum lttng_error_code notif_thread_unregister_ret; + + notif_thread_unregister_ret = + notification_thread_command_unregister_trigger( + notification_thread, trigger); + + if (notif_thread_unregister_ret != LTTNG_OK) { + /* Return the original error code. */ + ERR("Failed to unregister trigger from notification thread during error recovery: trigger name = '%s', trigger owner uid = %d, error code = %d", + trigger_name, + (int) trigger_owner, + ret_code); + } + } + break; } + case LTTNG_DOMAIN_UST: + ust_app_global_update_all_event_notifier_rules(); + break; + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: + { + /* Agent domains. */ + struct agent *agt = agent_find_by_event_notifier_domain( + trigger_domain); - *adds_event_notifier = lttng_condition_get_type(condition) == - LTTNG_CONDITION_TYPE_EVENT_RULE_HIT; -end: + if (!agt) { + agt = agent_create(trigger_domain); + if (!agt) { + ret_code = LTTNG_ERR_NOMEM; + goto end_unlock_session_list; + } + + agent_add(agt, the_trigger_agents_ht_by_domain); + } + + ret_code = trigger_agent_enable(trigger, agt); + if (ret_code != LTTNG_OK) { + goto end_unlock_session_list; + } + + break; + } + case LTTNG_DOMAIN_NONE: + default: + abort(); + } + + ret_code = LTTNG_OK; +end_unlock_session_list: + session_unlock_list(); return ret_code; } enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_creds, struct lttng_trigger *trigger, + bool is_trigger_anonymous, struct notification_thread_handle *notification_thread, struct lttng_trigger **return_trigger) { enum lttng_error_code ret_code; - bool must_update_event_notifiers; const char *trigger_name; uid_t trigger_owner; enum lttng_trigger_status trigger_status; trigger_status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; trigger_status = lttng_trigger_get_owner_uid( trigger, &trigger_owner); @@ -4372,8 +4445,8 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c * it is safe to use without any locking as its properties are * immutable. */ - ret_code = notification_thread_command_register_trigger(notification_thread, - trigger); + ret_code = notification_thread_command_register_trigger( + notification_thread, trigger, is_trigger_anonymous); if (ret_code != LTTNG_OK) { DBG("Failed to register trigger to notification thread: trigger name = '%s', trigger owner uid = %d, error code = %d", trigger_name, (int) trigger_owner, ret_code); @@ -4382,74 +4455,19 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c trigger_status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; - - ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifiers); - if (ret_code != LTTNG_OK) { - ERR("Failed to determine if event modifies event notifiers: trigger name = '%s', trigger owner uid = %d, error code = %d", - trigger_name, (int) trigger_owner, ret_code); - goto end; - } + trigger_name : "(anonymous)"; /* * Synchronize tracers if the trigger adds an event notifier. */ - if (must_update_event_notifiers) { - const enum lttng_domain_type trigger_domain = - lttng_trigger_get_underlying_domain_type_restriction(trigger); - - session_lock_list(); - switch (trigger_domain) { - case LTTNG_DOMAIN_KERNEL: - { - ret_code = kernel_register_event_notifier( - trigger, cmd_creds); - if (ret_code != LTTNG_OK) { - const enum lttng_error_code notif_thread_unregister_ret = - notification_thread_command_unregister_trigger( - notification_thread, - trigger); - - if (notif_thread_unregister_ret != LTTNG_OK) { - /* Return the original error code. */ - ERR("Failed to unregister trigger from notification thread during error recovery: trigger name = '%s', trigger owner uid = %d, error code = %d", - trigger_name, - (int) trigger_owner, - ret_code); - } - } - break; - } - case LTTNG_DOMAIN_UST: - ust_app_global_update_all_event_notifier_rules(); - break; - case LTTNG_DOMAIN_NONE: - abort(); - default: - { - /* Agent domains. */ - struct agent *agt = agent_find_by_event_notifier_domain( - trigger_domain); - - if (!agt) { - agt = agent_create(trigger_domain); - if (!agt) { - ret_code = LTTNG_ERR_NOMEM; - goto end_unlock_session_list; - } - agent_add(agt, trigger_agents_ht_by_domain); - } - - ret_code = trigger_agent_enable(trigger, agt); - if (ret_code != LTTNG_OK) { - goto end_unlock_session_list; - } - - break; - } + if (lttng_trigger_needs_tracer_notifier(trigger)) { + ret_code = synchronize_tracer_notifier_register(notification_thread, + trigger, cmd_creds); + if (ret_code != LTTNG_OK) { + ERR("Error registering tracer notifier: %s", + lttng_strerror(-ret_code)); + goto end; } - - session_unlock_list(); } /* @@ -4467,6 +4485,62 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c } end: return ret_code; +} + +static +enum lttng_error_code synchronize_tracer_notifier_unregister( + const struct lttng_trigger *trigger) +{ + enum lttng_error_code ret_code; + const struct lttng_condition *condition = + lttng_trigger_get_const_condition(trigger); + const enum lttng_domain_type trigger_domain = + lttng_trigger_get_underlying_domain_type_restriction( + trigger); + + assert(condition); + assert(lttng_condition_get_type(condition) == + LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES); + + session_lock_list(); + switch (trigger_domain) { + case LTTNG_DOMAIN_KERNEL: + ret_code = kernel_unregister_event_notifier(trigger); + if (ret_code != LTTNG_OK) { + goto end_unlock_session_list; + } + + break; + case LTTNG_DOMAIN_UST: + ust_app_global_update_all_event_notifier_rules(); + break; + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: + { + /* Agent domains. */ + struct agent *agt = agent_find_by_event_notifier_domain( + trigger_domain); + + /* + * This trigger was never registered in the first place. Calling + * this function under those circumstances is an internal error. + */ + assert(agt); + ret_code = trigger_agent_disable(trigger, agt); + if (ret_code != LTTNG_OK) { + goto end_unlock_session_list; + } + + break; + } + case LTTNG_DOMAIN_NONE: + default: + abort(); + } + + ret_code = LTTNG_OK; + end_unlock_session_list: session_unlock_list(); return ret_code; @@ -4477,15 +4551,14 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd struct notification_thread_handle *notification_thread) { enum lttng_error_code ret_code; - bool must_update_event_notifiers; const char *trigger_name; uid_t trigger_owner; enum lttng_trigger_status trigger_status; + struct lttng_trigger *sessiond_trigger = NULL; trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(unnamed)"; - trigger_status = lttng_trigger_get_owner_uid( - trigger, &trigger_owner); + trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(anonymous)"; + trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner); assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); DBG("Running unregister trigger command: trigger name = '%s', trigger owner uid = %d, command creds uid = %d", @@ -4509,18 +4582,34 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd } } - ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifiers); + /* Fetch the sessiond side trigger object. */ + ret_code = notification_thread_command_get_trigger( + notification_thread, trigger, &sessiond_trigger); if (ret_code != LTTNG_OK) { - ERR("Failed to determine if event modifies event notifiers: trigger name = '%s', trigger owner uid = %d, error code = %d", + DBG("Failed to get trigger from notification thread during unregister: trigger name = '%s', trigger owner uid = %d, error code = %d", trigger_name, (int) trigger_owner, ret_code); goto end; } + assert(sessiond_trigger); + + /* + * From this point on, no matter what, consider the trigger + * unregistered. + * + * We set the unregistered state of the sessiond side trigger object in + * the client thread since we want to minimize the possibility of the + * notification thread being stalled due to a long execution of an + * action that required the trigger lock. + */ + lttng_trigger_set_as_unregistered(sessiond_trigger); + ret_code = notification_thread_command_unregister_trigger(notification_thread, trigger); if (ret_code != LTTNG_OK) { DBG("Failed to unregister trigger from notification thread: trigger name = '%s', trigger owner uid = %d, error code = %d", trigger_name, (int) trigger_owner, ret_code); + goto end; } /* @@ -4529,62 +4618,25 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd * the tracers from producing notifications associated with this * event notifier. */ - if (must_update_event_notifiers) { - const enum lttng_domain_type trigger_domain = - lttng_trigger_get_underlying_domain_type_restriction( - trigger); - - session_lock_list(); - switch (trigger_domain) { - case LTTNG_DOMAIN_KERNEL: - { - ret_code = kernel_unregister_event_notifier( - trigger); - break; - } - case LTTNG_DOMAIN_UST: - ust_app_global_update_all_event_notifier_rules(); - break; - case LTTNG_DOMAIN_NONE: - abort(); - default: - { - /* Agent domains. */ - struct agent *agt = agent_find_by_event_notifier_domain( - trigger_domain); - - if (!agt) { - agt = agent_create(trigger_domain); - if (!agt) { - ret_code = LTTNG_ERR_NOMEM; - goto end_unlock_session_list; - } - agent_add(agt, trigger_agents_ht_by_domain); - } - - ret_code = trigger_agent_disable(trigger, agt); - if (ret_code != LTTNG_OK) { - goto end_unlock_session_list; - } - - break; - } + if (lttng_trigger_needs_tracer_notifier(trigger)) { + ret_code = synchronize_tracer_notifier_unregister(trigger); + if (ret_code != LTTNG_OK) { + ERR("Error unregistering trigger to tracer."); + goto end; } - session_unlock_list(); } end: + lttng_trigger_put(sessiond_trigger); return ret_code; -end_unlock_session_list: - session_unlock_list(); - return ret_code;} +} -int cmd_list_triggers(struct command_ctx *cmd_ctx, +enum lttng_error_code cmd_list_triggers(struct command_ctx *cmd_ctx, struct notification_thread_handle *notification_thread, struct lttng_triggers **return_triggers) { - int ret = 0; + int ret; enum lttng_error_code ret_code; struct lttng_triggers *triggers = NULL; @@ -4592,17 +4644,165 @@ int cmd_list_triggers(struct command_ctx *cmd_ctx, ret_code = notification_thread_command_list_triggers( notification_thread, cmd_ctx->creds.uid, &triggers); if (ret_code != LTTNG_OK) { - ret = ret_code; + goto end; + } + + ret = lttng_triggers_remove_hidden_triggers(triggers); + if (ret) { + ret_code = LTTNG_ERR_UNK; goto end; } *return_triggers = triggers; triggers = NULL; - ret = LTTNG_OK; + ret_code = LTTNG_OK; end: lttng_triggers_destroy(triggers); - return ret; + return ret_code; } + +enum lttng_error_code cmd_execute_error_query(const struct lttng_credentials *cmd_creds, + const struct lttng_error_query *query, + struct lttng_error_query_results **_results, + struct notification_thread_handle *notification_thread) +{ + enum lttng_error_code ret_code; + const struct lttng_trigger *query_target_trigger; + const struct lttng_action *query_target_action = NULL; + struct lttng_trigger *matching_trigger = NULL; + const char *trigger_name; + uid_t trigger_owner; + enum lttng_trigger_status trigger_status; + struct lttng_error_query_results *results = NULL; + + switch (lttng_error_query_get_target_type(query)) { + case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER: + query_target_trigger = lttng_error_query_trigger_borrow_target(query); + break; + case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION: + query_target_trigger = + lttng_error_query_condition_borrow_target(query); + break; + case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION: + query_target_trigger = lttng_error_query_action_borrow_trigger_target( + query); + break; + default: + abort(); + } + + assert(query_target_trigger); + + ret_code = notification_thread_command_get_trigger(notification_thread, + query_target_trigger, &matching_trigger); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* No longer needed. */ + query_target_trigger = NULL; + + if (lttng_error_query_get_target_type(query) == + LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION) { + /* Get the sessiond-side version of the target action. */ + query_target_action = + lttng_error_query_action_borrow_action_target( + query, matching_trigger); + } + + trigger_status = lttng_trigger_get_name(matching_trigger, &trigger_name); + trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? + trigger_name : "(anonymous)"; + trigger_status = lttng_trigger_get_owner_uid(matching_trigger, + &trigger_owner); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + results = lttng_error_query_results_create(); + if (!results) { + ret_code = LTTNG_ERR_NOMEM; + goto end; + } + + DBG("Running \"execute error query\" command: trigger name = '%s', trigger owner uid = %d, command creds uid = %d", + trigger_name, (int) trigger_owner, + (int) lttng_credentials_get_uid(cmd_creds)); + + /* + * Validate the trigger credentials against the command credentials. + * Only the root user can target a trigger with non-matching + * credentials. + */ + if (!lttng_credentials_is_equal_uid( + lttng_trigger_get_credentials(matching_trigger), + cmd_creds)) { + if (lttng_credentials_get_uid(cmd_creds) != 0) { + ERR("Trigger credentials do not match the command credentials: trigger name = '%s', trigger owner uid = %d, command creds uid = %d", + trigger_name, (int) trigger_owner, + (int) lttng_credentials_get_uid(cmd_creds)); + ret_code = LTTNG_ERR_INVALID_TRIGGER; + goto end; + } + } + + switch (lttng_error_query_get_target_type(query)) { + case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER: + trigger_status = lttng_trigger_add_error_results( + matching_trigger, results); + + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + default: + ret_code = LTTNG_ERR_UNK; + goto end; + } + + break; + case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION: + { + trigger_status = lttng_trigger_condition_add_error_results( + matching_trigger, results); + + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + default: + ret_code = LTTNG_ERR_UNK; + goto end; + } + + break; + } + case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION: + { + const enum lttng_action_status action_status = + lttng_action_add_error_query_results( + query_target_action, results); + + switch (action_status) { + case LTTNG_ACTION_STATUS_OK: + break; + default: + ret_code = LTTNG_ERR_UNK; + goto end; + } + + break; + } + default: + abort(); + break; + } + + *_results = results; + results = NULL; + ret_code = LTTNG_OK; +end: + lttng_trigger_put(matching_trigger); + lttng_error_query_results_destroy(results); + return ret_code; +} + /* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination. @@ -4853,6 +5053,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, consumer_copy_output(snapshot_output->consumer); strcpy(snapshot_kernel_consumer_output->chunk_path, snapshot_chunk_name); + + /* Copy the original domain subdir. */ + strcpy(snapshot_kernel_consumer_output->domain_subdir, + original_kernel_consumer_output->domain_subdir); + ret = consumer_copy_sockets(snapshot_kernel_consumer_output, original_kernel_consumer_output); if (ret < 0) { @@ -4875,6 +5080,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, consumer_copy_output(snapshot_output->consumer); strcpy(snapshot_ust_consumer_output->chunk_path, snapshot_chunk_name); + + /* Copy the original domain subdir. */ + strcpy(snapshot_ust_consumer_output->domain_subdir, + original_ust_consumer_output->domain_subdir); + ret = consumer_copy_sockets(snapshot_ust_consumer_output, original_ust_consumer_output); if (ret < 0) { @@ -5124,7 +5334,7 @@ int cmd_set_session_shm_path(struct ltt_session *session, sizeof(session->shm_path)); session->shm_path[sizeof(session->shm_path) - 1] = '\0'; - return 0; + return LTTNG_OK; } /* @@ -5297,8 +5507,8 @@ int cmd_rotate_session(struct ltt_session *session, chunk_being_archived = NULL; if (!quiet_rotation) { ret = notification_thread_command_session_rotation_ongoing( - notification_thread_handle, - session->name, session->uid, session->gid, + the_notification_thread_handle, session->name, + session->uid, session->gid, ongoing_rotation_chunk_id); if (ret != LTTNG_OK) { ERR("Failed to notify notification thread that a session rotation is ongoing for session %s", @@ -5477,7 +5687,7 @@ end: * 'activate' to false means deactivate the rotation schedule and validate that * 'new_value' has the same value as the currently active value. * - * Return 0 on success or else a positive LTTNG_ERR code. + * Return LTTNG_OK on success or else a positive LTTNG_ERR code. */ int cmd_rotation_set_schedule(struct ltt_session *session, bool activate, enum lttng_rotation_schedule_type schedule_type,