lttng: enable-channel: move kernel tracer status check to util
[lttng-tools.git] / src / bin / lttng / commands / disable_rotation.cpp
CommitLineData
259c2674 1/*
ab5be9fa 2 * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
259c2674 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
259c2674 5 *
259c2674
JD
6 */
7
8#define _LGPL_SOURCE
28ab034a
JG
9#include "../command.hpp"
10
11#include <common/mi-lttng.hpp>
12#include <common/sessiond-comm/sessiond-comm.hpp>
13
14#include <lttng/lttng.h>
15
16#include <ctype.h>
17#include <inttypes.h>
259c2674
JD
18#include <popt.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <sys/stat.h>
23#include <sys/types.h>
24#include <unistd.h>
259c2674
JD
25
26static char *opt_session_name;
27static struct mi_writer *writer;
28
3ae5c539
JD
29#ifdef LTTNG_EMBED_HELP
30static const char help_msg[] =
31#include <lttng-disable-rotation.1.h>
28ab034a 32 ;
3ae5c539
JD
33#endif
34
259c2674
JD
35enum {
36 OPT_HELP = 1,
37 OPT_LIST_OPTIONS,
38 OPT_TIMER,
90936dcf 39 OPT_SIZE,
259c2674
JD
40};
41
42static struct poptOption long_options[] = {
43 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
cd9adb8b
JG
44 { "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr },
45 { "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr },
46 { "session", 's', POPT_ARG_STRING, &opt_session_name, 0, nullptr, nullptr },
47 { "timer", 0, POPT_ARG_NONE, nullptr, OPT_TIMER, nullptr, nullptr },
48 { "size", 0, POPT_ARG_NONE, nullptr, OPT_SIZE, nullptr, nullptr },
49 { nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
259c2674
JD
50};
51
66ea93b1 52static const char *schedule_type_str[] = {
48a40005
SM
53 "periodic",
54 "size-based",
66ea93b1
JG
55};
56
28ab034a
JG
57static const struct lttng_rotation_schedule *
58get_schedule(const char *session_name,
59 const struct lttng_rotation_schedules *schedules,
60 enum lttng_rotation_schedule_type schedule_type)
259c2674 61{
66ea93b1
JG
62 unsigned int count, i;
63 enum lttng_rotation_status status;
cd9adb8b 64 const struct lttng_rotation_schedule *ret = nullptr;
259c2674 65
66ea93b1
JG
66 status = lttng_rotation_schedules_get_count(schedules, &count);
67 if (status != LTTNG_ROTATION_STATUS_OK) {
68 ERR("Unable to determine the number of rotation schedules of session %s",
28ab034a 69 session_name);
66ea93b1 70 goto end;
259c2674
JD
71 }
72
66ea93b1 73 for (i = 0; i < count; i++) {
cd9adb8b 74 const struct lttng_rotation_schedule *schedule = nullptr;
66ea93b1
JG
75
76 schedule = lttng_rotation_schedules_get_at_index(schedules, i);
77 if (!schedule) {
28ab034a 78 ERR("Unable to retrieve rotation schedule at index %u", i);
66ea93b1 79 goto end;
259c2674 80 }
259c2674 81
28ab034a 82 if (lttng_rotation_schedule_get_type(schedule) == schedule_type) {
66ea93b1
JG
83 ret = schedule;
84 break;
259c2674
JD
85 }
86 }
87
66ea93b1
JG
88 if (!ret) {
89 ERR("No %s rotation schedule active on session %s",
28ab034a
JG
90 schedule_type_str[schedule_type],
91 session_name);
259c2674 92 }
66ea93b1
JG
93end:
94 return ret;
95}
96
28ab034a 97static struct lttng_rotation_schedule *create_empty_schedule(enum lttng_rotation_schedule_type type)
66ea93b1 98{
cd9adb8b 99 struct lttng_rotation_schedule *schedule = nullptr;
66ea93b1
JG
100
101 switch (type) {
102 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
103 schedule = lttng_rotation_schedule_periodic_create();
104 break;
105 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
106 schedule = lttng_rotation_schedule_size_threshold_create();
107 break;
108 default:
109 abort();
90936dcf 110 }
66ea93b1
JG
111 return schedule;
112}
259c2674 113
66ea93b1 114static enum cmd_error_code remove_schedule(const char *session_name,
28ab034a 115 enum lttng_rotation_schedule_type schedule_type)
66ea93b1
JG
116{
117 enum cmd_error_code cmd_ret;
118 int ret;
cd9adb8b
JG
119 const struct lttng_rotation_schedule *schedule = nullptr;
120 struct lttng_rotation_schedules *schedules = nullptr;
66ea93b1
JG
121 enum lttng_rotation_status status;
122 const char *schedule_type_name;
cd9adb8b 123 struct lttng_rotation_schedule *empty_schedule = nullptr;
66ea93b1
JG
124
125 switch (schedule_type) {
126 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
127 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
128 break;
129 default:
130 ERR("Unknown schedule type");
131 abort();
132 }
133
134 schedule_type_name = schedule_type_str[schedule_type];
135
136 ret = lttng_session_list_rotation_schedules(session_name, &schedules);
137 if (ret != LTTNG_OK) {
28ab034a 138 ERR("Failed to list rotation schedules of session %s", session_name);
259c2674
JD
139 goto error;
140 }
141
66ea93b1
JG
142 schedule = get_schedule(session_name, schedules, schedule_type);
143 if (!schedule) {
144 cmd_ret = CMD_ERROR;
145 /*
146 * get_schedule() logs its own errors.
147 * A temporaty schedule is created to serialize an MI rotation
148 * schedule descriptor of the appropriate type that has no
149 * attributes set.
150 */
151 empty_schedule = create_empty_schedule(schedule_type);
152 if (!empty_schedule) {
153 goto error;
259c2674 154 }
66ea93b1
JG
155 goto skip_removal;
156 }
259c2674 157
66ea93b1
JG
158 status = lttng_session_remove_rotation_schedule(session_name, schedule);
159 switch (status) {
160 case LTTNG_ROTATION_STATUS_OK:
28ab034a 161 MSG("Disabled %s rotation on session %s", schedule_type_name, session_name);
66ea93b1
JG
162 cmd_ret = CMD_SUCCESS;
163 break;
164 case LTTNG_ROTATION_STATUS_SCHEDULE_NOT_SET:
28ab034a 165 ERR("No %s rotation schedule set on session %s", schedule_type_name, session_name);
66ea93b1
JG
166 cmd_ret = CMD_ERROR;
167 break;
168 case LTTNG_ROTATION_STATUS_ERROR:
169 case LTTNG_ROTATION_STATUS_INVALID:
170 default:
171 ERR("Failed to disable %s rotation schedule on session %s",
28ab034a
JG
172 schedule_type_name,
173 session_name);
66ea93b1
JG
174 cmd_ret = CMD_ERROR;
175 break;
259c2674
JD
176 }
177
66ea93b1
JG
178skip_removal:
179 if (lttng_opt_mi) {
28ab034a
JG
180 ret = mi_lttng_rotation_schedule_result(
181 writer, schedule ? schedule : empty_schedule, cmd_ret == CMD_SUCCESS);
66ea93b1
JG
182 if (ret < 0) {
183 goto error;
184 }
185 }
259c2674 186
259c2674 187end:
66ea93b1
JG
188 lttng_rotation_schedules_destroy(schedules);
189 lttng_rotation_schedule_destroy(empty_schedule);
190 return cmd_ret;
191error:
192 cmd_ret = CMD_ERROR;
193 goto end;
259c2674
JD
194}
195
196/*
197 * cmd_disable_rotation
198 *
66ea93b1 199 * The 'disable-rotation <options>' first level command
259c2674
JD
200 */
201int cmd_disable_rotation(int argc, const char **argv)
202{
66ea93b1
JG
203 int popt_ret, opt, ret = 0;
204 enum cmd_error_code cmd_ret = CMD_SUCCESS;
259c2674 205 static poptContext pc;
cd9adb8b 206 char *session_name = nullptr;
259c2674 207 bool free_session_name = false;
66ea93b1 208 bool periodic_rotation = false, size_rotation = false;
259c2674 209
cd9adb8b 210 pc = poptGetContext(nullptr, argc, argv, long_options, 0);
259c2674
JD
211 popt_ret = poptReadDefaultConfig(pc, 0);
212 if (popt_ret) {
62140c46 213 cmd_ret = CMD_ERROR;
259c2674
JD
214 ERR("poptReadDefaultConfig");
215 goto end;
216 }
217
218 while ((opt = poptGetNextOpt(pc)) != -1) {
219 switch (opt) {
220 case OPT_HELP:
221 SHOW_HELP();
222 goto end;
223 case OPT_LIST_OPTIONS:
224 list_cmd_options(stdout, long_options);
225 goto end;
226 case OPT_TIMER:
66ea93b1 227 periodic_rotation = true;
259c2674 228 break;
90936dcf 229 case OPT_SIZE:
66ea93b1 230 size_rotation = true;
90936dcf 231 break;
259c2674 232 default:
62140c46 233 cmd_ret = CMD_UNDEFINED;
259c2674
JD
234 goto end;
235 }
236 }
237
cd9adb8b 238 if (opt_session_name == nullptr) {
259c2674 239 session_name = get_session_name();
cd9adb8b 240 if (session_name == nullptr) {
66ea93b1 241 goto error;
259c2674
JD
242 }
243 free_session_name = true;
244 } else {
245 session_name = opt_session_name;
246 }
247
248 /* Mi check */
249 if (lttng_opt_mi) {
250 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
251 if (!writer) {
66ea93b1 252 goto error;
259c2674
JD
253 }
254
255 /* Open command element */
256 ret = mi_lttng_writer_command_open(writer,
28ab034a 257 mi_lttng_element_command_disable_rotation);
259c2674 258 if (ret) {
66ea93b1 259 goto error;
259c2674
JD
260 }
261
262 /* Open output element */
28ab034a 263 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
259c2674 264 if (ret) {
66ea93b1 265 goto error;
259c2674
JD
266 }
267 }
268
66ea93b1
JG
269 if (!periodic_rotation && !size_rotation) {
270 ERR("No session rotation schedule type provided.");
271 cmd_ret = CMD_ERROR;
272 goto close_command;
259c2674
JD
273 }
274
66ea93b1
JG
275 if (lttng_opt_mi) {
276 ret = mi_lttng_writer_open_element(writer,
28ab034a 277 mi_lttng_element_rotation_schedule_results);
66ea93b1
JG
278 if (ret) {
279 goto error;
280 }
281
28ab034a
JG
282 ret = mi_lttng_writer_write_element_string(
283 writer, mi_lttng_element_session_name, session_name);
66ea93b1
JG
284 if (ret) {
285 goto error;
286 }
259c2674
JD
287 }
288
66ea93b1
JG
289 if (periodic_rotation) {
290 /*
291 * Continue processing even on error as multiple schedules can
292 * be specified at once.
293 */
28ab034a 294 cmd_ret = remove_schedule(session_name, LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC);
66ea93b1
JG
295 }
296
297 if (size_rotation) {
a14a81cb 298 enum cmd_error_code tmp_ret;
66ea93b1
JG
299
300 /* Don't overwrite cmd_ret if it already indicates an error. */
28ab034a
JG
301 tmp_ret =
302 remove_schedule(session_name, LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD);
66ea93b1
JG
303 cmd_ret = cmd_ret ? cmd_ret : tmp_ret;
304 }
305
306 if (lttng_opt_mi) {
307 /* Close rotation schedule results element */
308 ret = mi_lttng_writer_close_element(writer);
309 if (ret) {
310 goto error;
311 }
312 }
313
314close_command:
259c2674
JD
315 /* Mi closing */
316 if (lttng_opt_mi) {
317 /* Close output element */
318 ret = mi_lttng_writer_close_element(writer);
319 if (ret) {
66ea93b1 320 goto error;
259c2674
JD
321 }
322
323 /* Success ? */
28ab034a
JG
324 ret = mi_lttng_writer_write_element_bool(
325 writer, mi_lttng_element_command_success, cmd_ret == CMD_SUCCESS);
259c2674 326 if (ret) {
66ea93b1 327 goto error;
259c2674
JD
328 }
329
330 /* Command element close */
331 ret = mi_lttng_writer_command_close(writer);
332 if (ret) {
66ea93b1 333 goto error;
259c2674
JD
334 }
335 }
336
337end:
66ea93b1 338 (void) mi_lttng_writer_destroy(writer);
259c2674
JD
339 poptFreeContext(pc);
340 if (free_session_name) {
341 free(session_name);
342 }
66ea93b1
JG
343 return cmd_ret;
344error:
345 cmd_ret = CMD_ERROR;
346 goto end;
259c2674 347}
This page took 0.072382 seconds and 4 git commands to generate.