Fix: Possible dereference of null pointers
[lttng-tools.git] / src / lib / lttng-ctl / snapshot.c
1 /*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
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 #define _GNU_SOURCE
19 #define _LGPL_SOURCE
20 #include <assert.h>
21 #include <string.h>
22
23 #include <common/sessiond-comm/sessiond-comm.h>
24 #include <lttng/lttng-error.h>
25 #include <lttng/snapshot.h>
26 #include <lttng/snapshot-internal.h>
27
28 #include "lttng-ctl-helper.h"
29
30 /*
31 * Add an output object to a session identified by name.
32 *
33 * Return 0 on success or else a negative LTTNG_ERR code.
34 */
35 int lttng_snapshot_add_output(const char *session_name,
36 struct lttng_snapshot_output *output)
37 {
38 int ret;
39 struct lttcomm_session_msg lsm;
40 struct lttcomm_lttng_output_id *reply;
41
42 if (!session_name || !output) {
43 return -LTTNG_ERR_INVALID;
44 }
45
46 memset(&lsm, 0, sizeof(lsm));
47 lsm.cmd_type = LTTNG_SNAPSHOT_ADD_OUTPUT;
48
49 lttng_ctl_copy_string(lsm.session.name, session_name,
50 sizeof(lsm.session.name));
51 memcpy(&lsm.u.snapshot_output.output, output,
52 sizeof(lsm.u.snapshot_output.output));
53
54 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &reply);
55 if (ret < 0) {
56 return ret;
57 }
58
59 output->id = reply->id;
60 free(reply);
61
62 return 0;
63 }
64
65 /*
66 * Delete an output object to a session identified by name.
67 *
68 * Return 0 on success or else a negative LTTNG_ERR code.
69 */
70 int lttng_snapshot_del_output(const char *session_name,
71 struct lttng_snapshot_output *output)
72 {
73 struct lttcomm_session_msg lsm;
74
75 if (!session_name || !output) {
76 return -LTTNG_ERR_INVALID;
77 }
78
79 memset(&lsm, 0, sizeof(lsm));
80 lsm.cmd_type = LTTNG_SNAPSHOT_DEL_OUTPUT;
81
82 lttng_ctl_copy_string(lsm.session.name, session_name,
83 sizeof(lsm.session.name));
84 memcpy(&lsm.u.snapshot_output.output, output,
85 sizeof(lsm.u.snapshot_output.output));
86
87 return lttng_ctl_ask_sessiond(&lsm, NULL);
88 }
89
90 /*
91 * List all snapshot output(s) of a session identified by name. The output list
92 * object is populated and can be iterated over with the get_next call below.
93 *
94 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
95 * is untouched.
96 */
97 int lttng_snapshot_list_output(const char *session_name,
98 struct lttng_snapshot_output_list **list)
99 {
100 int ret;
101 struct lttcomm_session_msg lsm;
102 struct lttng_snapshot_output_list *new_list = NULL;
103
104 if (!session_name || !list) {
105 ret = -LTTNG_ERR_INVALID;
106 goto error;
107 }
108
109 memset(&lsm, 0, sizeof(lsm));
110 lsm.cmd_type = LTTNG_SNAPSHOT_LIST_OUTPUT;
111
112 lttng_ctl_copy_string(lsm.session.name, session_name,
113 sizeof(lsm.session.name));
114
115 new_list = zmalloc(sizeof(*new_list));
116 if (!new_list) {
117 ret = -LTTNG_ERR_NOMEM;
118 goto error;
119 }
120
121 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &new_list->array);
122 if (ret < 0) {
123 goto free_error;
124 }
125
126 new_list->count = ret / sizeof(struct lttng_snapshot_output);
127 *list = new_list;
128 return 0;
129
130 free_error:
131 free(new_list);
132 error:
133 return ret;
134 }
135
136 /*
137 * Return the next available snapshot output object in the given list. A list
138 * output command MUST have been done before.
139 *
140 * Return the next object on success or else NULL indicating the end of the
141 * list.
142 */
143 struct lttng_snapshot_output *lttng_snapshot_output_list_get_next(
144 struct lttng_snapshot_output_list *list)
145 {
146 struct lttng_snapshot_output *output = NULL;
147
148 if (!list) {
149 goto error;
150 }
151
152 /* We've reached the end. */
153 if (list->index == list->count) {
154 goto end;
155 }
156
157 output = &list->array[list->index];
158 list->index++;
159
160 end:
161 error:
162 return output;
163 }
164
165 /*
166 * Free an output list object.
167 */
168 void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list *list)
169 {
170 if (!list) {
171 return;
172 }
173
174 free(list->array);
175 free(list);
176 }
177
178 /*
179 * Snapshot a trace for the given session.
180 *
181 * The output object can be NULL but an add output MUST be done prior to this
182 * call. If it's not NULL, it will be used to snapshot a trace.
183 *
184 * The wait parameter is ignored for now. The snapshot record command will
185 * ALWAYS wait for the snapshot to complete before returning meaning the
186 * snapshot has been written on disk or streamed over the network to a relayd.
187 *
188 * Return 0 on success or else a negative LTTNG_ERR value.
189 */
190 int lttng_snapshot_record(const char *session_name,
191 struct lttng_snapshot_output *output, int wait)
192 {
193 struct lttcomm_session_msg lsm;
194
195 if (!session_name) {
196 return -LTTNG_ERR_INVALID;
197 }
198
199 memset(&lsm, 0, sizeof(lsm));
200 lsm.cmd_type = LTTNG_SNAPSHOT_RECORD;
201
202 lttng_ctl_copy_string(lsm.session.name, session_name,
203 sizeof(lsm.session.name));
204
205 /*
206 * Not having an output object will use the default one of the session that
207 * would need to be set by a call to add output prior to calling snapshot
208 * record.
209 */
210 if (output) {
211 memcpy(&lsm.u.snapshot_record.output, output,
212 sizeof(lsm.u.snapshot_record.output));
213 }
214
215 /* The wait param is ignored. */
216
217 return lttng_ctl_ask_sessiond(&lsm, NULL);
218 }
219
220 /*
221 * Return an newly allocated snapshot output object or NULL on error.
222 */
223 struct lttng_snapshot_output *lttng_snapshot_output_create(void)
224 {
225 struct lttng_snapshot_output *output;
226
227 output = zmalloc(sizeof(struct lttng_snapshot_output));
228 if (!output) {
229 goto error;
230 }
231
232 output->max_size = (uint64_t) -1ULL;
233
234 error:
235 return output;
236 }
237
238 /*
239 * Free a given snapshot output object.
240 */
241 void lttng_snapshot_output_destroy(struct lttng_snapshot_output *obj)
242 {
243 if (obj) {
244 free(obj);
245 }
246 }
247
248 /*
249 * Getter family functions of snapshot output.
250 */
251
252 uint32_t lttng_snapshot_output_get_id(struct lttng_snapshot_output *output)
253 {
254 return output->id;
255 }
256
257 const char *lttng_snapshot_output_get_name(
258 struct lttng_snapshot_output *output)
259 {
260 return output->name;
261 }
262
263 const char *lttng_snapshot_output_get_data_url(struct lttng_snapshot_output *output)
264 {
265 return output->data_url;
266 }
267
268 const char *lttng_snapshot_output_get_ctrl_url(struct lttng_snapshot_output *output)
269 {
270 return output->ctrl_url;
271 }
272
273 uint64_t lttng_snapshot_output_get_maxsize(
274 struct lttng_snapshot_output *output)
275 {
276 return output->max_size;
277 }
278
279 /*
280 * Setter family functions for snapshot output.
281 */
282
283 int lttng_snapshot_output_set_id(uint32_t id,
284 struct lttng_snapshot_output *output)
285 {
286 if (!output || id == 0) {
287 return -LTTNG_ERR_INVALID;
288 }
289
290 output->id = id;
291 return 0;
292 }
293
294 int lttng_snapshot_output_set_size(uint64_t size,
295 struct lttng_snapshot_output *output)
296 {
297 if (!output) {
298 return -LTTNG_ERR_INVALID;
299 }
300
301 output->max_size = size;
302 return 0;
303 }
304
305 int lttng_snapshot_output_set_name(const char *name,
306 struct lttng_snapshot_output *output)
307 {
308 if (!output || !name) {
309 return -LTTNG_ERR_INVALID;
310 }
311
312 lttng_ctl_copy_string(output->name, name, sizeof(output->name));
313 return 0;
314 }
315
316 int lttng_snapshot_output_set_ctrl_url(const char *url,
317 struct lttng_snapshot_output *output)
318 {
319 if (!output || !url) {
320 return -LTTNG_ERR_INVALID;
321 }
322
323 lttng_ctl_copy_string(output->ctrl_url, url, sizeof(output->ctrl_url));
324 return 0;
325 }
326
327 int lttng_snapshot_output_set_data_url(const char *url,
328 struct lttng_snapshot_output *output)
329 {
330 if (!output || !url) {
331 return -LTTNG_ERR_INVALID;
332 }
333
334 lttng_ctl_copy_string(output->data_url, url, sizeof(output->data_url));
335 return 0;
336 }
This page took 0.034975 seconds and 4 git commands to generate.