lttng: destroy: ensure a cmd_error_code is returned by the command
[lttng-tools.git] / src / bin / lttng / commands / disable_channels.cpp
CommitLineData
26cc6b4e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
26cc6b4e 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
26cc6b4e 5 *
26cc6b4e
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
28ab034a
JG
9#include "../command.hpp"
10
11#include <common/mi-lttng.hpp>
12
13#include <lttng/domain-internal.hpp>
14
26cc6b4e
DG
15#include <popt.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <unistd.h>
50534d6f 22
e14f64a8 23static int opt_kernel;
5440dc42 24static char *opt_session_name;
26cc6b4e 25static int opt_userspace;
26cc6b4e 26
4fc83d94
PP
27#ifdef LTTNG_EMBED_HELP
28static const char help_msg[] =
29#include <lttng-disable-channel.1.h>
28ab034a 30 ;
4fc83d94
PP
31#endif
32
26cc6b4e
DG
33enum {
34 OPT_HELP = 1,
35 OPT_USERSPACE,
679b4943 36 OPT_LIST_OPTIONS,
26cc6b4e
DG
37};
38
cd80958d 39static struct lttng_handle *handle;
50534d6f 40static struct mi_writer *writer;
cd80958d 41
26cc6b4e
DG
42static struct poptOption long_options[] = {
43 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
cd9adb8b
JG
44 { "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr },
45 { "session", 's', POPT_ARG_STRING, &opt_session_name, 0, nullptr, nullptr },
46 { "kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, nullptr, nullptr },
47 { "userspace", 'u', POPT_ARG_NONE, nullptr, OPT_USERSPACE, nullptr, nullptr },
48 { "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr },
49 { nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
26cc6b4e
DG
50};
51
28ab034a 52static int mi_partial_channel_print(char *channel_name, unsigned int enabled, int success)
50534d6f
JRJ
53{
54 int ret;
55
a0377dfe
FD
56 LTTNG_ASSERT(writer);
57 LTTNG_ASSERT(channel_name);
50534d6f
JRJ
58
59 /* Open channel element */
60 ret = mi_lttng_writer_open_element(writer, config_element_channel);
61 if (ret) {
62 goto end;
63 }
64
65 /* Name */
28ab034a 66 ret = mi_lttng_writer_write_element_string(writer, config_element_name, channel_name);
50534d6f
JRJ
67 if (ret) {
68 goto end;
69 }
70
71 /* Enabled ? */
28ab034a 72 ret = mi_lttng_writer_write_element_bool(writer, config_element_enabled, enabled);
50534d6f
JRJ
73 if (ret) {
74 goto end;
75 }
76
77 /* Success ? */
28ab034a 78 ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_success, success);
50534d6f
JRJ
79 if (ret) {
80 goto end;
81 }
82
83 /* Closing channel element */
84 ret = mi_lttng_writer_close_element(writer);
85
86end:
87 return ret;
88}
89
26cc6b4e 90/*
cd80958d 91 * Disabling channel using the lttng API.
26cc6b4e 92 */
5b915816 93static int disable_channels(char *session_name, char *channel_list)
26cc6b4e 94{
66cefebd
JG
95 int ret = CMD_SUCCESS;
96 /* Normal case for disable channed is enabled = false */
97 bool warn = false, success, enabled = false;
26cc6b4e 98 char *channel_name;
7d29a247 99 struct lttng_domain dom;
26cc6b4e 100
441c16a7
MD
101 memset(&dom, 0, sizeof(dom));
102
d78d6610 103 /* Create lttng domain */
7d29a247
DG
104 if (opt_kernel) {
105 dom.type = LTTNG_DOMAIN_KERNEL;
d78d6610 106 } else if (opt_userspace) {
78f0bacd 107 dom.type = LTTNG_DOMAIN_UST;
78f0bacd 108 } else {
3ecec76a 109 /* Checked by the caller. */
a0377dfe 110 abort();
7d29a247
DG
111 }
112
cd80958d 113 handle = lttng_create_handle(session_name, &dom);
cd9adb8b 114 if (handle == nullptr) {
cd80958d
DG
115 ret = -1;
116 goto error;
117 }
118
50534d6f
JRJ
119 /* Prepare MI */
120 if (lttng_opt_mi) {
121 /* open a channels element */
122 ret = mi_lttng_writer_open_element(writer, config_element_channels);
123 if (ret) {
124 ret = CMD_ERROR;
125 goto error;
126 }
50534d6f
JRJ
127 }
128
26cc6b4e 129 /* Strip channel list */
5b915816 130 channel_name = strtok(channel_list, ",");
cd9adb8b 131 while (channel_name != nullptr) {
78f0bacd
DG
132 DBG("Disabling channel %s", channel_name);
133
134 ret = lttng_disable_channel(handle, channel_name);
135 if (ret < 0) {
28ab034a
JG
136 ERR("Channel %s: %s (session %s)",
137 channel_name,
138 lttng_strerror(ret),
139 session_name);
66cefebd 140 warn = true;
50534d6f
JRJ
141
142 /*
143 * Mi:
144 * We assume that if an error occurred the channel is still active.
145 * This might not be the case but is a good assumption.
9618049b
JRJ
146 * The client should look at the stderr stream
147 * for more informations.
50534d6f 148 */
66cefebd
JG
149 enabled = true;
150 success = false;
50534d6f 151
26cc6b4e 152 } else {
7885e399 153 MSG("%s channel %s disabled for session %s",
28ab034a
JG
154 lttng_domain_type_str(dom.type),
155 channel_name,
156 session_name);
66cefebd
JG
157 enabled = false;
158 success = true;
50534d6f
JRJ
159 }
160
161 /* Print the channel */
162 if (lttng_opt_mi) {
163 ret = mi_partial_channel_print(channel_name, enabled, success);
164 if (ret) {
165 ret = CMD_ERROR;
166 goto error;
167 }
26cc6b4e
DG
168 }
169
170 /* Next channel */
cd9adb8b 171 channel_name = strtok(nullptr, ",");
26cc6b4e
DG
172 }
173
ae856491
DG
174 ret = CMD_SUCCESS;
175
50534d6f
JRJ
176 /* Close Mi */
177 if (lttng_opt_mi) {
178 /* Close channels element */
179 ret = mi_lttng_writer_close_element(writer);
180 if (ret) {
181 ret = CMD_ERROR;
182 goto error;
183 }
184 }
185
26cc6b4e 186error:
50534d6f
JRJ
187 /* Bypass the warning if a more important error happened */
188 if (!ret && warn) {
ae856491
DG
189 ret = CMD_WARNING;
190 }
191
cd80958d
DG
192 lttng_destroy_handle(handle);
193
26cc6b4e
DG
194 return ret;
195}
196
197/*
198 * cmd_disable_channels
199 *
200 * Disable channel to trace session
201 */
202int cmd_disable_channels(int argc, const char **argv)
203{
50534d6f 204 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
26cc6b4e 205 static poptContext pc;
cd9adb8b
JG
206 char *session_name = nullptr;
207 char *channel_list = nullptr;
208 const char *arg_channel_list = nullptr;
209 const char *leftover = nullptr;
26cc6b4e 210
cd9adb8b 211 pc = poptGetContext(nullptr, argc, argv, long_options, 0);
26cc6b4e
DG
212 poptReadDefaultConfig(pc, 0);
213
214 while ((opt = poptGetNextOpt(pc)) != -1) {
215 switch (opt) {
216 case OPT_HELP:
4ba92f18 217 SHOW_HELP();
26cc6b4e
DG
218 goto end;
219 case OPT_USERSPACE:
220 opt_userspace = 1;
221 break;
679b4943
SM
222 case OPT_LIST_OPTIONS:
223 list_cmd_options(stdout, long_options);
679b4943 224 goto end;
26cc6b4e 225 default:
26cc6b4e
DG
226 ret = CMD_UNDEFINED;
227 goto end;
228 }
229 }
230
28ab034a 231 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace, false);
3ecec76a
PP
232 if (ret) {
233 ret = CMD_ERROR;
234 goto end;
235 }
236
5b915816 237 arg_channel_list = poptGetArg(pc);
cd9adb8b 238 if (arg_channel_list == nullptr) {
5b915816
MJ
239 ERR("Missing channel name(s).");
240 ret = CMD_ERROR;
241 goto end;
242 }
243
244 channel_list = strdup(arg_channel_list);
cd9adb8b 245 if (channel_list == nullptr) {
5b915816 246 PERROR("Failed to copy channel name");
ca1c3607 247 ret = CMD_ERROR;
26cc6b4e
DG
248 goto end;
249 }
250
68c7f6e5
JD
251 leftover = poptGetArg(pc);
252 if (leftover) {
253 ERR("Unknown argument: %s", leftover);
254 ret = CMD_ERROR;
255 goto end;
256 }
257
cd80958d
DG
258 if (!opt_session_name) {
259 session_name = get_session_name();
cd9adb8b 260 if (session_name == nullptr) {
ca1c3607 261 ret = CMD_ERROR;
cd80958d
DG
262 goto end;
263 }
264 } else {
265 session_name = opt_session_name;
266 }
267
50534d6f
JRJ
268 /* Mi check */
269 if (lttng_opt_mi) {
270 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
271 if (!writer) {
272 ret = -LTTNG_ERR_NOMEM;
273 goto end;
274 }
275
276 /* Open command element */
277 ret = mi_lttng_writer_command_open(writer,
28ab034a 278 mi_lttng_element_command_disable_channel);
50534d6f
JRJ
279 if (ret) {
280 ret = CMD_ERROR;
281 goto end;
282 }
283
284 /* Open output element */
28ab034a 285 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
50534d6f
JRJ
286 if (ret) {
287 ret = CMD_ERROR;
288 goto end;
289 }
290 }
291
5b915816 292 command_ret = disable_channels(session_name, channel_list);
50534d6f
JRJ
293 if (command_ret) {
294 success = 0;
295 }
296
297 /* Mi closing */
298 if (lttng_opt_mi) {
299 /* Close output element */
300 ret = mi_lttng_writer_close_element(writer);
301 if (ret) {
302 ret = CMD_ERROR;
303 goto end;
304 }
305
306 /* Success ? */
28ab034a 307 ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_success, success);
50534d6f
JRJ
308 if (ret) {
309 ret = CMD_ERROR;
310 goto end;
311 }
312
313 /* Command element close */
314 ret = mi_lttng_writer_command_close(writer);
315 if (ret) {
316 ret = CMD_ERROR;
317 goto end;
318 }
319 }
26cc6b4e
DG
320
321end:
50534d6f
JRJ
322 /* Mi clean-up */
323 if (writer && mi_lttng_writer_destroy(writer)) {
324 /* Preserve original error code */
325 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
326 }
327
5853fd43
DG
328 if (!opt_session_name && session_name) {
329 free(session_name);
330 }
50534d6f 331
5b915816
MJ
332 free(channel_list);
333
50534d6f
JRJ
334 /* Overwrite ret if an error occurred in disable_channels */
335 ret = command_ret ? command_ret : ret;
336
ca1c3607 337 poptFreeContext(pc);
26cc6b4e
DG
338 return ret;
339}
This page took 0.109841 seconds and 4 git commands to generate.