2 * Copyright (C) 2019 Simon Marchi <simon.marchi@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/rate-policy-internal.hpp>
14 #include <lttng/action/rate-policy.h>
15 #include <lttng/action/stop-session-internal.hpp>
16 #include <lttng/action/stop-session.h>
18 #define IS_STOP_SESSION_ACTION(action) \
19 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_STOP_SESSION)
22 struct lttng_action_stop_session
{
23 struct lttng_action parent
;
27 struct lttng_rate_policy
*policy
;
30 struct lttng_action_stop_session_comm
{
31 /* Includes the trailing \0. */
32 uint32_t session_name_len
;
37 * - session name (null terminated)
44 static const struct lttng_rate_policy
*
45 lttng_action_stop_session_internal_get_rate_policy(const struct lttng_action
*action
);
47 static struct lttng_action_stop_session
*
48 action_stop_session_from_action(struct lttng_action
*action
)
52 return lttng::utils::container_of(action
, <tng_action_stop_session::parent
);
55 static const struct lttng_action_stop_session
*
56 action_stop_session_from_action_const(const struct lttng_action
*action
)
60 return lttng::utils::container_of(action
, <tng_action_stop_session::parent
);
63 static bool lttng_action_stop_session_validate(struct lttng_action
*action
)
66 struct lttng_action_stop_session
*action_stop_session
;
73 action_stop_session
= action_stop_session_from_action(action
);
75 /* A non-empty session name is mandatory. */
76 if (!action_stop_session
->session_name
|| strlen(action_stop_session
->session_name
) == 0) {
86 static bool lttng_action_stop_session_is_equal(const struct lttng_action
*_a
,
87 const struct lttng_action
*_b
)
89 bool is_equal
= false;
90 const struct lttng_action_stop_session
*a
, *b
;
92 a
= action_stop_session_from_action_const(_a
);
93 b
= action_stop_session_from_action_const(_b
);
95 /* Action is not valid if this is not true. */
96 LTTNG_ASSERT(a
->session_name
);
97 LTTNG_ASSERT(b
->session_name
);
98 if (strcmp(a
->session_name
, b
->session_name
) != 0) {
102 is_equal
= lttng_rate_policy_is_equal(a
->policy
, b
->policy
);
107 static int lttng_action_stop_session_serialize(struct lttng_action
*action
,
108 struct lttng_payload
*payload
)
110 struct lttng_action_stop_session
*action_stop_session
;
111 struct lttng_action_stop_session_comm comm
;
112 size_t session_name_len
;
115 LTTNG_ASSERT(action
);
116 LTTNG_ASSERT(payload
);
118 action_stop_session
= action_stop_session_from_action(action
);
120 LTTNG_ASSERT(action_stop_session
->session_name
);
122 DBG("Serializing stop session action: session-name: %s", action_stop_session
->session_name
);
124 session_name_len
= strlen(action_stop_session
->session_name
) + 1;
125 comm
.session_name_len
= session_name_len
;
127 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
133 ret
= lttng_dynamic_buffer_append(
134 &payload
->buffer
, action_stop_session
->session_name
, session_name_len
);
140 ret
= lttng_rate_policy_serialize(action_stop_session
->policy
, payload
);
151 static void lttng_action_stop_session_destroy(struct lttng_action
*action
)
153 struct lttng_action_stop_session
*action_stop_session
;
159 action_stop_session
= action_stop_session_from_action(action
);
161 lttng_rate_policy_destroy(action_stop_session
->policy
);
162 free(action_stop_session
->session_name
);
163 free(action_stop_session
);
169 ssize_t
lttng_action_stop_session_create_from_payload(struct lttng_payload_view
*view
,
170 struct lttng_action
**p_action
)
172 ssize_t consumed_len
, ret
;
173 const struct lttng_action_stop_session_comm
*comm
;
174 const char *session_name
;
175 struct lttng_action
*action
= nullptr;
176 enum lttng_action_status status
;
177 struct lttng_rate_policy
*policy
= nullptr;
179 comm
= (typeof(comm
)) view
->buffer
.data
;
180 session_name
= (const char *) &comm
->data
;
183 if (!lttng_buffer_view_contains_string(
184 &view
->buffer
, session_name
, comm
->session_name_len
)) {
188 consumed_len
= sizeof(*comm
) + comm
->session_name_len
;
192 struct lttng_payload_view policy_view
=
193 lttng_payload_view_from_view(view
, consumed_len
, -1);
194 ret
= lttng_rate_policy_create_from_payload(&policy_view
, &policy
);
202 action
= lttng_action_stop_session_create();
208 status
= lttng_action_stop_session_set_session_name(action
, session_name
);
209 if (status
!= LTTNG_ACTION_STATUS_OK
) {
214 LTTNG_ASSERT(policy
);
215 status
= lttng_action_stop_session_set_rate_policy(action
, policy
);
216 if (status
!= LTTNG_ACTION_STATUS_OK
) {
225 lttng_rate_policy_destroy(policy
);
226 lttng_action_stop_session_destroy(action
);
231 static enum lttng_error_code
232 lttng_action_stop_session_mi_serialize(const struct lttng_action
*action
, struct mi_writer
*writer
)
235 enum lttng_error_code ret_code
;
236 enum lttng_action_status status
;
237 const char *session_name
= nullptr;
238 const struct lttng_rate_policy
*policy
= nullptr;
240 LTTNG_ASSERT(action
);
241 LTTNG_ASSERT(IS_STOP_SESSION_ACTION(action
));
243 status
= lttng_action_stop_session_get_session_name(action
, &session_name
);
244 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
245 LTTNG_ASSERT(session_name
!= nullptr);
247 status
= lttng_action_stop_session_get_rate_policy(action
, &policy
);
248 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
249 LTTNG_ASSERT(policy
!= nullptr);
251 /* Open action stop session. */
252 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_action_start_session
);
258 ret
= mi_lttng_writer_write_element_string(
259 writer
, mi_lttng_element_session_name
, session_name
);
265 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
266 if (ret_code
!= LTTNG_OK
) {
270 /* Close action stop session element. */
271 ret
= mi_lttng_writer_close_element(writer
);
280 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
285 struct lttng_action
*lttng_action_stop_session_create(void)
287 struct lttng_action_stop_session
*action_stop
= nullptr;
288 struct lttng_rate_policy
*policy
= nullptr;
289 enum lttng_action_status status
;
291 /* Create a every N = 1 rate policy. */
292 policy
= lttng_rate_policy_every_n_create(1);
297 action_stop
= zmalloc
<lttng_action_stop_session
>();
302 lttng_action_init(&action_stop
->parent
,
303 LTTNG_ACTION_TYPE_STOP_SESSION
,
304 lttng_action_stop_session_validate
,
305 lttng_action_stop_session_serialize
,
306 lttng_action_stop_session_is_equal
,
307 lttng_action_stop_session_destroy
,
308 lttng_action_stop_session_internal_get_rate_policy
,
309 lttng_action_generic_add_error_query_results
,
310 lttng_action_stop_session_mi_serialize
);
312 status
= lttng_action_stop_session_set_rate_policy(&action_stop
->parent
, policy
);
313 if (status
!= LTTNG_ACTION_STATUS_OK
) {
314 lttng_action_destroy(&action_stop
->parent
);
315 action_stop
= nullptr;
320 lttng_rate_policy_destroy(policy
);
321 return &action_stop
->parent
;
324 enum lttng_action_status
lttng_action_stop_session_set_session_name(struct lttng_action
*action
,
325 const char *session_name
)
327 struct lttng_action_stop_session
*action_stop_session
;
328 enum lttng_action_status status
;
330 if (!action
|| !IS_STOP_SESSION_ACTION(action
) || !session_name
||
331 strlen(session_name
) == 0) {
332 status
= LTTNG_ACTION_STATUS_INVALID
;
336 action_stop_session
= action_stop_session_from_action(action
);
338 free(action_stop_session
->session_name
);
340 action_stop_session
->session_name
= strdup(session_name
);
341 if (!action_stop_session
->session_name
) {
342 status
= LTTNG_ACTION_STATUS_ERROR
;
346 status
= LTTNG_ACTION_STATUS_OK
;
351 enum lttng_action_status
352 lttng_action_stop_session_get_session_name(const struct lttng_action
*action
,
353 const char **session_name
)
355 const struct lttng_action_stop_session
*action_stop_session
;
356 enum lttng_action_status status
;
358 if (!action
|| !IS_STOP_SESSION_ACTION(action
) || !session_name
) {
359 status
= LTTNG_ACTION_STATUS_INVALID
;
363 action_stop_session
= action_stop_session_from_action_const(action
);
365 *session_name
= action_stop_session
->session_name
;
367 status
= LTTNG_ACTION_STATUS_OK
;
372 enum lttng_action_status
373 lttng_action_stop_session_set_rate_policy(struct lttng_action
*action
,
374 const struct lttng_rate_policy
*policy
)
376 enum lttng_action_status status
;
377 struct lttng_action_stop_session
*stop_session_action
;
378 struct lttng_rate_policy
*copy
= nullptr;
380 if (!action
|| !policy
|| !IS_STOP_SESSION_ACTION(action
)) {
381 status
= LTTNG_ACTION_STATUS_INVALID
;
385 copy
= lttng_rate_policy_copy(policy
);
387 status
= LTTNG_ACTION_STATUS_ERROR
;
390 stop_session_action
= action_stop_session_from_action(action
);
392 /* Free the previous rate policy .*/
393 lttng_rate_policy_destroy(stop_session_action
->policy
);
395 stop_session_action
->policy
= copy
;
396 status
= LTTNG_ACTION_STATUS_OK
;
400 lttng_rate_policy_destroy(copy
);
404 enum lttng_action_status
405 lttng_action_stop_session_get_rate_policy(const struct lttng_action
*action
,
406 const struct lttng_rate_policy
**policy
)
408 enum lttng_action_status status
;
409 const struct lttng_action_stop_session
*stop_session_action
;
411 if (!action
|| !policy
|| !IS_STOP_SESSION_ACTION(action
)) {
412 status
= LTTNG_ACTION_STATUS_INVALID
;
416 stop_session_action
= action_stop_session_from_action_const(action
);
418 *policy
= stop_session_action
->policy
;
419 status
= LTTNG_ACTION_STATUS_OK
;
424 static const struct lttng_rate_policy
*
425 lttng_action_stop_session_internal_get_rate_policy(const struct lttng_action
*action
)
427 const struct lttng_action_stop_session
*_action
;
428 _action
= action_stop_session_from_action_const(action
);
430 return _action
->policy
;