2 * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
14 #include <sys/types.h>
19 #include <common/sessiond-comm/sessiond-comm.h>
20 #include <common/mi-lttng.h>
22 #include "../command.h"
23 #include <lttng/lttng.h>
25 static char *opt_session_name
;
26 static struct mi_writer
*writer
;
28 #ifdef LTTNG_EMBED_HELP
29 static const char help_msg
[] =
30 #include <lttng-disable-rotation.1.h>
41 static struct poptOption long_options
[] = {
42 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
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},
46 {"timer", 0, POPT_ARG_NONE
, 0, OPT_TIMER
, 0, 0},
47 {"size", 0, POPT_ARG_NONE
, 0, OPT_SIZE
, 0, 0},
51 static const char *schedule_type_str
[] = {
56 static 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
)
61 unsigned int count
, i
;
62 enum lttng_rotation_status status
;
63 const struct lttng_rotation_schedule
*ret
= NULL
;
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",
72 for (i
= 0; i
< count
; i
++) {
73 const struct lttng_rotation_schedule
*schedule
= NULL
;
75 schedule
= lttng_rotation_schedules_get_at_index(schedules
, i
);
77 ERR("Unable to retrieve rotation schedule at index %u",
82 if (lttng_rotation_schedule_get_type(schedule
) ==
90 ERR("No %s rotation schedule active on session %s",
91 schedule_type_str
[schedule_type
], session_name
);
97 static struct lttng_rotation_schedule
*create_empty_schedule(
98 enum lttng_rotation_schedule_type type
)
100 struct lttng_rotation_schedule
*schedule
= NULL
;
103 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
:
104 schedule
= lttng_rotation_schedule_periodic_create();
106 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
:
107 schedule
= lttng_rotation_schedule_size_threshold_create();
115 static enum cmd_error_code
remove_schedule(const char *session_name
,
116 enum lttng_rotation_schedule_type schedule_type
)
118 enum cmd_error_code cmd_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
;
126 switch (schedule_type
) {
127 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
:
128 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
:
131 ERR("Unknown schedule type");
135 schedule_type_name
= schedule_type_str
[schedule_type
];
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",
144 schedule
= get_schedule(session_name
, schedules
, schedule_type
);
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
153 empty_schedule
= create_empty_schedule(schedule_type
);
154 if (!empty_schedule
) {
160 status
= lttng_session_remove_rotation_schedule(session_name
, schedule
);
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
;
167 case LTTNG_ROTATION_STATUS_SCHEDULE_NOT_SET
:
168 ERR("No %s rotation schedule set on session %s",
173 case LTTNG_ROTATION_STATUS_ERROR
:
174 case LTTNG_ROTATION_STATUS_INVALID
:
176 ERR("Failed to disable %s rotation schedule on session %s",
177 schedule_type_name
, session_name
);
184 ret
= mi_lttng_rotation_schedule_result(writer
,
185 schedule
? schedule
: empty_schedule
,
186 cmd_ret
== CMD_SUCCESS
);
193 lttng_rotation_schedules_destroy(schedules
);
194 lttng_rotation_schedule_destroy(empty_schedule
);
202 * cmd_disable_rotation
204 * The 'disable-rotation <options>' first level command
206 int cmd_disable_rotation(int argc
, const char **argv
)
208 int popt_ret
, opt
, ret
= 0;
209 enum cmd_error_code cmd_ret
= CMD_SUCCESS
;
210 static poptContext pc
;
211 char *session_name
= NULL
;
212 bool free_session_name
= false;
213 bool periodic_rotation
= false, size_rotation
= false;
215 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
216 popt_ret
= poptReadDefaultConfig(pc
, 0);
219 ERR("poptReadDefaultConfig");
223 while ((opt
= poptGetNextOpt(pc
)) != -1) {
228 case OPT_LIST_OPTIONS
:
229 list_cmd_options(stdout
, long_options
);
232 periodic_rotation
= true;
235 size_rotation
= true;
238 cmd_ret
= CMD_UNDEFINED
;
243 if (opt_session_name
== NULL
) {
244 session_name
= get_session_name();
245 if (session_name
== NULL
) {
248 free_session_name
= true;
250 session_name
= opt_session_name
;
255 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
260 /* Open command element */
261 ret
= mi_lttng_writer_command_open(writer
,
262 mi_lttng_element_command_disable_rotation
);
267 /* Open output element */
268 ret
= mi_lttng_writer_open_element(writer
,
269 mi_lttng_element_command_output
);
275 if (!periodic_rotation
&& !size_rotation
) {
276 ERR("No session rotation schedule type provided.");
282 ret
= mi_lttng_writer_open_element(writer
,
283 mi_lttng_element_rotation_schedule_results
);
288 ret
= mi_lttng_writer_write_element_string(writer
,
289 mi_lttng_element_session_name
,
296 if (periodic_rotation
) {
298 * Continue processing even on error as multiple schedules can
299 * be specified at once.
301 cmd_ret
= remove_schedule(session_name
,
302 LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
);
306 enum cmd_error_code tmp_ret
;
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
;
315 /* Close rotation schedule results element */
316 ret
= mi_lttng_writer_close_element(writer
);
325 /* Close output element */
326 ret
= mi_lttng_writer_close_element(writer
);
332 ret
= mi_lttng_writer_write_element_bool(writer
,
333 mi_lttng_element_command_success
,
334 cmd_ret
== CMD_SUCCESS
);
339 /* Command element close */
340 ret
= mi_lttng_writer_command_close(writer
);
347 (void) mi_lttng_writer_destroy(writer
);
349 if (free_session_name
) {