liblttng-ctl: use lttng_payload for serialize/create_from_buffer
[lttng-tools.git] / src / common / actions / stop-session.c
1 /*
2 * Copyright (C) 2019 Simon Marchi <simon.marchi@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 <common/macros.h>
11 #include <lttng/action/action-internal.h>
12 #include <lttng/action/stop-session-internal.h>
13 #include <lttng/action/stop-session.h>
14
15 #define IS_STOP_SESSION_ACTION(action) \
16 (lttng_action_get_type_const(action) == LTTNG_ACTION_TYPE_STOP_SESSION)
17
18 struct lttng_action_stop_session {
19 struct lttng_action parent;
20
21 /* Owned by this. */
22 char *session_name;
23 };
24
25 struct lttng_action_stop_session_comm {
26 /* Includes the trailing \0. */
27 uint32_t session_name_len;
28
29 /*
30 * Variable data:
31 *
32 * - session name (null terminated)
33 */
34 char data[];
35 } LTTNG_PACKED;
36
37 static struct lttng_action_stop_session *action_stop_session_from_action(
38 struct lttng_action *action)
39 {
40 assert(action);
41
42 return container_of(action, struct lttng_action_stop_session, parent);
43 }
44
45 static const struct lttng_action_stop_session *
46 action_stop_session_from_action_const(const struct lttng_action *action)
47 {
48 assert(action);
49
50 return container_of(action, struct lttng_action_stop_session, parent);
51 }
52
53 static bool lttng_action_stop_session_validate(struct lttng_action *action)
54 {
55 bool valid;
56 struct lttng_action_stop_session *action_stop_session;
57
58 if (!action) {
59 valid = false;
60 goto end;
61 }
62
63 action_stop_session = action_stop_session_from_action(action);
64
65 /* A non-empty session name is mandatory. */
66 if (!action_stop_session->session_name ||
67 strlen(action_stop_session->session_name) == 0) {
68 valid = false;
69 goto end;
70 }
71
72 valid = true;
73 end:
74 return valid;
75 }
76
77 static bool lttng_action_stop_session_is_equal(
78 const struct lttng_action *_a, const struct lttng_action *_b)
79 {
80 bool is_equal = false;
81 const struct lttng_action_stop_session *a, *b;
82
83 a = action_stop_session_from_action_const(_a);
84 b = action_stop_session_from_action_const(_b);
85
86 /* Action is not valid if this is not true. */
87 assert(a->session_name);
88 assert(b->session_name);
89 if (strcmp(a->session_name, b->session_name)) {
90 goto end;
91 }
92
93 is_equal = true;
94 end:
95 return is_equal;
96 }
97
98 static int lttng_action_stop_session_serialize(
99 struct lttng_action *action, struct lttng_payload *payload)
100 {
101 struct lttng_action_stop_session *action_stop_session;
102 struct lttng_action_stop_session_comm comm;
103 size_t session_name_len;
104 int ret;
105
106 assert(action);
107 assert(payload);
108
109 action_stop_session = action_stop_session_from_action(action);
110
111 assert(action_stop_session->session_name);
112
113 DBG("Serializing stop session action: session-name: %s",
114 action_stop_session->session_name);
115
116 session_name_len = strlen(action_stop_session->session_name) + 1;
117 comm.session_name_len = session_name_len;
118
119 ret = lttng_dynamic_buffer_append(
120 &payload->buffer, &comm, sizeof(comm));
121 if (ret) {
122 ret = -1;
123 goto end;
124 }
125
126 ret = lttng_dynamic_buffer_append(&payload->buffer,
127 action_stop_session->session_name, session_name_len);
128 if (ret) {
129 ret = -1;
130 goto end;
131 }
132
133 ret = 0;
134 end:
135 return ret;
136 }
137
138 static void lttng_action_stop_session_destroy(struct lttng_action *action)
139 {
140 struct lttng_action_stop_session *action_stop_session;
141
142 if (!action) {
143 goto end;
144 }
145
146 action_stop_session = action_stop_session_from_action(action);
147
148 free(action_stop_session->session_name);
149 free(action_stop_session);
150
151 end:
152 return;
153 }
154
155 ssize_t lttng_action_stop_session_create_from_payload(
156 struct lttng_payload_view *view,
157 struct lttng_action **p_action)
158 {
159 ssize_t consumed_len;
160 const struct lttng_action_stop_session_comm *comm;
161 const char *session_name;
162 struct lttng_action *action;
163 enum lttng_action_status status;
164
165 action = lttng_action_stop_session_create();
166 if (!action) {
167 consumed_len = -1;
168 goto end;
169 }
170
171 comm = (typeof(comm)) view->buffer.data;
172 session_name = (const char *) &comm->data;
173
174 if (!lttng_buffer_view_contains_string(
175 &view->buffer, session_name, comm->session_name_len)) {
176 consumed_len = -1;
177 goto end;
178 }
179
180 status = lttng_action_stop_session_set_session_name(
181 action, session_name);
182 if (status != LTTNG_ACTION_STATUS_OK) {
183 consumed_len = -1;
184 goto end;
185 }
186
187 consumed_len = sizeof(*comm) + comm->session_name_len;
188 *p_action = action;
189 action = NULL;
190
191 end:
192 lttng_action_stop_session_destroy(action);
193
194 return consumed_len;
195 }
196
197 struct lttng_action *lttng_action_stop_session_create(void)
198 {
199 struct lttng_action *action;
200
201 action = zmalloc(sizeof(struct lttng_action_stop_session));
202 if (!action) {
203 goto end;
204 }
205
206 lttng_action_init(action, LTTNG_ACTION_TYPE_STOP_SESSION,
207 lttng_action_stop_session_validate,
208 lttng_action_stop_session_serialize,
209 lttng_action_stop_session_is_equal,
210 lttng_action_stop_session_destroy);
211
212 end:
213 return action;
214 }
215
216 enum lttng_action_status lttng_action_stop_session_set_session_name(
217 struct lttng_action *action, const char *session_name)
218 {
219 struct lttng_action_stop_session *action_stop_session;
220 enum lttng_action_status status;
221
222 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name ||
223 strlen(session_name) == 0) {
224 status = LTTNG_ACTION_STATUS_INVALID;
225 goto end;
226 }
227
228 action_stop_session = action_stop_session_from_action(action);
229
230 free(action_stop_session->session_name);
231
232 action_stop_session->session_name = strdup(session_name);
233 if (!action_stop_session->session_name) {
234 status = LTTNG_ACTION_STATUS_ERROR;
235 goto end;
236 }
237
238 status = LTTNG_ACTION_STATUS_OK;
239 end:
240 return status;
241 }
242
243 enum lttng_action_status lttng_action_stop_session_get_session_name(
244 const struct lttng_action *action, const char **session_name)
245 {
246 const struct lttng_action_stop_session *action_stop_session;
247 enum lttng_action_status status;
248
249 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name) {
250 status = LTTNG_ACTION_STATUS_INVALID;
251 goto end;
252 }
253
254 action_stop_session = action_stop_session_from_action_const(action);
255
256 *session_name = action_stop_session->session_name;
257
258 status = LTTNG_ACTION_STATUS_OK;
259 end:
260 return status;
261 }
This page took 0.048522 seconds and 4 git commands to generate.