action-executor: consider action firing policy on action execution
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Wed, 7 Apr 2021 13:19:18 +0000 (09:19 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 18 Apr 2021 23:28:57 +0000 (19:28 -0400)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I83f73e905e87a401187e243ed3beafa41964434a

12 files changed:
include/lttng/action/action-internal.h
include/lttng/action/firing-policy-internal.h
include/lttng/action/group-internal.h
src/bin/lttng-sessiond/action-executor.c
src/common/actions/action.c
src/common/actions/firing-policy.c
src/common/actions/group.c
src/common/actions/notify.c
src/common/actions/rotate-session.c
src/common/actions/snapshot-session.c
src/common/actions/start-session.c
src/common/actions/stop-session.c

index 9e43a34d026491726e064acc6bede25bf3e92b88..1422a6dceed667050da6870928a6d02ecd0d2db2 100644 (file)
@@ -18,6 +18,8 @@
 #include <sys/types.h>
 #include <urcu/ref.h>
 
 #include <sys/types.h>
 #include <urcu/ref.h>
 
+struct lttng_firing_policy;
+
 typedef bool (*action_validate_cb)(struct lttng_action *action);
 typedef void (*action_destroy_cb)(struct lttng_action *action);
 typedef int (*action_serialize_cb)(struct lttng_action *action,
 typedef bool (*action_validate_cb)(struct lttng_action *action);
 typedef void (*action_destroy_cb)(struct lttng_action *action);
 typedef int (*action_serialize_cb)(struct lttng_action *action,
@@ -27,6 +29,8 @@ typedef bool (*action_equal_cb)(const struct lttng_action *a,
 typedef ssize_t (*action_create_from_payload_cb)(
                struct lttng_payload_view *view,
                struct lttng_action **action);
 typedef ssize_t (*action_create_from_payload_cb)(
                struct lttng_payload_view *view,
                struct lttng_action **action);
+typedef const struct lttng_firing_policy *(*action_get_firing_policy_cb)(
+               const struct lttng_action *action);
 
 struct lttng_action {
        struct urcu_ref ref;
 
 struct lttng_action {
        struct urcu_ref ref;
@@ -35,6 +39,21 @@ struct lttng_action {
        action_serialize_cb serialize;
        action_equal_cb equal;
        action_destroy_cb destroy;
        action_serialize_cb serialize;
        action_equal_cb equal;
        action_destroy_cb destroy;
+       action_get_firing_policy_cb get_firing_policy;
+
+       /* Internal use only. */
+
+       /* The number of time the actions was enqueued for execution. */
+       uint64_t execution_request_counter;
+       /*
+        * The number of time the action was actually executed.
+        * Action firing policy can impact on this number.
+        * */
+       uint64_t execution_counter;
+       /*
+        * The number of time the action execution failed.
+        */
+       uint64_t execution_failure_counter;
 };
 
 struct lttng_action_comm {
 };
 
 struct lttng_action_comm {
@@ -48,7 +67,8 @@ void lttng_action_init(struct lttng_action *action,
                action_validate_cb validate,
                action_serialize_cb serialize,
                action_equal_cb equal,
                action_validate_cb validate,
                action_serialize_cb serialize,
                action_equal_cb equal,
-               action_destroy_cb destroy);
+               action_destroy_cb destroy,
+               action_get_firing_policy_cb get_firing_policy);
 
 LTTNG_HIDDEN
 bool lttng_action_validate(struct lttng_action *action);
 
 LTTNG_HIDDEN
 bool lttng_action_validate(struct lttng_action *action);
@@ -74,4 +94,16 @@ void lttng_action_put(struct lttng_action *action);
 LTTNG_HIDDEN
 const char* lttng_action_type_string(enum lttng_action_type action_type);
 
 LTTNG_HIDDEN
 const char* lttng_action_type_string(enum lttng_action_type action_type);
 
+LTTNG_HIDDEN
+void lttng_action_increase_execution_request_count(struct lttng_action *action);
+
+LTTNG_HIDDEN
+void lttng_action_increase_execution_count(struct lttng_action *action);
+
+LTTNG_HIDDEN
+void lttng_action_increase_execution_failure_count(struct lttng_action *action);
+
+LTTNG_HIDDEN
+bool lttng_action_should_execute(const struct lttng_action *action);
+
 #endif /* LTTNG_ACTION_INTERNAL_H */
 #endif /* LTTNG_ACTION_INTERNAL_H */
index 0fd62ee990ae6cec84aedad5baae09d1e92751c0..a6e607676cad77407fa7637f948a084aa63dc9c7 100644 (file)
@@ -33,4 +33,8 @@ LTTNG_HIDDEN
 struct lttng_firing_policy *lttng_firing_policy_copy(
                const struct lttng_firing_policy *source);
 
 struct lttng_firing_policy *lttng_firing_policy_copy(
                const struct lttng_firing_policy *source);
 
+LTTNG_HIDDEN
+bool lttng_firing_policy_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter);
+
 #endif /* LTTNG_FIRING_POLICY */
 #endif /* LTTNG_FIRING_POLICY */
index cddee55ed99cff01acb81e7e746bc556bd7d424d..0cb89d54bb80a76a66acd6e3fc74737017cd6b0c 100644 (file)
@@ -26,4 +26,8 @@ extern ssize_t lttng_action_group_create_from_payload(
                struct lttng_payload_view *view,
                struct lttng_action **group);
 
                struct lttng_payload_view *view,
                struct lttng_action **group);
 
+LTTNG_HIDDEN
+extern struct lttng_action *lttng_action_group_borrow_mutable_at_index(
+               const struct lttng_action *group, unsigned int index);
+
 #endif /* LTTNG_ACTION_GROUP_INTERNAL_H */
 #endif /* LTTNG_ACTION_GROUP_INTERNAL_H */
index bce7268e5bac05ccf695f5415d06447f2df1ee41..6c828c8f05221536e6a887337591a34e30dfe7ae 100644 (file)
@@ -15,6 +15,7 @@
 #include <common/macros.h>
 #include <common/optional.h>
 #include <lttng/action/action-internal.h>
 #include <common/macros.h>
 #include <common/optional.h>
 #include <lttng/action/action-internal.h>
+#include <lttng/action/group-internal.h>
 #include <lttng/action/group.h>
 #include <lttng/action/notify-internal.h>
 #include <lttng/action/notify.h>
 #include <lttng/action/group.h>
 #include <lttng/action/notify-internal.h>
 #include <lttng/action/notify.h>
@@ -62,29 +63,33 @@ struct action_executor {
  */
 typedef int (*action_executor_handler)(struct action_executor *executor,
                const struct action_work_item *,
  */
 typedef int (*action_executor_handler)(struct action_executor *executor,
                const struct action_work_item *,
-               const struct lttng_action *action);
+               struct lttng_action *action);
 
 static int action_executor_notify_handler(struct action_executor *executor,
                const struct action_work_item *,
 
 static int action_executor_notify_handler(struct action_executor *executor,
                const struct action_work_item *,
-               const struct lttng_action *);
-static int action_executor_start_session_handler(struct action_executor *executor,
+               struct lttng_action *);
+static int action_executor_start_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *,
                const struct action_work_item *,
-               const struct lttng_action *);
-static int action_executor_stop_session_handler(struct action_executor *executor,
+               struct lttng_action *);
+static int action_executor_stop_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *,
                const struct action_work_item *,
-               const struct lttng_action *);
-static int action_executor_rotate_session_handler(struct action_executor *executor,
+               struct lttng_action *);
+static int action_executor_rotate_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *,
                const struct action_work_item *,
-               const struct lttng_action *);
-static int action_executor_snapshot_session_handler(struct action_executor *executor,
+               struct lttng_action *);
+static int action_executor_snapshot_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *,
                const struct action_work_item *,
-               const struct lttng_action *);
+               struct lttng_action *);
 static int action_executor_group_handler(struct action_executor *executor,
                const struct action_work_item *,
 static int action_executor_group_handler(struct action_executor *executor,
                const struct action_work_item *,
-               const struct lttng_action *);
+               struct lttng_action *);
 static int action_executor_generic_handler(struct action_executor *executor,
                const struct action_work_item *,
 static int action_executor_generic_handler(struct action_executor *executor,
                const struct action_work_item *,
-               const struct lttng_action *);
+               struct lttng_action *);
 
 static const action_executor_handler action_executors[] = {
        [LTTNG_ACTION_TYPE_NOTIFY] = action_executor_notify_handler,
 
 static const action_executor_handler action_executors[] = {
        [LTTNG_ACTION_TYPE_NOTIFY] = action_executor_notify_handler,
@@ -185,7 +190,7 @@ end:
 
 static int action_executor_notify_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
 
 static int action_executor_notify_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
        return notification_client_list_send_evaluation(work_item->client_list,
                        work_item->trigger,
 {
        return notification_client_list_send_evaluation(work_item->client_list,
                        work_item->trigger,
@@ -196,9 +201,10 @@ static int action_executor_notify_handler(struct action_executor *executor,
                        client_handle_transmission_status, executor);
 }
 
                        client_handle_transmission_status, executor);
 }
 
-static int action_executor_start_session_handler(struct action_executor *executor,
+static int action_executor_start_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *work_item,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
        int ret = 0;
        const char *session_name;
 {
        int ret = 0;
        const char *session_name;
@@ -243,6 +249,7 @@ static int action_executor_start_session_handler(struct action_executor *executo
                WARN("Failed to start session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
                WARN("Failed to start session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
+               lttng_action_increase_execution_failure_count(action);
                break;
        }
 
                break;
        }
 
@@ -255,9 +262,10 @@ end:
        return ret;
 }
 
        return ret;
 }
 
-static int action_executor_stop_session_handler(struct action_executor *executor,
+static int action_executor_stop_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *work_item,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
        int ret = 0;
        const char *session_name;
 {
        int ret = 0;
        const char *session_name;
@@ -280,6 +288,7 @@ static int action_executor_stop_session_handler(struct action_executor *executor
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
+               lttng_action_increase_execution_failure_count(action);
                goto error_unlock_list;
        }
 
                goto error_unlock_list;
        }
 
@@ -302,6 +311,7 @@ static int action_executor_stop_session_handler(struct action_executor *executor
                WARN("Failed to stop session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
                WARN("Failed to stop session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
+               lttng_action_increase_execution_failure_count(action);
                break;
        }
 
                break;
        }
 
@@ -314,9 +324,10 @@ end:
        return ret;
 }
 
        return ret;
 }
 
-static int action_executor_rotate_session_handler(struct action_executor *executor,
+static int action_executor_rotate_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *work_item,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
        int ret = 0;
        const char *session_name;
 {
        int ret = 0;
        const char *session_name;
@@ -339,6 +350,7 @@ static int action_executor_rotate_session_handler(struct action_executor *execut
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
+               lttng_action_increase_execution_failure_count(action);
                goto error_unlock_list;
        }
 
                goto error_unlock_list;
        }
 
@@ -357,6 +369,7 @@ static int action_executor_rotate_session_handler(struct action_executor *execut
        case LTTNG_ERR_ROTATION_PENDING:
                DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation is already ongoing",
                                session_name, get_trigger_name(work_item->trigger));
        case LTTNG_ERR_ROTATION_PENDING:
                DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation is already ongoing",
                                session_name, get_trigger_name(work_item->trigger));
+               lttng_action_increase_execution_failure_count(action);
                break;
        case LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
        case LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
                break;
        case LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
        case LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
@@ -367,6 +380,7 @@ static int action_executor_rotate_session_handler(struct action_executor *execut
                WARN("Failed to start a rotation of session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
                WARN("Failed to start a rotation of session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
+               lttng_action_increase_execution_failure_count(action);
                break;
        }
 
                break;
        }
 
@@ -379,9 +393,10 @@ end:
        return ret;
 }
 
        return ret;
 }
 
-static int action_executor_snapshot_session_handler(struct action_executor *executor,
+static int action_executor_snapshot_session_handler(
+               struct action_executor *executor,
                const struct action_work_item *work_item,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
        int ret = 0;
        const char *session_name;
 {
        int ret = 0;
        const char *session_name;
@@ -419,6 +434,7 @@ static int action_executor_snapshot_session_handler(struct action_executor *exec
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
                DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
                                session_name, get_action_name(action),
                                get_trigger_name(work_item->trigger));
+               lttng_action_increase_execution_failure_count(action);
                goto error_unlock_list;
        }
 
                goto error_unlock_list;
        }
 
@@ -438,6 +454,7 @@ static int action_executor_snapshot_session_handler(struct action_executor *exec
                WARN("Failed to record snapshot of session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
                WARN("Failed to record snapshot of session `%s` on behalf of trigger `%s`: %s",
                                session_name, get_trigger_name(work_item->trigger),
                                lttng_strerror(-cmd_ret));
+               lttng_action_increase_execution_failure_count(action);
                break;
        }
 
                break;
        }
 
@@ -452,7 +469,7 @@ end:
 
 static int action_executor_group_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
 
 static int action_executor_group_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
-               const struct lttng_action *action_group)
+               struct lttng_action *action_group)
 {
        int ret = 0;
        unsigned int i, count;
 {
        int ret = 0;
        unsigned int i, count;
@@ -468,8 +485,8 @@ static int action_executor_group_handler(struct action_executor *executor,
 
        DBG("Action group has %u action%s", count, count != 1 ? "s" : "");
        for (i = 0; i < count; i++) {
 
        DBG("Action group has %u action%s", count, count != 1 ? "s" : "");
        for (i = 0; i < count; i++) {
-               const struct lttng_action *action =
-                               lttng_action_group_get_at_index(
+               struct lttng_action *action =
+                               lttng_action_group_borrow_mutable_at_index(
                                                action_group, i);
 
                ret = action_executor_generic_handler(
                                                action_group, i);
 
                ret = action_executor_generic_handler(
@@ -486,27 +503,39 @@ end:
 
 static int action_executor_generic_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
 
 static int action_executor_generic_handler(struct action_executor *executor,
                const struct action_work_item *work_item,
-               const struct lttng_action *action)
+               struct lttng_action *action)
 {
 {
+       int ret;
        const enum lttng_action_type action_type = lttng_action_get_type(action);
 
        assert(action_type != LTTNG_ACTION_TYPE_UNKNOWN);
 
        const enum lttng_action_type action_type = lttng_action_get_type(action);
 
        assert(action_type != LTTNG_ACTION_TYPE_UNKNOWN);
 
+       lttng_action_increase_execution_request_count(action);
+       if (!lttng_action_should_execute(action)) {
+               DBG("Policy prevented execution of action `%s` of trigger `%s` action work item %" PRIu64,
+                               get_action_name(action),
+                               get_trigger_name(work_item->trigger),
+                               work_item->id);
+               ret = 0;
+               goto end;
+       }
+
+       lttng_action_increase_execution_count(action);
        DBG("Executing action `%s` of trigger `%s` action work item %" PRIu64,
                        get_action_name(action),
                        get_trigger_name(work_item->trigger),
                        work_item->id);
        DBG("Executing action `%s` of trigger `%s` action work item %" PRIu64,
                        get_action_name(action),
                        get_trigger_name(work_item->trigger),
                        work_item->id);
-
-       return action_executors[action_type](
-                       executor, work_item, action);
+       ret = action_executors[action_type](executor, work_item, action);
+end:
+       return ret;
 }
 
 static int action_work_item_execute(struct action_executor *executor,
                struct action_work_item *work_item)
 {
        int ret;
 }
 
 static int action_work_item_execute(struct action_executor *executor,
                struct action_work_item *work_item)
 {
        int ret;
-       const struct lttng_action *action =
-                       lttng_trigger_get_const_action(work_item->trigger);
+       struct lttng_action *action =
+                       lttng_trigger_get_action(work_item->trigger);
 
        DBG("Starting execution of action work item %" PRIu64 " of trigger `%s`",
                        work_item->id, get_trigger_name(work_item->trigger));
 
        DBG("Starting execution of action work item %" PRIu64 " of trigger `%s`",
                        work_item->id, get_trigger_name(work_item->trigger));
index 95a0c0f4d20a19eb743b60d392c65934a82d656f..07eefeeb050ab14877abcf2d55ac4b93e78d91b1 100644 (file)
@@ -8,6 +8,7 @@
 #include <assert.h>
 #include <common/error.h>
 #include <lttng/action/action-internal.h>
 #include <assert.h>
 #include <common/error.h>
 #include <lttng/action/action-internal.h>
+#include <lttng/action/firing-policy-internal.h>
 #include <lttng/action/group-internal.h>
 #include <lttng/action/notify-internal.h>
 #include <lttng/action/rotate-session-internal.h>
 #include <lttng/action/group-internal.h>
 #include <lttng/action/notify-internal.h>
 #include <lttng/action/rotate-session-internal.h>
@@ -44,13 +45,13 @@ enum lttng_action_type lttng_action_get_type(const struct lttng_action *action)
 }
 
 LTTNG_HIDDEN
 }
 
 LTTNG_HIDDEN
-void lttng_action_init(
-               struct lttng_action *action,
+void lttng_action_init(struct lttng_action *action,
                enum lttng_action_type type,
                action_validate_cb validate,
                action_serialize_cb serialize,
                action_equal_cb equal,
                enum lttng_action_type type,
                action_validate_cb validate,
                action_serialize_cb serialize,
                action_equal_cb equal,
-               action_destroy_cb destroy)
+               action_destroy_cb destroy,
+               action_get_firing_policy_cb get_firing_policy)
 {
        urcu_ref_init(&action->ref);
        action->type = type;
 {
        urcu_ref_init(&action->ref);
        action->type = type;
@@ -58,6 +59,11 @@ void lttng_action_init(
        action->serialize = serialize;
        action->equal = equal;
        action->destroy = destroy;
        action->serialize = serialize;
        action->equal = equal;
        action->destroy = destroy;
+       action->get_firing_policy = get_firing_policy;
+
+       action->execution_request_counter = 0;
+       action->execution_counter = 0;
+       action->execution_failure_counter = 0;
 }
 
 static
 }
 
 static
@@ -243,3 +249,44 @@ bool lttng_action_is_equal(const struct lttng_action *a,
 end:
        return is_equal;
 }
 end:
        return is_equal;
 }
+
+LTTNG_HIDDEN
+void lttng_action_increase_execution_request_count(struct lttng_action *action)
+{
+       action->execution_request_counter++;
+}
+
+LTTNG_HIDDEN
+void lttng_action_increase_execution_count(struct lttng_action *action)
+{
+       action->execution_counter++;
+}
+
+LTTNG_HIDDEN
+void lttng_action_increase_execution_failure_count(struct lttng_action *action)
+{
+       action->execution_failure_counter++;
+}
+
+LTTNG_HIDDEN
+bool lttng_action_should_execute(const struct lttng_action *action)
+{
+       const struct lttng_firing_policy *policy = NULL;
+       bool execute = false;
+
+       if (action->get_firing_policy == NULL) {
+               execute = true;
+               goto end;
+       }
+
+       policy = action->get_firing_policy(action);
+       if (policy == NULL) {
+               execute = true;
+               goto end;
+       }
+
+       execute = lttng_firing_policy_should_execute(
+                       policy, action->execution_request_counter);
+end:
+       return execute;
+}
index 6152d61d8066735aafc5fc914396653e0497f67f..8c5a5bffccf3252bd610c17739e60aec83f711a8 100644 (file)
@@ -78,6 +78,14 @@ static void lttng_firing_policy_init(struct lttng_firing_policy *firing_policy,
                firing_policy_destroy_cb destroy,
                firing_policy_copy_cb copy);
 
                firing_policy_destroy_cb destroy,
                firing_policy_copy_cb copy);
 
+/* Forward declaration. Every n */
+static bool lttng_firing_policy_every_n_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter);
+
+/* Forward declaration. Once after N */
+static bool lttng_firing_policy_once_after_n_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter);
+
 LTTNG_HIDDEN
 const char *lttng_firing_policy_type_string(
                enum lttng_firing_policy_type firing_policy_type)
 LTTNG_HIDDEN
 const char *lttng_firing_policy_type_string(
                enum lttng_firing_policy_type firing_policy_type)
@@ -319,6 +327,23 @@ end:
        return is_equal;
 }
 
        return is_equal;
 }
 
+LTTNG_HIDDEN
+bool lttng_firing_policy_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter)
+{
+       switch (policy->type) {
+       case LTTNG_FIRING_POLICY_TYPE_EVERY_N:
+               return lttng_firing_policy_every_n_should_execute(
+                               policy, counter);
+       case LTTNG_FIRING_POLICY_TYPE_ONCE_AFTER_N:
+               return lttng_firing_policy_once_after_n_should_execute(
+                               policy, counter);
+       default:
+               abort();
+               break;
+       }
+}
+
 /* Every N */
 static const struct lttng_firing_policy_every_n *
 firing_policy_every_n_from_firing_policy_const(
 /* Every N */
 static const struct lttng_firing_policy_every_n *
 firing_policy_every_n_from_firing_policy_const(
@@ -400,6 +425,13 @@ struct lttng_firing_policy *lttng_firing_policy_every_n_create(
 {
        struct lttng_firing_policy_every_n *policy = NULL;
 
 {
        struct lttng_firing_policy_every_n *policy = NULL;
 
+       if (interval == 0) {
+               /*
+                * An interval of 0 is invalid since it would never be fired.
+                */
+               goto end;
+       }
+
        policy = zmalloc(sizeof(struct lttng_firing_policy_every_n));
        if (!policy) {
                goto end;
        policy = zmalloc(sizeof(struct lttng_firing_policy_every_n));
        if (!policy) {
                goto end;
@@ -438,6 +470,29 @@ end:
        return status;
 }
 
        return status;
 }
 
+static bool lttng_firing_policy_every_n_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter)
+{
+       const struct lttng_firing_policy_every_n *every_n_policy;
+       assert(policy);
+       bool execute = false;
+
+       every_n_policy = firing_policy_every_n_from_firing_policy_const(policy);
+
+       if (every_n_policy->interval == 0) {
+               abort();
+       }
+
+       execute = (counter % every_n_policy->interval) == 0;
+
+       DBG("Policy every N = %" PRIu64
+                       ": execution %s. Execution count: %" PRIu64,
+                       every_n_policy->interval,
+                       execute ? "accepted" : "denied", counter);
+
+       return execute;
+}
+
 /* Once after N */
 
 static const struct lttng_firing_policy_once_after_n *
 /* Once after N */
 
 static const struct lttng_firing_policy_once_after_n *
@@ -524,6 +579,11 @@ struct lttng_firing_policy *lttng_firing_policy_once_after_n_create(
 {
        struct lttng_firing_policy_once_after_n *policy = NULL;
 
 {
        struct lttng_firing_policy_once_after_n *policy = NULL;
 
+       if (threshold == 0) {
+               /* threshold is expected to be > 0 */
+               goto end;
+       }
+
        policy = zmalloc(sizeof(struct lttng_firing_policy_once_after_n));
        if (!policy) {
                goto end;
        policy = zmalloc(sizeof(struct lttng_firing_policy_once_after_n));
        if (!policy) {
                goto end;
@@ -571,3 +631,24 @@ struct lttng_firing_policy *lttng_firing_policy_copy(
        assert(source->copy);
        return source->copy(source);
 }
        assert(source->copy);
        return source->copy(source);
 }
+
+static bool lttng_firing_policy_once_after_n_should_execute(
+               const struct lttng_firing_policy *policy, uint64_t counter)
+{
+       const struct lttng_firing_policy_once_after_n *once_after_n_policy;
+       bool execute = false;
+       assert(policy);
+
+       once_after_n_policy =
+                       firing_policy_once_after_n_from_firing_policy_const(
+                                       policy);
+
+       execute = counter == once_after_n_policy->threshold;
+
+       DBG("Policy once after N = %" PRIu64
+           ": execution %s. Execution count: %" PRIu64,
+                       once_after_n_policy->threshold,
+                       execute ? "accepted" : "denied", counter);
+
+       return counter == once_after_n_policy->threshold;
+}
index 4ac239c9d62c14f43c7b2ddf0623c5e901aeaf5d..afb832ee646a766b40142f87eae385eb178b7fa4 100644 (file)
@@ -266,8 +266,8 @@ struct lttng_action *lttng_action_group_create(void)
        lttng_action_init(action, LTTNG_ACTION_TYPE_GROUP,
                        lttng_action_group_validate,
                        lttng_action_group_serialize,
        lttng_action_init(action, LTTNG_ACTION_TYPE_GROUP,
                        lttng_action_group_validate,
                        lttng_action_group_serialize,
-                       lttng_action_group_is_equal,
-                       lttng_action_group_destroy);
+                       lttng_action_group_is_equal, lttng_action_group_destroy,
+                       NULL);
 
        lttng_dynamic_pointer_array_init(&action_group->actions,
                        destroy_lttng_action_group_element);
 
        lttng_dynamic_pointer_array_init(&action_group->actions,
                        destroy_lttng_action_group_element);
@@ -333,10 +333,17 @@ end:
 
 const struct lttng_action *lttng_action_group_get_at_index(
                const struct lttng_action *group, unsigned int index)
 
 const struct lttng_action *lttng_action_group_get_at_index(
                const struct lttng_action *group, unsigned int index)
+{
+       return lttng_action_group_borrow_mutable_at_index(group, index);
+}
+
+LTTNG_HIDDEN
+struct lttng_action *lttng_action_group_borrow_mutable_at_index(
+               const struct lttng_action *group, unsigned int index)
 {
        unsigned int count;
        const struct lttng_action_group *action_group;
 {
        unsigned int count;
        const struct lttng_action_group *action_group;
-       const struct lttng_action * action = NULL;
+       struct lttng_action *action = NULL;
 
        if (lttng_action_group_get_count(group, &count) !=
                        LTTNG_ACTION_STATUS_OK) {
 
        if (lttng_action_group_get_count(group, &count) !=
                        LTTNG_ACTION_STATUS_OK) {
index 85029a5e25908665396dca4770fd135e399c6018..3ce1b00f901f332ecd58a7ee4f8db77c2b95329e 100644 (file)
@@ -73,6 +73,16 @@ bool lttng_action_notify_is_equal(const struct lttng_action *a,
        return lttng_firing_policy_is_equal(_a->policy, _b->policy);
 }
 
        return lttng_firing_policy_is_equal(_a->policy, _b->policy);
 }
 
+static const struct lttng_firing_policy *
+lttng_action_notify_internal_get_firing_policy(
+               const struct lttng_action *action)
+{
+       const struct lttng_action_notify *_action;
+       _action = action_notify_from_action_const(action);
+
+       return _action->policy;
+}
+
 struct lttng_action *lttng_action_notify_create(void)
 {
        struct lttng_firing_policy *policy = NULL;
 struct lttng_action *lttng_action_notify_create(void)
 {
        struct lttng_firing_policy *policy = NULL;
@@ -93,7 +103,8 @@ struct lttng_action *lttng_action_notify_create(void)
        lttng_action_init(&notify->parent, LTTNG_ACTION_TYPE_NOTIFY, NULL,
                        lttng_action_notify_serialize,
                        lttng_action_notify_is_equal,
        lttng_action_init(&notify->parent, LTTNG_ACTION_TYPE_NOTIFY, NULL,
                        lttng_action_notify_serialize,
                        lttng_action_notify_is_equal,
-                       lttng_action_notify_destroy);
+                       lttng_action_notify_destroy,
+                       lttng_action_notify_internal_get_firing_policy);
 
        notify->policy = policy;
        policy = NULL;
 
        notify->policy = policy;
        policy = NULL;
index 815e919d843c1cce33bc1953570d60e8eef6d268..f2ac2d04dcc0e04fa587de24aefcc12c0cce1c65 100644 (file)
@@ -38,6 +38,10 @@ struct lttng_action_rotate_session_comm {
        char data[];
 } LTTNG_PACKED;
 
        char data[];
 } LTTNG_PACKED;
 
+static const struct lttng_firing_policy *
+lttng_action_rotate_session_internal_get_firing_policy(
+               const struct lttng_action *action);
+
 static struct lttng_action_rotate_session *action_rotate_session_from_action(
                struct lttng_action *action)
 {
 static struct lttng_action_rotate_session *action_rotate_session_from_action(
                struct lttng_action *action)
 {
@@ -247,7 +251,8 @@ struct lttng_action *lttng_action_rotate_session_create(void)
                        lttng_action_rotate_session_validate,
                        lttng_action_rotate_session_serialize,
                        lttng_action_rotate_session_is_equal,
                        lttng_action_rotate_session_validate,
                        lttng_action_rotate_session_serialize,
                        lttng_action_rotate_session_is_equal,
-                       lttng_action_rotate_session_destroy);
+                       lttng_action_rotate_session_destroy,
+                       lttng_action_rotate_session_internal_get_firing_policy);
 
        status = lttng_action_rotate_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
 
        status = lttng_action_rotate_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
@@ -361,3 +366,13 @@ enum lttng_action_status lttng_action_rotate_session_get_firing_policy(
 end:
        return status;
 }
 end:
        return status;
 }
+
+static const struct lttng_firing_policy *
+lttng_action_rotate_session_internal_get_firing_policy(
+               const struct lttng_action *action)
+{
+       const struct lttng_action_rotate_session *_action;
+       _action = action_rotate_session_from_action_const(action);
+
+       return _action->policy;
+}
index 7c5775eb8da724d298c3b14799e4bd8dc2fbeac9..5d01784958de3eed0bd07d1119d51b9c73204142 100644 (file)
@@ -55,6 +55,10 @@ struct lttng_action_snapshot_session_comm {
        char data[];
 } LTTNG_PACKED;
 
        char data[];
 } LTTNG_PACKED;
 
+static const struct lttng_firing_policy *
+lttng_action_snapshot_session_internal_get_firing_policy(
+               const struct lttng_action *action);
+
 static struct lttng_action_snapshot_session *
 action_snapshot_session_from_action(struct lttng_action *action)
 {
 static struct lttng_action_snapshot_session *
 action_snapshot_session_from_action(struct lttng_action *action)
 {
@@ -390,7 +394,8 @@ 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_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_firing_policy);
 
        status = lttng_action_snapshot_session_set_firing_policy(
                        action, policy);
 
        status = lttng_action_snapshot_session_set_firing_policy(
                        action, policy);
@@ -559,3 +564,13 @@ enum lttng_action_status lttng_action_snapshot_session_get_firing_policy(
 end:
        return status;
 }
 end:
        return status;
 }
+
+static const struct lttng_firing_policy *
+lttng_action_snapshot_session_internal_get_firing_policy(
+               const struct lttng_action *action)
+{
+       const struct lttng_action_snapshot_session *_action;
+       _action = action_snapshot_session_from_action_const(action);
+
+       return _action->policy;
+}
index 28dc27f82a68cf8206d1da0f10dc944e1dcb4b47..07aeaf779ef5bd1c84b8f18e47cb09e3dfc842ba 100644 (file)
@@ -38,6 +38,10 @@ struct lttng_action_start_session_comm {
        char data[];
 } LTTNG_PACKED;
 
        char data[];
 } LTTNG_PACKED;
 
+static const struct lttng_firing_policy *
+lttng_action_start_session_internal_get_firing_policy(
+               const struct lttng_action *action);
+
 static struct lttng_action_start_session *action_start_session_from_action(
                struct lttng_action *action)
 {
 static struct lttng_action_start_session *action_start_session_from_action(
                struct lttng_action *action)
 {
@@ -250,7 +254,8 @@ struct lttng_action *lttng_action_start_session_create(void)
                        lttng_action_start_session_validate,
                        lttng_action_start_session_serialize,
                        lttng_action_start_session_is_equal,
                        lttng_action_start_session_validate,
                        lttng_action_start_session_serialize,
                        lttng_action_start_session_is_equal,
-                       lttng_action_start_session_destroy);
+                       lttng_action_start_session_destroy,
+                       lttng_action_start_session_internal_get_firing_policy);
 
        status = lttng_action_start_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
 
        status = lttng_action_start_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
@@ -364,3 +369,13 @@ enum lttng_action_status lttng_action_start_session_get_firing_policy(
 end:
        return status;
 }
 end:
        return status;
 }
+
+static const struct lttng_firing_policy *
+lttng_action_start_session_internal_get_firing_policy(
+               const struct lttng_action *action)
+{
+       const struct lttng_action_start_session *_action;
+       _action = action_start_session_from_action_const(action);
+
+       return _action->policy;
+}
index 232bd7265362184478f73c3c36a188a7f72c832f..b3ff63188f2e05952dae5fdd5f7b93d591111a4d 100644 (file)
@@ -38,6 +38,10 @@ struct lttng_action_stop_session_comm {
        char data[];
 } LTTNG_PACKED;
 
        char data[];
 } LTTNG_PACKED;
 
+static const struct lttng_firing_policy *
+lttng_action_stop_session_internal_get_firing_policy(
+               const struct lttng_action *action);
+
 static struct lttng_action_stop_session *action_stop_session_from_action(
                struct lttng_action *action)
 {
 static struct lttng_action_stop_session *action_stop_session_from_action(
                struct lttng_action *action)
 {
@@ -251,7 +255,8 @@ struct lttng_action *lttng_action_stop_session_create(void)
                        lttng_action_stop_session_validate,
                        lttng_action_stop_session_serialize,
                        lttng_action_stop_session_is_equal,
                        lttng_action_stop_session_validate,
                        lttng_action_stop_session_serialize,
                        lttng_action_stop_session_is_equal,
-                       lttng_action_stop_session_destroy);
+                       lttng_action_stop_session_destroy,
+                       lttng_action_stop_session_internal_get_firing_policy);
 
        status = lttng_action_stop_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
 
        status = lttng_action_stop_session_set_firing_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
@@ -363,3 +368,13 @@ enum lttng_action_status lttng_action_stop_session_get_firing_policy(
 end:
        return status;
 }
 end:
        return status;
 }
+
+static const struct lttng_firing_policy *
+lttng_action_stop_session_internal_get_firing_policy(
+               const struct lttng_action *action)
+{
+       const struct lttng_action_stop_session *_action;
+       _action = action_stop_session_from_action_const(action);
+
+       return _action->policy;
+}
This page took 0.0376 seconds and 4 git commands to generate.