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