d9907cc67e34b3c33304f989b69d920c81cb1c03
[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 void lttng_rotation_schedule_attr_set_size(
153 struct lttng_rotation_schedule_attr *attr, uint64_t size)
154 {
155 attr->size = size;
156 }
157
158 enum lttng_rotation_status lttng_rotation_handle_get_state(
159 struct lttng_rotation_handle *rotation_handle,
160 enum lttng_rotation_state *state)
161 {
162 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
163 struct lttng_rotation_get_info_return *info = NULL;
164 int ret;
165
166 if (!rotation_handle || !state) {
167 status = LTTNG_ROTATION_STATUS_INVALID;
168 goto end;
169 }
170
171 status = ask_rotation_info(rotation_handle, &info);
172 if (status != LTTNG_ROTATION_STATUS_OK) {
173 goto end;
174 }
175
176 *state = (enum lttng_rotation_state) info->status;
177 if (rotation_handle->archive_location.is_set ||
178 *state != LTTNG_ROTATION_STATE_COMPLETED) {
179 /*
180 * The path is only provided by the sessiond once
181 * the session rotation is completed, but not expired.
182 */
183 goto end;
184 }
185
186 /*
187 * Cache the location since the rotation may expire before the user
188 * has a chance to query it.
189 */
190 ret = lttng_strncpy(rotation_handle->archive_location.path,
191 info->path,
192 sizeof(rotation_handle->archive_location.path));
193 if (ret) {
194 status = LTTNG_ROTATION_STATUS_ERROR;
195 goto end;
196 }
197 rotation_handle->archive_location.is_set = true;
198 end:
199 free(info);
200 return status;
201 }
202
203 enum lttng_rotation_status lttng_rotation_handle_get_completed_archive_location(
204 struct lttng_rotation_handle *rotation_handle,
205 const char **path)
206 {
207 int ret;
208 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
209 struct lttng_rotation_get_info_return *info = NULL;
210
211 if (!rotation_handle || !path) {
212 status = LTTNG_ROTATION_STATUS_INVALID;
213 goto end;
214 }
215
216 /* Use the cached location we got from a previous query. */
217 if (rotation_handle->archive_location.is_set) {
218 *path = rotation_handle->archive_location.path;
219 goto end;
220 }
221
222 status = ask_rotation_info(rotation_handle, &info);
223 if (status != LTTNG_ROTATION_STATUS_OK) {
224 goto end;
225 }
226
227 if ((enum lttng_rotation_state) info->status !=
228 LTTNG_ROTATION_STATE_COMPLETED) {
229 status = LTTNG_ROTATION_STATUS_UNAVAILABLE;
230 goto end;
231 }
232
233 ret = lttng_strncpy(rotation_handle->archive_location.path,
234 info->path,
235 sizeof(rotation_handle->archive_location.path));
236 if (ret) {
237 status = LTTNG_ROTATION_STATUS_ERROR;
238 goto end;
239 }
240 rotation_handle->archive_location.is_set = true;
241 end:
242 free(info);
243 return status;
244 }
245
246 void lttng_rotation_handle_destroy(
247 struct lttng_rotation_handle *rotation_handle)
248 {
249 free(rotation_handle);
250 }
251
252 static
253 int init_rotation_handle(struct lttng_rotation_handle *rotation_handle,
254 struct lttng_rotate_session_return *rotate_return,
255 struct lttng_rotation_immediate_attr *attr)
256 {
257 int ret;
258
259 ret = lttng_strncpy(rotation_handle->session_name, attr->session_name,
260 sizeof(rotation_handle->session_name));
261 if (ret) {
262 goto end;
263 }
264
265 rotation_handle->rotation_id = rotate_return->rotation_id;
266 end:
267 return ret;
268 }
269
270 /*
271 * Rotate the output folder of the session.
272 *
273 * Return 0 on success else a negative LTTng error code.
274 */
275 int lttng_rotate_session(struct lttng_rotation_immediate_attr *attr,
276 struct lttng_rotation_handle **rotation_handle)
277 {
278 struct lttcomm_session_msg lsm;
279 struct lttng_rotate_session_return *rotate_return = NULL;
280 int ret;
281
282 if (!attr) {
283 ret = -LTTNG_ERR_INVALID;
284 goto end;
285 }
286
287 memset(&lsm, 0, sizeof(lsm));
288 lsm.cmd_type = LTTNG_ROTATE_SESSION;
289 lttng_ctl_copy_string(lsm.session.name, attr->session_name,
290 sizeof(lsm.session.name));
291
292 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &rotate_return);
293 if (ret < 0) {
294 *rotation_handle = NULL;
295 goto end;
296 }
297
298 *rotation_handle = zmalloc(sizeof(struct lttng_rotation_handle));
299 if (!*rotation_handle) {
300 ret = -LTTNG_ERR_NOMEM;
301 goto end;
302 }
303
304 init_rotation_handle(*rotation_handle, rotate_return, attr);
305
306 ret = 0;
307
308 end:
309 free(rotate_return);
310 return ret;
311 }
312
313 /*
314 * Configure the automatic rotate parameters.
315 */
316 int lttng_rotation_set_schedule(
317 struct lttng_rotation_schedule_attr *attr)
318 {
319 struct lttcomm_session_msg lsm;
320 int ret;
321
322 if (!attr) {
323 ret = -LTTNG_ERR_INVALID;
324 goto end;
325 }
326
327 memset(&lsm, 0, sizeof(lsm));
328 lsm.cmd_type = LTTNG_ROTATION_SET_SCHEDULE;
329 lttng_ctl_copy_string(lsm.session.name, attr->session_name,
330 sizeof(lsm.session.name));
331 lsm.u.rotate_setup.timer_us = attr->timer_us;
332 lsm.u.rotate_setup.size = attr->size;
333
334 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
335
336 end:
337 return ret;
338 }
339
340 int lttng_rotation_schedule_get_timer_period(const char *session_name,
341 uint64_t *rotate_timer)
342 {
343 struct lttcomm_session_msg lsm;
344 struct lttng_rotation_schedule_get_timer_period *get_timer = NULL;
345 int ret;
346
347 memset(&lsm, 0, sizeof(lsm));
348 lsm.cmd_type = LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD;
349 lttng_ctl_copy_string(lsm.session.name, session_name,
350 sizeof(lsm.session.name));
351
352 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_timer);
353 if (ret < 0) {
354 ret = -1;
355 goto end;
356 }
357
358 *rotate_timer = get_timer->rotate_timer;
359 ret = 0;
360 end:
361 free(get_timer);
362 return ret;
363 }
364
365 int lttng_rotation_schedule_get_size(const char *session_name,
366 uint64_t *rotate_size)
367 {
368 struct lttcomm_session_msg lsm;
369 struct lttng_rotation_schedule_get_size *get_size = NULL;
370 int ret;
371
372 memset(&lsm, 0, sizeof(lsm));
373 lsm.cmd_type = LTTNG_ROTATION_SCHEDULE_GET_SIZE;
374 lttng_ctl_copy_string(lsm.session.name, session_name,
375 sizeof(lsm.session.name));
376
377 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_size);
378 if (ret < 0) {
379 ret = -1;
380 goto end;
381 }
382
383 *rotate_size = get_size->rotate_size;
384
385 ret = 0;
386
387 end:
388 free(get_size);
389 return ret;
390 }
This page took 0.036792 seconds and 4 git commands to generate.