X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Flttng-ctl.c;h=7a38699d9c8438cbedd423a12fd2204884dc266f;hb=a5c2d2a71919b8d1542b62f6d32579125cc2c8f8;hp=38df4cb7b11c1234c5b33f8b92d1731ea541585f;hpb=e1b624d005769d1a2e9eb39fee63c73c6395fd76;p=lttng-tools.git diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 38df4cb7b..7a38699d9 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -18,14 +18,15 @@ #include #include +#include #include #include #include #include -#include #include -#include +#include #include +#include #include #include #include @@ -34,20 +35,20 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include -#include +#include "lttng-ctl-helper.h" #include #include -#include #include -#include "lttng-ctl-helper.h" #define COPY_DOMAIN_PACKED(dst, src) \ do { \ @@ -116,7 +117,8 @@ static int send_session_msg(struct lttcomm_session_msg *lsm) goto end; } - DBG("LSM cmd type : %d", lsm->cmd_type); + DBG("LSM cmd type: '%s' (%d)", lttcomm_sessiond_command_str(lsm->cmd_type), + lsm->cmd_type); ret = lttcomm_send_creds_unix_sock(sessiond_socket, lsm, sizeof(struct lttcomm_session_msg)); @@ -652,7 +654,12 @@ int lttng_ctl_ask_sessiond_payload(struct lttng_payload_view *message, /* Check error code if OK */ if (llm.ret_code != LTTNG_OK) { - ret = -llm.ret_code; + if (llm.ret_code < LTTNG_OK || llm.ret_code >= LTTNG_ERR_NR) { + /* Invalid error code received. */ + ret = -LTTNG_ERR_UNK; + } else { + ret = -llm.ret_code; + } goto end; } @@ -1264,15 +1271,15 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle, assert(fd_count == 0 || fd_count == 1); if (fd_count == 1) { - struct fd_handle *handle = + struct fd_handle *h = lttng_payload_view_pop_fd_handle(&view); - if (!handle) { + if (!h) { goto mem_error; } - fd_to_send = fd_handle_get_fd(handle); - fd_handle_put(handle); + fd_to_send = fd_handle_get_fd(h); + fd_handle_put(h); } ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm, @@ -2064,7 +2071,7 @@ int lttng_destroy_session_no_wait(const char *session_name) enum lttng_error_code ret_code; ret_code = lttng_destroy_session_ext(session_name, NULL); - return ret_code == LTTNG_OK ? ret_code : -ret_code; + return ret_code == LTTNG_OK ? 0 : -ret_code; } /* @@ -3075,11 +3082,14 @@ end: return ret; } -int lttng_register_trigger(struct lttng_trigger *trigger) +static +int _lttng_register_trigger(struct lttng_trigger *trigger, const char *name, + bool generate_name) { int ret; struct lttcomm_session_msg lsm = { .cmd_type = LTTNG_REGISTER_TRIGGER, + .u.trigger.is_trigger_anonymous = !name && !generate_name, }; struct lttcomm_session_msg *message_lsm; struct lttng_payload message; @@ -3090,7 +3100,8 @@ int lttng_register_trigger(struct lttng_trigger *trigger) .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()), .gid = LTTNG_OPTIONAL_INIT_UNSET, }; - + const char *unused_trigger_name = NULL; + enum lttng_trigger_status trigger_status; lttng_payload_init(&message); lttng_payload_init(&reply); @@ -3100,6 +3111,21 @@ int lttng_register_trigger(struct lttng_trigger *trigger) goto end; } + trigger_status = lttng_trigger_get_name(trigger, &unused_trigger_name); + if (trigger_status != LTTNG_TRIGGER_STATUS_UNSET) { + /* Re-using already registered trigger. */ + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (name) { + trigger_status = lttng_trigger_set_name(trigger, name); + if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } + } + if (!trigger->creds.uid.is_set) { /* Use the client's credentials as the trigger credentials. */ lttng_trigger_set_credentials(trigger, &user_creds); @@ -3120,14 +3146,14 @@ int lttng_register_trigger(struct lttng_trigger *trigger) if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) { if (lttng_credentials_get_uid(&user_creds) != 0) { ret = -LTTNG_ERR_EPERM; - goto end; + goto end_unset_name; } } } if (!lttng_trigger_validate(trigger)) { ret = -LTTNG_ERR_INVALID_TRIGGER; - goto end; + goto end_unset_name; } domain_type = lttng_trigger_get_underlying_domain_type_restriction( @@ -3138,21 +3164,21 @@ int lttng_register_trigger(struct lttng_trigger *trigger) ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); if (ret) { ret = -LTTNG_ERR_NOMEM; - goto end; + goto end_unset_name; } - /* - * This is needed to populate the trigger object size for the command - * header. - */ - message_lsm = (struct lttcomm_session_msg *) message.buffer.data; - ret = lttng_trigger_serialize(trigger, &message); if (ret < 0) { ret = -LTTNG_ERR_UNK; - goto end; + goto end_unset_name; } + /* + * This is needed to populate the trigger object size for the command + * header. + */ + message_lsm = (struct lttcomm_session_msg *) message.buffer.data; + message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm); { @@ -3164,7 +3190,7 @@ int lttng_register_trigger(struct lttng_trigger *trigger) &message_view); ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply); if (ret < 0) { - goto end; + goto end_unset_name; } } @@ -3176,18 +3202,27 @@ int lttng_register_trigger(struct lttng_trigger *trigger) ret = lttng_trigger_create_from_payload( &reply_view, &reply_trigger); if (ret < 0) { - ret = -LTTNG_ERR_FATAL; - goto end; + ret = -LTTNG_ERR_INVALID_PROTOCOL; + goto end_unset_name; } } - ret = lttng_trigger_assign_name(trigger, reply_trigger); - if (ret < 0) { - ret = -LTTNG_ERR_FATAL; - goto end; + if (name || generate_name) { + ret = lttng_trigger_assign_name(trigger, reply_trigger); + if (ret < 0) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } } ret = 0; + goto end; + +end_unset_name: + trigger_status = lttng_trigger_set_name(trigger, NULL); + if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { + ret = -LTTNG_ERR_UNK; + } end: lttng_payload_reset(&message); lttng_payload_reset(&reply); @@ -3195,13 +3230,114 @@ end: return ret; } -int lttng_unregister_trigger(struct lttng_trigger *trigger) +int lttng_register_trigger(struct lttng_trigger *trigger) +{ + /* Register an anonymous trigger. */ + return _lttng_register_trigger(trigger, NULL, false); +} + +enum lttng_error_code lttng_register_trigger_with_name( + struct lttng_trigger *trigger, const char *name) +{ + const int ret = _lttng_register_trigger(trigger, name, false); + + return ret == 0 ? LTTNG_OK : (enum lttng_error_code) -ret; +} + +enum lttng_error_code lttng_register_trigger_with_automatic_name( + struct lttng_trigger *trigger) +{ + const int ret = _lttng_register_trigger(trigger, false, true); + + return ret == 0 ? LTTNG_OK : (enum lttng_error_code) -ret; +} + +enum lttng_error_code lttng_error_query_execute( + const struct lttng_error_query *query, + const struct lttng_endpoint *endpoint, + struct lttng_error_query_results **results) +{ + int ret; + enum lttng_error_code ret_code; + struct lttcomm_session_msg lsm = { + .cmd_type = LTTNG_EXECUTE_ERROR_QUERY, + }; + struct lttng_payload message; + struct lttng_payload reply; + struct lttcomm_session_msg *message_lsm; + + lttng_payload_init(&message); + lttng_payload_init(&reply); + + if (!query || !results) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + + if (endpoint != lttng_session_daemon_command_endpoint) { + ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET; + goto end; + } + + ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); + if (ret) { + ret_code = LTTNG_ERR_NOMEM; + goto end; + } + + ret = lttng_error_query_serialize(query, &message); + if (ret) { + ret_code = LTTNG_ERR_UNK; + goto end; + } + + message_lsm = (struct lttcomm_session_msg *) message.buffer.data; + message_lsm->u.error_query.length = + (uint32_t) message.buffer.size - sizeof(lsm); + + { + struct lttng_payload_view message_view = + lttng_payload_view_from_payload( + &message, 0, -1); + + message_lsm->fd_count = lttng_payload_view_get_fd_handle_count( + &message_view); + ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply); + if (ret < 0) { + ret_code = -ret; + goto end; + } + } + + { + ssize_t reply_create_ret; + struct lttng_payload_view reply_view = + lttng_payload_view_from_payload( + &reply, 0, reply.buffer.size); + + reply_create_ret = lttng_error_query_results_create_from_payload( + &reply_view, results); + if (reply_create_ret < 0) { + ret_code = LTTNG_ERR_INVALID_PROTOCOL; + goto end; + } + } + + ret_code = LTTNG_OK; +end: + lttng_payload_reset(&message); + lttng_payload_reset(&reply); + return ret_code; +} + +int lttng_unregister_trigger(const struct lttng_trigger *trigger) { int ret; struct lttcomm_session_msg lsm; struct lttcomm_session_msg *message_lsm; struct lttng_payload message; struct lttng_payload reply; + struct lttng_trigger *copy = NULL; const struct lttng_credentials user_creds = { .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()), .gid = LTTNG_OPTIONAL_INIT_UNSET, @@ -3215,9 +3351,15 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) goto end; } - if (!trigger->creds.uid.is_set) { - /* Use the client's credentials as the trigger credentials. */ - lttng_trigger_set_credentials(trigger, &user_creds); + copy = lttng_trigger_copy(trigger); + if (!copy) { + ret = -LTTNG_ERR_UNK; + goto end; + } + + if (!copy->creds.uid.is_set) { + /* Use the client credentials as the trigger credentials */ + lttng_trigger_set_credentials(copy, &user_creds); } else { /* * Validate that either the current trigger credentials and the @@ -3230,8 +3372,7 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) * "safety" checks. */ const struct lttng_credentials *trigger_creds = - lttng_trigger_get_credentials(trigger); - + lttng_trigger_get_credentials(copy); if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) { if (lttng_credentials_get_uid(&user_creds) != 0) { ret = -LTTNG_ERR_EPERM; @@ -3240,7 +3381,7 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) } } - if (!lttng_trigger_validate(trigger)) { + if (!lttng_trigger_validate(copy)) { ret = -LTTNG_ERR_INVALID_TRIGGER; goto end; } @@ -3254,18 +3395,18 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) goto end; } + ret = lttng_trigger_serialize(copy, &message); + if (ret < 0) { + ret = -LTTNG_ERR_UNK; + goto end; + } + /* * This is needed to populate the trigger object size for the command * header and number of fds sent. */ message_lsm = (struct lttcomm_session_msg *) message.buffer.data; - ret = lttng_trigger_serialize(trigger, &message); - if (ret < 0) { - ret = -LTTNG_ERR_UNK; - goto end; - } - message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm); { @@ -3288,6 +3429,7 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) ret = 0; end: + lttng_trigger_destroy(copy); lttng_payload_reset(&message); lttng_payload_reset(&reply); return ret;