remove debug
[deliverable/lttng-tools.git] / src / bin / lttng / commands / rotate.c
CommitLineData
6e0be6cc
JD
1/*
2 * Copyright (C) 2017 - Julien Desfossez <jdesfossez@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _LGPL_SOURCE
19#include <popt.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
8cf2762e
JD
26#include <inttypes.h>
27#include <ctype.h>
6e0be6cc
JD
28
29#include <common/sessiond-comm/sessiond-comm.h>
30#include <common/mi-lttng.h>
31
32#include "../command.h"
33#include <lttng/rotate.h>
34
35static char *opt_session_name;
36static int opt_no_wait;
37static struct mi_writer *writer;
38
39enum {
40 OPT_HELP = 1,
41 OPT_LIST_OPTIONS,
8cf2762e
JD
42 OPT_TIMER,
43 OPT_SIZE,
6e0be6cc
JD
44};
45
46static struct poptOption long_options[] = {
47 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
48 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
49 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
50 {"no-wait", 'n', POPT_ARG_VAL, &opt_no_wait, 1, 0, 0},
8cf2762e
JD
51 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
52 {"timer", 0, POPT_ARG_INT, 0, OPT_TIMER, 0, 0},
53 {"size", 0, POPT_ARG_INT, 0, OPT_SIZE, 0, 0},
6e0be6cc
JD
54 {0, 0, 0, 0, 0, 0, 0}
55};
56
57static int mi_print_session(char *session_name, int enabled)
58{
59 int ret;
60
61 /* Open session element */
62 ret = mi_lttng_writer_open_element(writer, config_element_session);
63 if (ret) {
64 goto end;
65 }
66
67 /* Print session name element */
68 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
69 session_name);
70 if (ret) {
71 goto end;
72 }
73
74 ret = mi_lttng_writer_write_element_bool(writer, config_element_enabled,
75 enabled);
76 if (ret) {
77 goto end;
78 }
79
80 /* Close session element */
81 ret = mi_lttng_writer_close_element(writer);
82
83end:
84 return ret;
85}
86
8cf2762e
JD
87static int setup_rotate(char *session_name, uint64_t timer, uint64_t size)
88{
89 int ret = 0;
90 struct lttng_rotate_session_attr *attr = NULL;
91
92 attr = lttng_rotate_session_attr_create();
93 if (!attr) {
94 goto error;
95 }
96
97 ret = lttng_rotate_session_attr_set_session_name(attr, session_name);
98 if (ret < 0) {
99 goto error;
100 }
101
102 lttng_rotate_session_attr_set_timer(attr, timer);
103 lttng_rotate_session_attr_set_size(attr, size);
104
105 if (timer) {
106 DBG("Configuring session %s to rotate every %" PRIu64 " us",
107 session_name, timer);
108 }
109 if (size) {
110 DBG("Configuring session %s to rotate every %" PRIu64 " bytes written",
111 session_name, size);
112 }
113
114 ret = lttng_rotate_setup(attr);
115
116 goto end;
117
118error:
119 ret = -1;
120end:
121 return ret;
122}
123
124static int rotate_tracing(char *session_name)
6e0be6cc
JD
125{
126 int ret;
8cf2762e 127 char *path = NULL;
6e0be6cc
JD
128 struct lttng_rotate_session_attr *attr = NULL;
129 struct lttng_rotate_session_handle *handle = NULL;
130 enum lttng_rotate_status rotate_status;
131
132 attr = lttng_rotate_session_attr_create();
133 if (!attr) {
134 goto error;
135 }
136
6e0be6cc
JD
137 ret = lttng_rotate_session_attr_set_session_name(attr, session_name);
138 if (ret < 0) {
139 goto error;
140 }
141
142 DBG("Rotating the output files of session %s", session_name);
143
144 ret = lttng_rotate_session(attr, &handle);
145 if (ret < 0) {
146 switch (-ret) {
147 case LTTNG_ERR_SESSION_NOT_STARTED:
148 WARN("Tracing session %s not started yet", session_name);
149 break;
150 default:
151 ERR("%s", lttng_strerror(ret));
152 break;
153 }
154 goto error;
155 }
156
157 if (!opt_no_wait) {
158 _MSG("Waiting for data availability");
159 fflush(stdout);
160 do {
161 ret = lttng_rotate_session_pending(handle);
162 if (ret < 0) {
163 goto error;
164 }
165
166 /*
167 * Data sleep time before retrying (in usec). Don't sleep if the call
168 * returned value indicates availability.
169 */
170 if (ret) {
171 usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME);
172 _MSG(".");
173 fflush(stdout);
174 }
175 } while (ret == 1);
176 MSG("");
177 }
178
179 rotate_status = lttng_rotate_session_get_status(handle);
180 switch(rotate_status) {
181 case LTTNG_ROTATE_COMPLETED:
182 lttng_rotate_session_get_output_path(handle, &path);
183 MSG("Output files of session %s rotated to %s", session_name, path);
184 ret = CMD_SUCCESS;
185 goto end;
186 case LTTNG_ROTATE_STARTED:
187 MSG("Rotation started for session %s", session_name);
188 free(path);
189 if (lttng_opt_mi) {
190 ret = mi_print_session(session_name, 1);
191 if (ret) {
192 ret = CMD_ERROR;
193 goto error;
194 }
195 }
196
197 ret = CMD_SUCCESS;
198 goto end;
199 case LTTNG_ROTATE_EXPIRED:
200 MSG("Output files of session %s rotated, but handle expired", session_name);
201 if (lttng_opt_mi) {
202 ret = mi_print_session(session_name, 1);
203 if (ret) {
204 ret = CMD_ERROR;
205 goto error;
206 }
207 }
208
209 ret = CMD_SUCCESS;
210 goto end;
211 case LTTNG_ROTATE_ERROR:
212 MSG("An error occurred with the rotation of session %s", session_name);
213 if (lttng_opt_mi) {
214 ret = mi_print_session(session_name, 1);
215 if (ret) {
216 ret = CMD_ERROR;
217 goto error;
218 }
219 }
220
4a478f45
JD
221 ret = CMD_SUCCESS;
222 goto end;
223 case LTTNG_ROTATE_EMPTY:
224 MSG("Empty session, nothing to rotate.");
6e0be6cc
JD
225 ret = CMD_SUCCESS;
226 goto end;
227 }
228
229error:
230 ret = CMD_ERROR;
231end:
6e0be6cc
JD
232 lttng_rotate_session_handle_destroy(handle);
233 lttng_rotate_session_attr_destroy(attr);
234 return ret;
235}
236
237/*
238 * cmd_rotate
239 *
240 * The 'rotate <options>' first level command
241 */
242int cmd_rotate(int argc, const char **argv)
243{
244 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
245 static poptContext pc;
8cf2762e
JD
246 char *session_name = NULL;
247 char *opt_arg = NULL;
248 uint64_t timer = 0, size = 0;
6e0be6cc
JD
249
250 pc = poptGetContext(NULL, argc, argv, long_options, 0);
251 poptReadDefaultConfig(pc, 0);
252
253 while ((opt = poptGetNextOpt(pc)) != -1) {
254 switch (opt) {
255 case OPT_HELP:
256 SHOW_HELP();
257 goto end;
258 case OPT_LIST_OPTIONS:
259 list_cmd_options(stdout, long_options);
260 goto end;
8cf2762e
JD
261 case OPT_TIMER:
262 {
263 errno = 0;
264 opt_arg = poptGetOptArg(pc);
265 timer = strtoull(opt_arg, NULL, 0);
266 if (errno != 0 || !isdigit(opt_arg[0])) {
267 ERR("Wrong value in --timer parameter: %s", opt_arg);
268 ret = CMD_ERROR;
269 goto end;
270 }
271 DBG("Rotation timer set to %" PRIu64, timer);
272 break;
273 }
274 case OPT_SIZE:
275 {
276 errno = 0;
277 opt_arg = poptGetOptArg(pc);
278 size = strtoull(opt_arg, NULL, 0);
279 if (errno != 0 || !isdigit(opt_arg[0])) {
280 ERR("Wrong value in --timer parameter: %s", opt_arg);
281 ret = CMD_ERROR;
282 goto end;
283 }
284 DBG("Rotation size set to %" PRIu64, size);
285 break;
286 }
6e0be6cc
JD
287 default:
288 ret = CMD_UNDEFINED;
289 goto end;
290 }
291 }
292
8cf2762e
JD
293 if (opt_session_name == NULL) {
294 session_name = get_session_name();
295 if (session_name == NULL) {
296 goto end;
297 }
298 } else {
299 session_name = opt_session_name;
300 }
6e0be6cc
JD
301
302 /* Mi check */
303 if (lttng_opt_mi) {
304 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
305 if (!writer) {
306 ret = -LTTNG_ERR_NOMEM;
307 goto end;
308 }
309
310 /* Open command element */
311 ret = mi_lttng_writer_command_open(writer,
312 mi_lttng_element_command_start);
313 if (ret) {
314 ret = CMD_ERROR;
315 goto end;
316 }
317
318 /* Open output element */
319 ret = mi_lttng_writer_open_element(writer,
320 mi_lttng_element_command_output);
321 if (ret) {
322 ret = CMD_ERROR;
323 goto end;
324 }
325
326 /*
327 * Open sessions element
328 * For validation purpose
329 */
330 ret = mi_lttng_writer_open_element(writer,
331 config_element_sessions);
332 if (ret) {
333 ret = CMD_ERROR;
334 goto end;
335 }
336 }
337
8cf2762e
JD
338 /* No config options, just rotate the session now */
339 if (timer == 0 && size == 0) {
340 command_ret = rotate_tracing(session_name);
341 } else {
342 command_ret = setup_rotate(session_name, timer, size);
343 }
6e0be6cc 344 if (command_ret) {
8cf2762e 345 ERR("%s", lttng_strerror(command_ret));
6e0be6cc
JD
346 success = 0;
347 }
348
349 /* Mi closing */
350 if (lttng_opt_mi) {
351 /* Close sessions and output element */
352 ret = mi_lttng_close_multi_element(writer, 2);
353 if (ret) {
354 ret = CMD_ERROR;
355 goto end;
356 }
357
358 /* Success ? */
359 ret = mi_lttng_writer_write_element_bool(writer,
360 mi_lttng_element_command_success, success);
361 if (ret) {
362 ret = CMD_ERROR;
363 goto end;
364 }
365
366 /* Command element close */
367 ret = mi_lttng_writer_command_close(writer);
368 if (ret) {
369 ret = CMD_ERROR;
370 goto end;
371 }
372 }
373
374end:
375 /* Mi clean-up */
376 if (writer && mi_lttng_writer_destroy(writer)) {
377 /* Preserve original error code */
378 ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
379 }
380
381 /* Overwrite ret if an error occurred with start_tracing */
382 ret = command_ret ? command_ret : ret;
383 poptFreeContext(pc);
8cf2762e 384 free(session_name);
6e0be6cc
JD
385 return ret;
386}
This page took 0.039069 seconds and 5 git commands to generate.