lttng: enable-event: wrap the use of poptContext into a unique_ptr
[lttng-tools.git] / src / bin / lttng / commands / disable_rotation.cpp
... / ...
CommitLineData
1/*
2 * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#define _LGPL_SOURCE
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>
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>
25
26static char *opt_session_name;
27static struct mi_writer *writer;
28
29#ifdef LTTNG_EMBED_HELP
30static const char help_msg[] =
31#include <lttng-disable-rotation.1.h>
32 ;
33#endif
34
35enum {
36 OPT_HELP = 1,
37 OPT_LIST_OPTIONS,
38 OPT_TIMER,
39 OPT_SIZE,
40};
41
42static struct poptOption long_options[] = {
43 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
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 }
50};
51
52static const char *schedule_type_str[] = {
53 "periodic",
54 "size-based",
55};
56
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)
61{
62 unsigned int count, i;
63 enum lttng_rotation_status status;
64 const struct lttng_rotation_schedule *ret = nullptr;
65
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",
69 session_name);
70 goto end;
71 }
72
73 for (i = 0; i < count; i++) {
74 const struct lttng_rotation_schedule *schedule = nullptr;
75
76 schedule = lttng_rotation_schedules_get_at_index(schedules, i);
77 if (!schedule) {
78 ERR("Unable to retrieve rotation schedule at index %u", i);
79 goto end;
80 }
81
82 if (lttng_rotation_schedule_get_type(schedule) == schedule_type) {
83 ret = schedule;
84 break;
85 }
86 }
87
88 if (!ret) {
89 ERR("No %s rotation schedule active on session %s",
90 schedule_type_str[schedule_type],
91 session_name);
92 }
93end:
94 return ret;
95}
96
97static struct lttng_rotation_schedule *create_empty_schedule(enum lttng_rotation_schedule_type type)
98{
99 struct lttng_rotation_schedule *schedule = nullptr;
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();
110 }
111 return schedule;
112}
113
114static enum cmd_error_code remove_schedule(const char *session_name,
115 enum lttng_rotation_schedule_type schedule_type)
116{
117 enum cmd_error_code cmd_ret;
118 int ret;
119 const struct lttng_rotation_schedule *schedule = nullptr;
120 struct lttng_rotation_schedules *schedules = nullptr;
121 enum lttng_rotation_status status;
122 const char *schedule_type_name;
123 struct lttng_rotation_schedule *empty_schedule = nullptr;
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) {
138 ERR("Failed to list rotation schedules of session %s", session_name);
139 goto error;
140 }
141
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;
154 }
155 goto skip_removal;
156 }
157
158 status = lttng_session_remove_rotation_schedule(session_name, schedule);
159 switch (status) {
160 case LTTNG_ROTATION_STATUS_OK:
161 MSG("Disabled %s rotation on session %s", schedule_type_name, session_name);
162 cmd_ret = CMD_SUCCESS;
163 break;
164 case LTTNG_ROTATION_STATUS_SCHEDULE_NOT_SET:
165 ERR("No %s rotation schedule set on session %s", schedule_type_name, session_name);
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",
172 schedule_type_name,
173 session_name);
174 cmd_ret = CMD_ERROR;
175 break;
176 }
177
178skip_removal:
179 if (lttng_opt_mi) {
180 ret = mi_lttng_rotation_schedule_result(
181 writer, schedule ? schedule : empty_schedule, cmd_ret == CMD_SUCCESS);
182 if (ret < 0) {
183 goto error;
184 }
185 }
186
187end:
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;
194}
195
196/*
197 * cmd_disable_rotation
198 *
199 * The 'disable-rotation <options>' first level command
200 */
201int cmd_disable_rotation(int argc, const char **argv)
202{
203 int popt_ret, opt, ret = 0;
204 enum cmd_error_code cmd_ret = CMD_SUCCESS;
205 static poptContext pc;
206 char *session_name = nullptr;
207 bool free_session_name = false;
208 bool periodic_rotation = false, size_rotation = false;
209
210 pc = poptGetContext(nullptr, argc, argv, long_options, 0);
211 popt_ret = poptReadDefaultConfig(pc, 0);
212 if (popt_ret) {
213 cmd_ret = CMD_ERROR;
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:
227 periodic_rotation = true;
228 break;
229 case OPT_SIZE:
230 size_rotation = true;
231 break;
232 default:
233 cmd_ret = CMD_UNDEFINED;
234 goto end;
235 }
236 }
237
238 if (opt_session_name == nullptr) {
239 session_name = get_session_name();
240 if (session_name == nullptr) {
241 goto error;
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) {
252 goto error;
253 }
254
255 /* Open command element */
256 ret = mi_lttng_writer_command_open(writer,
257 mi_lttng_element_command_disable_rotation);
258 if (ret) {
259 goto error;
260 }
261
262 /* Open output element */
263 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
264 if (ret) {
265 goto error;
266 }
267 }
268
269 if (!periodic_rotation && !size_rotation) {
270 ERR("No session rotation schedule type provided.");
271 cmd_ret = CMD_ERROR;
272 goto close_command;
273 }
274
275 if (lttng_opt_mi) {
276 ret = mi_lttng_writer_open_element(writer,
277 mi_lttng_element_rotation_schedule_results);
278 if (ret) {
279 goto error;
280 }
281
282 ret = mi_lttng_writer_write_element_string(
283 writer, mi_lttng_element_session_name, session_name);
284 if (ret) {
285 goto error;
286 }
287 }
288
289 if (periodic_rotation) {
290 /*
291 * Continue processing even on error as multiple schedules can
292 * be specified at once.
293 */
294 cmd_ret = remove_schedule(session_name, LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC);
295 }
296
297 if (size_rotation) {
298 enum cmd_error_code tmp_ret;
299
300 /* Don't overwrite cmd_ret if it already indicates an error. */
301 tmp_ret =
302 remove_schedule(session_name, LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD);
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:
315 /* Mi closing */
316 if (lttng_opt_mi) {
317 /* Close output element */
318 ret = mi_lttng_writer_close_element(writer);
319 if (ret) {
320 goto error;
321 }
322
323 /* Success ? */
324 ret = mi_lttng_writer_write_element_bool(
325 writer, mi_lttng_element_command_success, cmd_ret == CMD_SUCCESS);
326 if (ret) {
327 goto error;
328 }
329
330 /* Command element close */
331 ret = mi_lttng_writer_command_close(writer);
332 if (ret) {
333 goto error;
334 }
335 }
336
337end:
338 (void) mi_lttng_writer_destroy(writer);
339 poptFreeContext(pc);
340 if (free_session_name) {
341 free(session_name);
342 }
343 return cmd_ret;
344error:
345 cmd_ret = CMD_ERROR;
346 goto end;
347}
This page took 0.023567 seconds and 4 git commands to generate.