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