2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
17 #include "lttng-ctl-helper.h"
20 * Add an output object to a session identified by name.
22 * Return 0 on success or else a negative LTTNG_ERR code.
24 int lttng_snapshot_add_output(const char *session_name
,
25 struct lttng_snapshot_output
*output
)
28 struct lttcomm_session_msg lsm
;
29 struct lttcomm_lttng_output_id
*reply
;
31 if (!session_name
|| !output
) {
32 ret
= -LTTNG_ERR_INVALID
;
36 memset(&lsm
, 0, sizeof(lsm
));
37 lsm
.cmd_type
= LTTNG_SNAPSHOT_ADD_OUTPUT
;
39 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
40 sizeof(lsm
.session
.name
));
42 ret
= -LTTNG_ERR_INVALID
;
46 memcpy(&lsm
.u
.snapshot_output
.output
, output
,
47 sizeof(lsm
.u
.snapshot_output
.output
));
49 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &reply
);
54 output
->id
= reply
->id
;
62 * Delete an output object to a session identified by name.
64 * Return 0 on success or else a negative LTTNG_ERR code.
66 int lttng_snapshot_del_output(const char *session_name
,
67 struct lttng_snapshot_output
*output
)
70 struct lttcomm_session_msg lsm
;
72 if (!session_name
|| !output
) {
73 ret
= -LTTNG_ERR_INVALID
;
77 memset(&lsm
, 0, sizeof(lsm
));
78 lsm
.cmd_type
= LTTNG_SNAPSHOT_DEL_OUTPUT
;
80 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
81 sizeof(lsm
.session
.name
));
83 ret
= -LTTNG_ERR_INVALID
;
87 memcpy(&lsm
.u
.snapshot_output
.output
, output
,
88 sizeof(lsm
.u
.snapshot_output
.output
));
90 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
96 * List all snapshot output(s) of a session identified by name. The output list
97 * object is populated and can be iterated over with the get_next call below.
99 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
102 int lttng_snapshot_list_output(const char *session_name
,
103 struct lttng_snapshot_output_list
**list
)
106 struct lttcomm_session_msg lsm
;
107 struct lttng_snapshot_output_list
*new_list
= NULL
;
109 if (!session_name
|| !list
) {
110 ret
= -LTTNG_ERR_INVALID
;
114 memset(&lsm
, 0, sizeof(lsm
));
115 lsm
.cmd_type
= LTTNG_SNAPSHOT_LIST_OUTPUT
;
117 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
118 sizeof(lsm
.session
.name
));
120 ret
= -LTTNG_ERR_INVALID
;
124 new_list
= zmalloc(sizeof(*new_list
));
126 ret
= -LTTNG_ERR_NOMEM
;
130 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &new_list
->array
);
135 new_list
->count
= ret
/ sizeof(struct lttng_snapshot_output
);
146 * Return the next available snapshot output object in the given list. A list
147 * output command MUST have been done before.
149 * Return the next object on success or else NULL indicating the end of the
152 struct lttng_snapshot_output
*lttng_snapshot_output_list_get_next(
153 struct lttng_snapshot_output_list
*list
)
155 struct lttng_snapshot_output
*output
= NULL
;
161 /* We've reached the end. */
162 if (list
->index
== list
->count
) {
166 output
= &list
->array
[list
->index
];
175 * Free an output list object.
177 void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list
*list
)
188 * Snapshot a trace for the given session.
190 * The output object can be NULL but an add output MUST be done prior to this
191 * call. If it's not NULL, it will be used to snapshot a trace.
193 * The wait parameter is ignored for now. The snapshot record command will
194 * ALWAYS wait for the snapshot to complete before returning meaning the
195 * snapshot has been written on disk or streamed over the network to a relayd.
197 * Return 0 on success or else a negative LTTNG_ERR value.
199 int lttng_snapshot_record(const char *session_name
,
200 struct lttng_snapshot_output
*output
, int wait
)
203 struct lttcomm_session_msg lsm
;
206 ret
= -LTTNG_ERR_INVALID
;
210 memset(&lsm
, 0, sizeof(lsm
));
211 lsm
.cmd_type
= LTTNG_SNAPSHOT_RECORD
;
213 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
214 sizeof(lsm
.session
.name
));
216 ret
= -LTTNG_ERR_INVALID
;
221 * Not having an output object will use the default one of the session that
222 * would need to be set by a call to add output prior to calling snapshot
226 memcpy(&lsm
.u
.snapshot_record
.output
, output
,
227 sizeof(lsm
.u
.snapshot_record
.output
));
230 /* The wait param is ignored. */
231 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
237 * Return an newly allocated snapshot output object or NULL on error.
239 struct lttng_snapshot_output
*lttng_snapshot_output_create(void)
241 struct lttng_snapshot_output
*output
;
243 output
= zmalloc(sizeof(struct lttng_snapshot_output
));
248 output
->max_size
= (uint64_t) -1ULL;
255 * Free a given snapshot output object.
257 void lttng_snapshot_output_destroy(struct lttng_snapshot_output
*obj
)
265 * Getter family functions of snapshot output.
268 uint32_t lttng_snapshot_output_get_id(const struct lttng_snapshot_output
*output
)
273 const char *lttng_snapshot_output_get_name(
274 const struct lttng_snapshot_output
*output
)
279 const char *lttng_snapshot_output_get_data_url(const struct lttng_snapshot_output
*output
)
281 return output
->data_url
;
284 const char *lttng_snapshot_output_get_ctrl_url(const struct lttng_snapshot_output
*output
)
286 return output
->ctrl_url
;
289 uint64_t lttng_snapshot_output_get_maxsize(
290 const struct lttng_snapshot_output
*output
)
292 return output
->max_size
;
296 * Setter family functions for snapshot output.
299 int lttng_snapshot_output_set_id(uint32_t id
,
300 struct lttng_snapshot_output
*output
)
302 if (!output
|| id
== 0) {
303 return -LTTNG_ERR_INVALID
;
310 int lttng_snapshot_output_set_size(uint64_t size
,
311 struct lttng_snapshot_output
*output
)
314 return -LTTNG_ERR_INVALID
;
317 output
->max_size
= size
;
321 int lttng_snapshot_output_set_name(const char *name
,
322 struct lttng_snapshot_output
*output
)
326 if (!output
|| !name
) {
327 ret
= -LTTNG_ERR_INVALID
;
331 ret
= lttng_strncpy(output
->name
, name
, sizeof(output
->name
));
333 ret
= -LTTNG_ERR_INVALID
;
341 int lttng_snapshot_output_set_ctrl_url(const char *url
,
342 struct lttng_snapshot_output
*output
)
346 if (!output
|| !url
) {
347 ret
= -LTTNG_ERR_INVALID
;
351 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
353 ret
= -LTTNG_ERR_INVALID
;
361 int lttng_snapshot_output_set_data_url(const char *url
,
362 struct lttng_snapshot_output
*output
)
366 if (!output
|| !url
) {
367 ret
= -LTTNG_ERR_INVALID
;
371 ret
= lttng_strncpy(output
->data_url
, url
, sizeof(output
->data_url
));
373 ret
= -LTTNG_ERR_INVALID
;
381 int lttng_snapshot_output_set_local_path(const char *path
,
382 struct lttng_snapshot_output
*output
)
385 struct lttng_uri
*uris
= NULL
;
388 if (!path
|| !output
) {
389 ret
= -LTTNG_ERR_INVALID
;
393 num_uris
= uri_parse_str_urls(path
, NULL
, &uris
);
395 ret
= -LTTNG_ERR_INVALID
;
399 if (uris
[0].dtype
!= LTTNG_DST_PATH
) {
400 ret
= -LTTNG_ERR_INVALID
;
404 ret
= lttng_strncpy(output
->ctrl_url
, path
, sizeof(output
->ctrl_url
));
406 ret
= -LTTNG_ERR_INVALID
;
415 int lttng_snapshot_output_set_network_url(const char *url
,
416 struct lttng_snapshot_output
*output
)
419 struct lttng_uri
*uris
= NULL
;
422 if (!url
|| !output
) {
423 ret
= -LTTNG_ERR_INVALID
;
427 num_uris
= uri_parse_str_urls(url
, NULL
, &uris
);
429 ret
= -LTTNG_ERR_INVALID
;
433 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&&
434 uris
[0].dtype
!= LTTNG_DST_IPV6
) {
435 ret
= -LTTNG_ERR_INVALID
;
439 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&&
440 uris
[1].dtype
!= LTTNG_DST_IPV6
) {
441 ret
= -LTTNG_ERR_INVALID
;
445 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
447 ret
= -LTTNG_ERR_INVALID
;
456 int lttng_snapshot_output_set_network_urls(
457 const char *ctrl_url
, const char *data_url
,
458 struct lttng_snapshot_output
*output
)
461 struct lttng_uri
*uris
= NULL
;
464 if (!ctrl_url
|| !data_url
|| !output
) {
465 ret
= -LTTNG_ERR_INVALID
;
469 num_uris
= uri_parse_str_urls(ctrl_url
, data_url
, &uris
);
471 ret
= -LTTNG_ERR_INVALID
;
475 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&&
476 uris
[0].dtype
!= LTTNG_DST_IPV6
) {
477 ret
= -LTTNG_ERR_INVALID
;
481 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&&
482 uris
[1].dtype
!= LTTNG_DST_IPV6
) {
483 ret
= -LTTNG_ERR_INVALID
;
487 ret
= lttng_strncpy(output
->ctrl_url
, ctrl_url
, sizeof(output
->ctrl_url
));
489 ret
= -LTTNG_ERR_INVALID
;
493 ret
= lttng_strncpy(output
->data_url
, data_url
, sizeof(output
->data_url
));
495 ret
= -LTTNG_ERR_INVALID
;