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