2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include "lttng-ctl-helper.hpp"
11 #include <common/sessiond-comm/sessiond-comm.hpp>
13 #include <lttng/lttng-error.h>
14 #include <lttng/snapshot-internal.hpp>
15 #include <lttng/snapshot.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
, 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
= LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_ADD_OUTPUT
;
38 ret
= lttng_strncpy(lsm
.session
.name
, session_name
, sizeof(lsm
.session
.name
));
40 ret
= -LTTNG_ERR_INVALID
;
44 memcpy(&lsm
.u
.snapshot_output
.output
, output
, sizeof(lsm
.u
.snapshot_output
.output
));
46 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &reply
);
51 output
->id
= reply
->id
;
59 * Delete an output object to a session identified by name.
61 * Return 0 on success or else a negative LTTNG_ERR code.
63 int lttng_snapshot_del_output(const char *session_name
, struct lttng_snapshot_output
*output
)
66 struct lttcomm_session_msg lsm
;
68 if (!session_name
|| !output
) {
69 ret
= -LTTNG_ERR_INVALID
;
73 memset(&lsm
, 0, sizeof(lsm
));
74 lsm
.cmd_type
= LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_DEL_OUTPUT
;
76 ret
= lttng_strncpy(lsm
.session
.name
, session_name
, sizeof(lsm
.session
.name
));
78 ret
= -LTTNG_ERR_INVALID
;
82 memcpy(&lsm
.u
.snapshot_output
.output
, output
, sizeof(lsm
.u
.snapshot_output
.output
));
84 ret
= lttng_ctl_ask_sessiond(&lsm
, nullptr);
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.
93 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
96 int lttng_snapshot_list_output(const char *session_name
, struct lttng_snapshot_output_list
**list
)
99 struct lttcomm_session_msg lsm
;
100 struct lttng_snapshot_output_list
*new_list
= nullptr;
102 if (!session_name
|| !list
) {
103 ret
= -LTTNG_ERR_INVALID
;
107 memset(&lsm
, 0, sizeof(lsm
));
108 lsm
.cmd_type
= LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_LIST_OUTPUT
;
110 ret
= lttng_strncpy(lsm
.session
.name
, session_name
, sizeof(lsm
.session
.name
));
112 ret
= -LTTNG_ERR_INVALID
;
116 new_list
= zmalloc
<lttng_snapshot_output_list
>();
118 ret
= -LTTNG_ERR_NOMEM
;
122 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &new_list
->array
);
127 new_list
->count
= ret
/ sizeof(struct lttng_snapshot_output
);
138 * Return the next available snapshot output object in the given list. A list
139 * output command MUST have been done before.
141 * Return the next object on success or else NULL indicating the end of the
144 struct lttng_snapshot_output
*
145 lttng_snapshot_output_list_get_next(struct lttng_snapshot_output_list
*list
)
147 struct lttng_snapshot_output
*output
= nullptr;
153 /* We've reached the end. */
154 if (list
->index
== list
->count
) {
158 output
= &list
->array
[list
->index
];
167 * Free an output list object.
169 void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list
*list
)
180 * Snapshot a trace for the given session.
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.
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.
189 * Return 0 on success or else a negative LTTNG_ERR value.
191 int lttng_snapshot_record(const char *session_name
,
192 struct lttng_snapshot_output
*output
,
193 int wait
__attribute__((unused
)))
196 struct lttcomm_session_msg lsm
;
199 ret
= -LTTNG_ERR_INVALID
;
203 memset(&lsm
, 0, sizeof(lsm
));
204 lsm
.cmd_type
= LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_RECORD
;
206 ret
= lttng_strncpy(lsm
.session
.name
, session_name
, sizeof(lsm
.session
.name
));
208 ret
= -LTTNG_ERR_INVALID
;
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
218 memcpy(&lsm
.u
.snapshot_record
.output
, output
, sizeof(lsm
.u
.snapshot_record
.output
));
221 /* The wait param is ignored. */
222 ret
= lttng_ctl_ask_sessiond(&lsm
, nullptr);
228 * Return an newly allocated snapshot output object or NULL on error.
230 struct lttng_snapshot_output
*lttng_snapshot_output_create(void)
232 struct lttng_snapshot_output
*output
;
234 output
= zmalloc
<lttng_snapshot_output
>();
239 output
->max_size
= (uint64_t) -1ULL;
246 * Free a given snapshot output object.
248 void lttng_snapshot_output_destroy(struct lttng_snapshot_output
*obj
)
256 * Getter family functions of snapshot output.
259 uint32_t lttng_snapshot_output_get_id(const struct lttng_snapshot_output
*output
)
264 const char *lttng_snapshot_output_get_name(const struct lttng_snapshot_output
*output
)
269 const char *lttng_snapshot_output_get_data_url(const struct lttng_snapshot_output
*output
)
271 return output
->data_url
;
274 const char *lttng_snapshot_output_get_ctrl_url(const struct lttng_snapshot_output
*output
)
276 return output
->ctrl_url
;
279 uint64_t lttng_snapshot_output_get_maxsize(const struct lttng_snapshot_output
*output
)
281 return output
->max_size
;
285 * Setter family functions for snapshot output.
288 int lttng_snapshot_output_set_id(uint32_t id
, struct lttng_snapshot_output
*output
)
290 if (!output
|| id
== 0) {
291 return -LTTNG_ERR_INVALID
;
298 int lttng_snapshot_output_set_size(uint64_t size
, struct lttng_snapshot_output
*output
)
301 return -LTTNG_ERR_INVALID
;
304 output
->max_size
= size
;
308 int lttng_snapshot_output_set_name(const char *name
, struct lttng_snapshot_output
*output
)
312 if (!output
|| !name
) {
313 ret
= -LTTNG_ERR_INVALID
;
317 ret
= lttng_strncpy(output
->name
, name
, sizeof(output
->name
));
319 ret
= -LTTNG_ERR_INVALID
;
327 int lttng_snapshot_output_set_ctrl_url(const char *url
, struct lttng_snapshot_output
*output
)
331 if (!output
|| !url
) {
332 ret
= -LTTNG_ERR_INVALID
;
336 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
338 ret
= -LTTNG_ERR_INVALID
;
346 int lttng_snapshot_output_set_data_url(const char *url
, struct lttng_snapshot_output
*output
)
350 if (!output
|| !url
) {
351 ret
= -LTTNG_ERR_INVALID
;
355 ret
= lttng_strncpy(output
->data_url
, url
, sizeof(output
->data_url
));
357 ret
= -LTTNG_ERR_INVALID
;
365 int lttng_snapshot_output_set_local_path(const char *path
, struct lttng_snapshot_output
*output
)
368 struct lttng_uri
*uris
= nullptr;
371 if (!path
|| !output
) {
372 ret
= -LTTNG_ERR_INVALID
;
376 num_uris
= uri_parse_str_urls(path
, nullptr, &uris
);
378 ret
= -LTTNG_ERR_INVALID
;
382 if (uris
[0].dtype
!= LTTNG_DST_PATH
) {
383 ret
= -LTTNG_ERR_INVALID
;
387 ret
= lttng_strncpy(output
->ctrl_url
, path
, sizeof(output
->ctrl_url
));
389 ret
= -LTTNG_ERR_INVALID
;
398 int lttng_snapshot_output_set_network_url(const char *url
, struct lttng_snapshot_output
*output
)
401 struct lttng_uri
*uris
= nullptr;
404 if (!url
|| !output
) {
405 ret
= -LTTNG_ERR_INVALID
;
409 num_uris
= uri_parse_str_urls(url
, nullptr, &uris
);
411 ret
= -LTTNG_ERR_INVALID
;
415 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&& uris
[0].dtype
!= LTTNG_DST_IPV6
) {
416 ret
= -LTTNG_ERR_INVALID
;
420 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&& uris
[1].dtype
!= LTTNG_DST_IPV6
) {
421 ret
= -LTTNG_ERR_INVALID
;
425 ret
= lttng_strncpy(output
->ctrl_url
, url
, sizeof(output
->ctrl_url
));
427 ret
= -LTTNG_ERR_INVALID
;
436 int lttng_snapshot_output_set_network_urls(const char *ctrl_url
,
437 const char *data_url
,
438 struct lttng_snapshot_output
*output
)
441 struct lttng_uri
*uris
= nullptr;
444 if (!ctrl_url
|| !data_url
|| !output
) {
445 ret
= -LTTNG_ERR_INVALID
;
449 num_uris
= uri_parse_str_urls(ctrl_url
, data_url
, &uris
);
451 ret
= -LTTNG_ERR_INVALID
;
455 if (uris
[0].dtype
!= LTTNG_DST_IPV4
&& uris
[0].dtype
!= LTTNG_DST_IPV6
) {
456 ret
= -LTTNG_ERR_INVALID
;
460 if (uris
[1].dtype
!= LTTNG_DST_IPV4
&& uris
[1].dtype
!= LTTNG_DST_IPV6
) {
461 ret
= -LTTNG_ERR_INVALID
;
465 ret
= lttng_strncpy(output
->ctrl_url
, ctrl_url
, sizeof(output
->ctrl_url
));
467 ret
= -LTTNG_ERR_INVALID
;
471 ret
= lttng_strncpy(output
->data_url
, data_url
, sizeof(output
->data_url
));
473 ret
= -LTTNG_ERR_INVALID
;