lttng rotate command
[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 void lttng_rotation_immediate_attr_destroy(
36 struct lttng_rotation_immediate_attr *attr)
37 {
38 free(attr);
39 }
40
41 enum lttng_rotation_status lttng_rotation_immediate_attr_set_session_name(
42 struct lttng_rotation_immediate_attr *attr,
43 const char *session_name)
44 {
45 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
46 int ret;
47
48 if (!attr || !session_name) {
49 status = LTTNG_ROTATION_STATUS_INVALID;
50 goto error;
51 }
52
53 ret = lttng_strncpy(attr->session_name, session_name,
54 sizeof(attr->session_name));
55 if (ret) {
56 status = LTTNG_ROTATION_STATUS_INVALID;
57 goto error;
58 }
59
60 error:
61 return status;
62 }
63
64 static
65 enum lttng_rotation_status ask_rotation_info(
66 struct lttng_rotation_handle *rotation_handle,
67 struct lttng_rotation_get_info_return **info)
68 {
69 /* lsm.get_rotation_state.rotation_id */
70 struct lttcomm_session_msg lsm;
71 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
72 int ret;
73
74 if (!rotation_handle || !info) {
75 status = LTTNG_ROTATION_STATUS_INVALID;
76 goto end;
77 }
78
79 memset(&lsm, 0, sizeof(lsm));
80 lsm.cmd_type = LTTNG_ROTATION_GET_INFO;
81 lsm.u.get_rotation_info.rotation_id = rotation_handle->rotation_id;
82
83 ret = lttng_strncpy(lsm.session.name, rotation_handle->session_name,
84 sizeof(lsm.session.name));
85 if (ret) {
86 status = LTTNG_ROTATION_STATUS_INVALID;
87 goto end;
88 }
89
90 ret = lttng_ctl_ask_sessiond(&lsm, (void **) info);
91 if (ret < 0) {
92 status = LTTNG_ROTATION_STATUS_ERROR;
93 goto end;
94 }
95 end:
96 return status;
97
98 }
99
100 enum lttng_rotation_status lttng_rotation_handle_get_state(
101 struct lttng_rotation_handle *rotation_handle,
102 enum lttng_rotation_state *state)
103 {
104 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
105 struct lttng_rotation_get_info_return *info = NULL;
106 int ret;
107
108 if (!rotation_handle || !state) {
109 status = LTTNG_ROTATION_STATUS_INVALID;
110 goto end;
111 }
112
113 status = ask_rotation_info(rotation_handle, &info);
114 if (status != LTTNG_ROTATION_STATUS_OK) {
115 goto end;
116 }
117
118 *state = (enum lttng_rotation_state) info->status;
119 if (rotation_handle->archive_location.is_set ||
120 *state != LTTNG_ROTATION_STATE_COMPLETED) {
121 /*
122 * The path is only provided by the sessiond once
123 * the session rotation is completed, but not expired.
124 */
125 goto end;
126 }
127
128 /*
129 * Cache the location since the rotation may expire before the user
130 * has a chance to query it.
131 */
132 ret = lttng_strncpy(rotation_handle->archive_location.path,
133 info->path,
134 sizeof(rotation_handle->archive_location.path));
135 if (ret) {
136 status = LTTNG_ROTATION_STATUS_ERROR;
137 goto end;
138 }
139 rotation_handle->archive_location.is_set = true;
140 end:
141 free(info);
142 return status;
143 }
144
145 enum lttng_rotation_status lttng_rotation_handle_get_completed_archive_location(
146 struct lttng_rotation_handle *rotation_handle,
147 const char **path)
148 {
149 int ret;
150 enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK;
151 struct lttng_rotation_get_info_return *info = NULL;
152
153 if (!rotation_handle || !path) {
154 status = LTTNG_ROTATION_STATUS_INVALID;
155 goto end;
156 }
157
158 /* Use the cached location we got from a previous query. */
159 if (rotation_handle->archive_location.is_set) {
160 *path = rotation_handle->archive_location.path;
161 goto end;
162 }
163
164 status = ask_rotation_info(rotation_handle, &info);
165 if (status != LTTNG_ROTATION_STATUS_OK) {
166 goto end;
167 }
168
169 if ((enum lttng_rotation_state) info->status !=
170 LTTNG_ROTATION_STATE_COMPLETED) {
171 status = LTTNG_ROTATION_STATUS_UNAVAILABLE;
172 goto end;
173 }
174
175 ret = lttng_strncpy(rotation_handle->archive_location.path,
176 info->path,
177 sizeof(rotation_handle->archive_location.path));
178 if (ret) {
179 status = LTTNG_ROTATION_STATUS_ERROR;
180 goto end;
181 }
182 rotation_handle->archive_location.is_set = true;
183 end:
184 free(info);
185 return status;
186 }
187
188 void lttng_rotation_handle_destroy(
189 struct lttng_rotation_handle *rotation_handle)
190 {
191 free(rotation_handle);
192 }
193
194 static
195 int init_rotation_handle(struct lttng_rotation_handle *rotation_handle,
196 struct lttng_rotate_session_return *rotate_return,
197 struct lttng_rotation_immediate_attr *attr)
198 {
199 int ret;
200
201 ret = lttng_strncpy(rotation_handle->session_name, attr->session_name,
202 sizeof(rotation_handle->session_name));
203 if (ret) {
204 goto end;
205 }
206
207 rotation_handle->rotation_id = rotate_return->rotation_id;
208 end:
209 return ret;
210 }
211
212 /*
213 * Rotate the output folder of the session.
214 *
215 * Return 0 on success else a negative LTTng error code.
216 */
217 int lttng_rotate_session(struct lttng_rotation_immediate_attr *attr,
218 struct lttng_rotation_handle **rotation_handle)
219 {
220 struct lttcomm_session_msg lsm;
221 struct lttng_rotate_session_return *rotate_return = NULL;
222 int ret;
223
224 if (!attr) {
225 ret = -LTTNG_ERR_INVALID;
226 goto end;
227 }
228
229 memset(&lsm, 0, sizeof(lsm));
230 lsm.cmd_type = LTTNG_ROTATE_SESSION;
231 lttng_ctl_copy_string(lsm.session.name, attr->session_name,
232 sizeof(lsm.session.name));
233
234 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &rotate_return);
235 if (ret < 0) {
236 *rotation_handle = NULL;
237 goto end;
238 }
239
240 *rotation_handle = zmalloc(sizeof(struct lttng_rotation_handle));
241 if (!*rotation_handle) {
242 ret = -LTTNG_ERR_NOMEM;
243 goto end;
244 }
245
246 init_rotation_handle(*rotation_handle, rotate_return, attr);
247
248 ret = 0;
249
250 end:
251 free(rotate_return);
252 return ret;
253 }
This page took 0.035275 seconds and 5 git commands to generate.