Rename action group to action list
[lttng-tools.git] / src / common / actions / action.c
... / ...
CommitLineData
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 <assert.h>
9#include <common/error.h>
10#include <lttng/action/action-internal.h>
11#include <lttng/action/group-internal.h>
12#include <lttng/action/notify-internal.h>
13#include <lttng/action/rate-policy-internal.h>
14#include <lttng/action/rotate-session-internal.h>
15#include <lttng/action/snapshot-session-internal.h>
16#include <lttng/action/start-session-internal.h>
17#include <lttng/action/stop-session-internal.h>
18#include <lttng/error-query-internal.h>
19
20LTTNG_HIDDEN
21const char *lttng_action_type_string(enum lttng_action_type action_type)
22{
23 switch (action_type) {
24 case LTTNG_ACTION_TYPE_UNKNOWN:
25 return "UNKNOWN";
26 case LTTNG_ACTION_TYPE_GROUP:
27 return "GROUP";
28 case LTTNG_ACTION_TYPE_NOTIFY:
29 return "NOTIFY";
30 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
31 return "ROTATE_SESSION";
32 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
33 return "SNAPSHOT_SESSION";
34 case LTTNG_ACTION_TYPE_START_SESSION:
35 return "START_SESSION";
36 case LTTNG_ACTION_TYPE_STOP_SESSION:
37 return "STOP_SESSION";
38 default:
39 return "???";
40 }
41}
42
43enum lttng_action_type lttng_action_get_type(const struct lttng_action *action)
44{
45 return action ? action->type : LTTNG_ACTION_TYPE_UNKNOWN;
46}
47
48LTTNG_HIDDEN
49void lttng_action_init(struct lttng_action *action,
50 enum lttng_action_type type,
51 action_validate_cb validate,
52 action_serialize_cb serialize,
53 action_equal_cb equal,
54 action_destroy_cb destroy,
55 action_get_rate_policy_cb get_rate_policy,
56 action_add_error_query_results_cb add_error_query_results)
57{
58 urcu_ref_init(&action->ref);
59 action->type = type;
60 action->validate = validate;
61 action->serialize = serialize;
62 action->equal = equal;
63 action->destroy = destroy;
64 action->get_rate_policy = get_rate_policy;
65 action->add_error_query_results = add_error_query_results;
66
67 action->execution_request_counter = 0;
68 action->execution_counter = 0;
69 action->execution_failure_counter = 0;
70}
71
72static
73void action_destroy_ref(struct urcu_ref *ref)
74{
75 struct lttng_action *action =
76 container_of(ref, struct lttng_action, ref);
77
78 action->destroy(action);
79}
80
81LTTNG_HIDDEN
82void lttng_action_get(struct lttng_action *action)
83{
84 urcu_ref_get(&action->ref);
85}
86
87LTTNG_HIDDEN
88void lttng_action_put(struct lttng_action *action)
89{
90 if (!action) {
91 return;
92 }
93
94 assert(action->destroy);
95 urcu_ref_put(&action->ref, action_destroy_ref);
96}
97
98void lttng_action_destroy(struct lttng_action *action)
99{
100 lttng_action_put(action);
101}
102
103LTTNG_HIDDEN
104bool lttng_action_validate(struct lttng_action *action)
105{
106 bool valid;
107
108 if (!action) {
109 valid = false;
110 goto end;
111 }
112
113 if (!action->validate) {
114 /* Sub-class guarantees that it can never be invalid. */
115 valid = true;
116 goto end;
117 }
118
119 valid = action->validate(action);
120end:
121 return valid;
122}
123
124LTTNG_HIDDEN
125int lttng_action_serialize(struct lttng_action *action,
126 struct lttng_payload *payload)
127{
128 int ret;
129 struct lttng_action_comm action_comm = {
130 .action_type = (int8_t) action->type,
131 };
132
133 ret = lttng_dynamic_buffer_append(&payload->buffer, &action_comm,
134 sizeof(action_comm));
135 if (ret) {
136 goto end;
137 }
138
139 ret = action->serialize(action, payload);
140 if (ret) {
141 goto end;
142 }
143end:
144 return ret;
145}
146
147LTTNG_HIDDEN
148ssize_t lttng_action_create_from_payload(struct lttng_payload_view *view,
149 struct lttng_action **action)
150{
151 ssize_t consumed_len, specific_action_consumed_len;
152 action_create_from_payload_cb create_from_payload_cb;
153 const struct lttng_action_comm *action_comm;
154 const struct lttng_payload_view action_comm_view =
155 lttng_payload_view_from_view(
156 view, 0, sizeof(*action_comm));
157
158 if (!view || !action) {
159 consumed_len = -1;
160 goto end;
161 }
162
163 if (!lttng_payload_view_is_valid(&action_comm_view)) {
164 /* Payload not large enough to contain the header. */
165 consumed_len = -1;
166 goto end;
167 }
168
169 action_comm = (const struct lttng_action_comm *) action_comm_view.buffer.data;
170
171 DBG("Create action from payload: action-type=%s",
172 lttng_action_type_string(action_comm->action_type));
173
174 switch (action_comm->action_type) {
175 case LTTNG_ACTION_TYPE_NOTIFY:
176 create_from_payload_cb = lttng_action_notify_create_from_payload;
177 break;
178 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
179 create_from_payload_cb =
180 lttng_action_rotate_session_create_from_payload;
181 break;
182 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
183 create_from_payload_cb =
184 lttng_action_snapshot_session_create_from_payload;
185 break;
186 case LTTNG_ACTION_TYPE_START_SESSION:
187 create_from_payload_cb =
188 lttng_action_start_session_create_from_payload;
189 break;
190 case LTTNG_ACTION_TYPE_STOP_SESSION:
191 create_from_payload_cb =
192 lttng_action_stop_session_create_from_payload;
193 break;
194 case LTTNG_ACTION_TYPE_GROUP:
195 create_from_payload_cb = lttng_action_list_create_from_payload;
196 break;
197 default:
198 ERR("Failed to create action from payload, unhandled action type: action-type=%u (%s)",
199 action_comm->action_type,
200 lttng_action_type_string(
201 action_comm->action_type));
202 consumed_len = -1;
203 goto end;
204 }
205
206 {
207 /* Create buffer view for the action-type-specific data. */
208 struct lttng_payload_view specific_action_view =
209 lttng_payload_view_from_view(view,
210 sizeof(struct lttng_action_comm),
211 -1);
212
213 specific_action_consumed_len = create_from_payload_cb(
214 &specific_action_view, action);
215 }
216 if (specific_action_consumed_len < 0) {
217 ERR("Failed to create specific action from buffer.");
218 consumed_len = -1;
219 goto end;
220 }
221
222 assert(*action);
223
224 consumed_len = sizeof(struct lttng_action_comm) +
225 specific_action_consumed_len;
226
227end:
228 return consumed_len;
229}
230
231LTTNG_HIDDEN
232bool lttng_action_is_equal(const struct lttng_action *a,
233 const struct lttng_action *b)
234{
235 bool is_equal = false;
236
237 if (!a || !b) {
238 goto end;
239 }
240
241 if (a->type != b->type) {
242 goto end;
243 }
244
245 if (a == b) {
246 is_equal = true;
247 goto end;
248 }
249
250 assert(a->equal);
251 is_equal = a->equal(a, b);
252end:
253 return is_equal;
254}
255
256LTTNG_HIDDEN
257void lttng_action_increase_execution_request_count(struct lttng_action *action)
258{
259 action->execution_request_counter++;
260}
261
262LTTNG_HIDDEN
263void lttng_action_increase_execution_count(struct lttng_action *action)
264{
265 action->execution_counter++;
266}
267
268LTTNG_HIDDEN
269void lttng_action_increase_execution_failure_count(struct lttng_action *action)
270{
271 uatomic_inc(&action->execution_failure_counter);
272}
273
274LTTNG_HIDDEN
275bool lttng_action_should_execute(const struct lttng_action *action)
276{
277 const struct lttng_rate_policy *policy = NULL;
278 bool execute = false;
279
280 if (action->get_rate_policy == NULL) {
281 execute = true;
282 goto end;
283 }
284
285 policy = action->get_rate_policy(action);
286 if (policy == NULL) {
287 execute = true;
288 goto end;
289 }
290
291 execute = lttng_rate_policy_should_execute(
292 policy, action->execution_request_counter);
293end:
294 return execute;
295}
296
297LTTNG_HIDDEN
298enum lttng_action_status lttng_action_add_error_query_results(
299 const struct lttng_action *action,
300 struct lttng_error_query_results *results)
301{
302 return action->add_error_query_results(action, results);
303}
304
305LTTNG_HIDDEN
306enum lttng_action_status lttng_action_generic_add_error_query_results(
307 const struct lttng_action *action,
308 struct lttng_error_query_results *results)
309{
310 enum lttng_action_status action_status;
311 struct lttng_error_query_result *error_counter = NULL;
312 const uint64_t execution_failure_counter =
313 uatomic_read(&action->execution_failure_counter);
314
315 error_counter = lttng_error_query_result_counter_create(
316 "total execution failures",
317 "Aggregated count of errors encountered when executing the action",
318 execution_failure_counter);
319 if (!error_counter) {
320 action_status = LTTNG_ACTION_STATUS_ERROR;
321 goto end;
322 }
323
324 if (lttng_error_query_results_add_result(
325 results, error_counter)) {
326 action_status = LTTNG_ACTION_STATUS_ERROR;
327 goto end;
328 }
329
330 /* Ownership transferred to the results. */
331 error_counter = NULL;
332 action_status = LTTNG_ACTION_STATUS_OK;
333end:
334 lttng_error_query_result_destroy(error_counter);
335 return action_status;
336}
This page took 0.024749 seconds and 4 git commands to generate.