Commit | Line | Data |
---|---|---|
d68c9a04 | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com> |
d68c9a04 | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: LGPL-2.1-only |
d68c9a04 | 5 | * |
d68c9a04 JD |
6 | */ |
7 | ||
8 | #define _LGPL_SOURCE | |
28ab034a JG |
9 | #include "lttng-ctl-helper.hpp" |
10 | ||
11 | #include <common/macros.hpp> | |
12 | #include <common/sessiond-comm/sessiond-comm.hpp> | |
d68c9a04 | 13 | |
c9e313bc | 14 | #include <lttng/location-internal.hpp> |
28ab034a | 15 | #include <lttng/lttng-error.h> |
c9e313bc | 16 | #include <lttng/rotate-internal.hpp> |
28ab034a | 17 | #include <lttng/rotation.h> |
d68c9a04 | 18 | |
28ab034a | 19 | #include <string.h> |
d68c9a04 | 20 | |
28ab034a JG |
21 | static enum lttng_rotation_status ask_rotation_info(struct lttng_rotation_handle *rotation_handle, |
22 | struct lttng_rotation_get_info_return **info) | |
d68c9a04 JD |
23 | { |
24 | /* lsm.get_rotation_state.rotation_id */ | |
25 | struct lttcomm_session_msg lsm; | |
26 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
27 | int ret; | |
28 | ||
29 | if (!rotation_handle || !info) { | |
30 | status = LTTNG_ROTATION_STATUS_INVALID; | |
31 | goto end; | |
32 | } | |
33 | ||
34 | memset(&lsm, 0, sizeof(lsm)); | |
37a5ef39 | 35 | lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ROTATION_GET_INFO; |
d68c9a04 JD |
36 | lsm.u.get_rotation_info.rotation_id = rotation_handle->rotation_id; |
37 | ||
28ab034a JG |
38 | ret = lttng_strncpy( |
39 | lsm.session.name, rotation_handle->session_name, sizeof(lsm.session.name)); | |
d68c9a04 JD |
40 | if (ret) { |
41 | status = LTTNG_ROTATION_STATUS_INVALID; | |
42 | goto end; | |
43 | } | |
44 | ||
45 | ret = lttng_ctl_ask_sessiond(&lsm, (void **) info); | |
46 | if (ret < 0) { | |
47 | status = LTTNG_ROTATION_STATUS_ERROR; | |
48 | goto end; | |
49 | } | |
50 | end: | |
51 | return status; | |
d68c9a04 JD |
52 | } |
53 | ||
28ab034a JG |
54 | static struct lttng_trace_archive_location * |
55 | create_trace_archive_location_from_get_info(const struct lttng_rotation_get_info_return *info) | |
dd73d57b JG |
56 | { |
57 | struct lttng_trace_archive_location *location; | |
58 | ||
59 | switch (info->location_type) { | |
60 | case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL: | |
61 | location = lttng_trace_archive_location_local_create( | |
28ab034a | 62 | info->location.local.absolute_path); |
dd73d57b JG |
63 | break; |
64 | case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY: | |
65 | location = lttng_trace_archive_location_relay_create( | |
28ab034a JG |
66 | info->location.relay.host, |
67 | (lttng_trace_archive_location_relay_protocol_type) | |
68 | info->location.relay.protocol, | |
69 | info->location.relay.ports.control, | |
70 | info->location.relay.ports.data, | |
71 | info->location.relay.relative_path); | |
dd73d57b JG |
72 | break; |
73 | default: | |
cd9adb8b | 74 | location = nullptr; |
dd73d57b JG |
75 | break; |
76 | } | |
77 | return location; | |
78 | } | |
79 | ||
28ab034a JG |
80 | enum lttng_rotation_status |
81 | lttng_rotation_handle_get_state(struct lttng_rotation_handle *rotation_handle, | |
82 | enum lttng_rotation_state *state) | |
d68c9a04 JD |
83 | { |
84 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
cd9adb8b | 85 | struct lttng_rotation_get_info_return *info = nullptr; |
d68c9a04 JD |
86 | |
87 | if (!rotation_handle || !state) { | |
88 | status = LTTNG_ROTATION_STATUS_INVALID; | |
89 | goto end; | |
90 | } | |
91 | ||
92 | status = ask_rotation_info(rotation_handle, &info); | |
93 | if (status != LTTNG_ROTATION_STATUS_OK) { | |
94 | goto end; | |
95 | } | |
96 | ||
97 | *state = (enum lttng_rotation_state) info->status; | |
28ab034a | 98 | if (rotation_handle->archive_location || *state != LTTNG_ROTATION_STATE_COMPLETED) { |
d68c9a04 JD |
99 | /* |
100 | * The path is only provided by the sessiond once | |
101 | * the session rotation is completed, but not expired. | |
102 | */ | |
103 | goto end; | |
104 | } | |
105 | ||
106 | /* | |
107 | * Cache the location since the rotation may expire before the user | |
108 | * has a chance to query it. | |
109 | */ | |
28ab034a | 110 | rotation_handle->archive_location = create_trace_archive_location_from_get_info(info); |
dd73d57b | 111 | if (!rotation_handle->archive_location) { |
d68c9a04 JD |
112 | status = LTTNG_ROTATION_STATUS_ERROR; |
113 | goto end; | |
114 | } | |
d68c9a04 JD |
115 | end: |
116 | free(info); | |
117 | return status; | |
118 | } | |
119 | ||
28ab034a JG |
120 | enum lttng_rotation_status |
121 | lttng_rotation_handle_get_archive_location(struct lttng_rotation_handle *rotation_handle, | |
122 | const struct lttng_trace_archive_location **location) | |
d68c9a04 | 123 | { |
d68c9a04 | 124 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; |
cd9adb8b | 125 | struct lttng_rotation_get_info_return *info = nullptr; |
d68c9a04 | 126 | |
dd73d57b | 127 | if (!rotation_handle || !location) { |
d68c9a04 JD |
128 | status = LTTNG_ROTATION_STATUS_INVALID; |
129 | goto end; | |
130 | } | |
131 | ||
132 | /* Use the cached location we got from a previous query. */ | |
dd73d57b JG |
133 | if (rotation_handle->archive_location) { |
134 | *location = rotation_handle->archive_location; | |
d68c9a04 JD |
135 | goto end; |
136 | } | |
137 | ||
138 | status = ask_rotation_info(rotation_handle, &info); | |
139 | if (status != LTTNG_ROTATION_STATUS_OK) { | |
140 | goto end; | |
141 | } | |
142 | ||
28ab034a | 143 | if ((enum lttng_rotation_state) info->status != LTTNG_ROTATION_STATE_COMPLETED) { |
d68c9a04 JD |
144 | status = LTTNG_ROTATION_STATUS_UNAVAILABLE; |
145 | goto end; | |
146 | } | |
147 | ||
28ab034a | 148 | rotation_handle->archive_location = create_trace_archive_location_from_get_info(info); |
dd73d57b | 149 | if (!rotation_handle->archive_location) { |
d68c9a04 JD |
150 | status = LTTNG_ROTATION_STATUS_ERROR; |
151 | goto end; | |
152 | } | |
d68c9a04 JD |
153 | end: |
154 | free(info); | |
155 | return status; | |
156 | } | |
157 | ||
28ab034a | 158 | void lttng_rotation_handle_destroy(struct lttng_rotation_handle *rotation_handle) |
d68c9a04 | 159 | { |
06b180a1 JR |
160 | if (!rotation_handle) { |
161 | return; | |
162 | } | |
d3740619 | 163 | lttng_trace_archive_location_put(rotation_handle->archive_location); |
d68c9a04 JD |
164 | free(rotation_handle); |
165 | } | |
166 | ||
28ab034a JG |
167 | static int init_rotation_handle(struct lttng_rotation_handle *rotation_handle, |
168 | const char *session_name, | |
169 | struct lttng_rotate_session_return *rotate_return) | |
d68c9a04 JD |
170 | { |
171 | int ret; | |
172 | ||
28ab034a JG |
173 | ret = lttng_strncpy( |
174 | rotation_handle->session_name, session_name, sizeof(rotation_handle->session_name)); | |
d68c9a04 JD |
175 | if (ret) { |
176 | goto end; | |
177 | } | |
178 | ||
179 | rotation_handle->rotation_id = rotate_return->rotation_id; | |
180 | end: | |
181 | return ret; | |
182 | } | |
183 | ||
184 | /* | |
185 | * Rotate the output folder of the session. | |
186 | * | |
187 | * Return 0 on success else a negative LTTng error code. | |
188 | */ | |
dbd512ea | 189 | int lttng_rotate_session(const char *session_name, |
28ab034a JG |
190 | struct lttng_rotation_immediate_descriptor *descriptor |
191 | __attribute__((unused)), | |
192 | struct lttng_rotation_handle **rotation_handle) | |
d68c9a04 JD |
193 | { |
194 | struct lttcomm_session_msg lsm; | |
cd9adb8b | 195 | struct lttng_rotate_session_return *rotate_return = nullptr; |
d68c9a04 | 196 | int ret; |
dbd512ea | 197 | size_t session_name_len; |
d68c9a04 | 198 | |
dbd512ea JG |
199 | if (!session_name) { |
200 | ret = -LTTNG_ERR_INVALID; | |
201 | goto end; | |
202 | } | |
203 | ||
204 | session_name_len = strlen(session_name); | |
205 | if (session_name_len >= sizeof(lsm.session.name) || | |
206 | session_name_len >= member_sizeof(struct lttng_rotation_handle, session_name)) { | |
d68c9a04 JD |
207 | ret = -LTTNG_ERR_INVALID; |
208 | goto end; | |
209 | } | |
210 | ||
211 | memset(&lsm, 0, sizeof(lsm)); | |
37a5ef39 | 212 | lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ROTATE_SESSION; |
e1b624d0 | 213 | |
28ab034a | 214 | ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name)); |
e1b624d0 | 215 | /* Source length already validated. */ |
a0377dfe | 216 | LTTNG_ASSERT(ret == 0); |
d68c9a04 JD |
217 | |
218 | ret = lttng_ctl_ask_sessiond(&lsm, (void **) &rotate_return); | |
1320cab1 | 219 | if (ret <= 0) { |
cd9adb8b | 220 | *rotation_handle = nullptr; |
d68c9a04 JD |
221 | goto end; |
222 | } | |
223 | ||
64803277 | 224 | *rotation_handle = zmalloc<lttng_rotation_handle>(); |
d68c9a04 JD |
225 | if (!*rotation_handle) { |
226 | ret = -LTTNG_ERR_NOMEM; | |
227 | goto end; | |
228 | } | |
229 | ||
66ea93b1 | 230 | init_rotation_handle(*rotation_handle, session_name, rotate_return); |
d68c9a04 JD |
231 | |
232 | ret = 0; | |
233 | ||
234 | end: | |
235 | free(rotate_return); | |
236 | return ret; | |
237 | } | |
259c2674 JD |
238 | |
239 | /* | |
66ea93b1 JG |
240 | * Update the automatic rotation parameters. |
241 | * 'add' as true enables the provided schedule, false removes the shedule. | |
242 | * | |
243 | * The external API makes it appear as though arbitrary schedules can | |
244 | * be added or removed at will. However, the session daemon is | |
245 | * currently limited to one schedule per type (per session). | |
246 | * | |
247 | * The additional flexibility of the public API is offered for future | |
248 | * rotation schedules that could indicate more precise criteria than | |
249 | * size and time (e.g. a domain) where it could make sense to add | |
250 | * multiple schedules of a given type to a session. | |
251 | * | |
252 | * Hence, the exact schedule that the user wishes to remove (and not | |
253 | * just its type) must be passed so that the session daemon can | |
254 | * validate that is exists before clearing it. | |
259c2674 | 255 | */ |
28ab034a JG |
256 | static enum lttng_rotation_status lttng_rotation_update_schedule( |
257 | const char *session_name, const struct lttng_rotation_schedule *schedule, bool add) | |
259c2674 JD |
258 | { |
259 | struct lttcomm_session_msg lsm; | |
66ea93b1 | 260 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; |
259c2674 JD |
261 | int ret; |
262 | ||
66ea93b1 JG |
263 | if (!session_name || !schedule) { |
264 | status = LTTNG_ROTATION_STATUS_INVALID; | |
dbd512ea JG |
265 | goto end; |
266 | } | |
267 | ||
268 | if (strlen(session_name) >= sizeof(lsm.session.name)) { | |
66ea93b1 | 269 | status = LTTNG_ROTATION_STATUS_INVALID; |
259c2674 JD |
270 | goto end; |
271 | } | |
272 | ||
273 | memset(&lsm, 0, sizeof(lsm)); | |
37a5ef39 | 274 | lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ROTATION_SET_SCHEDULE; |
28ab034a | 275 | ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name)); |
e1b624d0 | 276 | /* Source length already validated. */ |
a0377dfe | 277 | LTTNG_ASSERT(ret == 0); |
66ea93b1 JG |
278 | |
279 | lsm.u.rotation_set_schedule.type = (uint32_t) schedule->type; | |
280 | switch (schedule->type) { | |
281 | case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD: | |
282 | { | |
7370c955 JG |
283 | uint64_t threshold; |
284 | ||
28ab034a | 285 | status = lttng_rotation_schedule_size_threshold_get_threshold(schedule, &threshold); |
66ea93b1 | 286 | if (status != LTTNG_ROTATION_STATUS_OK) { |
ed9f1fb2 JG |
287 | if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) { |
288 | status = LTTNG_ROTATION_STATUS_INVALID; | |
289 | } | |
66ea93b1 JG |
290 | goto end; |
291 | } | |
7370c955 | 292 | lsm.u.rotation_set_schedule.value = threshold; |
66ea93b1 JG |
293 | lsm.u.rotation_set_schedule.set = !!add; |
294 | break; | |
295 | } | |
296 | case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC: | |
297 | { | |
7370c955 JG |
298 | uint64_t period; |
299 | ||
28ab034a | 300 | status = lttng_rotation_schedule_periodic_get_period(schedule, &period); |
66ea93b1 | 301 | if (status != LTTNG_ROTATION_STATUS_OK) { |
ed9f1fb2 JG |
302 | if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) { |
303 | status = LTTNG_ROTATION_STATUS_INVALID; | |
304 | } | |
66ea93b1 JG |
305 | goto end; |
306 | } | |
7370c955 | 307 | lsm.u.rotation_set_schedule.value = period; |
66ea93b1 JG |
308 | lsm.u.rotation_set_schedule.set = !!add; |
309 | break; | |
310 | } | |
311 | default: | |
312 | status = LTTNG_ROTATION_STATUS_INVALID; | |
313 | goto end; | |
314 | } | |
259c2674 | 315 | |
cd9adb8b | 316 | ret = lttng_ctl_ask_sessiond(&lsm, nullptr); |
66ea93b1 JG |
317 | if (ret >= 0) { |
318 | goto end; | |
319 | } | |
320 | ||
321 | switch (-ret) { | |
322 | case LTTNG_ERR_ROTATION_SCHEDULE_SET: | |
323 | status = LTTNG_ROTATION_STATUS_SCHEDULE_ALREADY_SET; | |
324 | break; | |
325 | case LTTNG_ERR_ROTATION_SCHEDULE_NOT_SET: | |
326 | status = LTTNG_ROTATION_STATUS_INVALID; | |
327 | break; | |
328 | default: | |
329 | status = LTTNG_ROTATION_STATUS_ERROR; | |
330 | } | |
259c2674 | 331 | end: |
66ea93b1 JG |
332 | return status; |
333 | } | |
334 | ||
cd9adb8b | 335 | static struct lttng_rotation_schedules *lttng_rotation_schedules_create() |
66ea93b1 | 336 | { |
64803277 | 337 | return zmalloc<lttng_rotation_schedules>(); |
259c2674 | 338 | } |
329f3443 | 339 | |
28ab034a JG |
340 | static void lttng_schedules_add(struct lttng_rotation_schedules *schedules, |
341 | struct lttng_rotation_schedule *schedule) | |
66ea93b1 JG |
342 | { |
343 | schedules->schedules[schedules->count++] = schedule; | |
344 | } | |
345 | ||
28ab034a | 346 | static int get_schedules(const char *session_name, struct lttng_rotation_schedules **_schedules) |
329f3443 | 347 | { |
329f3443 | 348 | int ret; |
66ea93b1 | 349 | struct lttcomm_session_msg lsm; |
cd9adb8b JG |
350 | struct lttng_session_list_schedules_return *schedules_comm = nullptr; |
351 | struct lttng_rotation_schedules *schedules = nullptr; | |
352 | struct lttng_rotation_schedule *periodic = nullptr, *size = nullptr; | |
329f3443 | 353 | |
e1b624d0 JG |
354 | if (!session_name) { |
355 | ret = -LTTNG_ERR_INVALID; | |
356 | goto end; | |
357 | } | |
358 | ||
329f3443 | 359 | memset(&lsm, 0, sizeof(lsm)); |
37a5ef39 | 360 | lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SESSION_LIST_ROTATION_SCHEDULES; |
28ab034a | 361 | ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name)); |
e1b624d0 JG |
362 | if (ret) { |
363 | ret = -LTTNG_ERR_INVALID; | |
364 | goto end; | |
365 | } | |
329f3443 | 366 | |
66ea93b1 | 367 | ret = lttng_ctl_ask_sessiond(&lsm, (void **) &schedules_comm); |
329f3443 | 368 | if (ret < 0) { |
329f3443 JD |
369 | goto end; |
370 | } | |
371 | ||
66ea93b1 JG |
372 | schedules = lttng_rotation_schedules_create(); |
373 | if (!schedules) { | |
374 | ret = -LTTNG_ERR_NOMEM; | |
375 | goto end; | |
376 | } | |
377 | ||
378 | if (schedules_comm->periodic.set == 1) { | |
379 | enum lttng_rotation_status status; | |
380 | ||
381 | periodic = lttng_rotation_schedule_periodic_create(); | |
382 | if (!periodic) { | |
383 | ret = -LTTNG_ERR_NOMEM; | |
384 | goto end; | |
385 | } | |
386 | ||
387 | status = lttng_rotation_schedule_periodic_set_period( | |
28ab034a | 388 | periodic, schedules_comm->periodic.value); |
66ea93b1 JG |
389 | if (status != LTTNG_ROTATION_STATUS_OK) { |
390 | /* | |
391 | * This would imply that the session daemon returned | |
392 | * an invalid periodic rotation schedule value. | |
393 | */ | |
394 | ret = -LTTNG_ERR_UNK; | |
395 | goto end; | |
396 | } | |
397 | ||
398 | lttng_schedules_add(schedules, periodic); | |
cd9adb8b | 399 | periodic = nullptr; |
66ea93b1 JG |
400 | } |
401 | ||
402 | if (schedules_comm->size.set == 1) { | |
403 | enum lttng_rotation_status status; | |
404 | ||
405 | size = lttng_rotation_schedule_size_threshold_create(); | |
406 | if (!size) { | |
407 | ret = -LTTNG_ERR_NOMEM; | |
408 | goto end; | |
409 | } | |
410 | ||
411 | status = lttng_rotation_schedule_size_threshold_set_threshold( | |
28ab034a | 412 | size, schedules_comm->size.value); |
66ea93b1 JG |
413 | if (status != LTTNG_ROTATION_STATUS_OK) { |
414 | /* | |
415 | * This would imply that the session daemon returned | |
416 | * an invalid size threshold schedule value. | |
417 | */ | |
418 | ret = -LTTNG_ERR_UNK; | |
419 | goto end; | |
420 | } | |
421 | ||
422 | lttng_schedules_add(schedules, size); | |
cd9adb8b | 423 | size = nullptr; |
66ea93b1 JG |
424 | } |
425 | ||
426 | ret = LTTNG_OK; | |
329f3443 | 427 | end: |
66ea93b1 JG |
428 | free(schedules_comm); |
429 | free(periodic); | |
430 | free(size); | |
431 | *_schedules = schedules; | |
329f3443 JD |
432 | return ret; |
433 | } | |
434 | ||
28ab034a JG |
435 | enum lttng_rotation_schedule_type |
436 | lttng_rotation_schedule_get_type(const struct lttng_rotation_schedule *schedule) | |
329f3443 | 437 | { |
66ea93b1 JG |
438 | return schedule ? schedule->type : LTTNG_ROTATION_SCHEDULE_TYPE_UNKNOWN; |
439 | } | |
329f3443 | 440 | |
28ab034a | 441 | struct lttng_rotation_schedule *lttng_rotation_schedule_size_threshold_create(void) |
66ea93b1 JG |
442 | { |
443 | struct lttng_rotation_schedule_size_threshold *schedule; | |
329f3443 | 444 | |
64803277 | 445 | schedule = zmalloc<lttng_rotation_schedule_size_threshold>(); |
66ea93b1 | 446 | if (!schedule) { |
329f3443 JD |
447 | goto end; |
448 | } | |
449 | ||
66ea93b1 JG |
450 | schedule->parent.type = LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD; |
451 | end: | |
452 | return &schedule->parent; | |
453 | } | |
454 | ||
455 | enum lttng_rotation_status | |
28ab034a JG |
456 | lttng_rotation_schedule_size_threshold_get_threshold(const struct lttng_rotation_schedule *schedule, |
457 | uint64_t *size_threshold_bytes) | |
66ea93b1 JG |
458 | { |
459 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
460 | struct lttng_rotation_schedule_size_threshold *size_schedule; | |
329f3443 | 461 | |
ed9f1fb2 | 462 | if (!schedule || !size_threshold_bytes || |
28ab034a | 463 | schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD) { |
66ea93b1 JG |
464 | status = LTTNG_ROTATION_STATUS_INVALID; |
465 | goto end; | |
466 | } | |
467 | ||
0114db0e | 468 | size_schedule = lttng::utils::container_of(schedule, |
28ab034a | 469 | <tng_rotation_schedule_size_threshold::parent); |
66ea93b1 JG |
470 | if (size_schedule->size.set) { |
471 | *size_threshold_bytes = size_schedule->size.bytes; | |
472 | } else { | |
473 | status = LTTNG_ROTATION_STATUS_UNAVAILABLE; | |
474 | goto end; | |
475 | } | |
476 | end: | |
477 | return status; | |
478 | } | |
479 | ||
480 | enum lttng_rotation_status | |
28ab034a JG |
481 | lttng_rotation_schedule_size_threshold_set_threshold(struct lttng_rotation_schedule *schedule, |
482 | uint64_t size_threshold_bytes) | |
66ea93b1 JG |
483 | { |
484 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
485 | struct lttng_rotation_schedule_size_threshold *size_schedule; | |
486 | ||
28ab034a JG |
487 | if (!schedule || size_threshold_bytes == 0 || size_threshold_bytes == -1ULL || |
488 | schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD) { | |
66ea93b1 JG |
489 | status = LTTNG_ROTATION_STATUS_INVALID; |
490 | goto end; | |
491 | } | |
329f3443 | 492 | |
0114db0e | 493 | size_schedule = lttng::utils::container_of(schedule, |
28ab034a | 494 | <tng_rotation_schedule_size_threshold::parent); |
66ea93b1 JG |
495 | size_schedule->size.bytes = size_threshold_bytes; |
496 | size_schedule->size.set = true; | |
329f3443 | 497 | end: |
66ea93b1 JG |
498 | return status; |
499 | } | |
500 | ||
28ab034a | 501 | struct lttng_rotation_schedule *lttng_rotation_schedule_periodic_create(void) |
66ea93b1 JG |
502 | { |
503 | struct lttng_rotation_schedule_periodic *schedule; | |
504 | ||
64803277 | 505 | schedule = zmalloc<lttng_rotation_schedule_periodic>(); |
66ea93b1 JG |
506 | if (!schedule) { |
507 | goto end; | |
508 | } | |
509 | ||
510 | schedule->parent.type = LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC; | |
511 | end: | |
512 | return &schedule->parent; | |
513 | } | |
514 | ||
515 | enum lttng_rotation_status | |
28ab034a JG |
516 | lttng_rotation_schedule_periodic_get_period(const struct lttng_rotation_schedule *schedule, |
517 | uint64_t *period_us) | |
66ea93b1 JG |
518 | { |
519 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
520 | struct lttng_rotation_schedule_periodic *periodic_schedule; | |
521 | ||
28ab034a | 522 | if (!schedule || !period_us || schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC) { |
66ea93b1 JG |
523 | status = LTTNG_ROTATION_STATUS_INVALID; |
524 | goto end; | |
525 | } | |
526 | ||
28ab034a JG |
527 | periodic_schedule = |
528 | lttng::utils::container_of(schedule, <tng_rotation_schedule_periodic::parent); | |
66ea93b1 JG |
529 | if (periodic_schedule->period.set) { |
530 | *period_us = periodic_schedule->period.us; | |
531 | } else { | |
532 | status = LTTNG_ROTATION_STATUS_UNAVAILABLE; | |
533 | goto end; | |
534 | } | |
535 | end: | |
536 | return status; | |
537 | } | |
538 | ||
539 | enum lttng_rotation_status | |
28ab034a JG |
540 | lttng_rotation_schedule_periodic_set_period(struct lttng_rotation_schedule *schedule, |
541 | uint64_t period_us) | |
66ea93b1 JG |
542 | { |
543 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
544 | struct lttng_rotation_schedule_periodic *periodic_schedule; | |
545 | ||
ed9f1fb2 | 546 | if (!schedule || period_us == 0 || period_us == -1ULL || |
28ab034a | 547 | schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC) { |
66ea93b1 JG |
548 | status = LTTNG_ROTATION_STATUS_INVALID; |
549 | goto end; | |
550 | } | |
551 | ||
28ab034a JG |
552 | periodic_schedule = |
553 | lttng::utils::container_of(schedule, <tng_rotation_schedule_periodic::parent); | |
66ea93b1 JG |
554 | periodic_schedule->period.us = period_us; |
555 | periodic_schedule->period.set = true; | |
556 | end: | |
557 | return status; | |
558 | } | |
559 | ||
560 | void lttng_rotation_schedule_destroy(struct lttng_rotation_schedule *schedule) | |
561 | { | |
562 | if (!schedule) { | |
563 | return; | |
564 | } | |
565 | free(schedule); | |
566 | } | |
567 | ||
28ab034a | 568 | void lttng_rotation_schedules_destroy(struct lttng_rotation_schedules *schedules) |
66ea93b1 JG |
569 | { |
570 | unsigned int i; | |
571 | ||
572 | if (!schedules) { | |
573 | return; | |
574 | } | |
575 | ||
576 | for (i = 0; i < schedules->count; i++) { | |
577 | lttng_rotation_schedule_destroy(schedules->schedules[i]); | |
578 | } | |
579 | free(schedules); | |
580 | } | |
581 | ||
28ab034a JG |
582 | enum lttng_rotation_status |
583 | lttng_rotation_schedules_get_count(const struct lttng_rotation_schedules *schedules, | |
584 | unsigned int *count) | |
66ea93b1 JG |
585 | { |
586 | enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; | |
587 | ||
588 | if (!schedules || !count) { | |
589 | status = LTTNG_ROTATION_STATUS_INVALID; | |
590 | goto end; | |
591 | } | |
592 | ||
593 | *count = schedules->count; | |
594 | end: | |
595 | return status; | |
596 | } | |
597 | ||
28ab034a JG |
598 | const struct lttng_rotation_schedule * |
599 | lttng_rotation_schedules_get_at_index(const struct lttng_rotation_schedules *schedules, | |
600 | unsigned int index) | |
66ea93b1 | 601 | { |
cd9adb8b | 602 | const struct lttng_rotation_schedule *schedule = nullptr; |
66ea93b1 JG |
603 | |
604 | if (!schedules || index >= schedules->count) { | |
605 | goto end; | |
606 | } | |
607 | ||
608 | schedule = schedules->schedules[index]; | |
609 | end: | |
610 | return schedule; | |
611 | } | |
612 | ||
28ab034a JG |
613 | enum lttng_rotation_status |
614 | lttng_session_add_rotation_schedule(const char *session_name, | |
615 | const struct lttng_rotation_schedule *schedule) | |
66ea93b1 JG |
616 | { |
617 | return lttng_rotation_update_schedule(session_name, schedule, true); | |
618 | } | |
619 | ||
28ab034a JG |
620 | enum lttng_rotation_status |
621 | lttng_session_remove_rotation_schedule(const char *session_name, | |
622 | const struct lttng_rotation_schedule *schedule) | |
66ea93b1 JG |
623 | { |
624 | return lttng_rotation_update_schedule(session_name, schedule, false); | |
625 | } | |
626 | ||
28ab034a JG |
627 | int lttng_session_list_rotation_schedules(const char *session_name, |
628 | struct lttng_rotation_schedules **schedules) | |
66ea93b1 JG |
629 | { |
630 | return get_schedules(session_name, schedules); | |
329f3443 | 631 | } |