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_immediate_attr
*lttng_rotation_immediate_attr_create(void)
33 return zmalloc(sizeof(struct lttng_rotation_immediate_attr
));
36 struct lttng_rotation_schedule_attr
*lttng_rotation_schedule_attr_create(void)
38 return zmalloc(sizeof(struct lttng_rotation_schedule_attr
));
41 void lttng_rotation_immediate_attr_destroy(
42 struct lttng_rotation_immediate_attr
*attr
)
47 void lttng_rotation_schedule_attr_destroy(struct lttng_rotation_schedule_attr
*attr
)
55 enum lttng_rotation_status
lttng_rotation_immediate_attr_set_session_name(
56 struct lttng_rotation_immediate_attr
*attr
,
57 const char *session_name
)
59 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
62 if (!attr
|| !session_name
) {
63 status
= LTTNG_ROTATION_STATUS_INVALID
;
67 ret
= lttng_strncpy(attr
->session_name
, session_name
,
68 sizeof(attr
->session_name
));
70 status
= LTTNG_ROTATION_STATUS_INVALID
;
79 enum lttng_rotation_status
ask_rotation_info(
80 struct lttng_rotation_handle
*rotation_handle
,
81 struct lttng_rotation_get_info_return
**info
)
83 /* lsm.get_rotation_state.rotation_id */
84 struct lttcomm_session_msg lsm
;
85 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
88 if (!rotation_handle
|| !info
) {
89 status
= LTTNG_ROTATION_STATUS_INVALID
;
93 memset(&lsm
, 0, sizeof(lsm
));
94 lsm
.cmd_type
= LTTNG_ROTATION_GET_INFO
;
95 lsm
.u
.get_rotation_info
.rotation_id
= rotation_handle
->rotation_id
;
97 ret
= lttng_strncpy(lsm
.session
.name
, rotation_handle
->session_name
,
98 sizeof(lsm
.session
.name
));
100 status
= LTTNG_ROTATION_STATUS_INVALID
;
104 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) info
);
106 status
= LTTNG_ROTATION_STATUS_ERROR
;
114 enum lttng_rotation_status
lttng_rotation_schedule_attr_set_session_name(
115 struct lttng_rotation_schedule_attr
*attr
,
116 const char *session_name
)
118 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
121 if (!attr
|| !session_name
) {
122 status
= LTTNG_ROTATION_STATUS_INVALID
;
126 ret
= lttng_strncpy(attr
->session_name
, session_name
,
127 sizeof(attr
->session_name
));
129 status
= LTTNG_ROTATION_STATUS_INVALID
;
137 enum lttng_rotation_status
lttng_rotation_schedule_attr_set_timer_period(
138 struct lttng_rotation_schedule_attr
*attr
,
141 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
144 status
= LTTNG_ROTATION_STATUS_INVALID
;
148 attr
->timer_us
= timer
;
153 void lttng_rotation_schedule_attr_set_size(
154 struct lttng_rotation_schedule_attr
*attr
, uint64_t size
)
160 struct lttng_trace_archive_location
*
161 create_trace_archive_location_from_get_info(
162 const struct lttng_rotation_get_info_return
*info
)
164 struct lttng_trace_archive_location
*location
;
166 switch (info
->location_type
) {
167 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
168 location
= lttng_trace_archive_location_local_create(
169 info
->location
.local
.absolute_path
);
171 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
172 location
= lttng_trace_archive_location_relay_create(
173 info
->location
.relay
.host
,
174 info
->location
.relay
.protocol
,
175 info
->location
.relay
.ports
.control
,
176 info
->location
.relay
.ports
.data
,
177 info
->location
.relay
.relative_path
);
186 enum lttng_rotation_status
lttng_rotation_handle_get_state(
187 struct lttng_rotation_handle
*rotation_handle
,
188 enum lttng_rotation_state
*state
)
190 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
191 struct lttng_rotation_get_info_return
*info
= NULL
;
193 if (!rotation_handle
|| !state
) {
194 status
= LTTNG_ROTATION_STATUS_INVALID
;
198 status
= ask_rotation_info(rotation_handle
, &info
);
199 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
203 *state
= (enum lttng_rotation_state
) info
->status
;
204 if (rotation_handle
->archive_location
||
205 *state
!= LTTNG_ROTATION_STATE_COMPLETED
) {
207 * The path is only provided by the sessiond once
208 * the session rotation is completed, but not expired.
214 * Cache the location since the rotation may expire before the user
215 * has a chance to query it.
217 rotation_handle
->archive_location
=
218 create_trace_archive_location_from_get_info(info
);
219 if (!rotation_handle
->archive_location
) {
220 status
= LTTNG_ROTATION_STATUS_ERROR
;
228 enum lttng_rotation_status
lttng_rotation_handle_get_archive_location(
229 struct lttng_rotation_handle
*rotation_handle
,
230 const struct lttng_trace_archive_location
**location
)
232 enum lttng_rotation_status status
= LTTNG_ROTATION_STATUS_OK
;
233 struct lttng_rotation_get_info_return
*info
= NULL
;
235 if (!rotation_handle
|| !location
) {
236 status
= LTTNG_ROTATION_STATUS_INVALID
;
240 /* Use the cached location we got from a previous query. */
241 if (rotation_handle
->archive_location
) {
242 *location
= rotation_handle
->archive_location
;
246 status
= ask_rotation_info(rotation_handle
, &info
);
247 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
251 if ((enum lttng_rotation_state
) info
->status
!=
252 LTTNG_ROTATION_STATE_COMPLETED
) {
253 status
= LTTNG_ROTATION_STATUS_UNAVAILABLE
;
257 rotation_handle
->archive_location
=
258 create_trace_archive_location_from_get_info(info
);
259 if (!rotation_handle
->archive_location
) {
260 status
= LTTNG_ROTATION_STATUS_ERROR
;
268 void lttng_rotation_handle_destroy(
269 struct lttng_rotation_handle
*rotation_handle
)
271 if (!rotation_handle
) {
274 lttng_trace_archive_location_destroy(rotation_handle
->archive_location
);
275 free(rotation_handle
);
279 int init_rotation_handle(struct lttng_rotation_handle
*rotation_handle
,
280 struct lttng_rotate_session_return
*rotate_return
,
281 struct lttng_rotation_immediate_attr
*attr
)
285 ret
= lttng_strncpy(rotation_handle
->session_name
, attr
->session_name
,
286 sizeof(rotation_handle
->session_name
));
291 rotation_handle
->rotation_id
= rotate_return
->rotation_id
;
297 * Rotate the output folder of the session.
299 * Return 0 on success else a negative LTTng error code.
301 int lttng_rotate_session(struct lttng_rotation_immediate_attr
*attr
,
302 struct lttng_rotation_handle
**rotation_handle
)
304 struct lttcomm_session_msg lsm
;
305 struct lttng_rotate_session_return
*rotate_return
= NULL
;
309 ret
= -LTTNG_ERR_INVALID
;
313 memset(&lsm
, 0, sizeof(lsm
));
314 lsm
.cmd_type
= LTTNG_ROTATE_SESSION
;
315 lttng_ctl_copy_string(lsm
.session
.name
, attr
->session_name
,
316 sizeof(lsm
.session
.name
));
318 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &rotate_return
);
320 *rotation_handle
= NULL
;
324 *rotation_handle
= zmalloc(sizeof(struct lttng_rotation_handle
));
325 if (!*rotation_handle
) {
326 ret
= -LTTNG_ERR_NOMEM
;
330 init_rotation_handle(*rotation_handle
, rotate_return
, attr
);
340 * Configure the automatic rotate parameters.
342 int lttng_rotation_set_schedule(
343 struct lttng_rotation_schedule_attr
*attr
)
345 struct lttcomm_session_msg lsm
;
349 ret
= -LTTNG_ERR_INVALID
;
353 memset(&lsm
, 0, sizeof(lsm
));
354 lsm
.cmd_type
= LTTNG_ROTATION_SET_SCHEDULE
;
355 lttng_ctl_copy_string(lsm
.session
.name
, attr
->session_name
,
356 sizeof(lsm
.session
.name
));
357 lsm
.u
.rotate_setup
.timer_us
= attr
->timer_us
;
358 lsm
.u
.rotate_setup
.size
= attr
->size
;
360 ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
365 int lttng_rotation_schedule_get_timer_period(const char *session_name
,
366 uint64_t *rotate_timer
)
368 struct lttcomm_session_msg lsm
;
369 struct lttng_rotation_schedule_get_timer_period
*get_timer
= NULL
;
372 memset(&lsm
, 0, sizeof(lsm
));
373 lsm
.cmd_type
= LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD
;
374 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
375 sizeof(lsm
.session
.name
));
377 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &get_timer
);
383 *rotate_timer
= get_timer
->rotate_timer
;
390 int lttng_rotation_schedule_get_size(const char *session_name
,
391 uint64_t *rotate_size
)
393 struct lttcomm_session_msg lsm
;
394 struct lttng_rotation_schedule_get_size
*get_size
= NULL
;
397 memset(&lsm
, 0, sizeof(lsm
));
398 lsm
.cmd_type
= LTTNG_ROTATION_SCHEDULE_GET_SIZE
;
399 lttng_ctl_copy_string(lsm
.session
.name
, session_name
,
400 sizeof(lsm
.session
.name
));
402 ret
= lttng_ctl_ask_sessiond(&lsm
, (void **) &get_size
);
408 *rotate_size
= get_size
->rotate_size
;