Commit | Line | Data |
---|---|---|
8c42d845 | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
8c42d845 | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: GPL-2.0-only |
8c42d845 | 5 | * |
8c42d845 JG |
6 | */ |
7 | ||
6c1c0768 | 8 | #define _LGPL_SOURCE |
28ab034a JG |
9 | #include "../command.hpp" |
10 | ||
11 | #include <common/config/session-config.hpp> | |
12 | #include <common/mi-lttng.hpp> | |
13 | ||
14 | #include <lttng/lttng.h> | |
15 | ||
8c42d845 JG |
16 | #include <inttypes.h> |
17 | #include <popt.h> | |
18 | #include <stdio.h> | |
19 | #include <stdlib.h> | |
20 | #include <string.h> | |
8c42d845 | 21 | |
34be8e06 SM |
22 | static char *the_opt_input_path; |
23 | static char *the_opt_override_url; | |
24 | static char *the_opt_override_session_name; | |
25 | static int the_opt_force; | |
26 | static int the_opt_load_all; | |
8c42d845 | 27 | |
34be8e06 | 28 | static const char *the_session_name; |
11143783 | 29 | |
4fc83d94 PP |
30 | #ifdef LTTNG_EMBED_HELP |
31 | static const char help_msg[] = | |
32 | #include <lttng-load.1.h> | |
28ab034a | 33 | ; |
4fc83d94 PP |
34 | #endif |
35 | ||
8c42d845 JG |
36 | enum { |
37 | OPT_HELP = 1, | |
38 | OPT_ALL, | |
39 | OPT_FORCE, | |
13a810d5 | 40 | OPT_LIST_OPTIONS, |
8c42d845 JG |
41 | }; |
42 | ||
34be8e06 | 43 | static struct mi_writer *the_writer; |
1734c658 | 44 | |
34be8e06 | 45 | static struct poptOption the_load_opts[] = { |
8c42d845 | 46 | /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ |
cd9adb8b JG |
47 | { "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr }, |
48 | { "all", 'a', POPT_ARG_NONE, nullptr, OPT_ALL, nullptr, nullptr }, | |
49 | { "input-path", 'i', POPT_ARG_STRING, &the_opt_input_path, 0, nullptr, nullptr }, | |
50 | { "force", 'f', POPT_ARG_NONE, nullptr, OPT_FORCE, nullptr, nullptr }, | |
51 | { "override-url", 0, POPT_ARG_STRING, &the_opt_override_url, 0, nullptr, nullptr }, | |
52 | { "override-name", 0, POPT_ARG_STRING, &the_opt_override_session_name, 0, nullptr, nullptr }, | |
53 | { "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr }, | |
54 | { nullptr, 0, 0, nullptr, 0, nullptr, nullptr } | |
8c42d845 JG |
55 | }; |
56 | ||
1734c658 JRJ |
57 | static int mi_partial_session(const char *session_name) |
58 | { | |
59 | int ret; | |
a0377dfe FD |
60 | LTTNG_ASSERT(the_writer); |
61 | LTTNG_ASSERT(session_name); | |
1734c658 JRJ |
62 | |
63 | /* Open session element */ | |
34be8e06 | 64 | ret = mi_lttng_writer_open_element(the_writer, config_element_session); |
1734c658 JRJ |
65 | if (ret) { |
66 | goto end; | |
67 | } | |
68 | ||
28ab034a | 69 | ret = mi_lttng_writer_write_element_string(the_writer, config_element_name, session_name); |
1734c658 JRJ |
70 | if (ret) { |
71 | goto end; | |
72 | } | |
73 | ||
74 | /* Closing session element */ | |
34be8e06 | 75 | ret = mi_lttng_writer_close_element(the_writer); |
1734c658 JRJ |
76 | end: |
77 | return ret; | |
78 | } | |
79 | ||
80 | /* | |
81 | * Mi print of load command | |
82 | */ | |
83 | static int mi_load_print(const char *session_name) | |
84 | { | |
85 | int ret; | |
a0377dfe | 86 | LTTNG_ASSERT(the_writer); |
1734c658 | 87 | |
34be8e06 | 88 | if (the_opt_load_all) { |
1734c658 JRJ |
89 | /* We use a wildcard to represent all sessions */ |
90 | session_name = "*"; | |
91 | } | |
92 | ||
93 | /* Print load element */ | |
34be8e06 | 94 | ret = mi_lttng_writer_open_element(the_writer, mi_lttng_element_load); |
1734c658 JRJ |
95 | if (ret) { |
96 | goto end; | |
97 | } | |
98 | ||
99 | /* Print session element */ | |
100 | ret = mi_partial_session(session_name); | |
101 | if (ret) { | |
102 | goto end; | |
103 | } | |
104 | ||
105 | /* Path element */ | |
34be8e06 | 106 | if (the_opt_input_path) { |
28ab034a JG |
107 | ret = mi_lttng_writer_write_element_string( |
108 | the_writer, config_element_path, the_opt_input_path); | |
1734c658 JRJ |
109 | if (ret) { |
110 | goto end; | |
111 | } | |
112 | } | |
113 | ||
23cb2d55 | 114 | /* Print override elements */ |
34be8e06 | 115 | ret = mi_lttng_writer_open_element(the_writer, mi_lttng_element_load_overrides); |
23cb2d55 JR |
116 | if (ret) { |
117 | goto end; | |
118 | } | |
119 | ||
120 | /* Session name override element */ | |
34be8e06 | 121 | if (the_opt_override_session_name) { |
28ab034a JG |
122 | ret = mi_lttng_writer_write_element_string( |
123 | the_writer, config_element_name, the_opt_override_session_name); | |
23cb2d55 JR |
124 | if (ret) { |
125 | goto end; | |
126 | } | |
127 | } | |
128 | ||
129 | /* Session url override element */ | |
34be8e06 | 130 | if (the_opt_override_url) { |
28ab034a JG |
131 | ret = mi_lttng_writer_write_element_string( |
132 | the_writer, mi_lttng_element_load_override_url, the_opt_override_url); | |
23cb2d55 JR |
133 | if (ret) { |
134 | goto end; | |
135 | } | |
136 | } | |
1734c658 | 137 | |
23cb2d55 | 138 | /* Close override and load element */ |
34be8e06 | 139 | ret = mi_lttng_close_multi_element(the_writer, 2); |
1734c658 JRJ |
140 | end: |
141 | return ret; | |
142 | } | |
143 | ||
8c42d845 JG |
144 | /* |
145 | * The 'load <options>' first level command | |
146 | */ | |
147 | int cmd_load(int argc, const char **argv) | |
148 | { | |
b6d4654a | 149 | int ret, success; |
8c42d845 JG |
150 | int opt; |
151 | poptContext pc; | |
cd9adb8b JG |
152 | struct lttng_load_session_attr *session_attr = nullptr; |
153 | char *input_path = nullptr; | |
154 | const char *leftover = nullptr; | |
8c42d845 | 155 | |
cd9adb8b | 156 | pc = poptGetContext(nullptr, argc, argv, the_load_opts, 0); |
8c42d845 JG |
157 | poptReadDefaultConfig(pc, 0); |
158 | ||
159 | while ((opt = poptGetNextOpt(pc)) != -1) { | |
160 | switch (opt) { | |
161 | case OPT_HELP: | |
4ba92f18 | 162 | SHOW_HELP(); |
b6d4654a | 163 | ret = CMD_SUCCESS; |
8c42d845 JG |
164 | goto end; |
165 | case OPT_ALL: | |
34be8e06 | 166 | the_opt_load_all = 1; |
8c42d845 | 167 | break; |
13a810d5 | 168 | case OPT_LIST_OPTIONS: |
34be8e06 | 169 | list_cmd_options(stdout, the_load_opts); |
b6d4654a | 170 | ret = CMD_SUCCESS; |
13a810d5 | 171 | goto end; |
8c42d845 | 172 | case OPT_FORCE: |
34be8e06 | 173 | the_opt_force = 1; |
8c42d845 JG |
174 | break; |
175 | default: | |
8c42d845 JG |
176 | ret = CMD_UNDEFINED; |
177 | goto end; | |
178 | } | |
179 | } | |
180 | ||
623bc34c JG |
181 | ret = lttng_session_daemon_alive(); |
182 | if (!ret) { | |
183 | ERR("No session daemon is available"); | |
184 | ret = CMD_ERROR; | |
185 | goto end; | |
186 | } | |
187 | ||
34be8e06 SM |
188 | if (!the_opt_load_all) { |
189 | the_session_name = poptGetArg(pc); | |
190 | if (the_session_name) { | |
191 | DBG2("Loading session name: %s", the_session_name); | |
1734c658 JRJ |
192 | } else { |
193 | /* Default to load_all */ | |
34be8e06 | 194 | the_opt_load_all = 1; |
11143783 | 195 | } |
8c42d845 JG |
196 | } |
197 | ||
68c7f6e5 JD |
198 | leftover = poptGetArg(pc); |
199 | if (leftover) { | |
200 | ERR("Unknown argument: %s", leftover); | |
201 | ret = CMD_ERROR; | |
202 | goto end; | |
203 | } | |
204 | ||
1734c658 JRJ |
205 | /* Mi check */ |
206 | if (lttng_opt_mi) { | |
34be8e06 SM |
207 | the_writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); |
208 | if (!the_writer) { | |
b6d4654a | 209 | ret = CMD_ERROR; |
1734c658 JRJ |
210 | goto end; |
211 | } | |
212 | ||
213 | /* Open command element */ | |
28ab034a | 214 | ret = mi_lttng_writer_command_open(the_writer, mi_lttng_element_command_load); |
1734c658 JRJ |
215 | if (ret) { |
216 | ret = CMD_ERROR; | |
217 | goto end; | |
218 | } | |
219 | ||
220 | /* Open output element */ | |
28ab034a | 221 | ret = mi_lttng_writer_open_element(the_writer, mi_lttng_element_command_output); |
1734c658 JRJ |
222 | if (ret) { |
223 | ret = CMD_ERROR; | |
224 | goto end; | |
225 | } | |
226 | } | |
227 | ||
b6d4654a JR |
228 | /* Prepare load attributes */ |
229 | session_attr = lttng_load_session_attr_create(); | |
230 | if (!session_attr) { | |
231 | ERR("Failed to create load session attributes"); | |
232 | ret = CMD_ERROR; | |
233 | goto end; | |
234 | } | |
235 | ||
236 | /* | |
237 | * Set the input url | |
238 | * lttng_load_session_attr_set_input_url only suppports absolute path. | |
239 | * Use realpath to resolve any relative path. | |
240 | * */ | |
34be8e06 | 241 | if (the_opt_input_path) { |
cd9adb8b | 242 | input_path = realpath(the_opt_input_path, nullptr); |
b6d4654a JR |
243 | if (!input_path) { |
244 | PERROR("Invalid input path"); | |
245 | ret = CMD_ERROR; | |
246 | goto end; | |
247 | } | |
248 | } else { | |
cd9adb8b | 249 | input_path = nullptr; |
b6d4654a JR |
250 | } |
251 | ||
28ab034a | 252 | ret = lttng_load_session_attr_set_input_url(session_attr, input_path); |
b6d4654a JR |
253 | if (ret) { |
254 | ERR("Invalid input path"); | |
255 | ret = CMD_ERROR; | |
256 | goto end; | |
257 | } | |
258 | ||
259 | /* Set the session name. NULL means all sessions should be loaded */ | |
28ab034a | 260 | ret = lttng_load_session_attr_set_session_name(session_attr, the_session_name); |
b6d4654a JR |
261 | if (ret) { |
262 | ERR("Invalid session name"); | |
263 | ret = CMD_ERROR; | |
264 | goto end; | |
265 | } | |
266 | ||
267 | /* Set the overwrite attribute */ | |
34be8e06 | 268 | ret = lttng_load_session_attr_set_overwrite(session_attr, the_opt_force); |
b6d4654a JR |
269 | if (ret) { |
270 | ERR("Force argument could not be applied"); | |
271 | ret = CMD_ERROR; | |
272 | goto end; | |
273 | } | |
274 | ||
fe559816 | 275 | /* Set the overrides attributes if any */ |
34be8e06 | 276 | if (the_opt_override_url) { |
28ab034a | 277 | ret = lttng_load_session_attr_set_override_url(session_attr, the_opt_override_url); |
fe559816 JR |
278 | if (ret) { |
279 | ERR("Url override is invalid"); | |
280 | goto end; | |
281 | } | |
282 | } | |
283 | ||
34be8e06 SM |
284 | if (the_opt_override_session_name) { |
285 | if (the_opt_load_all) { | |
e1f481f6 JR |
286 | ERR("Options --all and --override-name cannot be used simultaneously"); |
287 | ret = CMD_ERROR; | |
288 | goto end; | |
289 | } | |
28ab034a JG |
290 | ret = lttng_load_session_attr_set_override_session_name( |
291 | session_attr, the_opt_override_session_name); | |
e1f481f6 JR |
292 | if (ret) { |
293 | ERR("Failed to set session name override"); | |
294 | ret = CMD_ERROR; | |
295 | goto end; | |
296 | } | |
297 | } | |
298 | ||
b6d4654a JR |
299 | ret = lttng_load_session(session_attr); |
300 | if (ret) { | |
301 | ERR("%s", lttng_strerror(ret)); | |
1734c658 | 302 | success = 0; |
b6d4654a | 303 | ret = CMD_ERROR; |
279d6193 | 304 | } else { |
34be8e06 | 305 | if (the_opt_load_all) { |
279d6193 | 306 | MSG("All sessions have been loaded successfully"); |
34be8e06 SM |
307 | } else if (the_session_name) { |
308 | ret = config_init((char *) the_session_name); | |
8e525b95 | 309 | if (ret < 0) { |
28ab034a | 310 | WARN("Could not set %s as the default session", the_session_name); |
8e525b95 | 311 | } |
34be8e06 | 312 | MSG("Session %s has been loaded successfully", the_session_name); |
732b768a DG |
313 | } else { |
314 | MSG("Session has been loaded successfully"); | |
279d6193 | 315 | } |
fe559816 | 316 | |
34be8e06 | 317 | if (the_opt_override_session_name) { |
28ab034a | 318 | MSG("Session name overridden with %s", the_opt_override_session_name); |
060e2e09 JR |
319 | } |
320 | ||
34be8e06 SM |
321 | if (the_opt_override_url) { |
322 | MSG("Session output url overridden with %s", the_opt_override_url); | |
fe559816 | 323 | } |
1734c658 | 324 | success = 1; |
b6d4654a | 325 | ret = CMD_SUCCESS; |
1734c658 JRJ |
326 | } |
327 | ||
328 | /* Mi Printing and closing */ | |
329 | if (lttng_opt_mi) { | |
330 | /* Mi print */ | |
34be8e06 | 331 | ret = mi_load_print(the_session_name); |
1734c658 JRJ |
332 | if (ret) { |
333 | ret = CMD_ERROR; | |
334 | goto end; | |
335 | } | |
336 | ||
337 | /* Close output element */ | |
34be8e06 | 338 | ret = mi_lttng_writer_close_element(the_writer); |
1734c658 JRJ |
339 | if (ret) { |
340 | ret = CMD_ERROR; | |
341 | goto end; | |
342 | } | |
343 | ||
344 | /* Success ? */ | |
28ab034a JG |
345 | ret = mi_lttng_writer_write_element_bool( |
346 | the_writer, mi_lttng_element_command_success, success); | |
1734c658 JRJ |
347 | if (ret) { |
348 | ret = CMD_ERROR; | |
349 | goto end; | |
350 | } | |
351 | ||
352 | /* Command element close */ | |
34be8e06 | 353 | ret = mi_lttng_writer_command_close(the_writer); |
1734c658 JRJ |
354 | if (ret) { |
355 | ret = CMD_ERROR; | |
356 | goto end; | |
357 | } | |
8c42d845 JG |
358 | } |
359 | end: | |
34be8e06 | 360 | if (the_writer && mi_lttng_writer_destroy(the_writer)) { |
b6d4654a | 361 | ERR("Failed to destroy mi lttng writer"); |
1734c658 JRJ |
362 | } |
363 | ||
b6d4654a JR |
364 | lttng_load_session_attr_destroy(session_attr); |
365 | free(input_path); | |
8c42d845 JG |
366 | poptFreeContext(pc); |
367 | return ret; | |
368 | } |