2 * Copyright (C) 2017 - Julien Desfossez <jdesfossez@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <lttng/lttng-error.h>
23 #include <lttng/rotation.h>
24 #include <lttng/location-internal.h>
25 #include <lttng/rotate-internal.h>
26 #include <common/sessiond-comm/sessiond-comm.h>
27 #include <common/macros.h>
29 #include "lttng-ctl-helper.h"
31 struct lttng_rotation_schedule_attr
*lttng_rotation_schedule_attr_create(void)
33 return zmalloc(sizeof(struct lttng_rotation_schedule_attr
));
36 void lttng_rotation_schedule_attr_destroy(struct lttng_rotation_schedule_attr
*attr
)
45 enum lttng_rotation_status
ask_rotation_info(
46 struct lttng_rotation_handle
*rotation_handle
,
47 struct lttng_rotation_get_info_return
**info
)
49 /* lsm.get_rotation_state.rotation_id */
50 struct lttcomm_session_msg lsm
;
51 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
54 if (!rotation_handle
|| !info
) {
55 status
= LTTNG_ROTATION_STATUS_INVALID
;
59 memset(&lsm
, 0, sizeof(lsm
));
60 lsm
.cmd_type
= LTTNG_ROTATION_GET_INFO
;
61 lsm
.u
.get_rotation_info
.rotation_id
= rotation_handle
->rotation_id
;
63 ret
= lttng_strncpy(lsm
.session
.name
, rotation_handle
->session_name
,
64 sizeof(lsm
.session
.name
));
66 status
= LTTNG_ROTATION_STATUS_INVALID
;
70 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) info
);
72 status
= LTTNG_ROTATION_STATUS_ERROR
;
80 enum lttng_rotation_status
lttng_rotation_schedule_attr_set_timer_period(
81 struct lttng_rotation_schedule_attr
*attr
,
84 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
87 status
= LTTNG_ROTATION_STATUS_INVALID
;
91 attr
->timer_us
= timer
;
96 void lttng_rotation_schedule_attr_set_size(
97 struct lttng_rotation_schedule_attr
*attr
, uint64_t size
)
103 struct lttng_trace_archive_location
*
104 create_trace_archive_location_from_get_info(
105 const struct lttng_rotation_get_info_return
*info
)
107 struct lttng_trace_archive_location
*location
;
109 switch (info
->location_type
) {
110 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
111 location
= lttng_trace_archive_location_local_create(
112 info
->location
.local
.absolute_path
);
114 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
115 location
= lttng_trace_archive_location_relay_create(
116 info
->location
.relay
.host
,
117 info
->location
.relay
.protocol
,
118 info
->location
.relay
.ports
.control
,
119 info
->location
.relay
.ports
.data
,
120 info
->location
.relay
.relative_path
);
129 enum lttng_rotation_status
lttng_rotation_handle_get_state(
130 struct lttng_rotation_handle
*rotation_handle
,
131 enum lttng_rotation_state
*state
)
133 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
134 struct lttng_rotation_get_info_return
*info
= NULL
;
136 if (!rotation_handle
|| !state
) {
137 status
= LTTNG_ROTATION_STATUS_INVALID
;
141 status
= ask_rotation_info(rotation_handle
, &info
);
142 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
146 *state
= (enum lttng_rotation_state
) info
->status
;
147 if (rotation_handle
->archive_location
||
148 *state
!= LTTNG_ROTATION_STATE_COMPLETED
) {
150 * The path is only provided by the sessiond once
151 * the session rotation is completed, but not expired.
157 * Cache the location since the rotation may expire before the user
158 * has a chance to query it.
160 rotation_handle
->archive_location
=
161 create_trace_archive_location_from_get_info(info
);
162 if (!rotation_handle
->archive_location
) {
163 status
= LTTNG_ROTATION_STATUS_ERROR
;
171 enum lttng_rotation_status
lttng_rotation_handle_get_archive_location(
172 struct lttng_rotation_handle
*rotation_handle
,
173 const struct lttng_trace_archive_location
**location
)
175 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
176 struct lttng_rotation_get_info_return
*info
= NULL
;
178 if (!rotation_handle
|| !location
) {
179 status
= LTTNG_ROTATION_STATUS_INVALID
;
183 /* Use the cached location we got from a previous query. */
184 if (rotation_handle
->archive_location
) {
185 *location
= rotation_handle
->archive_location
;
189 status
= ask_rotation_info(rotation_handle
, &info
);
190 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
194 if ((enum lttng_rotation_state
) info
->status
!=
195 LTTNG_ROTATION_STATE_COMPLETED
) {
196 status
= LTTNG_ROTATION_STATUS_UNAVAILABLE
;
200 rotation_handle
->archive_location
=
201 create_trace_archive_location_from_get_info(info
);
202 if (!rotation_handle
->archive_location
) {
203 status
= LTTNG_ROTATION_STATUS_ERROR
;
211 void lttng_rotation_handle_destroy(
212 struct lttng_rotation_handle
*rotation_handle
)
214 if (!rotation_handle
) {
217 lttng_trace_archive_location_destroy(rotation_handle
->archive_location
);
218 free(rotation_handle
);
222 int init_rotation_handle(struct lttng_rotation_handle
*rotation_handle
,
223 const char *session_name
,
224 struct lttng_rotate_session_return
*rotate_return
,
225 struct lttng_rotation_immediate_attr
*attr
)
229 ret
= lttng_strncpy(rotation_handle
->session_name
, session_name
,
230 sizeof(rotation_handle
->session_name
));
235 rotation_handle
->rotation_id
= rotate_return
->rotation_id
;
241 * Rotate the output folder of the session.
243 * Return 0 on success else a negative LTTng error code.
245 int lttng_rotate_session(const char *session_name
,
246 struct lttng_rotation_immediate_attr
*attr
,
247 struct lttng_rotation_handle
**rotation_handle
)
249 struct lttcomm_session_msg lsm
;
250 struct lttng_rotate_session_return
*rotate_return
= NULL
;
252 size_t session_name_len
;
255 ret
= -LTTNG_ERR_INVALID
;
259 session_name_len
= strlen(session_name
);
260 if (session_name_len
>= sizeof(lsm
.session
.name
) ||
261 session_name_len
>= member_sizeof(struct lttng_rotation_handle
, session_name
)) {
262 ret
= -LTTNG_ERR_INVALID
;
266 memset(&lsm
, 0, sizeof(lsm
));
267 lsm
.cmd_type
= LTTNG_ROTATE_SESSION
;
268 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
269 sizeof(lsm
.session
.name
));
271 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &rotate_return
);
273 *rotation_handle
= NULL
;
277 *rotation_handle
= zmalloc(sizeof(struct lttng_rotation_handle
));
278 if (!*rotation_handle
) {
279 ret
= -LTTNG_ERR_NOMEM
;
283 init_rotation_handle(*rotation_handle
, session_name
, rotate_return
,
294 * Configure the automatic rotate parameters.
296 int lttng_rotation_set_schedule(const char *session_name
,
297 struct lttng_rotation_schedule_attr
*attr
)
299 struct lttcomm_session_msg lsm
;
302 if (!attr
|| !session_name
) {
303 ret
= -LTTNG_ERR_INVALID
;
307 if (strlen(session_name
) >= sizeof(lsm
.session
.name
)) {
308 ret
= -LTTNG_ERR_INVALID
;
312 memset(&lsm
, 0, sizeof(lsm
));
313 lsm
.cmd_type
= LTTNG_ROTATION_SET_SCHEDULE
;
314 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
315 sizeof(lsm
.session
.name
));
316 lsm
.u
.rotate_setup
.timer_us
= attr
->timer_us
;
317 lsm
.u
.rotate_setup
.size
= attr
->size
;
319 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
324 int lttng_rotation_schedule_get_timer_period(const char *session_name
,
325 uint64_t *rotate_timer
)
327 struct lttcomm_session_msg lsm
;
328 struct lttng_rotation_schedule_get_timer_period
*get_timer
= NULL
;
331 memset(&lsm
, 0, sizeof(lsm
));
332 lsm
.cmd_type
= LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD
;
333 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
334 sizeof(lsm
.session
.name
));
336 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &get_timer
);
342 *rotate_timer
= get_timer
->rotate_timer
;
349 int lttng_rotation_schedule_get_size(const char *session_name
,
350 uint64_t *rotate_size
)
352 struct lttcomm_session_msg lsm
;
353 struct lttng_rotation_schedule_get_size
*get_size
= NULL
;
356 memset(&lsm
, 0, sizeof(lsm
));
357 lsm
.cmd_type
= LTTNG_ROTATION_SCHEDULE_GET_SIZE
;
358 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
359 sizeof(lsm
.session
.name
));
361 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &get_size
);
367 *rotate_size
= get_size
->rotate_size
;