lttng: destroy: ensure a cmd_error_code is returned by the command
[lttng-tools.git] / src / bin / lttng / commands / regenerate.cpp
1 /*
2 * Copyright (C) 2015 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
13 #include <ctype.h>
14 #include <popt.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 static char *opt_session_name;
21 static char *session_name = nullptr;
22
23 static int regenerate_metadata(int argc, const char **argv);
24 static int regenerate_statedump(int argc, const char **argv);
25
26 #ifdef LTTNG_EMBED_HELP
27 static const char help_msg[] =
28 #include <lttng-regenerate.1.h>
29 ;
30 #endif
31
32 enum {
33 OPT_HELP = 1,
34 OPT_LIST_OPTIONS,
35 OPT_LIST_COMMANDS,
36 };
37
38 static struct mi_writer *writer;
39
40 static struct poptOption long_options[] = {
41 /* { longName, shortName, argInfo, argPtr, value, descrip, argDesc, } */
42 {
43 "help",
44 'h',
45 POPT_ARG_NONE,
46 nullptr,
47 OPT_HELP,
48 nullptr,
49 nullptr,
50 },
51 { "session", 's', POPT_ARG_STRING, &opt_session_name, 0, nullptr, nullptr },
52 {
53 "list-options",
54 0,
55 POPT_ARG_NONE,
56 nullptr,
57 OPT_LIST_OPTIONS,
58 nullptr,
59 nullptr,
60 },
61 { "list-commands", 0, POPT_ARG_NONE, nullptr, OPT_LIST_COMMANDS, nullptr, nullptr },
62 {
63 nullptr,
64 0,
65 0,
66 nullptr,
67 0,
68 nullptr,
69 nullptr,
70 },
71 };
72
73 static struct cmd_struct actions[] = {
74 { "metadata", regenerate_metadata },
75 { "statedump", regenerate_statedump },
76 { nullptr, nullptr } /* Array closure */
77 };
78
79 /*
80 * Count and return the number of arguments in argv.
81 */
82 static int count_arguments(const char **argv)
83 {
84 int i = 0;
85
86 LTTNG_ASSERT(argv);
87
88 while (argv[i] != nullptr) {
89 i++;
90 }
91
92 return i;
93 }
94
95 static int regenerate_metadata(int argc, const char **argv __attribute__((unused)))
96 {
97 int ret;
98
99 if (argc > 1) {
100 ret = CMD_UNDEFINED;
101 goto end;
102 }
103 ret = lttng_regenerate_metadata(session_name);
104 if (ret == 0) {
105 MSG("Metadata successfully regenerated for session %s", session_name);
106 } else {
107 ERR("%s", lttng_strerror(ret));
108 }
109
110 end:
111 return ret;
112 }
113
114 static int regenerate_statedump(int argc, const char **argv __attribute__((unused)))
115 {
116 int ret;
117
118 if (argc > 1) {
119 ret = -LTTNG_ERR_INVALID;
120 goto end;
121 }
122 ret = lttng_regenerate_statedump(session_name);
123 if (ret == 0) {
124 MSG("State dump successfully regenerated for session %s", session_name);
125 }
126
127 end:
128 return ret;
129 }
130
131 static int handle_command(const char **argv)
132 {
133 struct cmd_struct *cmd;
134 int ret = CMD_SUCCESS, i = 0, argc, command_ret = CMD_SUCCESS;
135
136 if (argv == nullptr) {
137 ERR("No object specified for regenerate command.");
138 command_ret = CMD_ERROR;
139 goto end;
140 }
141
142 argc = count_arguments(argv);
143 LTTNG_ASSERT(argc >= 1);
144
145 cmd = &actions[i];
146 while (cmd->func != nullptr) {
147 /* Find command */
148 if (strcmp(argv[0], cmd->name) == 0) {
149 if (lttng_opt_mi) {
150 /* Action element */
151 ret = mi_lttng_writer_open_element(
152 writer, mi_lttng_element_command_regenerate_action);
153 if (ret) {
154 ret = CMD_ERROR;
155 goto end;
156 }
157
158 /* Name of the action */
159 ret = mi_lttng_writer_write_element_string(
160 writer, config_element_name, argv[0]);
161 if (ret) {
162 ret = CMD_ERROR;
163 goto end;
164 }
165 }
166 command_ret = cmd->func(argc, argv);
167 if (lttng_opt_mi) {
168 /* Close output and action element */
169 ret = mi_lttng_writer_close_element(writer);
170 if (ret) {
171 ret = CMD_ERROR;
172 goto end;
173 }
174 }
175 goto end;
176 }
177
178 cmd = &actions[i++];
179 }
180
181 ret = CMD_UNDEFINED;
182
183 end:
184 /* Overwrite ret if an error occurred in cmd->func() */
185 ret = command_ret ? command_ret : ret;
186 return ret;
187 }
188
189 /*
190 * regenerate command handling.
191 */
192 int cmd_regenerate(int argc, const char **argv)
193 {
194 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
195 static poptContext pc;
196
197 if (argc < 1) {
198 SHOW_HELP();
199 ret = CMD_ERROR;
200 goto end;
201 }
202
203 pc = poptGetContext(nullptr, argc, argv, long_options, 0);
204 poptReadDefaultConfig(pc, 0);
205
206 if (lttng_opt_mi) {
207 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
208 if (!writer) {
209 ret = -LTTNG_ERR_NOMEM;
210 goto end;
211 }
212 /* Open command element */
213 ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_regenerate);
214 if (ret) {
215 ret = CMD_ERROR;
216 goto end;
217 }
218
219 /* Open output element */
220 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
221 if (ret) {
222 ret = CMD_ERROR;
223 goto end;
224 }
225 }
226
227 while ((opt = poptGetNextOpt(pc)) != -1) {
228 switch (opt) {
229 case OPT_HELP:
230 SHOW_HELP();
231 goto end;
232 case OPT_LIST_OPTIONS:
233 list_cmd_options(stdout, long_options);
234 goto end;
235 case OPT_LIST_COMMANDS:
236 list_commands(actions, stdout);
237 goto end;
238 default:
239 SHOW_HELP();
240 ret = CMD_UNDEFINED;
241 goto end;
242 }
243 }
244
245 if (!opt_session_name) {
246 session_name = get_session_name();
247 if (session_name == nullptr) {
248 ret = CMD_ERROR;
249 goto end;
250 }
251 } else {
252 session_name = opt_session_name;
253 }
254
255 command_ret = handle_command(poptGetArgs(pc));
256 if (command_ret) {
257 success = 0;
258 }
259
260 if (lttng_opt_mi) {
261 /* Close output element */
262 ret = mi_lttng_writer_close_element(writer);
263 if (ret) {
264 ret = CMD_ERROR;
265 goto end;
266 }
267
268 /* Success ? */
269 ret = mi_lttng_writer_write_element_bool(
270 writer, mi_lttng_element_command_success, success);
271 if (ret) {
272 ret = CMD_ERROR;
273 goto end;
274 }
275
276 /* Command element close */
277 ret = mi_lttng_writer_command_close(writer);
278 if (ret) {
279 ret = CMD_ERROR;
280 goto end;
281 }
282 }
283
284 end:
285 /* Mi clean-up */
286 if (writer && mi_lttng_writer_destroy(writer)) {
287 /* Preserve original error code */
288 ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
289 }
290
291 if (!opt_session_name) {
292 free(session_name);
293 }
294
295 /* Overwrite ret if an error occurred during handle_command() */
296 ret = command_ret ? command_ret : ret;
297
298 poptFreeContext(pc);
299 return ret;
300 }
This page took 0.036551 seconds and 4 git commands to generate.