Commit | Line | Data |
---|---|---|
d68c9a04 | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com> |
d68c9a04 | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: GPL-2.0-only |
d68c9a04 | 5 | * |
d68c9a04 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> | |
d68c9a04 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> | |
d68c9a04 | 25 | |
d68c9a04 JD |
26 | static int opt_no_wait; |
27 | static struct mi_writer *writer; | |
28 | ||
3ae5c539 JD |
29 | #ifdef LTTNG_EMBED_HELP |
30 | static const char help_msg[] = | |
31 | #include <lttng-rotate.1.h> | |
28ab034a | 32 | ; |
3ae5c539 JD |
33 | #endif |
34 | ||
d68c9a04 JD |
35 | enum { |
36 | OPT_HELP = 1, | |
37 | OPT_LIST_OPTIONS, | |
38 | }; | |
39 | ||
40 | static struct poptOption long_options[] = { | |
41 | /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ | |
cd9adb8b JG |
42 | { "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr }, |
43 | { "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr }, | |
44 | { "no-wait", 'n', POPT_ARG_VAL, &opt_no_wait, 1, nullptr, nullptr }, | |
45 | { nullptr, 0, 0, nullptr, 0, nullptr, nullptr } | |
d68c9a04 JD |
46 | }; |
47 | ||
d68c9a04 JD |
48 | static int rotate_tracing(char *session_name) |
49 | { | |
50 | int ret; | |
91c4d516 | 51 | enum cmd_error_code cmd_ret = CMD_SUCCESS; |
cd9adb8b | 52 | struct lttng_rotation_handle *handle = nullptr; |
d68c9a04 JD |
53 | enum lttng_rotation_status rotation_status; |
54 | enum lttng_rotation_state rotation_state = LTTNG_ROTATION_STATE_ONGOING; | |
cd9adb8b | 55 | const struct lttng_trace_archive_location *location = nullptr; |
91c4d516 | 56 | bool print_location = true; |
d68c9a04 JD |
57 | |
58 | DBG("Rotating the output files of session %s", session_name); | |
59 | ||
cd9adb8b | 60 | ret = lttng_rotate_session(session_name, nullptr, &handle); |
d68c9a04 JD |
61 | if (ret < 0) { |
62 | switch (-ret) { | |
63 | case LTTNG_ERR_SESSION_NOT_STARTED: | |
64 | WARN("Tracing session %s not started yet", session_name); | |
91c4d516 JG |
65 | cmd_ret = CMD_WARNING; |
66 | goto end; | |
d68c9a04 JD |
67 | default: |
68 | ERR("%s", lttng_strerror(ret)); | |
91c4d516 | 69 | goto error; |
d68c9a04 | 70 | } |
91c4d516 JG |
71 | } |
72 | ||
73 | if (opt_no_wait) { | |
74 | rotation_state = LTTNG_ROTATION_STATE_ONGOING; | |
75 | goto skip_wait; | |
76 | } | |
77 | ||
78 | _MSG("Waiting for rotation to complete"); | |
79 | ret = fflush(stdout); | |
80 | if (ret) { | |
81 | PERROR("fflush"); | |
d68c9a04 JD |
82 | goto error; |
83 | } | |
84 | ||
91c4d516 | 85 | do { |
28ab034a | 86 | rotation_status = lttng_rotation_handle_get_state(handle, &rotation_state); |
91c4d516 | 87 | if (rotation_status != LTTNG_ROTATION_STATUS_OK) { |
d2956687 | 88 | MSG(""); |
91c4d516 | 89 | ERR("Failed to query the state of the rotation."); |
d68c9a04 JD |
90 | goto error; |
91 | } | |
92 | ||
91c4d516 | 93 | if (rotation_state == LTTNG_ROTATION_STATE_ONGOING) { |
c8f61fd4 | 94 | ret = usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME_US); |
91c4d516 | 95 | if (ret) { |
d2956687 | 96 | PERROR("\nusleep"); |
d68c9a04 JD |
97 | goto error; |
98 | } | |
91c4d516 | 99 | _MSG("."); |
d68c9a04 | 100 | |
91c4d516 JG |
101 | ret = fflush(stdout); |
102 | if (ret) { | |
d2956687 | 103 | PERROR("\nfflush"); |
91c4d516 | 104 | goto error; |
d68c9a04 | 105 | } |
91c4d516 JG |
106 | } |
107 | } while (rotation_state == LTTNG_ROTATION_STATE_ONGOING); | |
108 | MSG(""); | |
d68c9a04 | 109 | |
91c4d516 | 110 | skip_wait: |
d68c9a04 JD |
111 | switch (rotation_state) { |
112 | case LTTNG_ROTATION_STATE_COMPLETED: | |
28ab034a | 113 | rotation_status = lttng_rotation_handle_get_archive_location(handle, &location); |
d68c9a04 | 114 | if (rotation_status != LTTNG_ROTATION_STATUS_OK) { |
91c4d516 JG |
115 | ERR("Failed to retrieve the rotation's completed chunk archive location."); |
116 | cmd_ret = CMD_ERROR; | |
d68c9a04 | 117 | } |
91c4d516 | 118 | break; |
d68c9a04 | 119 | case LTTNG_ROTATION_STATE_EXPIRED: |
91c4d516 JG |
120 | break; |
121 | case LTTNG_ROTATION_STATE_ERROR: | |
122 | ERR("Failed to retrieve rotation state."); | |
91c4d516 JG |
123 | goto error; |
124 | case LTTNG_ROTATION_STATE_ONGOING: | |
125 | MSG("Rotation ongoing for session %s", session_name); | |
126 | print_location = false; | |
127 | break; | |
d68c9a04 | 128 | default: |
91c4d516 | 129 | ERR("Unexpected rotation state encountered."); |
d68c9a04 JD |
130 | goto error; |
131 | } | |
132 | ||
91c4d516 | 133 | if (!lttng_opt_mi && print_location) { |
28ab034a | 134 | ret = print_trace_archive_location(location, session_name); |
91c4d516 | 135 | } else if (lttng_opt_mi) { |
28ab034a | 136 | ret = mi_lttng_rotate(writer, session_name, rotation_state, location); |
91c4d516 JG |
137 | } |
138 | ||
139 | if (ret < 0) { | |
140 | cmd_ret = CMD_ERROR; | |
141 | } | |
142 | ||
d68c9a04 JD |
143 | end: |
144 | lttng_rotation_handle_destroy(handle); | |
91c4d516 JG |
145 | return cmd_ret; |
146 | error: | |
147 | cmd_ret = CMD_ERROR; | |
148 | goto end; | |
d68c9a04 JD |
149 | } |
150 | ||
151 | /* | |
152 | * cmd_rotate | |
153 | * | |
154 | * The 'rotate <options>' first level command | |
155 | */ | |
156 | int cmd_rotate(int argc, const char **argv) | |
157 | { | |
91c4d516 JG |
158 | int opt, ret; |
159 | enum cmd_error_code cmd_ret = CMD_SUCCESS; | |
d68c9a04 JD |
160 | int popt_ret; |
161 | static poptContext pc; | |
cd9adb8b JG |
162 | const char *arg_session_name = nullptr; |
163 | char *session_name = nullptr; | |
d68c9a04 | 164 | |
cd9adb8b | 165 | pc = poptGetContext(nullptr, argc, argv, long_options, 0); |
d68c9a04 JD |
166 | popt_ret = poptReadDefaultConfig(pc, 0); |
167 | if (popt_ret) { | |
d68c9a04 | 168 | ERR("poptReadDefaultConfig"); |
5b915816 MJ |
169 | cmd_ret = CMD_ERROR; |
170 | goto end; | |
d68c9a04 JD |
171 | } |
172 | ||
173 | while ((opt = poptGetNextOpt(pc)) != -1) { | |
174 | switch (opt) { | |
175 | case OPT_HELP: | |
176 | SHOW_HELP(); | |
177 | goto end; | |
178 | case OPT_LIST_OPTIONS: | |
179 | list_cmd_options(stdout, long_options); | |
180 | goto end; | |
181 | default: | |
91c4d516 | 182 | cmd_ret = CMD_UNDEFINED; |
d68c9a04 JD |
183 | goto end; |
184 | } | |
185 | } | |
186 | ||
5b915816 | 187 | arg_session_name = poptGetArg(pc); |
cd9adb8b | 188 | if (arg_session_name == nullptr) { |
d68c9a04 | 189 | session_name = get_session_name(); |
d68c9a04 | 190 | } else { |
5b915816 | 191 | session_name = strdup(arg_session_name); |
cd9adb8b | 192 | if (session_name == nullptr) { |
5b915816 MJ |
193 | PERROR("Failed to copy session name"); |
194 | } | |
195 | } | |
196 | ||
cd9adb8b | 197 | if (session_name == nullptr) { |
5b915816 MJ |
198 | cmd_ret = CMD_ERROR; |
199 | goto end; | |
d68c9a04 JD |
200 | } |
201 | ||
202 | /* Mi check */ | |
203 | if (lttng_opt_mi) { | |
204 | writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); | |
205 | if (!writer) { | |
5b915816 MJ |
206 | cmd_ret = CMD_ERROR; |
207 | goto end; | |
d68c9a04 JD |
208 | } |
209 | ||
210 | /* Open rotate command */ | |
28ab034a | 211 | ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_rotate); |
d68c9a04 | 212 | if (ret) { |
5b915816 MJ |
213 | cmd_ret = CMD_ERROR; |
214 | goto end; | |
d68c9a04 JD |
215 | } |
216 | ||
217 | /* Open output element */ | |
28ab034a | 218 | ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); |
d68c9a04 | 219 | if (ret) { |
5b915816 MJ |
220 | cmd_ret = CMD_ERROR; |
221 | goto end; | |
d68c9a04 | 222 | } |
d68c9a04 JD |
223 | } |
224 | ||
48a40005 | 225 | cmd_ret = (cmd_error_code) rotate_tracing(session_name); |
d68c9a04 JD |
226 | |
227 | /* Mi closing */ | |
228 | if (lttng_opt_mi) { | |
66ea93b1 | 229 | /* Close output element */ |
d68c9a04 JD |
230 | ret = mi_lttng_writer_close_element(writer); |
231 | if (ret) { | |
5b915816 MJ |
232 | cmd_ret = CMD_ERROR; |
233 | goto end; | |
d68c9a04 JD |
234 | } |
235 | /* Success ? */ | |
28ab034a JG |
236 | ret = mi_lttng_writer_write_element_bool( |
237 | writer, mi_lttng_element_command_success, cmd_ret == CMD_SUCCESS); | |
d68c9a04 | 238 | if (ret) { |
5b915816 MJ |
239 | cmd_ret = CMD_ERROR; |
240 | goto end; | |
d68c9a04 JD |
241 | } |
242 | ||
243 | /* Command element close */ | |
244 | ret = mi_lttng_writer_command_close(writer); | |
245 | if (ret) { | |
5b915816 MJ |
246 | cmd_ret = CMD_ERROR; |
247 | goto end; | |
d68c9a04 JD |
248 | } |
249 | } | |
250 | ||
d68c9a04 JD |
251 | /* Mi clean-up */ |
252 | if (writer && mi_lttng_writer_destroy(writer)) { | |
5b915816 MJ |
253 | cmd_ret = CMD_ERROR; |
254 | goto end; | |
d68c9a04 | 255 | } |
91c4d516 | 256 | end: |
5b915816 | 257 | free(session_name); |
d68c9a04 | 258 | poptFreeContext(pc); |
91c4d516 JG |
259 | |
260 | return cmd_ret; | |
d68c9a04 | 261 | } |