Fix: null pointer dereference in lttng_rotation_handle_destroy
[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 if (!rotation_handle) {
272 return;
273 }
274 lttng_trace_archive_location_destroy(rotation_handle->archive_location);
275 free(rotation_handle);
276 }
277
278 static
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)
282 {
283 int ret;
284
285 ret = lttng_strncpy(rotation_handle->session_name, attr->session_name,
286 sizeof(rotation_handle->session_name));
287 if (ret) {
288 goto end;
289 }
290
291 rotation_handle->rotation_id = rotate_return->rotation_id;
292 end:
293 return ret;
294 }
295
296 /*
297 * Rotate the output folder of the session.
298 *
299 * Return 0 on success else a negative LTTng error code.
300 */
301 int lttng_rotate_session(struct lttng_rotation_immediate_attr *attr,
302 struct lttng_rotation_handle **rotation_handle)
303 {
304 struct lttcomm_session_msg lsm;
305 struct lttng_rotate_session_return *rotate_return = NULL;
306 int ret;
307
308 if (!attr) {
309 ret = -LTTNG_ERR_INVALID;
310 goto end;
311 }
312
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));
317
318 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &rotate_return);
319 if (ret < 0) {
320 *rotation_handle = NULL;
321 goto end;
322 }
323
324 *rotation_handle = zmalloc(sizeof(struct lttng_rotation_handle));
325 if (!*rotation_handle) {
326 ret = -LTTNG_ERR_NOMEM;
327 goto end;
328 }
329
330 init_rotation_handle(*rotation_handle, rotate_return, attr);
331
332 ret = 0;
333
334 end:
335 free(rotate_return);
336 return ret;
337 }
338
339 /*
340 * Configure the automatic rotate parameters.
341 */
342 int lttng_rotation_set_schedule(
343 struct lttng_rotation_schedule_attr *attr)
344 {
345 struct lttcomm_session_msg lsm;
346 int ret;
347
348 if (!attr) {
349 ret = -LTTNG_ERR_INVALID;
350 goto end;
351 }
352
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;
359
360 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
361 end:
362 return ret;
363 }
364
365 int lttng_rotation_schedule_get_timer_period(const char *session_name,
366 uint64_t *rotate_timer)
367 {
368 struct lttcomm_session_msg lsm;
369 struct lttng_rotation_schedule_get_timer_period *get_timer = NULL;
370 int ret;
371
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));
376
377 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_timer);
378 if (ret < 0) {
379 ret = -1;
380 goto end;
381 }
382
383 *rotate_timer = get_timer->rotate_timer;
384 ret = 0;
385 end:
386 free(get_timer);
387 return ret;
388 }
389
390 int lttng_rotation_schedule_get_size(const char *session_name,
391 uint64_t *rotate_size)
392 {
393 struct lttcomm_session_msg lsm;
394 struct lttng_rotation_schedule_get_size *get_size = NULL;
395 int ret;
396
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));
401
402 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &get_size);
403 if (ret < 0) {
404 ret = -1;
405 goto end;
406 }
407
408 *rotate_size = get_size->rotate_size;
409
410 ret = 0;
411
412 end:
413 free(get_size);
414 return ret;
415 }
This page took 0.037841 seconds and 5 git commands to generate.