2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
16 #include "lttng-ctl-helper.h"
19 * Add an output object to a session identified by name.
21 * Return 0 on success or else a negative LTTNG_ERR code.
23 int lttng_snapshot_add_output(const char *session_name
,
24 struct lttng_snapshot_output
*output
)
27 struct lttcomm_session_msg lsm
;
28 struct lttcomm_lttng_output_id
*reply
;
30 if (!session_name
|| !output
) {
31 ret
= -LTTNG_ERR_INVALID
;
35 memset(&lsm
, 0, sizeof(lsm
));
36 lsm
.cmd_type
= LTTNG_SNAPSHOT_ADD_OUTPUT
;
38 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
39 sizeof(lsm
.session
.name
));
41 ret
= -LTTNG_ERR_INVALID
;
45 memcpy(&lsm
.u
.snapshot_output
.output
, output
,
46 sizeof(lsm
.u
.snapshot_output
.output
));
48 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &reply
);
53 output
->id
= reply
->id
;
61 * Delete an output object to a session identified by name.
63 * Return 0 on success or else a negative LTTNG_ERR code.
65 int lttng_snapshot_del_output(const char *session_name
,
66 struct lttng_snapshot_output
*output
)
69 struct lttcomm_session_msg lsm
;
71 if (!session_name
|| !output
) {
72 ret
= -LTTNG_ERR_INVALID
;
76 memset(&lsm
, 0, sizeof(lsm
));
77 lsm
.cmd_type
= LTTNG_SNAPSHOT_DEL_OUTPUT
;
79 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
80 sizeof(lsm
.session
.name
));
82 ret
= -LTTNG_ERR_INVALID
;
86 memcpy(&lsm
.u
.snapshot_output
.output
, output
,
87 sizeof(lsm
.u
.snapshot_output
.output
));
89 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
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.
98 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
101 int lttng_snapshot_list_output(const char *session_name
,
102 struct lttng_snapshot_output_list
**list
)
105 struct lttcomm_session_msg lsm
;
106 struct lttng_snapshot_output_list
*new_list
= NULL
;
108 if (!session_name
|| !list
) {
109 ret
= -LTTNG_ERR_INVALID
;
113 memset(&lsm
, 0, sizeof(lsm
));
114 lsm
.cmd_type
= LTTNG_SNAPSHOT_LIST_OUTPUT
;
116 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
117 sizeof(lsm
.session
.name
));
119 ret
= -LTTNG_ERR_INVALID
;
123 new_list
= (lttng_snapshot_output_list
*) zmalloc(sizeof(*new_list
));
125 ret
= -LTTNG_ERR_NOMEM
;
129 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &new_list
->array
);
134 new_list
->count
= ret
/ sizeof(struct lttng_snapshot_output
);
145 * Return the next available snapshot output object in the given list. A list
146 * output command MUST have been done before.
148 * Return the next object on success or else NULL indicating the end of the
151 struct lttng_snapshot_output
*lttng_snapshot_output_list_get_next(
152 struct lttng_snapshot_output_list
*list
)
154 struct lttng_snapshot_output
*output
= NULL
;
160 /* We've reached the end. */
161 if (list
->index
== list
->count
) {
165 output
= &list
->array
[list
->index
];
174 * Free an output list object.
176 void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list
*list
)
187 * Snapshot a trace for the given session.
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.
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.
196 * Return 0 on success or else a negative LTTNG_ERR value.
198 int lttng_snapshot_record(const char *session_name
,
199 struct lttng_snapshot_output
*output
, int wait
)
202 struct lttcomm_session_msg lsm
;
205 ret
= -LTTNG_ERR_INVALID
;
209 memset(&lsm
, 0, sizeof(lsm
));
210 lsm
.cmd_type
= LTTNG_SNAPSHOT_RECORD
;
212 ret
= lttng_strncpy(lsm
.session
.name
, session_name
,
213 sizeof(lsm
.session
.name
));
215 ret
= -LTTNG_ERR_INVALID
;
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
225 memcpy(&lsm
.u
.snapshot_record
.output
, output
,
226 sizeof(lsm
.u
.snapshot_record
.output
));
229 /* The wait param is ignored. */
230 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
236 * Return an newly allocated snapshot output object or NULL on error.
238 struct lttng_snapshot_output
*lttng_snapshot_output_create(void)
240 struct lttng_snapshot_output
*output
;
242 output
= (lttng_snapshot_output
*) zmalloc(sizeof(struct lttng_snapshot_output
));
247 output
->max_size
= (uint64_t) -1ULL;
254 * Free a given snapshot output object.
256 void lttng_snapshot_output_destroy(struct lttng_snapshot_output
*obj
)
264 * Getter family functions of snapshot output.
267 uint32_t lttng_snapshot_output_get_id(const struct lttng_snapshot_output
*output
)
272 const char *lttng_snapshot_output_get_name(
273 const struct lttng_snapshot_output
*output
)
278 const char *lttng_snapshot_output_get_data_url(const struct lttng_snapshot_output
*output
)
280 return output
->data_url
;
283 const char *lttng_snapshot_output_get_ctrl_url(const struct lttng_snapshot_output
*output
)
285 return output
->ctrl_url
;
288 uint64_t lttng_snapshot_output_get_maxsize(
289 const struct lttng_snapshot_output
*output
)
291 return output
->max_size
;
295 * Setter family functions for snapshot output.
298 int lttng_snapshot_output_set_id(uint32_t id
,
299 struct lttng_snapshot_output
*output
)
301 if (!output
|| id
== 0) {
302 return -LTTNG_ERR_INVALID
;
309 int lttng_snapshot_output_set_size(uint64_t size
,
310 struct lttng_snapshot_output
*output
)
313 return -LTTNG_ERR_INVALID
;
316 output
->max_size
= size
;
320 int lttng_snapshot_output_set_name(const char *name
,
321 struct lttng_snapshot_output
*output
)
325 if (!output
|| !name
) {
326 ret
= -LTTNG_ERR_INVALID
;
330 ret
= lttng_strncpy(output
->name
, name
, sizeof(output
->name
));
332 ret
= -LTTNG_ERR_INVALID
;
340 int lttng_snapshot_output_set_ctrl_url(const char *url
,
341 struct lttng_snapshot_output
*output
)
345 if (!output
|| !url
) {
346 ret
= -LTTNG_ERR_INVALID
;
350 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
352 ret
= -LTTNG_ERR_INVALID
;
360 int lttng_snapshot_output_set_data_url(const char *url
,
361 struct lttng_snapshot_output
*output
)
365 if (!output
|| !url
) {
366 ret
= -LTTNG_ERR_INVALID
;
370 ret
= lttng_strncpy(output
->data_url
, url
, sizeof(output
->data_url
));
372 ret
= -LTTNG_ERR_INVALID
;
380 int lttng_snapshot_output_set_local_path(const char *path
,
381 struct lttng_snapshot_output
*output
)
384 struct lttng_uri
*uris
= NULL
;
387 if (!path
|| !output
) {
388 ret
= -LTTNG_ERR_INVALID
;
392 num_uris
= uri_parse_str_urls(path
, NULL
, &uris
);
394 ret
= -LTTNG_ERR_INVALID
;
398 if (uris
[0].dtype
!= LTTNG_DST_PATH
) {
399 ret
= -LTTNG_ERR_INVALID
;
403 ret
= lttng_strncpy(output
->ctrl_url
, path
, sizeof(output
->ctrl_url
));
405 ret
= -LTTNG_ERR_INVALID
;
414 int lttng_snapshot_output_set_network_url(const char *url
,
415 struct lttng_snapshot_output
*output
)
418 struct lttng_uri
*uris
= NULL
;
421 if (!url
|| !output
) {
422 ret
= -LTTNG_ERR_INVALID
;
426 num_uris
= uri_parse_str_urls(url
, NULL
, &uris
);
428 ret
= -LTTNG_ERR_INVALID
;
432 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&&
433 uris
[0].dtype
!= LTTNG_DST_IPV6
) {
434 ret
= -LTTNG_ERR_INVALID
;
438 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&&
439 uris
[1].dtype
!= LTTNG_DST_IPV6
) {
440 ret
= -LTTNG_ERR_INVALID
;
444 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
446 ret
= -LTTNG_ERR_INVALID
;
455 int lttng_snapshot_output_set_network_urls(
456 const char *ctrl_url
, const char *data_url
,
457 struct lttng_snapshot_output
*output
)
460 struct lttng_uri
*uris
= NULL
;
463 if (!ctrl_url
|| !data_url
|| !output
) {
464 ret
= -LTTNG_ERR_INVALID
;
468 num_uris
= uri_parse_str_urls(ctrl_url
, data_url
, &uris
);
470 ret
= -LTTNG_ERR_INVALID
;
474 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&&
475 uris
[0].dtype
!= LTTNG_DST_IPV6
) {
476 ret
= -LTTNG_ERR_INVALID
;
480 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&&
481 uris
[1].dtype
!= LTTNG_DST_IPV6
) {
482 ret
= -LTTNG_ERR_INVALID
;
486 ret
= lttng_strncpy(output
->ctrl_url
, ctrl_url
, sizeof(output
->ctrl_url
));
488 ret
= -LTTNG_ERR_INVALID
;
492 ret
= lttng_strncpy(output
->data_url
, data_url
, sizeof(output
->data_url
));
494 ret
= -LTTNG_ERR_INVALID
;