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