MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / actions / snapshot-session.c
index 8b23d58e70aafb81e09893e37c02dc8b6a3199c6..6c765edeac12cf90b71202aab1d91439d7a1797d 100644 (file)
@@ -8,15 +8,18 @@
 #include <assert.h>
 #include <common/error.h>
 #include <common/macros.h>
-#include <common/snapshot.h>
-#include <common/payload.h>
+#include <common/mi-lttng.h>
 #include <common/payload-view.h>
+#include <common/payload.h>
+#include <common/snapshot.h>
+#include <inttypes.h>
 #include <lttng/action/action-internal.h>
+#include <lttng/action/rate-policy-internal.h>
+#include <lttng/action/rate-policy.h>
 #include <lttng/action/snapshot-session-internal.h>
 #include <lttng/action/snapshot-session.h>
-#include <lttng/snapshot.h>
 #include <lttng/snapshot-internal.h>
-#include <inttypes.h>
+#include <lttng/snapshot.h>
 
 #define IS_SNAPSHOT_SESSION_ACTION(action) \
        (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_SNAPSHOT_SESSION)
@@ -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,7 +128,7 @@ 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;
 }
@@ -177,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;
 }
@@ -200,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:
@@ -215,6 +244,7 @@ ssize_t lttng_action_snapshot_session_create_from_payload(
        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(
@@ -286,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;
 
@@ -295,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) {
@@ -314,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;
 }
 
@@ -419,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;
+}
This page took 0.028336 seconds and 4 git commands to generate.