lib: compile liblttng-ctl as C++
[lttng-tools.git] / src / lib / lttng-ctl / snapshot.cpp
CommitLineData
da3c9ec1 1/*
ab5be9fa 2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
da3c9ec1 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
da3c9ec1 5 *
da3c9ec1
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
da3c9ec1
DG
9#include <string.h>
10
11#include <common/sessiond-comm/sessiond-comm.h>
12#include <lttng/lttng-error.h>
13#include <lttng/snapshot.h>
14#include <lttng/snapshot-internal.h>
15
16#include "lttng-ctl-helper.h"
17
18/*
19 * Add an output object to a session identified by name.
20 *
21 * Return 0 on success or else a negative LTTNG_ERR code.
22 */
23int lttng_snapshot_add_output(const char *session_name,
24 struct lttng_snapshot_output *output)
25{
26 int ret;
27 struct lttcomm_session_msg lsm;
28 struct lttcomm_lttng_output_id *reply;
29
30 if (!session_name || !output) {
e1b624d0
JG
31 ret = -LTTNG_ERR_INVALID;
32 goto end;
da3c9ec1
DG
33 }
34
35 memset(&lsm, 0, sizeof(lsm));
36 lsm.cmd_type = LTTNG_SNAPSHOT_ADD_OUTPUT;
37
e1b624d0 38 ret = lttng_strncpy(lsm.session.name, session_name,
da3c9ec1 39 sizeof(lsm.session.name));
e1b624d0
JG
40 if (ret) {
41 ret = -LTTNG_ERR_INVALID;
42 goto end;
43 }
44
da3c9ec1
DG
45 memcpy(&lsm.u.snapshot_output.output, output,
46 sizeof(lsm.u.snapshot_output.output));
47
48 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &reply);
49 if (ret < 0) {
e1b624d0 50 goto end;
da3c9ec1
DG
51 }
52
53 output->id = reply->id;
54 free(reply);
e1b624d0
JG
55 ret = 0;
56end:
57 return ret;
da3c9ec1
DG
58}
59
60/*
61 * Delete an output object to a session identified by name.
62 *
63 * Return 0 on success or else a negative LTTNG_ERR code.
64 */
65int lttng_snapshot_del_output(const char *session_name,
66 struct lttng_snapshot_output *output)
67{
e1b624d0 68 int ret;
da3c9ec1
DG
69 struct lttcomm_session_msg lsm;
70
71 if (!session_name || !output) {
e1b624d0
JG
72 ret = -LTTNG_ERR_INVALID;
73 goto end;
da3c9ec1
DG
74 }
75
76 memset(&lsm, 0, sizeof(lsm));
77 lsm.cmd_type = LTTNG_SNAPSHOT_DEL_OUTPUT;
78
e1b624d0
JG
79 ret = lttng_strncpy(lsm.session.name, session_name,
80 sizeof(lsm.session.name));
81 if (ret) {
82 ret = -LTTNG_ERR_INVALID;
83 goto end;
84 }
85
da3c9ec1
DG
86 memcpy(&lsm.u.snapshot_output.output, output,
87 sizeof(lsm.u.snapshot_output.output));
88
e1b624d0
JG
89 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
90end:
91 return ret;
da3c9ec1
DG
92}
93
94/*
95 * List all snapshot output(s) of a session identified by name. The output list
96 * object is populated and can be iterated over with the get_next call below.
97 *
98 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
99 * is untouched.
100 */
101int lttng_snapshot_list_output(const char *session_name,
102 struct lttng_snapshot_output_list **list)
103{
104 int ret;
105 struct lttcomm_session_msg lsm;
106 struct lttng_snapshot_output_list *new_list = NULL;
107
108 if (!session_name || !list) {
109 ret = -LTTNG_ERR_INVALID;
110 goto error;
111 }
112
113 memset(&lsm, 0, sizeof(lsm));
114 lsm.cmd_type = LTTNG_SNAPSHOT_LIST_OUTPUT;
115
e1b624d0
JG
116 ret = lttng_strncpy(lsm.session.name, session_name,
117 sizeof(lsm.session.name));
118 if (ret) {
119 ret = -LTTNG_ERR_INVALID;
120 goto error;
121 }
da3c9ec1 122
4bd69c5f 123 new_list = (lttng_snapshot_output_list *) zmalloc(sizeof(*new_list));
da3c9ec1
DG
124 if (!new_list) {
125 ret = -LTTNG_ERR_NOMEM;
126 goto error;
127 }
128
129 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &new_list->array);
130 if (ret < 0) {
131 goto free_error;
132 }
133
134 new_list->count = ret / sizeof(struct lttng_snapshot_output);
135 *list = new_list;
136 return 0;
137
138free_error:
139 free(new_list);
140error:
141 return ret;
142}
143
144/*
145 * Return the next available snapshot output object in the given list. A list
146 * output command MUST have been done before.
147 *
148 * Return the next object on success or else NULL indicating the end of the
149 * list.
150 */
151struct lttng_snapshot_output *lttng_snapshot_output_list_get_next(
152 struct lttng_snapshot_output_list *list)
153{
154 struct lttng_snapshot_output *output = NULL;
155
156 if (!list) {
157 goto error;
158 }
159
160 /* We've reached the end. */
161 if (list->index == list->count) {
162 goto end;
163 }
164
165 output = &list->array[list->index];
166 list->index++;
167
168end:
169error:
170 return output;
171}
172
173/*
174 * Free an output list object.
175 */
176void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list *list)
177{
178 if (!list) {
179 return;
180 }
181
182 free(list->array);
183 free(list);
184}
185
186/*
187 * Snapshot a trace for the given session.
188 *
189 * The output object can be NULL but an add output MUST be done prior to this
190 * call. If it's not NULL, it will be used to snapshot a trace.
191 *
192 * The wait parameter is ignored for now. The snapshot record command will
193 * ALWAYS wait for the snapshot to complete before returning meaning the
194 * snapshot has been written on disk or streamed over the network to a relayd.
195 *
196 * Return 0 on success or else a negative LTTNG_ERR value.
197 */
198int lttng_snapshot_record(const char *session_name,
199 struct lttng_snapshot_output *output, int wait)
200{
e1b624d0 201 int ret;
da3c9ec1
DG
202 struct lttcomm_session_msg lsm;
203
204 if (!session_name) {
e1b624d0
JG
205 ret = -LTTNG_ERR_INVALID;
206 goto end;
da3c9ec1
DG
207 }
208
209 memset(&lsm, 0, sizeof(lsm));
210 lsm.cmd_type = LTTNG_SNAPSHOT_RECORD;
211
e1b624d0 212 ret = lttng_strncpy(lsm.session.name, session_name,
da3c9ec1 213 sizeof(lsm.session.name));
e1b624d0
JG
214 if (ret) {
215 ret = -LTTNG_ERR_INVALID;
216 goto end;
217 }
da3c9ec1
DG
218
219 /*
220 * Not having an output object will use the default one of the session that
221 * would need to be set by a call to add output prior to calling snapshot
222 * record.
223 */
224 if (output) {
225 memcpy(&lsm.u.snapshot_record.output, output,
226 sizeof(lsm.u.snapshot_record.output));
227 }
228
229 /* The wait param is ignored. */
e1b624d0
JG
230 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
231end:
232 return ret;
da3c9ec1
DG
233}
234
235/*
236 * Return an newly allocated snapshot output object or NULL on error.
237 */
238struct lttng_snapshot_output *lttng_snapshot_output_create(void)
239{
e1986656
DG
240 struct lttng_snapshot_output *output;
241
4bd69c5f 242 output = (lttng_snapshot_output *) zmalloc(sizeof(struct lttng_snapshot_output));
e1986656
DG
243 if (!output) {
244 goto error;
245 }
246
247 output->max_size = (uint64_t) -1ULL;
248
249error:
250 return output;
da3c9ec1
DG
251}
252
253/*
254 * Free a given snapshot output object.
255 */
256void lttng_snapshot_output_destroy(struct lttng_snapshot_output *obj)
257{
258 if (obj) {
259 free(obj);
260 }
261}
262
263/*
264 * Getter family functions of snapshot output.
265 */
266
0de2479d 267uint32_t lttng_snapshot_output_get_id(const struct lttng_snapshot_output *output)
da3c9ec1
DG
268{
269 return output->id;
270}
271
272const char *lttng_snapshot_output_get_name(
0de2479d 273 const struct lttng_snapshot_output *output)
da3c9ec1
DG
274{
275 return output->name;
276}
277
0de2479d 278const char *lttng_snapshot_output_get_data_url(const struct lttng_snapshot_output *output)
da3c9ec1
DG
279{
280 return output->data_url;
281}
282
0de2479d 283const char *lttng_snapshot_output_get_ctrl_url(const struct lttng_snapshot_output *output)
da3c9ec1
DG
284{
285 return output->ctrl_url;
286}
287
288uint64_t lttng_snapshot_output_get_maxsize(
0de2479d 289 const struct lttng_snapshot_output *output)
da3c9ec1
DG
290{
291 return output->max_size;
292}
293
294/*
295 * Setter family functions for snapshot output.
296 */
297
298int lttng_snapshot_output_set_id(uint32_t id,
299 struct lttng_snapshot_output *output)
300{
301 if (!output || id == 0) {
302 return -LTTNG_ERR_INVALID;
303 }
304
305 output->id = id;
306 return 0;
307}
308
309int lttng_snapshot_output_set_size(uint64_t size,
310 struct lttng_snapshot_output *output)
311{
312 if (!output) {
313 return -LTTNG_ERR_INVALID;
314 }
315
316 output->max_size = size;
317 return 0;
318}
319
320int lttng_snapshot_output_set_name(const char *name,
321 struct lttng_snapshot_output *output)
322{
e1b624d0
JG
323 int ret;
324
da3c9ec1 325 if (!output || !name) {
e1b624d0
JG
326 ret = -LTTNG_ERR_INVALID;
327 goto end;
da3c9ec1
DG
328 }
329
e1b624d0
JG
330 ret = lttng_strncpy(output->name, name, sizeof(output->name));
331 if (ret) {
332 ret = -LTTNG_ERR_INVALID;
333 goto end;
334 }
335
336end:
337 return ret;
da3c9ec1
DG
338}
339
340int lttng_snapshot_output_set_ctrl_url(const char *url,
341 struct lttng_snapshot_output *output)
342{
e1b624d0
JG
343 int ret;
344
da3c9ec1 345 if (!output || !url) {
e1b624d0
JG
346 ret = -LTTNG_ERR_INVALID;
347 goto end;
da3c9ec1
DG
348 }
349
e1b624d0
JG
350 ret = lttng_strncpy(output->ctrl_url, url, sizeof(output->ctrl_url));
351 if (ret) {
352 ret = -LTTNG_ERR_INVALID;
353 goto end;
354 }
355
356end:
357 return ret;
da3c9ec1
DG
358}
359
360int lttng_snapshot_output_set_data_url(const char *url,
361 struct lttng_snapshot_output *output)
362{
e1b624d0
JG
363 int ret;
364
da3c9ec1 365 if (!output || !url) {
e1b624d0
JG
366 ret = -LTTNG_ERR_INVALID;
367 goto end;
da3c9ec1
DG
368 }
369
e1b624d0
JG
370 ret = lttng_strncpy(output->data_url, url, sizeof(output->data_url));
371 if (ret) {
372 ret = -LTTNG_ERR_INVALID;
373 goto end;
374 }
375
376end:
377 return ret;
da3c9ec1 378}
b30fa191
JR
379
380int lttng_snapshot_output_set_local_path(const char *path,
381 struct lttng_snapshot_output *output)
382{
383 int ret;
384 struct lttng_uri *uris = NULL;
385 ssize_t num_uris;
386
387 if (!path || !output) {
388 ret = -LTTNG_ERR_INVALID;
389 goto end;
390 }
391
392 num_uris = uri_parse_str_urls(path, NULL, &uris);
393 if (num_uris != 1) {
394 ret = -LTTNG_ERR_INVALID;
395 goto end;
396 }
397
398 if (uris[0].dtype != LTTNG_DST_PATH) {
399 ret = -LTTNG_ERR_INVALID;
400 goto end;
401 }
402
403 ret = lttng_strncpy(output->ctrl_url, path, sizeof(output->ctrl_url));
404 if (ret != 0) {
405 ret = -LTTNG_ERR_INVALID;
406 goto end;
407 }
408
409end:
410 free(uris);
411 return ret;
412}
413
414int lttng_snapshot_output_set_network_url(const char *url,
415 struct lttng_snapshot_output *output)
416{
417 int ret;
418 struct lttng_uri *uris = NULL;
419 ssize_t num_uris;
420
421 if (!url || !output) {
422 ret = -LTTNG_ERR_INVALID;
423 goto end;
424 }
425
426 num_uris = uri_parse_str_urls(url, NULL, &uris);
427 if (num_uris != 2) {
428 ret = -LTTNG_ERR_INVALID;
429 goto end;
430 }
431
432 if (uris[0].dtype != LTTNG_DST_IPV4 &&
433 uris[0].dtype != LTTNG_DST_IPV6) {
434 ret = -LTTNG_ERR_INVALID;
435 goto end;
436 }
437
438 if (uris[1].dtype != LTTNG_DST_IPV4 &&
439 uris[1].dtype != LTTNG_DST_IPV6) {
440 ret = -LTTNG_ERR_INVALID;
441 goto end;
442 }
443
444 ret = lttng_strncpy(output->ctrl_url, url, sizeof(output->ctrl_url));
445 if (ret != 0) {
446 ret = -LTTNG_ERR_INVALID;
447 goto end;
448 }
449
450end:
451 free(uris);
452 return ret;
453}
454
455int lttng_snapshot_output_set_network_urls(
456 const char *ctrl_url, const char *data_url,
457 struct lttng_snapshot_output *output)
458{
459 int ret;
460 struct lttng_uri *uris = NULL;
461 ssize_t num_uris;
462
463 if (!ctrl_url || !data_url || !output) {
464 ret = -LTTNG_ERR_INVALID;
465 goto end;
466 }
467
468 num_uris = uri_parse_str_urls(ctrl_url, data_url, &uris);
469 if (num_uris != 2) {
470 ret = -LTTNG_ERR_INVALID;
471 goto end;
472 }
473
474 if (uris[0].dtype != LTTNG_DST_IPV4 &&
475 uris[0].dtype != LTTNG_DST_IPV6) {
476 ret = -LTTNG_ERR_INVALID;
477 goto end;
478 }
479
480 if (uris[1].dtype != LTTNG_DST_IPV4 &&
481 uris[1].dtype != LTTNG_DST_IPV6) {
482 ret = -LTTNG_ERR_INVALID;
483 goto end;
484 }
485
486 ret = lttng_strncpy(output->ctrl_url, ctrl_url, sizeof(output->ctrl_url));
487 if (ret != 0) {
488 ret = -LTTNG_ERR_INVALID;
489 goto end;
490 }
491
492 ret = lttng_strncpy(output->data_url, data_url, sizeof(output->data_url));
493 if (ret != 0) {
494 ret = -LTTNG_ERR_INVALID;
495 goto end;
496 }
497
498end:
499 free(uris);
500 return ret;
501}
This page took 0.064413 seconds and 4 git commands to generate.