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>
11 #include <lttng/action/action-internal.hpp>
12 #include <lttng/action/notify-internal.hpp>
13 #include <lttng/action/rate-policy-internal.hpp>
14 #include <lttng/lttng-error.h>
16 #define IS_NOTIFY_ACTION(action) \
17 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_NOTIFY)
19 static struct lttng_action_notify
*action_notify_from_action(
20 struct lttng_action
*action
)
24 return lttng::utils::container_of(action
, <tng_action_notify::parent
);
27 static const struct lttng_action_notify
*action_notify_from_action_const(
28 const struct lttng_action
*action
)
32 return lttng::utils::container_of(action
, <tng_action_notify::parent
);
36 void lttng_action_notify_destroy(struct lttng_action
*action
)
38 struct lttng_action_notify
*notify_action
;
39 notify_action
= action_notify_from_action(action
);
40 lttng_rate_policy_destroy(notify_action
->policy
);
45 int lttng_action_notify_serialize(struct lttng_action
*action
,
46 struct lttng_payload
*payload
)
49 struct lttng_action_notify
*notify_action
;
51 if (!action
|| !IS_NOTIFY_ACTION(action
) || !payload
) {
56 DBG("Serializing notify action");
58 notify_action
= action_notify_from_action(action
);
59 DBG("Serializing notify action rate policy");
60 ret
= lttng_rate_policy_serialize(notify_action
->policy
, payload
);
67 bool lttng_action_notify_is_equal(const struct lttng_action
*a
,
68 const struct lttng_action
*b
)
70 const struct lttng_action_notify
*_a
, *_b
;
72 _a
= action_notify_from_action_const(a
);
73 _b
= action_notify_from_action_const(b
);
74 return lttng_rate_policy_is_equal(_a
->policy
, _b
->policy
);
77 static const struct lttng_rate_policy
*
78 lttng_action_notify_internal_get_rate_policy(const struct lttng_action
*action
)
80 const struct lttng_action_notify
*_action
;
81 _action
= action_notify_from_action_const(action
);
83 return _action
->policy
;
86 static enum lttng_error_code
lttng_action_notify_mi_serialize(
87 const struct lttng_action
*action
, struct mi_writer
*writer
)
90 enum lttng_action_status status
;
91 enum lttng_error_code ret_code
;
92 const struct lttng_rate_policy
*policy
= NULL
;
95 LTTNG_ASSERT(IS_NOTIFY_ACTION(action
));
98 status
= lttng_action_notify_get_rate_policy(action
, &policy
);
99 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
100 LTTNG_ASSERT(policy
!= NULL
);
102 /* Open action notify. */
103 ret
= mi_lttng_writer_open_element(
104 writer
, mi_lttng_element_action_notify
);
109 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
110 if (ret_code
!= LTTNG_OK
) {
114 /* Close action notify element. */
115 ret
= mi_lttng_writer_close_element(writer
);
124 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
129 struct lttng_action
*lttng_action_notify_create(void)
131 struct lttng_rate_policy
*policy
= NULL
;
132 struct lttng_action_notify
*notify
= NULL
;
133 struct lttng_action
*action
= NULL
;
135 notify
= zmalloc
<lttng_action_notify
>();
140 /* Default policy. */
141 policy
= lttng_rate_policy_every_n_create(1);
146 lttng_action_init(¬ify
->parent
, LTTNG_ACTION_TYPE_NOTIFY
, NULL
,
147 lttng_action_notify_serialize
,
148 lttng_action_notify_is_equal
,
149 lttng_action_notify_destroy
,
150 lttng_action_notify_internal_get_rate_policy
,
151 lttng_action_generic_add_error_query_results
,
152 lttng_action_notify_mi_serialize
);
154 notify
->policy
= policy
;
157 action
= ¬ify
->parent
;
162 lttng_rate_policy_destroy(policy
);
166 ssize_t
lttng_action_notify_create_from_payload(
167 struct lttng_payload_view
*view
,
168 struct lttng_action
**action
)
170 enum lttng_action_status status
;
171 ssize_t consumed_length
;
172 struct lttng_rate_policy
*rate_policy
= NULL
;
173 struct lttng_action
*_action
= NULL
;
175 consumed_length
= lttng_rate_policy_create_from_payload(
178 consumed_length
= -1;
182 _action
= lttng_action_notify_create();
184 consumed_length
= -1;
188 status
= lttng_action_notify_set_rate_policy(_action
, rate_policy
);
189 if (status
!= LTTNG_ACTION_STATUS_OK
) {
190 consumed_length
= -1;
198 lttng_rate_policy_destroy(rate_policy
);
199 lttng_action_destroy(_action
);
200 return consumed_length
;
203 enum lttng_action_status
lttng_action_notify_set_rate_policy(
204 struct lttng_action
*action
,
205 const struct lttng_rate_policy
*policy
)
207 enum lttng_action_status status
;
208 struct lttng_action_notify
*notify_action
;
209 struct lttng_rate_policy
*copy
= NULL
;
211 if (!action
|| !policy
|| !IS_NOTIFY_ACTION(action
)) {
212 status
= LTTNG_ACTION_STATUS_INVALID
;
216 copy
= lttng_rate_policy_copy(policy
);
218 status
= LTTNG_ACTION_STATUS_ERROR
;
222 notify_action
= action_notify_from_action(action
);
224 /* Free the previous rate policy .*/
225 lttng_rate_policy_destroy(notify_action
->policy
);
227 /* Assign the policy. */
228 notify_action
->policy
= copy
;
229 status
= LTTNG_ACTION_STATUS_OK
;
233 lttng_rate_policy_destroy(copy
);
237 enum lttng_action_status
lttng_action_notify_get_rate_policy(
238 const struct lttng_action
*action
,
239 const struct lttng_rate_policy
**policy
)
241 enum lttng_action_status status
;
242 const struct lttng_action_notify
*notify_action
;
244 if (!action
|| !policy
|| !IS_NOTIFY_ACTION(action
)) {
245 status
= LTTNG_ACTION_STATUS_INVALID
;
249 notify_action
= action_notify_from_action_const(action
);
251 *policy
= notify_action
->policy
;
252 status
= LTTNG_ACTION_STATUS_OK
;