Extend the rotation API to provide network trace archive locations
[lttng-tools.git] / src / lib / lttng-ctl / rotate.c
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>
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>
28
29 #include "lttng-ctl-helper.h"
30
31 struct lttng_rotation_immediate_attr *lttng_rotation_immediate_attr_create(void)
32 {
33 return zmalloc(sizeof(struct lttng_rotation_immediate_attr));
34 }
35
36 struct lttng_rotation_schedule_attr *lttng_rotation_schedule_attr_create(void)
37 {
38 return zmalloc(sizeof(struct lttng_rotation_schedule_attr));
39 }
40
41 void lttng_rotation_immediate_attr_destroy(
42 struct lttng_rotation_immediate_attr *attr)
43 {
44 free(attr);
45 }
46
47 void lttng_rotation_schedule_attr_destroy(struct lttng_rotation_schedule_attr *attr)
48 {
49 if (attr) {
50 free(attr);
51 attr = NULL;
52 }
53 }
54
55 enum 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
74 error:
75 return status;
76 }
77
78 static
79 enum 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 }
109 end:
110 return status;
111
112 }
113
114 enum 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
133 error:
134 return status;
135 }
136
137 enum 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;
149 end:
150 return status;
151 }
152
153 void lttng_rotation_schedule_attr_set_size(
154 struct lttng_rotation_schedule_attr *attr, uint64_t size)
155 {
156 attr->size = size;
157 }
158
159 static
160 struct lttng_trace_archive_location *
161 create_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
186 enum 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;
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;
204 if (rotation_handle->archive_location ||
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 */
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;
221 goto end;
222 }
223 end:
224 free(info);
225 return status;
226 }
227
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)
231 {
232 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
233 struct lttng_rotation_get_info_return *info = NULL;
234
235 if (!rotation_handle || !location) {
236 status = LTTNG_ROTATION_STATUS_INVALID;
237 goto end;
238 }
239
240 /* Use the cached location we got from a previous query. */
241 if (rotation_handle->archive_location) {
242 *location = rotation_handle->archive_location;
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
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;
261 goto end;
262 }
263 end:
264 free(info);
265 return status;
266 }
267
268 void lttng_rotation_handle_destroy(
269 struct lttng_rotation_handle *rotation_handle)
270 {
271 lttng_trace_archive_location_destroy(rotation_handle->archive_location);
272 free(rotation_handle);
273 }
274
275 static
276 int 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;
289 end:
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 */
298 int 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
331 end:
332 free(rotate_return);
333 return ret;
334 }
335
336 /*
337 * Configure the automatic rotate parameters.
338 */
339 int 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;
355 lsm.u.rotate_setup.size = attr->size;
356
357 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
358 end:
359 return ret;
360 }
361
362 int 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;
381 ret = 0;
382 end:
383 free(get_timer);
384 return ret;
385 }
386
387 int 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
409 end:
410 free(get_size);
411 return ret;
412 }
This page took 0.06123 seconds and 5 git commands to generate.