2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
10 #include <common/mi-lttng.hpp>
12 #include <lttng/action/action-internal.hpp>
13 #include <lttng/action/notify-internal.hpp>
14 #include <lttng/action/rate-policy-internal.hpp>
15 #include <lttng/lttng-error.h>
17 #define IS_NOTIFY_ACTION(action) (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_NOTIFY)
19 static struct lttng_action_notify
*action_notify_from_action(struct lttng_action
*action
)
23 return lttng::utils::container_of(action
, <tng_action_notify::parent
);
26 static const struct lttng_action_notify
*
27 action_notify_from_action_const(const struct lttng_action
*action
)
31 return lttng::utils::container_of(action
, <tng_action_notify::parent
);
34 static void lttng_action_notify_destroy(struct lttng_action
*action
)
36 struct lttng_action_notify
*notify_action
;
37 notify_action
= action_notify_from_action(action
);
38 lttng_rate_policy_destroy(notify_action
->policy
);
42 static int lttng_action_notify_serialize(struct lttng_action
*action
, struct lttng_payload
*payload
)
45 struct lttng_action_notify
*notify_action
;
47 if (!action
|| !IS_NOTIFY_ACTION(action
) || !payload
) {
52 DBG("Serializing notify action");
54 notify_action
= action_notify_from_action(action
);
55 DBG("Serializing notify action rate policy");
56 ret
= lttng_rate_policy_serialize(notify_action
->policy
, payload
);
62 static bool lttng_action_notify_is_equal(const struct lttng_action
*a
, const struct lttng_action
*b
)
64 const struct lttng_action_notify
*_a
, *_b
;
66 _a
= action_notify_from_action_const(a
);
67 _b
= action_notify_from_action_const(b
);
68 return lttng_rate_policy_is_equal(_a
->policy
, _b
->policy
);
71 static const struct lttng_rate_policy
*
72 lttng_action_notify_internal_get_rate_policy(const struct lttng_action
*action
)
74 const struct lttng_action_notify
*_action
;
75 _action
= action_notify_from_action_const(action
);
77 return _action
->policy
;
80 static enum lttng_error_code
lttng_action_notify_mi_serialize(const struct lttng_action
*action
,
81 struct mi_writer
*writer
)
84 enum lttng_action_status status
;
85 enum lttng_error_code ret_code
;
86 const struct lttng_rate_policy
*policy
= nullptr;
89 LTTNG_ASSERT(IS_NOTIFY_ACTION(action
));
92 status
= lttng_action_notify_get_rate_policy(action
, &policy
);
93 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
94 LTTNG_ASSERT(policy
!= nullptr);
96 /* Open action notify. */
97 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_action_notify
);
102 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
103 if (ret_code
!= LTTNG_OK
) {
107 /* Close action notify element. */
108 ret
= mi_lttng_writer_close_element(writer
);
117 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
122 struct lttng_action
*lttng_action_notify_create(void)
124 struct lttng_rate_policy
*policy
= nullptr;
125 struct lttng_action_notify
*notify
= nullptr;
126 struct lttng_action
*action
= nullptr;
128 notify
= zmalloc
<lttng_action_notify
>();
133 /* Default policy. */
134 policy
= lttng_rate_policy_every_n_create(1);
139 lttng_action_init(¬ify
->parent
,
140 LTTNG_ACTION_TYPE_NOTIFY
,
142 lttng_action_notify_serialize
,
143 lttng_action_notify_is_equal
,
144 lttng_action_notify_destroy
,
145 lttng_action_notify_internal_get_rate_policy
,
146 lttng_action_generic_add_error_query_results
,
147 lttng_action_notify_mi_serialize
);
149 notify
->policy
= policy
;
152 action
= ¬ify
->parent
;
157 lttng_rate_policy_destroy(policy
);
161 ssize_t
lttng_action_notify_create_from_payload(struct lttng_payload_view
*view
,
162 struct lttng_action
**action
)
164 enum lttng_action_status status
;
165 ssize_t consumed_length
;
166 struct lttng_rate_policy
*rate_policy
= nullptr;
167 struct lttng_action
*_action
= nullptr;
169 consumed_length
= lttng_rate_policy_create_from_payload(view
, &rate_policy
);
171 consumed_length
= -1;
175 _action
= lttng_action_notify_create();
177 consumed_length
= -1;
181 status
= lttng_action_notify_set_rate_policy(_action
, rate_policy
);
182 if (status
!= LTTNG_ACTION_STATUS_OK
) {
183 consumed_length
= -1;
191 lttng_rate_policy_destroy(rate_policy
);
192 lttng_action_destroy(_action
);
193 return consumed_length
;
196 enum lttng_action_status
lttng_action_notify_set_rate_policy(struct lttng_action
*action
,
197 const struct lttng_rate_policy
*policy
)
199 enum lttng_action_status status
;
200 struct lttng_action_notify
*notify_action
;
201 struct lttng_rate_policy
*copy
= nullptr;
203 if (!action
|| !policy
|| !IS_NOTIFY_ACTION(action
)) {
204 status
= LTTNG_ACTION_STATUS_INVALID
;
208 copy
= lttng_rate_policy_copy(policy
);
210 status
= LTTNG_ACTION_STATUS_ERROR
;
214 notify_action
= action_notify_from_action(action
);
216 /* Free the previous rate policy .*/
217 lttng_rate_policy_destroy(notify_action
->policy
);
219 /* Assign the policy. */
220 notify_action
->policy
= copy
;
221 status
= LTTNG_ACTION_STATUS_OK
;
225 lttng_rate_policy_destroy(copy
);
229 enum lttng_action_status
230 lttng_action_notify_get_rate_policy(const struct lttng_action
*action
,
231 const struct lttng_rate_policy
**policy
)
233 enum lttng_action_status status
;
234 const struct lttng_action_notify
*notify_action
;
236 if (!action
|| !policy
|| !IS_NOTIFY_ACTION(action
)) {
237 status
= LTTNG_ACTION_STATUS_INVALID
;
241 notify_action
= action_notify_from_action_const(action
);
243 *policy
= notify_action
->policy
;
244 status
= LTTNG_ACTION_STATUS_OK
;