Implement firing policy for the notify action
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Fri, 9 Apr 2021 01:40:12 +0000 (21:40 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 17 Apr 2021 21:55:05 +0000 (17:55 -0400)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I40b25033868fd4ec9cb6764f3c47ef3e006bec3e

include/lttng/action/notify-internal.h
include/lttng/action/notify.h
src/common/actions/notify.c

index 1a6abe561a86818a9de41b0950d12c4cbfb71511..d727e6860119609eda2a370d6b0ccee6c1c88ec6 100644 (file)
@@ -13,6 +13,7 @@
 
 struct lttng_action_notify {
        struct lttng_action parent;
+       struct lttng_firing_policy *policy;
 };
 
 LTTNG_HIDDEN
index 17a3e9da542ebfca4073ff2f1b39009da14cb72d..b41ba0378f625dd8fdf9bcaeb347dd568645510d 100644 (file)
@@ -9,6 +9,7 @@
 #define LTTNG_ACTION_NOTIFY_H
 
 struct lttng_action;
+struct lttng_firing_policy;
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,11 +23,34 @@ extern "C" {
  * must have subscribed to a condition equivalent to the one paired to this
  * notify action in a trigger.
  *
+ * The default firing policy for a notify action is a "every 1" firing policy.
+ *
  * Returns a new action on success, NULL on failure. This action must be
  * destroyed using lttng_action_destroy().
  */
 extern struct lttng_action *lttng_action_notify_create(void);
 
+/*
+ * Set the firing policy of a notify action.
+ *
+ * Returns LTTNG_ACTION_STATUS_OK on success,
+ * LTTNG_ACTION_STATUS_ERROR on internal error,
+ * LTTNG_ACTION_STATUS_INVALID if invalid parameters are passed.
+ */
+extern enum lttng_action_status lttng_action_notify_set_firing_policy(
+               struct lttng_action *action,
+               const struct lttng_firing_policy *policy);
+
+/*
+ * Get the firing policy of a notify action.
+ *
+ * Returns LTTNG_ACTION_STATUS_OK on success,
+ * LTTNG_ACTION_STATUS_INVALID if invalid parameters are passed.
+ */
+extern enum lttng_action_status lttng_action_notify_get_firing_policy(
+               const struct lttng_action *action,
+               const struct lttng_firing_policy **policy);
+
 #ifdef __cplusplus
 }
 #endif
index fc7d170c70e8c3ac949c306eb49b267004356855..85029a5e25908665396dca4770fd135e399c6018 100644 (file)
  *
  */
 
+#include <assert.h>
+#include <common/error.h>
+#include <common/macros.h>
 #include <lttng/action/action-internal.h>
+#include <lttng/action/firing-policy-internal.h>
 #include <lttng/action/notify-internal.h>
-#include <common/macros.h>
-#include <assert.h>
+
+#define IS_NOTIFY_ACTION(action) \
+       (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_NOTIFY)
+
+static struct lttng_action_notify *action_notify_from_action(
+               struct lttng_action *action)
+{
+       assert(action);
+
+       return container_of(action, struct lttng_action_notify, parent);
+}
+
+static const struct lttng_action_notify *action_notify_from_action_const(
+               const struct lttng_action *action)
+{
+       assert(action);
+
+       return container_of(action, struct lttng_action_notify, parent);
+}
 
 static
 void lttng_action_notify_destroy(struct lttng_action *action)
 {
-       free(action);
+       struct lttng_action_notify *notify_action;
+       notify_action = action_notify_from_action(action);
+       lttng_firing_policy_destroy(notify_action->policy);
+       free(notify_action);
 }
 
 static
 int lttng_action_notify_serialize(struct lttng_action *action,
                struct lttng_payload *payload)
 {
-       return 0;
+       int ret;
+       struct lttng_action_notify *notify_action;
+
+       if (!action || !IS_NOTIFY_ACTION(action) || !payload) {
+               ret = -1;
+               goto end;
+       }
+
+       DBG("Serializing notify action");
+
+       notify_action = action_notify_from_action(action);
+       DBG("Serializing notify action firing policy");
+       ret = lttng_firing_policy_serialize(notify_action->policy, payload);
+
+end:
+       return ret;
 }
 
 static
 bool lttng_action_notify_is_equal(const struct lttng_action *a,
                const struct lttng_action *b)
 {
-       /* There is no discriminant between notify actions. */
-       return true;
+       const struct lttng_action_notify *_a, *_b;
+
+       _a = action_notify_from_action_const(a);
+       _b = action_notify_from_action_const(b);
+       return lttng_firing_policy_is_equal(_a->policy, _b->policy);
 }
 
 struct lttng_action *lttng_action_notify_create(void)
 {
-       struct lttng_action_notify *notify;
+       struct lttng_firing_policy *policy = NULL;
+       struct lttng_action_notify *notify = NULL;
+       struct lttng_action *action = NULL;
 
        notify = zmalloc(sizeof(struct lttng_action_notify));
        if (!notify) {
                goto end;
        }
 
+       /* Default policy. */
+       policy = lttng_firing_policy_every_n_create(1);
+       if (!policy) {
+               goto end;
+       }
+
        lttng_action_init(&notify->parent, LTTNG_ACTION_TYPE_NOTIFY, NULL,
                        lttng_action_notify_serialize,
                        lttng_action_notify_is_equal,
                        lttng_action_notify_destroy);
+
+       notify->policy = policy;
+       policy = NULL;
+
+       action = &notify->parent;
+       notify = NULL;
+
 end:
-       return &notify->parent;
+       free(notify);
+       lttng_firing_policy_destroy(policy);
+       return action;
 }
 
 ssize_t lttng_action_notify_create_from_payload(
                struct lttng_payload_view *view,
                struct lttng_action **action)
 {
+       enum lttng_action_status status;
        ssize_t consumed_length;
+       struct lttng_firing_policy *firing_policy = NULL;
+       struct lttng_action *_action = NULL;
 
-       *action = lttng_action_notify_create();
-       if (!*action) {
+       consumed_length = lttng_firing_policy_create_from_payload(
+                       view, &firing_policy);
+       if (!firing_policy) {
                consumed_length = -1;
                goto end;
        }
 
-       consumed_length = 0;
+       _action = lttng_action_notify_create();
+       if (!_action) {
+               consumed_length = -1;
+               goto end;
+       }
+
+       status = lttng_action_notify_set_firing_policy(_action, firing_policy);
+       if (status != LTTNG_ACTION_STATUS_OK) {
+               consumed_length = -1;
+               goto end;
+       }
+
+       *action = _action;
+       _action = NULL;
+
 end:
+       lttng_firing_policy_destroy(firing_policy);
+       lttng_action_destroy(_action);
        return consumed_length;
 }
+
+enum lttng_action_status lttng_action_notify_set_firing_policy(
+               struct lttng_action *action,
+               const struct lttng_firing_policy *policy)
+{
+       enum lttng_action_status status;
+       struct lttng_action_notify *notify_action;
+       struct lttng_firing_policy *copy = NULL;
+
+       if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
+               status = LTTNG_ACTION_STATUS_INVALID;
+               goto end;
+       }
+
+       copy = lttng_firing_policy_copy(policy);
+       if (!copy) {
+               status = LTTNG_ACTION_STATUS_ERROR;
+               goto end;
+       }
+
+       notify_action = action_notify_from_action(action);
+
+       /* Free the previous firing policy .*/
+       lttng_firing_policy_destroy(notify_action->policy);
+
+       /* Assign the policy. */
+       notify_action->policy = copy;
+       status = LTTNG_ACTION_STATUS_OK;
+       copy = NULL;
+
+end:
+       lttng_firing_policy_destroy(copy);
+       return status;
+}
+
+enum lttng_action_status lttng_action_notify_get_firing_policy(
+               const struct lttng_action *action,
+               const struct lttng_firing_policy **policy)
+{
+       enum lttng_action_status status;
+       const struct lttng_action_notify *notify_action;
+
+       if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
+               status = LTTNG_ACTION_STATUS_INVALID;
+               goto end;
+       }
+
+       notify_action = action_notify_from_action_const(action);
+
+       *policy = notify_action->policy;
+       status = LTTNG_ACTION_STATUS_OK;
+end:
+       return status;
+}
This page took 0.038848 seconds and 4 git commands to generate.