action list: missing renames from previous name "group"
[lttng-tools.git] / src / common / actions / action.c
CommitLineData
a58c490f 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
a58c490f 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
a58c490f 5 *
a58c490f
JG
6 */
7
14ec7e87
JR
8#include <assert.h>
9#include <common/error.h>
a58c490f 10#include <lttng/action/action-internal.h>
ad63a966 11#include <lttng/action/list-internal.h>
a58c490f 12#include <lttng/action/notify-internal.h>
7f4d5b07 13#include <lttng/action/rate-policy-internal.h>
bfb2ec6a 14#include <lttng/action/rotate-session-internal.h>
757c48a2 15#include <lttng/action/snapshot-session-internal.h>
58397d0d 16#include <lttng/action/start-session-internal.h>
931bdbaa 17#include <lttng/action/stop-session-internal.h>
588c4b0d 18#include <lttng/error-query-internal.h>
a58c490f 19
10615eee
JR
20LTTNG_HIDDEN
21const char *lttng_action_type_string(enum lttng_action_type action_type)
2666d352
SM
22{
23 switch (action_type) {
24 case LTTNG_ACTION_TYPE_UNKNOWN:
25 return "UNKNOWN";
7c2fae7c
JG
26 case LTTNG_ACTION_TYPE_LIST:
27 return "LIST";
2666d352
SM
28 case LTTNG_ACTION_TYPE_NOTIFY:
29 return "NOTIFY";
bfb2ec6a
SM
30 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
31 return "ROTATE_SESSION";
757c48a2
SM
32 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
33 return "SNAPSHOT_SESSION";
58397d0d
SM
34 case LTTNG_ACTION_TYPE_START_SESSION:
35 return "START_SESSION";
931bdbaa
SM
36 case LTTNG_ACTION_TYPE_STOP_SESSION:
37 return "STOP_SESSION";
2666d352
SM
38 default:
39 return "???";
40 }
41}
42
17182cfd 43enum lttng_action_type lttng_action_get_type(const struct lttng_action *action)
a58c490f
JG
44{
45 return action ? action->type : LTTNG_ACTION_TYPE_UNKNOWN;
46}
47
6acb3f46 48LTTNG_HIDDEN
2d57482c 49void lttng_action_init(struct lttng_action *action,
6acb3f46
SM
50 enum lttng_action_type type,
51 action_validate_cb validate,
52 action_serialize_cb serialize,
3dd04a6a 53 action_equal_cb equal,
2d57482c 54 action_destroy_cb destroy,
588c4b0d
JG
55 action_get_rate_policy_cb get_rate_policy,
56 action_add_error_query_results_cb add_error_query_results)
6acb3f46 57{
c852ce4e 58 urcu_ref_init(&action->ref);
6acb3f46
SM
59 action->type = type;
60 action->validate = validate;
61 action->serialize = serialize;
3dd04a6a 62 action->equal = equal;
6acb3f46 63 action->destroy = destroy;
7f4d5b07 64 action->get_rate_policy = get_rate_policy;
588c4b0d 65 action->add_error_query_results = add_error_query_results;
2d57482c
JR
66
67 action->execution_request_counter = 0;
68 action->execution_counter = 0;
69 action->execution_failure_counter = 0;
6acb3f46
SM
70}
71
c852ce4e
JG
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)
a58c490f
JG
89{
90 if (!action) {
91 return;
92 }
93
94 assert(action->destroy);
c852ce4e
JG
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);
a58c490f
JG
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
3647288f 125int lttng_action_serialize(struct lttng_action *action,
c0a66c84 126 struct lttng_payload *payload)
a58c490f 127{
3647288f
JG
128 int ret;
129 struct lttng_action_comm action_comm = {
130 .action_type = (int8_t) action->type,
131 };
132
c0a66c84 133 ret = lttng_dynamic_buffer_append(&payload->buffer, &action_comm,
3647288f
JG
134 sizeof(action_comm));
135 if (ret) {
a58c490f
JG
136 goto end;
137 }
138
c0a66c84 139 ret = action->serialize(action, payload);
3647288f 140 if (ret) {
a58c490f
JG
141 goto end;
142 }
a58c490f
JG
143end:
144 return ret;
145}
146
147LTTNG_HIDDEN
c0a66c84 148ssize_t lttng_action_create_from_payload(struct lttng_payload_view *view,
869a3c2d 149 struct lttng_action **action)
a58c490f 150{
869a3c2d 151 ssize_t consumed_len, specific_action_consumed_len;
c0a66c84 152 action_create_from_payload_cb create_from_payload_cb;
3e6e0df2
JG
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));
a58c490f 157
869a3c2d
SM
158 if (!view || !action) {
159 consumed_len = -1;
a58c490f
JG
160 goto end;
161 }
162
3e6e0df2
JG
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;
869a3c2d 170
c0a66c84 171 DBG("Create action from payload: action-type=%s",
2666d352
SM
172 lttng_action_type_string(action_comm->action_type));
173
a58c490f
JG
174 switch (action_comm->action_type) {
175 case LTTNG_ACTION_TYPE_NOTIFY:
c0a66c84 176 create_from_payload_cb = lttng_action_notify_create_from_payload;
a58c490f 177 break;
bfb2ec6a 178 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
c0a66c84
JG
179 create_from_payload_cb =
180 lttng_action_rotate_session_create_from_payload;
bfb2ec6a 181 break;
757c48a2
SM
182 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
183 create_from_payload_cb =
184 lttng_action_snapshot_session_create_from_payload;
185 break;
58397d0d 186 case LTTNG_ACTION_TYPE_START_SESSION:
c0a66c84
JG
187 create_from_payload_cb =
188 lttng_action_start_session_create_from_payload;
58397d0d 189 break;
931bdbaa 190 case LTTNG_ACTION_TYPE_STOP_SESSION:
c0a66c84
JG
191 create_from_payload_cb =
192 lttng_action_stop_session_create_from_payload;
931bdbaa 193 break;
7c2fae7c 194 case LTTNG_ACTION_TYPE_LIST:
702f26c8 195 create_from_payload_cb = lttng_action_list_create_from_payload;
0c51e8f3 196 break;
a58c490f 197 default:
c0a66c84 198 ERR("Failed to create action from payload, unhandled action type: action-type=%u (%s)",
2666d352
SM
199 action_comm->action_type,
200 lttng_action_type_string(
201 action_comm->action_type));
869a3c2d 202 consumed_len = -1;
a58c490f
JG
203 goto end;
204 }
205
c0a66c84
JG
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);
869a3c2d 212
c0a66c84
JG
213 specific_action_consumed_len = create_from_payload_cb(
214 &specific_action_view, action);
215 }
869a3c2d
SM
216 if (specific_action_consumed_len < 0) {
217 ERR("Failed to create specific action from buffer.");
218 consumed_len = -1;
a58c490f
JG
219 goto end;
220 }
869a3c2d
SM
221
222 assert(*action);
223
224 consumed_len = sizeof(struct lttng_action_comm) +
225 specific_action_consumed_len;
226
a58c490f 227end:
869a3c2d 228 return consumed_len;
a58c490f 229}
3dd04a6a
JR
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}
2d57482c
JR
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{
588c4b0d 271 uatomic_inc(&action->execution_failure_counter);
2d57482c
JR
272}
273
274LTTNG_HIDDEN
275bool lttng_action_should_execute(const struct lttng_action *action)
276{
7f4d5b07 277 const struct lttng_rate_policy *policy = NULL;
2d57482c
JR
278 bool execute = false;
279
7f4d5b07 280 if (action->get_rate_policy == NULL) {
2d57482c
JR
281 execute = true;
282 goto end;
283 }
284
7f4d5b07 285 policy = action->get_rate_policy(action);
2d57482c
JR
286 if (policy == NULL) {
287 execute = true;
288 goto end;
289 }
290
7f4d5b07 291 execute = lttng_rate_policy_should_execute(
2d57482c
JR
292 policy, action->execution_request_counter);
293end:
294 return execute;
295}
588c4b0d
JG
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.053708 seconds and 4 git commands to generate.