Fix: consumerd: consumed size miscomputed during statistics sampling
[lttng-tools.git] / src / common / actions / notify.cpp
1 /*
2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
10 #include <common/mi-lttng.hpp>
11
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>
16
17 #define IS_NOTIFY_ACTION(action) (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_NOTIFY)
18
19 static struct lttng_action_notify *action_notify_from_action(struct lttng_action *action)
20 {
21 LTTNG_ASSERT(action);
22
23 return lttng::utils::container_of(action, &lttng_action_notify::parent);
24 }
25
26 static const struct lttng_action_notify *
27 action_notify_from_action_const(const struct lttng_action *action)
28 {
29 LTTNG_ASSERT(action);
30
31 return lttng::utils::container_of(action, &lttng_action_notify::parent);
32 }
33
34 static void lttng_action_notify_destroy(struct lttng_action *action)
35 {
36 struct lttng_action_notify *notify_action;
37 notify_action = action_notify_from_action(action);
38 lttng_rate_policy_destroy(notify_action->policy);
39 free(notify_action);
40 }
41
42 static int lttng_action_notify_serialize(struct lttng_action *action, struct lttng_payload *payload)
43 {
44 int ret;
45 struct lttng_action_notify *notify_action;
46
47 if (!action || !IS_NOTIFY_ACTION(action) || !payload) {
48 ret = -1;
49 goto end;
50 }
51
52 DBG("Serializing notify action");
53
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);
57
58 end:
59 return ret;
60 }
61
62 static bool lttng_action_notify_is_equal(const struct lttng_action *a, const struct lttng_action *b)
63 {
64 const struct lttng_action_notify *_a, *_b;
65
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);
69 }
70
71 static const struct lttng_rate_policy *
72 lttng_action_notify_internal_get_rate_policy(const struct lttng_action *action)
73 {
74 const struct lttng_action_notify *_action;
75 _action = action_notify_from_action_const(action);
76
77 return _action->policy;
78 }
79
80 static enum lttng_error_code lttng_action_notify_mi_serialize(const struct lttng_action *action,
81 struct mi_writer *writer)
82 {
83 int ret;
84 enum lttng_action_status status;
85 enum lttng_error_code ret_code;
86 const struct lttng_rate_policy *policy = nullptr;
87
88 LTTNG_ASSERT(action);
89 LTTNG_ASSERT(IS_NOTIFY_ACTION(action));
90 LTTNG_ASSERT(writer);
91
92 status = lttng_action_notify_get_rate_policy(action, &policy);
93 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
94 LTTNG_ASSERT(policy != nullptr);
95
96 /* Open action notify. */
97 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_action_notify);
98 if (ret) {
99 goto mi_error;
100 }
101
102 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
103 if (ret_code != LTTNG_OK) {
104 goto end;
105 }
106
107 /* Close action notify element. */
108 ret = mi_lttng_writer_close_element(writer);
109 if (ret) {
110 goto mi_error;
111 }
112
113 ret_code = LTTNG_OK;
114 goto end;
115
116 mi_error:
117 ret_code = LTTNG_ERR_MI_IO_FAIL;
118 end:
119 return ret_code;
120 }
121
122 struct lttng_action *lttng_action_notify_create(void)
123 {
124 struct lttng_rate_policy *policy = nullptr;
125 struct lttng_action_notify *notify = nullptr;
126 struct lttng_action *action = nullptr;
127
128 notify = zmalloc<lttng_action_notify>();
129 if (!notify) {
130 goto end;
131 }
132
133 /* Default policy. */
134 policy = lttng_rate_policy_every_n_create(1);
135 if (!policy) {
136 goto end;
137 }
138
139 lttng_action_init(&notify->parent,
140 LTTNG_ACTION_TYPE_NOTIFY,
141 nullptr,
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);
148
149 notify->policy = policy;
150 policy = nullptr;
151
152 action = &notify->parent;
153 notify = nullptr;
154
155 end:
156 free(notify);
157 lttng_rate_policy_destroy(policy);
158 return action;
159 }
160
161 ssize_t lttng_action_notify_create_from_payload(struct lttng_payload_view *view,
162 struct lttng_action **action)
163 {
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;
168
169 consumed_length = lttng_rate_policy_create_from_payload(view, &rate_policy);
170 if (!rate_policy) {
171 consumed_length = -1;
172 goto end;
173 }
174
175 _action = lttng_action_notify_create();
176 if (!_action) {
177 consumed_length = -1;
178 goto end;
179 }
180
181 status = lttng_action_notify_set_rate_policy(_action, rate_policy);
182 if (status != LTTNG_ACTION_STATUS_OK) {
183 consumed_length = -1;
184 goto end;
185 }
186
187 *action = _action;
188 _action = nullptr;
189
190 end:
191 lttng_rate_policy_destroy(rate_policy);
192 lttng_action_destroy(_action);
193 return consumed_length;
194 }
195
196 enum lttng_action_status lttng_action_notify_set_rate_policy(struct lttng_action *action,
197 const struct lttng_rate_policy *policy)
198 {
199 enum lttng_action_status status;
200 struct lttng_action_notify *notify_action;
201 struct lttng_rate_policy *copy = nullptr;
202
203 if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
204 status = LTTNG_ACTION_STATUS_INVALID;
205 goto end;
206 }
207
208 copy = lttng_rate_policy_copy(policy);
209 if (!copy) {
210 status = LTTNG_ACTION_STATUS_ERROR;
211 goto end;
212 }
213
214 notify_action = action_notify_from_action(action);
215
216 /* Free the previous rate policy .*/
217 lttng_rate_policy_destroy(notify_action->policy);
218
219 /* Assign the policy. */
220 notify_action->policy = copy;
221 status = LTTNG_ACTION_STATUS_OK;
222 copy = nullptr;
223
224 end:
225 lttng_rate_policy_destroy(copy);
226 return status;
227 }
228
229 enum lttng_action_status
230 lttng_action_notify_get_rate_policy(const struct lttng_action *action,
231 const struct lttng_rate_policy **policy)
232 {
233 enum lttng_action_status status;
234 const struct lttng_action_notify *notify_action;
235
236 if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
237 status = LTTNG_ACTION_STATUS_INVALID;
238 goto end;
239 }
240
241 notify_action = action_notify_from_action_const(action);
242
243 *policy = notify_action->policy;
244 status = LTTNG_ACTION_STATUS_OK;
245 end:
246 return status;
247 }
This page took 0.082432 seconds and 4 git commands to generate.