2 * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include "../command.hpp"
11 #include <common/mi-lttng.hpp>
12 #include <common/sessiond-comm/sessiond-comm.hpp>
14 #include <lttng/lttng.h>
23 #include <sys/types.h>
26 static char *opt_session_name
;
27 static struct mi_writer
*writer
;
29 #ifdef LTTNG_EMBED_HELP
30 static const char help_msg
[] =
31 #include <lttng-disable-rotation.1.h>
42 static 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 }
52 static const char *schedule_type_str
[] = {
57 static const struct lttng_rotation_schedule
*
58 get_schedule(const char *session_name
,
59 const struct lttng_rotation_schedules
*schedules
,
60 enum lttng_rotation_schedule_type schedule_type
)
62 unsigned int count
, i
;
63 enum lttng_rotation_status status
;
64 const struct lttng_rotation_schedule
*ret
= nullptr;
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",
73 for (i
= 0; i
< count
; i
++) {
74 const struct lttng_rotation_schedule
*schedule
= nullptr;
76 schedule
= lttng_rotation_schedules_get_at_index(schedules
, i
);
78 ERR("Unable to retrieve rotation schedule at index %u", i
);
82 if (lttng_rotation_schedule_get_type(schedule
) == schedule_type
) {
89 ERR("No %s rotation schedule active on session %s",
90 schedule_type_str
[schedule_type
],
97 static struct lttng_rotation_schedule
*create_empty_schedule(enum lttng_rotation_schedule_type type
)
99 struct lttng_rotation_schedule
*schedule
= nullptr;
102 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
:
103 schedule
= lttng_rotation_schedule_periodic_create();
105 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
:
106 schedule
= lttng_rotation_schedule_size_threshold_create();
114 static enum cmd_error_code
remove_schedule(const char *session_name
,
115 enum lttng_rotation_schedule_type schedule_type
)
117 enum cmd_error_code cmd_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;
125 switch (schedule_type
) {
126 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
:
127 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
:
130 ERR("Unknown schedule type");
134 schedule_type_name
= schedule_type_str
[schedule_type
];
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
);
142 schedule
= get_schedule(session_name
, schedules
, schedule_type
);
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
151 empty_schedule
= create_empty_schedule(schedule_type
);
152 if (!empty_schedule
) {
158 status
= lttng_session_remove_rotation_schedule(session_name
, schedule
);
160 case LTTNG_ROTATION_STATUS_OK
:
161 MSG("Disabled %s rotation on session %s", schedule_type_name
, session_name
);
162 cmd_ret
= CMD_SUCCESS
;
164 case LTTNG_ROTATION_STATUS_SCHEDULE_NOT_SET
:
165 ERR("No %s rotation schedule set on session %s", schedule_type_name
, session_name
);
168 case LTTNG_ROTATION_STATUS_ERROR
:
169 case LTTNG_ROTATION_STATUS_INVALID
:
171 ERR("Failed to disable %s rotation schedule on session %s",
180 ret
= mi_lttng_rotation_schedule_result(
181 writer
, schedule
? schedule
: empty_schedule
, cmd_ret
== CMD_SUCCESS
);
188 lttng_rotation_schedules_destroy(schedules
);
189 lttng_rotation_schedule_destroy(empty_schedule
);
197 * cmd_disable_rotation
199 * The 'disable-rotation <options>' first level command
201 int cmd_disable_rotation(int argc
, const char **argv
)
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;
210 pc
= poptGetContext(nullptr, argc
, argv
, long_options
, 0);
211 popt_ret
= poptReadDefaultConfig(pc
, 0);
214 ERR("poptReadDefaultConfig");
218 while ((opt
= poptGetNextOpt(pc
)) != -1) {
223 case OPT_LIST_OPTIONS
:
224 list_cmd_options(stdout
, long_options
);
227 periodic_rotation
= true;
230 size_rotation
= true;
233 cmd_ret
= CMD_UNDEFINED
;
238 if (opt_session_name
== nullptr) {
239 session_name
= get_session_name();
240 if (session_name
== nullptr) {
243 free_session_name
= true;
245 session_name
= opt_session_name
;
250 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
255 /* Open command element */
256 ret
= mi_lttng_writer_command_open(writer
,
257 mi_lttng_element_command_disable_rotation
);
262 /* Open output element */
263 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_command_output
);
269 if (!periodic_rotation
&& !size_rotation
) {
270 ERR("No session rotation schedule type provided.");
276 ret
= mi_lttng_writer_open_element(writer
,
277 mi_lttng_element_rotation_schedule_results
);
282 ret
= mi_lttng_writer_write_element_string(
283 writer
, mi_lttng_element_session_name
, session_name
);
289 if (periodic_rotation
) {
291 * Continue processing even on error as multiple schedules can
292 * be specified at once.
294 cmd_ret
= remove_schedule(session_name
, LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
);
298 enum cmd_error_code tmp_ret
;
300 /* Don't overwrite cmd_ret if it already indicates an error. */
302 remove_schedule(session_name
, LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
);
303 cmd_ret
= cmd_ret
? cmd_ret
: tmp_ret
;
307 /* Close rotation schedule results element */
308 ret
= mi_lttng_writer_close_element(writer
);
317 /* Close output element */
318 ret
= mi_lttng_writer_close_element(writer
);
324 ret
= mi_lttng_writer_write_element_bool(
325 writer
, mi_lttng_element_command_success
, cmd_ret
== CMD_SUCCESS
);
330 /* Command element close */
331 ret
= mi_lttng_writer_command_close(writer
);
338 (void) mi_lttng_writer_destroy(writer
);
340 if (free_session_name
) {