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