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