Extend the rotation API to provide network trace archive locations
[lttng-tools.git] / src / lib / lttng-ctl / rotate.c
CommitLineData
d68c9a04
JD
1/*
2 * Copyright (C) 2017 - Julien Desfossez <jdesfossez@efficios.com>
3 *
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.
7 *
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
11 * for more details.
12 *
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
16 */
17
18#define _LGPL_SOURCE
19#include <assert.h>
20#include <string.h>
21
22#include <lttng/lttng-error.h>
23#include <lttng/rotation.h>
dd73d57b 24#include <lttng/location-internal.h>
d68c9a04
JD
25#include <lttng/rotate-internal.h>
26#include <common/sessiond-comm/sessiond-comm.h>
27#include <common/macros.h>
28
29#include "lttng-ctl-helper.h"
30
31struct lttng_rotation_immediate_attr *lttng_rotation_immediate_attr_create(void)
32{
33 return zmalloc(sizeof(struct lttng_rotation_immediate_attr));
34}
35
259c2674
JD
36struct lttng_rotation_schedule_attr *lttng_rotation_schedule_attr_create(void)
37{
38 return zmalloc(sizeof(struct lttng_rotation_schedule_attr));
39}
40
d68c9a04
JD
41void lttng_rotation_immediate_attr_destroy(
42 struct lttng_rotation_immediate_attr *attr)
43{
44 free(attr);
45}
46
259c2674
JD
47void lttng_rotation_schedule_attr_destroy(struct lttng_rotation_schedule_attr *attr)
48{
49 if (attr) {
50 free(attr);
51 attr = NULL;
52 }
53}
54
d68c9a04
JD
55enum lttng_rotation_status lttng_rotation_immediate_attr_set_session_name(
56 struct lttng_rotation_immediate_attr *attr,
57 const char *session_name)
58{
59 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
60 int ret;
61
62 if (!attr || !session_name) {
63 status = LTTNG_ROTATION_STATUS_INVALID;
64 goto error;
65 }
66
67 ret = lttng_strncpy(attr->session_name, session_name,
68 sizeof(attr->session_name));
69 if (ret) {
70 status = LTTNG_ROTATION_STATUS_INVALID;
71 goto error;
72 }
73
74error:
75 return status;
76}
77
78static
79enum lttng_rotation_status ask_rotation_info(
80 struct lttng_rotation_handle *rotation_handle,
81 struct lttng_rotation_get_info_return **info)
82{
83 /* lsm.get_rotation_state.rotation_id */
84 struct lttcomm_session_msg lsm;
85 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
86 int ret;
87
88 if (!rotation_handle || !info) {
89 status = LTTNG_ROTATION_STATUS_INVALID;
90 goto end;
91 }
92
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;
96
97 ret = lttng_strncpy(lsm.session.name, rotation_handle->session_name,
98 sizeof(lsm.session.name));
99 if (ret) {
100 status = LTTNG_ROTATION_STATUS_INVALID;
101 goto end;
102 }
103
104 ret = lttng_ctl_ask_sessiond(&lsm, (void **) info);
105 if (ret < 0) {
106 status = LTTNG_ROTATION_STATUS_ERROR;
107 goto end;
108 }
109end:
110 return status;
111
112}
113
259c2674
JD
114enum lttng_rotation_status lttng_rotation_schedule_attr_set_session_name(
115 struct lttng_rotation_schedule_attr *attr,
116 const char *session_name)
117{
118 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
119 int ret;
120
121 if (!attr || !session_name) {
122 status = LTTNG_ROTATION_STATUS_INVALID;
123 goto error;
124 }
125
126 ret = lttng_strncpy(attr->session_name, session_name,
127 sizeof(attr->session_name));
128 if (ret) {
129 status = LTTNG_ROTATION_STATUS_INVALID;
130 goto error;
131 }
132
133error:
134 return status;
135}
136
137enum lttng_rotation_status lttng_rotation_schedule_attr_set_timer_period(
138 struct lttng_rotation_schedule_attr *attr,
139 uint64_t timer)
140{
141 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
142
143 if (!attr) {
144 status = LTTNG_ROTATION_STATUS_INVALID;
145 goto end;
146 }
147
148 attr->timer_us = timer;
149end:
150 return status;
151}
152
90936dcf
JD
153void lttng_rotation_schedule_attr_set_size(
154 struct lttng_rotation_schedule_attr *attr, uint64_t size)
155{
156 attr->size = size;
157}
158
dd73d57b
JG
159static
160struct lttng_trace_archive_location *
161create_trace_archive_location_from_get_info(
162 const struct lttng_rotation_get_info_return *info)
163{
164 struct lttng_trace_archive_location *location;
165
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);
170 break;
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);
178 break;
179 default:
180 location = NULL;
181 break;
182 }
183 return location;
184}
185
d68c9a04
JD
186enum lttng_rotation_status lttng_rotation_handle_get_state(
187 struct lttng_rotation_handle *rotation_handle,
188 enum lttng_rotation_state *state)
189{
190 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
191 struct lttng_rotation_get_info_return *info = NULL;
d68c9a04
JD
192
193 if (!rotation_handle || !state) {
194 status = LTTNG_ROTATION_STATUS_INVALID;
195 goto end;
196 }
197
198 status = ask_rotation_info(rotation_handle, &info);
199 if (status != LTTNG_ROTATION_STATUS_OK) {
200 goto end;
201 }
202
203 *state = (enum lttng_rotation_state) info->status;
dd73d57b 204 if (rotation_handle->archive_location ||
d68c9a04
JD
205 *state != LTTNG_ROTATION_STATE_COMPLETED) {
206 /*
207 * The path is only provided by the sessiond once
208 * the session rotation is completed, but not expired.
209 */
210 goto end;
211 }
212
213 /*
214 * Cache the location since the rotation may expire before the user
215 * has a chance to query it.
216 */
dd73d57b
JG
217 rotation_handle->archive_location =
218 create_trace_archive_location_from_get_info(info);
219 if (!rotation_handle->archive_location) {
d68c9a04
JD
220 status = LTTNG_ROTATION_STATUS_ERROR;
221 goto end;
222 }
d68c9a04
JD
223end:
224 free(info);
225 return status;
226}
227
dd73d57b 228enum lttng_rotation_status lttng_rotation_handle_get_archive_location(
d68c9a04 229 struct lttng_rotation_handle *rotation_handle,
dd73d57b 230 const struct lttng_trace_archive_location **location)
d68c9a04 231{
d68c9a04
JD
232 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
233 struct lttng_rotation_get_info_return *info = NULL;
234
dd73d57b 235 if (!rotation_handle || !location) {
d68c9a04
JD
236 status = LTTNG_ROTATION_STATUS_INVALID;
237 goto end;
238 }
239
240 /* Use the cached location we got from a previous query. */
dd73d57b
JG
241 if (rotation_handle->archive_location) {
242 *location = rotation_handle->archive_location;
d68c9a04
JD
243 goto end;
244 }
245
246 status = ask_rotation_info(rotation_handle, &info);
247 if (status != LTTNG_ROTATION_STATUS_OK) {
248 goto end;
249 }
250
251 if ((enum lttng_rotation_state) info->status !=
252 LTTNG_ROTATION_STATE_COMPLETED) {
253 status = LTTNG_ROTATION_STATUS_UNAVAILABLE;
254 goto end;
255 }
256
dd73d57b
JG
257 rotation_handle->archive_location =
258 create_trace_archive_location_from_get_info(info);
259 if (!rotation_handle->archive_location) {
d68c9a04
JD
260 status = LTTNG_ROTATION_STATUS_ERROR;
261 goto end;
262 }
d68c9a04
JD
263end:
264 free(info);
265 return status;
266}
267
268void lttng_rotation_handle_destroy(
269 struct lttng_rotation_handle *rotation_handle)
270{
dd73d57b 271 lttng_trace_archive_location_destroy(rotation_handle->archive_location);
d68c9a04
JD
272 free(rotation_handle);
273}
274
275static
276int init_rotation_handle(struct lttng_rotation_handle *rotation_handle,
277 struct lttng_rotate_session_return *rotate_return,
278 struct lttng_rotation_immediate_attr *attr)
279{
280 int ret;
281
282 ret = lttng_strncpy(rotation_handle->session_name, attr->session_name,
283 sizeof(rotation_handle->session_name));
284 if (ret) {
285 goto end;
286 }
287
288 rotation_handle->rotation_id = rotate_return->rotation_id;
289end:
290 return ret;
291}
292
293/*
294 * Rotate the output folder of the session.
295 *
296 * Return 0 on success else a negative LTTng error code.
297 */
298int lttng_rotate_session(struct lttng_rotation_immediate_attr *attr,
299 struct lttng_rotation_handle **rotation_handle)
300{
301 struct lttcomm_session_msg lsm;
302 struct lttng_rotate_session_return *rotate_return = NULL;
303 int ret;
304
305 if (!attr) {
306 ret = -LTTNG_ERR_INVALID;
307 goto end;
308 }
309
310 memset(&lsm, 0, sizeof(lsm));
311 lsm.cmd_type = LTTNG_ROTATE_SESSION;
312 lttng_ctl_copy_string(lsm.session.name, attr->session_name,
313 sizeof(lsm.session.name));
314
315 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &rotate_return);
316 if (ret < 0) {
317 *rotation_handle = NULL;
318 goto end;
319 }
320
321 *rotation_handle = zmalloc(sizeof(struct lttng_rotation_handle));
322 if (!*rotation_handle) {
323 ret = -LTTNG_ERR_NOMEM;
324 goto end;
325 }
326
327 init_rotation_handle(*rotation_handle, rotate_return, attr);
328
329 ret = 0;
330
331end:
332 free(rotate_return);
333 return ret;
334}
259c2674
JD
335
336/*
337 * Configure the automatic rotate parameters.
338 */
339int lttng_rotation_set_schedule(
340 struct lttng_rotation_schedule_attr *attr)
341{
342 struct lttcomm_session_msg lsm;
343 int ret;
344
345 if (!attr) {
346 ret = -LTTNG_ERR_INVALID;
347 goto end;
348 }
349
350 memset(&lsm, 0, sizeof(lsm));
351 lsm.cmd_type = LTTNG_ROTATION_SET_SCHEDULE;
352 lttng_ctl_copy_string(lsm.session.name, attr->session_name,
353 sizeof(lsm.session.name));
354 lsm.u.rotate_setup.timer_us = attr->timer_us;
90936dcf 355 lsm.u.rotate_setup.size = attr->size;
259c2674
JD
356
357 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
259c2674
JD
358end:
359 return ret;
360}
329f3443
JD
361
362int lttng_rotation_schedule_get_timer_period(const char *session_name,
363 uint64_t *rotate_timer)
364{
365 struct lttcomm_session_msg lsm;
366 struct lttng_rotation_schedule_get_timer_period *get_timer = NULL;
367 int ret;
368
369 memset(&lsm, 0, sizeof(lsm));
370 lsm.cmd_type = LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD;
371 lttng_ctl_copy_string(lsm.session.name, session_name,
372 sizeof(lsm.session.name));
373
374 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_timer);
375 if (ret < 0) {
376 ret = -1;
377 goto end;
378 }
379
380 *rotate_timer = get_timer->rotate_timer;
329f3443 381 ret = 0;
329f3443
JD
382end:
383 free(get_timer);
384 return ret;
385}
386
387int lttng_rotation_schedule_get_size(const char *session_name,
388 uint64_t *rotate_size)
389{
390 struct lttcomm_session_msg lsm;
391 struct lttng_rotation_schedule_get_size *get_size = NULL;
392 int ret;
393
394 memset(&lsm, 0, sizeof(lsm));
395 lsm.cmd_type = LTTNG_ROTATION_SCHEDULE_GET_SIZE;
396 lttng_ctl_copy_string(lsm.session.name, session_name,
397 sizeof(lsm.session.name));
398
399 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_size);
400 if (ret < 0) {
401 ret = -1;
402 goto end;
403 }
404
405 *rotate_size = get_size->rotate_size;
406
407 ret = 0;
408
409end:
410 free(get_size);
411 return ret;
412}
This page took 0.059744 seconds and 4 git commands to generate.