SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / common / actions / stop-session.c
1 /*
2 * Copyright (C) 2019 EfficiOS, Inc.
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include <assert.h>
19 #include <common/error.h>
20 #include <common/macros.h>
21 #include <lttng/action/action-internal.h>
22 #include <lttng/action/stop-session-internal.h>
23 #include <lttng/action/stop-session.h>
24
25 struct lttng_action_stop_session {
26 struct lttng_action parent;
27
28 /* Owned by this. */
29 char *session_name;
30 };
31
32 struct lttng_action_stop_session_comm {
33 /* Includes the trailing \0. */
34 uint32_t session_name_len;
35
36 /*
37 * Variable data:
38 *
39 * - session name (null terminated)
40 */
41 char data[];
42 } LTTNG_PACKED;
43
44 static struct lttng_action_stop_session *action_stop_session_from_action(
45 struct lttng_action *action)
46 {
47 assert(action);
48
49 return container_of(action, struct lttng_action_stop_session, parent);
50 }
51
52 static const struct lttng_action_stop_session *action_stop_session_from_action_const(
53 const struct lttng_action *action)
54 {
55 assert(action);
56
57 return container_of(action, struct lttng_action_stop_session, parent);
58 }
59
60 static bool lttng_action_stop_session_validate(struct lttng_action *action)
61 {
62 bool valid;
63 struct lttng_action_stop_session *action_stop_session;
64
65 if (!action) {
66 valid = false;
67 goto end;
68 }
69
70 action_stop_session = action_stop_session_from_action(action);
71
72 /* A non-empty session name is mandatory. */
73 if (!action_stop_session->session_name ||
74 strlen(action_stop_session->session_name) == 0) {
75 valid = false;
76 goto end;
77 }
78
79 valid = true;
80 end:
81 return valid;
82 }
83
84 static bool lttng_action_stop_session_is_equal(const struct lttng_action *_a, const struct lttng_action *_b)
85 {
86 bool is_equal = false;
87 const struct lttng_action_stop_session *a, *b;
88
89 a = action_stop_session_from_action_const(_a);
90 b = action_stop_session_from_action_const(_b);
91
92 /* Action is not valid if this is not true. */
93 assert(a->session_name);
94 assert(b->session_name);
95 if (strcmp(a->session_name, b->session_name)) {
96 goto end;
97 }
98
99 is_equal = true;
100 end:
101 return is_equal;
102 }
103
104 static int lttng_action_stop_session_serialize(
105 struct lttng_action *action, struct lttng_dynamic_buffer *buf)
106 {
107 struct lttng_action_stop_session *action_stop_session;
108 struct lttng_action_stop_session_comm comm;
109 size_t session_name_len;
110 int ret;
111
112 assert(action);
113 assert(buf);
114
115 action_stop_session = action_stop_session_from_action(action);
116
117 assert(action_stop_session->session_name);
118
119 DBG("Serializing stop session action: session-name: %s",
120 action_stop_session->session_name);
121
122 session_name_len = strlen(action_stop_session->session_name) + 1;
123 comm.session_name_len = session_name_len;
124
125 ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
126 if (ret) {
127 ret = -1;
128 goto end;
129 }
130
131 ret = lttng_dynamic_buffer_append(buf,
132 action_stop_session->session_name, session_name_len);
133 if (ret) {
134 ret = -1;
135 goto end;
136 }
137
138 ret = 0;
139 end:
140 return ret;
141 }
142
143 static void lttng_action_stop_session_destroy(struct lttng_action *action)
144 {
145 struct lttng_action_stop_session *action_stop_session;
146
147 if (!action) {
148 goto end;
149 }
150
151 action_stop_session = action_stop_session_from_action(action);
152
153 free(action_stop_session->session_name);
154 free(action_stop_session);
155
156 end:
157 return;
158 }
159
160 ssize_t lttng_action_stop_session_create_from_buffer(
161 const struct lttng_buffer_view *view,
162 struct lttng_action **p_action)
163 {
164 ssize_t consumed_len;
165 struct lttng_action_stop_session_comm *comm;
166 const char *session_name;
167 struct lttng_action *action;
168 enum lttng_action_status status;
169
170 action = lttng_action_stop_session_create();
171 if (!action) {
172 consumed_len = -1;
173 goto end;
174 }
175
176 comm = (struct lttng_action_stop_session_comm *) view->data;
177 session_name = (const char *) &comm->data;
178
179 if (!lttng_buffer_view_validate_string(
180 view, session_name, comm->session_name_len)) {
181 consumed_len = -1;
182 goto end;
183 }
184
185 status = lttng_action_stop_session_set_session_name(
186 action, session_name);
187 if (status != LTTNG_ACTION_STATUS_OK) {
188 consumed_len = -1;
189 goto end;
190 }
191
192 consumed_len = sizeof(struct lttng_action_stop_session_comm) +
193 comm->session_name_len;
194 *p_action = action;
195 action = NULL;
196
197 end:
198 lttng_action_stop_session_destroy(action);
199
200 return consumed_len;
201 }
202
203 struct lttng_action *lttng_action_stop_session_create(void)
204 {
205 struct lttng_action *action;
206
207 action = zmalloc(sizeof(struct lttng_action_stop_session));
208 if (!action) {
209 goto end;
210 }
211
212 lttng_action_init(action, LTTNG_ACTION_TYPE_STOP_SESSION,
213 lttng_action_stop_session_validate,
214 lttng_action_stop_session_serialize,
215 lttng_action_stop_session_is_equal,
216 lttng_action_stop_session_destroy);
217
218 end:
219 return action;
220 }
221
222 enum lttng_action_status lttng_action_stop_session_set_session_name(
223 struct lttng_action *action, const char *session_name)
224 {
225 struct lttng_action_stop_session *action_stop_session;
226 enum lttng_action_status status;
227
228 if (!action || !session_name || strlen(session_name) == 0) {
229 status = LTTNG_ACTION_STATUS_INVALID;
230 goto end;
231 }
232
233 action_stop_session = action_stop_session_from_action(action);
234
235 free(action_stop_session->session_name);
236
237 action_stop_session->session_name = strdup(session_name);
238 if (!action_stop_session->session_name) {
239 status = LTTNG_ACTION_STATUS_ERROR;
240 goto end;
241 }
242
243 status = LTTNG_ACTION_STATUS_OK;
244 end:
245 return status;
246 }
247
248 enum lttng_action_status lttng_action_stop_session_get_session_name(
249 const struct lttng_action *action, const char **session_name)
250 {
251 const struct lttng_action_stop_session *action_stop_session;
252 enum lttng_action_status status;
253
254 if (!action || !session_name) {
255 status = LTTNG_ACTION_STATUS_INVALID;
256 goto end;
257 }
258
259 action_stop_session = action_stop_session_from_action_const(action);
260
261 *session_name = action_stop_session->session_name;
262
263 status = LTTNG_ACTION_STATUS_OK;
264 end:
265 return status;
266 }
This page took 0.03468 seconds and 5 git commands to generate.