X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Factions%2Fsnapshot-session.c;h=6c765edeac12cf90b71202aab1d91439d7a1797d;hb=6a751b953a43c566b74818ec6325db0978e16c66;hp=9e8e43577492b3f4d5bd0f3610fb529d7c37299a;hpb=757c48a28258e64fe251b6803ccdba7898590d70;p=lttng-tools.git diff --git a/src/common/actions/snapshot-session.c b/src/common/actions/snapshot-session.c index 9e8e43577..6c765edea 100644 --- a/src/common/actions/snapshot-session.c +++ b/src/common/actions/snapshot-session.c @@ -8,18 +8,21 @@ #include #include #include +#include +#include +#include #include -#include -#include +#include #include +#include +#include #include #include -#include #include -#include +#include #define IS_SNAPSHOT_SESSION_ACTION(action) \ - (lttng_action_get_type_const(action) == LTTNG_ACTION_TYPE_SNAPSHOT_SESSION) + (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_SNAPSHOT_SESSION) struct lttng_action_snapshot_session { struct lttng_action parent; @@ -34,23 +37,29 @@ struct lttng_action_snapshot_session { * Owned by this. */ struct lttng_snapshot_output *output; + struct lttng_rate_policy *policy; }; struct lttng_action_snapshot_session_comm { /* All string lengths include the trailing \0. */ uint32_t session_name_len; uint32_t snapshot_output_len; + uint32_t rate_policy_len; /* * Variable data (all strings are null-terminated): * * - session name string * - snapshot output object - * + * - policy object */ char data[]; } LTTNG_PACKED; +static const struct lttng_rate_policy * +lttng_action_snapshot_session_internal_get_rate_policy( + const struct lttng_action *action); + static struct lttng_action_snapshot_session * action_snapshot_session_from_action(struct lttng_action *action) { @@ -119,21 +128,14 @@ static bool lttng_action_snapshot_session_is_equal( goto end; } - is_equal = true; + is_equal = lttng_rate_policy_is_equal(a->policy, b->policy); end: return is_equal; } -static size_t serialize_strlen(const char *s) +static size_t serialize_strlen(const char *str) { - - size_t len = 0; - - if (s) { - len = strlen(s) + 1; - } - - return len; + return str ? strlen(str) + 1 : 0; } static int lttng_action_snapshot_session_serialize( @@ -148,7 +150,6 @@ static int lttng_action_snapshot_session_serialize( assert(payload); size_before_comm = payload->buffer.size; - size_before_comm = size_before_comm + sizeof(comm); action_snapshot_session = action_snapshot_session_from_action(action); comm.session_name_len = @@ -185,13 +186,32 @@ static int lttng_action_snapshot_session_serialize( goto end; } - /* Adjust action length in header. */ comm_in_payload = (typeof(comm_in_payload))( payload->buffer.data + size_before_comm); + /* Adjust action length in header. */ comm_in_payload->snapshot_output_len = payload->buffer.size - size_before_output; } + /* Serialize the rate policy. */ + { + const size_t size_before_output = payload->buffer.size; + struct lttng_action_snapshot_session_comm *comm_in_payload; + + ret = lttng_rate_policy_serialize( + action_snapshot_session->policy, payload); + if (ret) { + ret = -1; + goto end; + } + + comm_in_payload = (typeof(comm_in_payload))( + payload->buffer.data + size_before_comm); + /* Adjust rate policy length in header. */ + comm_in_payload->rate_policy_len = + payload->buffer.size - size_before_output; + } + end: return ret; } @@ -208,6 +228,7 @@ static void lttng_action_snapshot_session_destroy(struct lttng_action *action) free(action_snapshot_session->session_name); lttng_snapshot_output_destroy(action_snapshot_session->output); + lttng_rate_policy_destroy(action_snapshot_session->policy); free(action_snapshot_session); end: @@ -219,18 +240,27 @@ ssize_t lttng_action_snapshot_session_create_from_payload( struct lttng_action **p_action) { ssize_t consumed_len; - const struct lttng_action_snapshot_session_comm *comm; const char *variable_data; struct lttng_action *action; enum lttng_action_status status; struct lttng_snapshot_output *snapshot_output = NULL; + struct lttng_rate_policy *policy = NULL; + const struct lttng_action_snapshot_session_comm *comm; + const struct lttng_payload_view snapshot_session_comm_view = + lttng_payload_view_from_view( + view, 0, sizeof(*comm)); action = lttng_action_snapshot_session_create(); if (!action) { goto error; } - comm = (typeof(comm)) view->buffer.data; + if (!lttng_payload_view_is_valid(&snapshot_session_comm_view)) { + /* Payload not large enough to contain the header. */ + goto error; + } + + comm = (typeof(comm)) snapshot_session_comm_view.buffer.data; variable_data = (const char *) &comm->data; consumed_len = sizeof(struct lttng_action_snapshot_session_comm); @@ -257,8 +287,8 @@ ssize_t lttng_action_snapshot_session_create_from_payload( lttng_payload_view_from_view(view, consumed_len, comm->snapshot_output_len); - if (!snapshot_output_buffer_view.buffer.data) { - fprintf(stderr, "Failed to create buffer view for snapshot output.\n"); + if (!lttng_payload_view_is_valid(&snapshot_output_buffer_view)) { + ERR("Failed to create buffer view for snapshot output."); goto error; } @@ -267,8 +297,7 @@ ssize_t lttng_action_snapshot_session_create_from_payload( &snapshot_output_buffer_view, &snapshot_output); if (snapshot_output_consumed_len != comm->snapshot_output_len) { - fprintf(stderr, - "Failed to deserialize snapshot output object: " + ERR("Failed to deserialize snapshot output object: " "consumed-len: %zd, expected-len: %" PRIu32, snapshot_output_consumed_len, comm->snapshot_output_len); @@ -287,6 +316,48 @@ ssize_t lttng_action_snapshot_session_create_from_payload( variable_data += comm->snapshot_output_len; consumed_len += comm->snapshot_output_len; + + /* Rate policy. */ + if (comm->rate_policy_len <= 0) { + ERR("Rate policy should be present."); + goto error; + } + { + ssize_t rate_policy_consumed_len; + struct lttng_payload_view policy_view = + lttng_payload_view_from_view(view, consumed_len, + comm->rate_policy_len); + + if (!lttng_payload_view_is_valid(&policy_view)) { + ERR("Failed to create buffer view for rate policy."); + goto error; + } + + rate_policy_consumed_len = + lttng_rate_policy_create_from_payload( + &policy_view, &policy); + if (rate_policy_consumed_len < 0) { + goto error; + } + + if (rate_policy_consumed_len != comm->rate_policy_len) { + ERR("Failed to deserialize rate policy object: " + "consumed-len: %zd, expected-len: %" PRIu32, + rate_policy_consumed_len, + comm->rate_policy_len); + goto error; + } + + status = lttng_action_snapshot_session_set_rate_policy( + action, policy); + if (status != LTTNG_ACTION_STATUS_OK) { + goto error; + } + } + + variable_data += comm->rate_policy_len; + consumed_len += comm->rate_policy_len; + *p_action = action; action = NULL; @@ -296,15 +367,94 @@ error: consumed_len = -1; end: + lttng_rate_policy_destroy(policy); lttng_action_snapshot_session_destroy(action); lttng_snapshot_output_destroy(snapshot_output); return consumed_len; } +static enum lttng_error_code lttng_action_snapshot_session_mi_serialize( + const struct lttng_action *action, struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + enum lttng_action_status status; + const char *session_name = NULL; + const struct lttng_snapshot_output *output = NULL; + const struct lttng_rate_policy *policy = NULL; + + assert(action); + assert(IS_SNAPSHOT_SESSION_ACTION(action)); + + status = lttng_action_snapshot_session_get_session_name( + action, &session_name); + assert(status == LTTNG_ACTION_STATUS_OK); + assert(session_name != NULL); + + status = lttng_action_snapshot_session_get_rate_policy(action, &policy); + assert(status == LTTNG_ACTION_STATUS_OK); + assert(policy != NULL); + + /* Open action snapshot session element. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_action_snapshot_session); + if (ret) { + goto mi_error; + } + + /* Session name. */ + ret = mi_lttng_writer_write_element_string( + writer, mi_lttng_element_session_name, session_name); + if (ret) { + goto mi_error; + } + + /* Output if any. */ + status = lttng_action_snapshot_session_get_output(action, &output); + if (status == LTTNG_ACTION_STATUS_OK) { + assert(output != NULL); + ret_code = lttng_snapshot_output_mi_serialize(output, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + } else if (status != LTTNG_ACTION_STATUS_UNSET) { + /* This should not happen at this point. */ + abort(); + } + + /* Rate policy. */ + ret_code = lttng_rate_policy_mi_serialize(policy, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close action_snapshot_session 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_snapshot_session_create(void) { - struct lttng_action *action; + struct lttng_action *action = NULL; + struct lttng_rate_policy *policy = NULL; + enum lttng_action_status status; + + /* Create a every N = 1 rate policy. */ + policy = lttng_rate_policy_every_n_create(1); + if (!policy) { + goto end; + } action = zmalloc(sizeof(struct lttng_action_snapshot_session)); if (!action) { @@ -315,9 +465,20 @@ struct lttng_action *lttng_action_snapshot_session_create(void) lttng_action_snapshot_session_validate, lttng_action_snapshot_session_serialize, lttng_action_snapshot_session_is_equal, - lttng_action_snapshot_session_destroy); + lttng_action_snapshot_session_destroy, + lttng_action_snapshot_session_internal_get_rate_policy, + lttng_action_generic_add_error_query_results, + lttng_action_snapshot_session_mi_serialize); + + status = lttng_action_snapshot_session_set_rate_policy(action, policy); + if (status != LTTNG_ACTION_STATUS_OK) { + free(action); + action = NULL; + goto end; + } end: + lttng_rate_policy_destroy(policy); return action; } @@ -420,3 +581,68 @@ enum lttng_action_status lttng_action_snapshot_session_get_output( end: return status; } + +enum lttng_action_status lttng_action_snapshot_session_set_rate_policy( + struct lttng_action *action, + const struct lttng_rate_policy *policy) +{ + enum lttng_action_status status; + struct lttng_action_snapshot_session *snapshot_session_action; + struct lttng_rate_policy *copy = NULL; + + if (!action || !policy || !IS_SNAPSHOT_SESSION_ACTION(action)) { + status = LTTNG_ACTION_STATUS_INVALID; + goto end; + } + + copy = lttng_rate_policy_copy(policy); + if (!copy) { + status = LTTNG_ACTION_STATUS_ERROR; + goto end; + } + + snapshot_session_action = action_snapshot_session_from_action(action); + + /* Free the previous rate policy .*/ + lttng_rate_policy_destroy(snapshot_session_action->policy); + + /* Assign the policy. */ + snapshot_session_action->policy = copy; + status = LTTNG_ACTION_STATUS_OK; + copy = NULL; + +end: + lttng_rate_policy_destroy(copy); + return status; +} + +enum lttng_action_status lttng_action_snapshot_session_get_rate_policy( + const struct lttng_action *action, + const struct lttng_rate_policy **policy) +{ + enum lttng_action_status status; + const struct lttng_action_snapshot_session *snapshot_session_action; + + if (!action || !policy || !IS_SNAPSHOT_SESSION_ACTION(action)) { + status = LTTNG_ACTION_STATUS_INVALID; + goto end; + } + + snapshot_session_action = + action_snapshot_session_from_action_const(action); + + *policy = snapshot_session_action->policy; + status = LTTNG_ACTION_STATUS_OK; +end: + return status; +} + +static const struct lttng_rate_policy * +lttng_action_snapshot_session_internal_get_rate_policy( + const struct lttng_action *action) +{ + const struct lttng_action_snapshot_session *_action; + _action = action_snapshot_session_from_action_const(action); + + return _action->policy; +}