actions: introduce start session action
[lttng-tools.git] / src / common / actions / start-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/start-session-internal.h>
13 #include <lttng/action/start-session.h>
14
15 #define IS_START_SESSION_ACTION(action) \
16 (lttng_action_get_type_const(action) == LTTNG_ACTION_TYPE_START_SESSION)
17
18 struct lttng_action_start_session {
19 struct lttng_action parent;
20
21 /* Owned by this. */
22 char *session_name;
23 };
24
25 struct lttng_action_start_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_start_session *action_start_session_from_action(
38 struct lttng_action *action)
39 {
40 assert(action);
41
42 return container_of(action, struct lttng_action_start_session, parent);
43 }
44
45 static const struct lttng_action_start_session *
46 action_start_session_from_action_const(const struct lttng_action *action)
47 {
48 assert(action);
49
50 return container_of(action, struct lttng_action_start_session, parent);
51 }
52
53 static bool lttng_action_start_session_validate(struct lttng_action *action)
54 {
55 bool valid;
56 struct lttng_action_start_session *action_start_session;
57
58 if (!action) {
59 valid = false;
60 goto end;
61 }
62
63 action_start_session = action_start_session_from_action(action);
64
65 /* A non-empty session name is mandatory. */
66 if (!action_start_session->session_name ||
67 strlen(action_start_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_start_session_is_equal(
78 const struct lttng_action *_a, const struct lttng_action *_b)
79 {
80 bool is_equal = false;
81 struct lttng_action_start_session *a, *b;
82
83 a = container_of(_a, struct lttng_action_start_session, parent);
84 b = container_of(_b, struct lttng_action_start_session, parent);
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_start_session_serialize(
99 struct lttng_action *action, struct lttng_dynamic_buffer *buf)
100 {
101 struct lttng_action_start_session *action_start_session;
102 struct lttng_action_start_session_comm comm;
103 size_t session_name_len;
104 int ret;
105
106 assert(action);
107 assert(buf);
108
109 action_start_session = action_start_session_from_action(action);
110
111 assert(action_start_session->session_name);
112
113 DBG("Serializing start session action: session-name: %s",
114 action_start_session->session_name);
115
116 session_name_len = strlen(action_start_session->session_name) + 1;
117 comm.session_name_len = session_name_len;
118
119 ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
120 if (ret) {
121 ret = -1;
122 goto end;
123 }
124
125 ret = lttng_dynamic_buffer_append(buf,
126 action_start_session->session_name, session_name_len);
127 if (ret) {
128 ret = -1;
129 goto end;
130 }
131
132 ret = 0;
133 end:
134 return ret;
135 }
136
137 static void lttng_action_start_session_destroy(struct lttng_action *action)
138 {
139 struct lttng_action_start_session *action_start_session;
140
141 if (!action) {
142 goto end;
143 }
144
145 action_start_session = action_start_session_from_action(action);
146
147 free(action_start_session->session_name);
148 free(action_start_session);
149
150 end:
151 return;
152 }
153
154 ssize_t lttng_action_start_session_create_from_buffer(
155 const struct lttng_buffer_view *view,
156 struct lttng_action **p_action)
157 {
158 ssize_t consumed_len;
159 const struct lttng_action_start_session_comm *comm;
160 const char *session_name;
161 struct lttng_action *action;
162 enum lttng_action_status status;
163
164 action = lttng_action_start_session_create();
165 if (!action) {
166 consumed_len = -1;
167 goto end;
168 }
169
170 comm = (const struct lttng_action_start_session_comm *) view->data;
171 session_name = (const char *) &comm->data;
172
173 if (!lttng_buffer_view_contains_string(
174 view, session_name, comm->session_name_len)) {
175 consumed_len = -1;
176 goto end;
177 }
178
179 status = lttng_action_start_session_set_session_name(
180 action, session_name);
181 if (status != LTTNG_ACTION_STATUS_OK) {
182 consumed_len = -1;
183 goto end;
184 }
185
186 consumed_len = sizeof(struct lttng_action_start_session_comm) +
187 comm->session_name_len;
188 *p_action = action;
189 action = NULL;
190
191 end:
192 lttng_action_start_session_destroy(action);
193
194 return consumed_len;
195 }
196
197 struct lttng_action *lttng_action_start_session_create(void)
198 {
199 struct lttng_action *action;
200
201 action = zmalloc(sizeof(struct lttng_action_start_session));
202 if (!action) {
203 goto end;
204 }
205
206 lttng_action_init(action, LTTNG_ACTION_TYPE_START_SESSION,
207 lttng_action_start_session_validate,
208 lttng_action_start_session_serialize,
209 lttng_action_start_session_is_equal,
210 lttng_action_start_session_destroy);
211
212 end:
213 return action;
214 }
215
216 enum lttng_action_status lttng_action_start_session_set_session_name(
217 struct lttng_action *action, const char *session_name)
218 {
219 struct lttng_action_start_session *action_start_session;
220 enum lttng_action_status status;
221
222 if (!action || !IS_START_SESSION_ACTION(action) || !session_name ||
223 strlen(session_name) == 0) {
224 status = LTTNG_ACTION_STATUS_INVALID;
225 goto end;
226 }
227
228 action_start_session = action_start_session_from_action(action);
229
230 free(action_start_session->session_name);
231
232 action_start_session->session_name = strdup(session_name);
233 if (!action_start_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_start_session_get_session_name(
244 const struct lttng_action *action, const char **session_name)
245 {
246 const struct lttng_action_start_session *action_start_session;
247 enum lttng_action_status status;
248
249 if (!action || !IS_START_SESSION_ACTION(action) || !session_name) {
250 status = LTTNG_ACTION_STATUS_INVALID;
251 goto end;
252 }
253
254 action_start_session = action_start_session_from_action_const(action);
255
256 *session_name = action_start_session->session_name;
257
258 status = LTTNG_ACTION_STATUS_OK;
259 end:
260 return status;
261 }
This page took 0.034254 seconds and 4 git commands to generate.