Commit | Line | Data |
---|---|---|
76bcac58 PP |
1 | #compdef lttng |
2 | # | |
3 | # Copyright (c) 2015-2023 Philippe Proulx <eeppeliteloop@gmail.com> | |
4 | # | |
5 | # Permission is hereby granted, free of charge, to any person obtaining | |
6 | # a copy of this software and associated documentation files (the | |
7 | # "Software"), to deal in the Software without restriction, including | |
8 | # without limitation the rights to use, copy, modify, merge, publish, | |
9 | # distribute, sublicense, and/or sell copies of the Software, and to | |
10 | # permit persons to whom the Software is furnished to do so, subject to | |
11 | # the following conditions: | |
12 | # | |
13 | # The above copyright notice and this permission notice shall be | |
14 | # included in all copies or substantial portions of the Software. | |
15 | # | |
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
20 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
21 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
22 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 | # | |
24 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
25 | # | |
26 | # This is a Zsh completion function for the lttng(1) command (see | |
27 | # <https://lttng.org/>), for versions 2.5 to 2.14. | |
28 | # | |
29 | # If you want, at your own risk, the function to work with versions | |
30 | # above 2.14, set `LTTNG_ZSH_COMP_IGNORE_VERSION_LIMIT=1`. | |
31 | # | |
32 | # Each subcommand changes the command part of the current context so | |
33 | # that you can target a specific subcommand with `zstyle`, for | |
34 | # example: | |
35 | # | |
36 | # $ zstyle ':completion:*:*:lttng-start:*:sessions' verbose yes | |
37 | # $ zstyle ':completion:*:*:lttng-add-context:type-option:*' \ | |
38 | # group-order perf-context-types static-context-types | |
39 | # | |
40 | # The relevant style arguments and tags are: | |
41 | # | |
42 | # `actions` tag (with the `lttng-snapshot` command): | |
43 | # Snapshot action names. | |
44 | # | |
45 | # `channel` argument and `channels` tag: | |
46 | # Channel names. | |
47 | # | |
48 | # The `verbose` style controls whether or not this function adds | |
49 | # completions as a list (with channel information for each item) or | |
50 | # simple channel names. | |
51 | # | |
52 | # If the verbose style is enabled, then the information part of each | |
53 | # item starts with either ` [enabled` or ` [disabled` (note the | |
54 | # two leading spaces), depending on the status of the channel. | |
55 | # | |
56 | # `commands` tag: | |
57 | # lttng(1) subcommand names. | |
58 | # | |
59 | # `log-levels` tag: | |
60 | # Log level names. | |
61 | # | |
62 | # `session` argument and `sessions` tag: | |
63 | # Recording session names. | |
64 | # | |
65 | # The `verbose` style controls whether or not this function adds | |
66 | # completions as a list (with recording session information for each | |
67 | # item) or simple recording session names. | |
68 | # | |
69 | # If the verbose style is enabled, then the information part of each | |
70 | # item starts with either ` [active` or ` [inactive` (note the two | |
71 | # leading spaces), depending on the status of the recording session. | |
72 | # | |
73 | # `type-option` argument: | |
74 | # `static-context-types` tag: | |
75 | # Statically-known context field types. | |
76 | # | |
77 | # `perf-context-types` tag: | |
78 | # perf counter context field types. | |
79 | # | |
80 | # `triggers` tag: | |
81 | # Trigger names. | |
82 | ||
83 | # Sets the `minor_version` variable to the minor version of LTTng-tools, | |
84 | # or to `0` if not found. | |
85 | __lttng_set_minor_version() { | |
86 | minor_version=0 | |
87 | ||
88 | local -a match | |
89 | ||
90 | if [[ $($prog_name --version) =~ '[[:blank:]]+2\.([[:digit:]]+)' ]]; then | |
91 | minor_version=$match[1] | |
92 | fi | |
93 | } | |
94 | ||
95 | # Runs the `lttng` command with `"$@"` using `$tracing_group`. | |
96 | __lttng_run() { | |
97 | $prog_name --no-sessiond --group=$tracing_group "$@" 2>/dev/null | |
98 | } | |
99 | ||
100 | # Runs the `lttng --mi=xml` command using the selected tracing group | |
101 | # (`$tracing_group`) with: | |
102 | # | |
103 | # `$1`: | |
104 | # A message of what's expected to show on error. | |
105 | # | |
106 | # Other arguments: | |
107 | # Passed to the command as is. | |
108 | # | |
109 | # This function returns 1 with LTTng-tools < 2.6 and if `xmllint` isn't | |
110 | # available. | |
111 | __lttng_mi_run() { | |
112 | local -r msg=$1 | |
113 | ||
114 | shift | |
115 | ||
116 | if ((minor_version < 6)); then | |
117 | # MI output requires LTTng-tools ≥ 2.6 | |
118 | _message -e descriptions $msg | |
119 | return 1 | |
120 | fi | |
121 | ||
122 | if ((! $+commands[xmllint])); then | |
123 | # XML output parsing requires xmllint | |
124 | _message -e descriptions $msg | |
125 | return 1 | |
126 | fi | |
127 | ||
128 | __lttng_run --mi=xml "$@" | |
129 | ||
130 | if (($? != 0)); then | |
131 | # Command failed | |
132 | _message -e descriptions $msg | |
133 | return 1 | |
134 | fi | |
135 | } | |
136 | ||
137 | # Call this instead of _arguments() within this function when you don't | |
138 | # need the `-C` option. | |
139 | __lttng_arguments() { | |
140 | _arguments -s -W : "$@" | |
141 | } | |
142 | ||
143 | # Returns whether or not the verbose style is enabled for the given | |
144 | # argument (`$1`) and tag (`$2`), using `$curcontext` for the other | |
145 | # parts of the full completion context. | |
146 | __lttng_style_is_verbose() { | |
147 | local -r arg=$1 tag=$2 | |
148 | local -r ccparts=("${(@s.:.)curcontext}") | |
149 | ||
150 | zstyle -t :completion:${ccparts[1]}:${ccparts[2]}:${ccparts[3]}:$arg:$tag verbose | |
151 | } | |
152 | ||
153 | # Returns 0 if a Linux kernel tracing domain option is set in | |
154 | # `$opt_args`, or `1` otherwise. | |
155 | __lttng_kernel_domain_opt_is_set() { | |
156 | (($+opt_args[-k] || $+opt_args[--kernel] || | |
157 | $+opt_args[domain--k] || $+opt_args[domain---kernel])) | |
158 | } | |
159 | ||
160 | # Returns 0 if a user space tracing domain option is set in | |
161 | # `$opt_args`, or `1` otherwise. | |
162 | __lttng_user_domain_opt_is_set() { | |
163 | (($+opt_args[-u] || $+opt_args[--userspace] || | |
164 | $+opt_args[domain--u] || $+opt_args[domain---userspace])) | |
165 | } | |
166 | ||
167 | # Returns 0 if a `java.util.logging` tracing domain option is set in | |
168 | # `$opt_args`, or `1` otherwise. | |
169 | __lttng_jul_domain_opt_is_set() { | |
170 | (($+opt_args[-j] || $+opt_args[--jul] || | |
171 | $+opt_args[domain--j] || $+opt_args[domain---jul])) | |
172 | } | |
173 | ||
e46c0fbb | 174 | # Returns 0 if an Apache Log4j 1.x tracing domain option is set in |
76bcac58 PP |
175 | # `$opt_args`, or `1` otherwise. |
176 | __lttng_log4j_domain_opt_is_set() { | |
177 | (($+opt_args[-l] || $+opt_args[--log4j] || | |
178 | $+opt_args[domain--l] || $+opt_args[domain---log4j])) | |
179 | } | |
180 | ||
e46c0fbb MJ |
181 | # Returns 0 if an Apache Log4j 2 tracing domain option is set in |
182 | # `$opt_args`, or `1` otherwise. | |
183 | __lttng_log4j2_domain_opt_is_set() { | |
184 | (($+opt_args[-L] || $+opt_args[--log4j2] || | |
185 | $+opt_args[domain--L] || $+opt_args[domain---log4j2])) | |
186 | } | |
187 | ||
76bcac58 PP |
188 | # Returns 0 if a Python tracing domain option is set in `$opt_args`, |
189 | # or `1` otherwise. | |
190 | __lttng_python_domain_opt_is_set() { | |
191 | (($+opt_args[-p] || $+opt_args[--python] || | |
192 | $+opt_args[domain--p] || $+opt_args[domain---python])) | |
193 | } | |
194 | ||
195 | # Adds completions for the name of an `lttng` command. | |
196 | __lttng_complete_cmd_name() { | |
197 | # LTTng-tools 2.5+ | |
198 | local cmd_names=( | |
199 | 'add-context:add context fields to be recorded' | |
200 | 'create:create a recording session' | |
201 | 'destroy:destroy a recording session' | |
202 | 'disable-channel:disable channels' | |
203 | 'disable-event:disable recording event rules' | |
204 | 'enable-channel:create or enable a channel' | |
205 | 'enable-event:create or enable recording event rules' | |
206 | 'help:show the help of a command' | |
207 | 'list:list recording sessions and instrumentation points' | |
208 | 'set-session:set the current recording session' | |
209 | 'snapshot:take a recording session snapshot' | |
210 | 'start:start a recording session' | |
211 | 'stop:stop a recording session' | |
212 | 'version:show LTTng-tools version information' | |
213 | 'view:launch a trace reader' | |
214 | ) | |
215 | ||
216 | # LTTng-tools 2.6+ | |
217 | if ((minor_version >= 6)); then | |
218 | cmd_names+=( | |
219 | 'load:load recording session configurations' | |
220 | 'save:save recording session configurations' | |
221 | ) | |
222 | fi | |
223 | ||
224 | # LTTng-tools 2.7+ | |
225 | if ((minor_version >= 7)); then | |
226 | cmd_names+=( | |
227 | 'track:allow specific processes to record events' | |
228 | 'untrack:disallow specific processes to record events' | |
229 | ) | |
230 | fi | |
231 | ||
232 | # LTTng-tools 2.8+ | |
233 | if ((minor_version >= 8)); then | |
234 | cmd_names+=( | |
235 | 'status:show the status of the current recording session' | |
236 | ) | |
237 | fi | |
238 | ||
239 | # LTTng-tools 2.9+ | |
240 | if ((minor_version >= 9)); then | |
241 | cmd_names+=( | |
242 | 'regenerate:regenerate specific recording session data' | |
243 | ) | |
244 | fi | |
245 | ||
246 | # LTTng-tools 2.11+ | |
247 | if ((minor_version >= 11)); then | |
248 | cmd_names+=( | |
249 | 'rotate:archive the current trace chunk of a recording session' | |
250 | 'enable-rotation:set a recording session rotation schedule' | |
251 | 'disable-rotation:unset a recording session rotation schedule' | |
252 | ) | |
253 | fi | |
254 | ||
255 | # LTTng-tools 2.12+ | |
256 | if ((minor_version >= 12)); then | |
257 | cmd_names+=( | |
258 | 'clear:clear a recording session' | |
259 | ) | |
260 | fi | |
261 | ||
262 | # LTTng-tools 2.13+ | |
263 | if ((minor_version >= 13)); then | |
264 | cmd_names+=( | |
265 | 'add-trigger:add a trigger' | |
266 | 'list-triggers:list triggers' | |
267 | 'remove-trigger:remove a trigger' | |
268 | ) | |
269 | fi | |
270 | ||
271 | # Add completions | |
272 | local expl | |
273 | ||
274 | _describe -t commands command cmd_names | |
275 | } | |
276 | ||
277 | # Adds completions for the name of an `lttng snapshot` action. | |
278 | __lttng_complete_snapshot_action_name() { | |
279 | local -r action_names=( | |
280 | 'add-output:add a snapshot output' | |
281 | 'del-output:remove a snapshot output' | |
282 | 'list-output:show the snapshot output' | |
283 | 'record:take a snapshot' | |
284 | ) | |
285 | ||
286 | # Add completions | |
287 | local expl | |
288 | ||
289 | _describe -t actions 'snapshot action' action_names | |
290 | } | |
291 | ||
292 | # Adds user ID completions. | |
293 | # | |
294 | # The added completions are displayed as user names, but the actual | |
295 | # completions are corresponding user IDs. | |
296 | __lttng_complete_uid() { | |
297 | if [[ ! -f /etc/passwd ]]; then | |
298 | # Weird flex but ok | |
299 | _message -e descriptions 'user ID' | |
300 | return | |
301 | fi | |
302 | ||
303 | # Read user names and IDs from `/etc/passwd` | |
304 | local line | |
305 | local -a uids names fields | |
306 | ||
307 | while read -r line; do | |
308 | if [[ -z ${line// } ]]; then | |
309 | # Skip empty line | |
310 | continue | |
311 | fi | |
312 | ||
313 | # Extract user ID and name | |
314 | fields=("${(@s/:/)line}") | |
315 | uids+=($fields[3]) | |
316 | names+=("$fields[1]") | |
317 | done < /etc/passwd | |
318 | ||
319 | # Add completions | |
320 | local expl | |
321 | ||
322 | _wanted users expl 'user ID' compadd -d names -a uids | |
323 | } | |
324 | ||
325 | # Adds completions for a context field type (for the `--type` option of | |
326 | # the `add-context` command). | |
327 | # | |
328 | # This function replaces the argument field of the current context with | |
329 | # `type-option`. | |
330 | # | |
331 | # This function relies on the tracing domain options of `$opt_args` to | |
332 | # restrict the offered completions. Without a tracing domain option, | |
333 | # this function adds all the possible context field type completions. | |
334 | # | |
335 | # This function runs `lttng add-context --list` to get the list of | |
336 | # available context field types. | |
337 | # | |
338 | # This function adds completions with both the `static-context-types` | |
339 | # and `perf-context-types` tags so that the Zsh user can hide a group or | |
340 | # select them with the `group-order` and `tag-order` style. | |
341 | __lttng_complete_context_type() { | |
342 | # Statically-known context field types | |
343 | local kernel_types=( | |
344 | pid procname prio nice vpid tid vtid ppid vppid hostname | |
345 | interruptible preemptible need_reschedule migratable | |
346 | callstack-kernel callstack-user cgroup_ns ipc_ns mnt_ns net_ns | |
347 | pid_ns time_ns user_ns uts_ns uid euid suid gid egid sgid vuid veuid | |
348 | vsuid vgid vegid vsgid | |
349 | ) | |
350 | local user_types=( | |
351 | vpid pthread_id procname ip cgroup_ns ipc_ns mnt_ns net_ns pid_ns | |
352 | time_ns user_ns uts_ns vuid veuid vsuid vgid vegid vsgid | |
353 | ) | |
354 | ||
355 | # Set `types` and `domain` depending on the selected tracing domain | |
356 | local -a types | |
357 | local domain descr_suffix | |
358 | ||
359 | if __lttng_kernel_domain_opt_is_set; then | |
360 | # Kernel context field types | |
361 | types=($kernel_types) | |
362 | domain=k | |
363 | elif __lttng_user_domain_opt_is_set; then | |
364 | # User space context field types | |
365 | types=($user_types) | |
366 | domain=u | |
367 | else | |
368 | # No supported tracing domain: offer all context field types | |
369 | types=($user_types $kernel_types) | |
370 | descr_suffix=' (all tracing domains)' | |
371 | fi | |
372 | ||
373 | # Get XML list of available context field types | |
374 | local -r msg='context type' | |
375 | local list_xml | |
376 | ||
377 | list_xml=$(__lttng_mi_run $msg add-context --list) | |
378 | ||
379 | if (($? != 0)); then | |
380 | return 1 | |
381 | fi | |
382 | ||
383 | # Convert to one context field type per line | |
384 | local lines | |
385 | ||
386 | lines=$(__lttng_xmllint_xpath $list_xml '//*[local-name()="symbol"]/text()') | |
387 | ||
388 | if (($? != 0)); then | |
389 | _guard '^-*' $msg | |
390 | return | |
391 | fi | |
392 | ||
393 | # Filter context field types depending on the selected tracing domain | |
394 | local -a static_items perf_items | |
395 | local line | |
396 | ||
397 | while read -r line; do | |
398 | if (($types[(Ie)$line])); then | |
399 | # Statically-known context field type | |
400 | static_items+=$line | |
401 | elif [[ $line = perf:cpu:* && $domain != u ]]; then | |
402 | # Per-CPU perf counter | |
403 | perf_items+=$line | |
404 | elif [[ $line = perf:thread:* && $domain != k ]]; then | |
405 | # Per-thread perf counter | |
406 | perf_items+=$line | |
407 | elif [[ $line = perf:* && $domain != u ]]; then | |
408 | # Other perf counter (Linux kernel tracing domain or none) | |
409 | perf_items+=$line | |
410 | fi | |
411 | done <<< $lines | |
412 | ||
413 | # Add completions | |
414 | _alternative -C type-option \ | |
415 | "static-context-types:statically-known context type${descr_suffix}:compadd -a static_items" \ | |
416 | "perf-context-types:perf counter context type${descr_suffix}:compadd -a perf_items" | |
417 | } | |
418 | ||
419 | # Adds completions for a trigger name. | |
420 | # | |
421 | # Relies on `$opt_args[--owner-uid]` to restrict the offered | |
422 | # completions. | |
423 | __lttng_complete_trigger_name() { | |
424 | # Get XML list of available triggers | |
425 | local msg='trigger name' | |
426 | local list_xml | |
427 | ||
428 | list_xml=$(__lttng_mi_run $msg list-triggers) | |
429 | ||
430 | if (($? != 0)); then | |
431 | return 1 | |
432 | fi | |
433 | ||
434 | # Create the owner UID predicate XPath part | |
435 | local owner_uid_xpath | |
436 | ||
437 | if (($+opt_args[--owner-uid])); then | |
438 | owner_uid_xpath="[./*[local-name()='owner_uid'] = ${opt_args[--owner-uid]}]" | |
439 | fi | |
440 | ||
441 | # Convert to one trigger name per line | |
442 | local lines | |
443 | ||
444 | lines=$(__lttng_xmllint_xpath $list_xml "//*[local-name()='trigger']$owner_uid_xpath/*[local-name()='name']/text()") | |
445 | ||
446 | if (($? != 0)); then | |
447 | _guard '^-*' $msg | |
448 | return | |
449 | fi | |
450 | ||
451 | local -a trigger_names | |
452 | ||
453 | while read -r line; do | |
454 | trigger_names+=$line | |
455 | done <<< $lines | |
456 | ||
457 | # Add completions | |
458 | local expl | |
459 | ||
460 | _wanted triggers expl $msg compadd -a trigger_names | |
461 | } | |
462 | ||
463 | # Runs `xmllint` with: | |
464 | # | |
465 | # `$1`: | |
466 | # An XML document to parse. | |
467 | # | |
468 | # `$2`: | |
469 | # An XPath to extract data. | |
470 | __lttng_xmllint_xpath() { | |
471 | local -r xml=$1 xpath=$2 | |
472 | ||
473 | xmllint --xpath $xpath - <<< $xml 2>/dev/null | |
474 | } | |
475 | ||
476 | # Prints the equivalent recording session status adjective (`active` or | |
477 | # `inactive`) for an `enabled` XML property, or `unknown` on error. | |
478 | __lttng_session_status_from_enabled_prop() { | |
479 | local -r prop=$1 | |
480 | ||
481 | case $prop in | |
482 | true) echo -n active;; | |
483 | false) echo -n inactive;; | |
484 | *) echo -n unknown;; | |
485 | esac | |
486 | } | |
487 | ||
488 | # Prints the value of the immediate XML property named `$3` of the child | |
489 | # node named `$2` within the parent node `$1`. | |
490 | __lttng_immediate_prop_from_xml() { | |
491 | local -r node_xml=$1 node_name=$2 prop_name=$3 | |
492 | ||
493 | __lttng_xmllint_xpath $node_xml "/*[local-name()='$node_name']/*[local-name()='$prop_name']/text()" | |
494 | } | |
495 | ||
496 | # Prints the value of the immediate XML `name` property of the child | |
497 | # node named `$2` within the parent node `$1`. | |
498 | __lttng_name_prop_from_xml() { | |
499 | local -r node_xml=$1 node_name=$2 | |
500 | ||
501 | __lttng_immediate_prop_from_xml $node_xml $node_name name | |
502 | } | |
503 | ||
504 | # Prints the value of the immediate XML `enabled` property of the child | |
505 | # node named `$2` within the parent node `$1`. | |
506 | __lttng_enabled_prop_from_xml() { | |
507 | local -r node_xml=$1 node_name=$2 | |
508 | ||
509 | __lttng_immediate_prop_from_xml $node_xml $node_name enabled | |
510 | } | |
511 | ||
512 | # Adds completions for a recording session name. | |
513 | # | |
514 | # Arguments: | |
515 | # | |
516 | # `$1`: | |
517 | # One of: | |
518 | # | |
519 | # `all`: | |
520 | # Add completions for active and inactive recording sessions. | |
521 | # | |
522 | # `active`: | |
523 | # Only add completions for active recording sessions. | |
524 | # | |
525 | # `inactive`: | |
526 | # Only add completions for inactive recording sessions. | |
527 | # | |
528 | # `$2`: | |
529 | # One of: | |
530 | # | |
531 | # `all`: | |
532 | # Add completions for recording sessions regardless of their | |
533 | # mode. | |
534 | # | |
535 | # `snapshot`: | |
536 | # Only add completions for snapshot recording sessions. | |
537 | # | |
538 | # `live`: | |
539 | # Only add completions for LTTng live recording sessions. | |
540 | __lttng_complete_session_name() { | |
541 | local -r req_status=$1 req_mode=$2 | |
542 | ||
543 | # Get XML document (summary of recording sessions) | |
544 | local session_summaries_xml | |
545 | ||
546 | session_summaries_xml=$(__lttng_mi_run 'recording session name' list) | |
547 | ||
548 | if (($? != 0)); then | |
549 | return 1 | |
550 | fi | |
551 | ||
552 | # Count recording sessions | |
553 | local -i session_count | |
554 | ||
555 | session_count=$(__lttng_xmllint_xpath $session_summaries_xml 'count(//*[local-name()="session"])') | |
556 | ||
557 | if (($? != 0 || session_count == 0)); then | |
558 | _guard '^-*' 'recording session name' | |
559 | return | |
560 | fi | |
561 | ||
562 | # Append the name and info of one recording session at a time | |
563 | local -a session_names session_infos | |
564 | local -i index iprop | |
565 | local session_name session_summary_xml snapshot_mode session_status session_info | |
566 | ||
567 | # For each recording session summary | |
568 | for index in {1..$session_count}; do | |
569 | # Get recording session summary XML node | |
570 | session_summary_xml=$(__lttng_xmllint_xpath $session_summaries_xml "//*[local-name()='session'][$index]") | |
571 | ||
572 | if (($? != 0)); then | |
573 | continue | |
574 | fi | |
575 | ||
576 | # Get recording session name | |
577 | session_name=$(__lttng_name_prop_from_xml $session_summary_xml session) | |
578 | ||
579 | if (($? != 0)); then | |
580 | continue | |
581 | fi | |
582 | ||
583 | # Get recording session status | |
584 | session_status=$(__lttng_enabled_prop_from_xml $session_summary_xml session) | |
585 | ||
586 | if (($? != 0)); then | |
587 | continue | |
588 | fi | |
589 | ||
590 | session_status=$(__lttng_session_status_from_enabled_prop $session_status) | |
591 | ||
592 | if [[ $req_status != all && $req_status != $session_status ]]; then | |
593 | # Skip recording session with unexpected status | |
594 | continue | |
595 | fi | |
596 | ||
597 | # Get recording session mode | |
598 | session_mode= | |
599 | iprop=$(__lttng_immediate_prop_from_xml $session_summary_xml session snapshot_mode) | |
600 | ||
601 | if (($? == 0 && iprop)); then | |
602 | session_mode=snapshot | |
603 | else | |
604 | iprop=$(__lttng_immediate_prop_from_xml $session_summary_xml session live_timer_interval) | |
605 | ||
606 | if (($? == 0 && iprop)); then | |
607 | session_mode=live | |
608 | fi | |
609 | fi | |
610 | ||
611 | if [[ $req_mode != all && $req_mode != $session_mode ]]; then | |
612 | # Skip recording session with unexpected mode | |
613 | continue | |
614 | fi | |
615 | ||
616 | session_info=$session_status | |
617 | ||
618 | if [[ -n $session_mode ]]; then | |
619 | session_info+=", $session_mode mode" | |
620 | fi | |
621 | ||
622 | session_names+=("$session_name") | |
623 | session_infos+=($session_info) | |
624 | done | |
625 | ||
626 | # No recording sessions: show message | |
627 | if (($#session_names == 0)); then | |
628 | _guard '^-*' 'recording session name' | |
629 | return | |
630 | fi | |
631 | ||
632 | # Compute maximum session info length | |
633 | local -i max_info_len=0 len | |
634 | ||
635 | for session_info in $session_infos; do | |
636 | len=$#session_info | |
637 | ||
638 | if ((len > max_info_len)); then | |
639 | max_info_len=$len | |
640 | fi | |
641 | done | |
642 | ||
643 | # Compute maximum session name length | |
644 | local -i max_name_len=0 | |
645 | ||
646 | for session_name in $session_names; do | |
647 | len=$#session_name | |
648 | ||
649 | if ((len > max_name_len)); then | |
650 | max_name_len=$len | |
651 | fi | |
652 | done | |
653 | ||
654 | # Some room for the longest info string, two spaces, and two brackets | |
655 | local -ir max_possible_name_len=$((COLUMNS - max_info_len - 5)) | |
656 | ||
657 | if ((max_name_len > max_possible_name_len)); then | |
658 | # Clamp | |
659 | max_name_len=$max_possible_name_len | |
660 | fi | |
661 | ||
662 | # Create the dislay strings (name, status, mode) | |
663 | local -a disps | |
664 | ||
665 | for index in {1..${#session_names}}; do | |
666 | disps+=("${(r:$max_name_len:: :)session_names[$index]} [$session_infos[$index]]") | |
667 | done | |
668 | ||
669 | # Add completions | |
670 | local expl | |
671 | ||
672 | if __lttng_style_is_verbose session sessions; then | |
673 | # Verbose mode (list with infos) | |
674 | _wanted -C session sessions expl 'recording session name' \ | |
675 | compadd -d disps -l -a session_names | |
676 | else | |
677 | # Just the recording session names | |
678 | _wanted -C session sessions expl 'recording session name' \ | |
679 | compadd -a session_names | |
680 | fi | |
681 | } | |
682 | ||
683 | # Prints the name of the Unix user's current recording session, if any. | |
684 | __lttng_cur_session_name() { | |
685 | local -r lttngrc_path=${LTTNG_HOME:-$HOME}/.lttngrc | |
686 | ||
687 | if [[ ! -f $lttngrc_path ]]; then | |
688 | return 1 | |
689 | fi | |
690 | ||
691 | local cur_session_name | |
692 | local -a match | |
693 | ||
694 | while read -r line; do | |
695 | if [[ $line =~ 'session=([^[:blank:]]+)' ]]; then | |
696 | cur_session_name=$match[1] | |
697 | break | |
698 | fi | |
699 | done < $lttngrc_path | |
700 | ||
701 | if [[ -z $cur_session_name ]]; then | |
702 | return 1 | |
703 | fi | |
704 | ||
705 | echo -n $cur_session_name | |
706 | } | |
707 | ||
708 | # Prints the equivalent status adjective (`enabled` or `disabled`) for | |
709 | # an `enabled` XML property, or `unknown` on error. | |
710 | __lttng_status_from_enabled_prop() { | |
711 | local -r prop=$1 | |
712 | ||
713 | case $prop in | |
714 | true) echo -n enabled;; | |
715 | false) echo -n disabled;; | |
716 | *) echo -n unknown;; | |
717 | esac | |
718 | } | |
719 | ||
720 | # Prints the XML document of `lttng list $2` (specifics of a single | |
721 | # recording session). | |
722 | # | |
723 | # `$1` is a message of what's expected to show on error. | |
724 | __lttng_session_xml() { | |
725 | local -r msg=$1 session_name=$2 | |
726 | ||
727 | __lttng_mi_run $msg list $session_name | |
728 | } | |
729 | ||
730 | # Adds completions for a channel name. | |
731 | # | |
732 | # This function relies on the tracing domain options of `$opt_args`, | |
733 | # `$opt_args[-s]`, `$opt_args[--session]`, and the first non-option | |
734 | # argument to restrict the offered completions. | |
735 | # | |
736 | # Arguments: | |
737 | # | |
738 | # `$1`: | |
739 | # One of: | |
740 | # | |
741 | # `all`: | |
742 | # Add completions for enabled and disabled channels. | |
743 | # | |
744 | # `enabled`: | |
745 | # Only add completions for enabled channels. | |
746 | # | |
747 | # `disabled`: | |
748 | # Only add completions for disabled channels. | |
749 | # | |
750 | # `$2`: | |
751 | # `opt`: | |
752 | # Use `$opt_args[-s]` and `$opt_args[--session]` to find the | |
753 | # name of the selected recording session. | |
754 | # | |
755 | # `arg`: | |
756 | # Use `$line[1]` to find the name of the selected recording | |
757 | # session. | |
758 | __lttng_complete_channel_name() { | |
759 | local -r req_status=$1 session_name_src=$2 | |
760 | ||
761 | shift 2 | |
762 | ||
763 | # Find the recording session name to use | |
764 | local session_name | |
765 | ||
766 | if [[ $session_name_src = opt ]]; then | |
767 | if (($+opt_args[-s])); then | |
768 | session_name=$opt_args[-s] | |
769 | elif (($+opt_args[--session])); then | |
770 | session_name=$opt_args[--session] | |
771 | fi | |
772 | elif [[ $session_name_src = arg ]]; then | |
773 | session_name=$line[1] | |
774 | fi | |
775 | ||
776 | if [[ -z $session_name ]]; then | |
777 | # Fall back to current recording session | |
778 | session_name=$(__lttng_cur_session_name) | |
779 | ||
780 | if (($? != 0)); then | |
781 | _guard '^-*' 'channel name' | |
782 | return | |
783 | fi | |
784 | fi | |
785 | ||
786 | # Get XML document (detailed recording session) | |
787 | local session_xml | |
788 | ||
789 | session_xml=$(__lttng_session_xml 'channel name' $session_name) | |
790 | ||
791 | if (($? != 0)); then | |
792 | return 1 | |
793 | fi | |
794 | ||
795 | # Count tracing domains | |
796 | local -i domain_count | |
797 | ||
798 | domain_count=$(__lttng_xmllint_xpath $session_xml 'count(//*[local-name()="domain"])') | |
799 | ||
800 | if (($? != 0 || domain_count == 0)); then | |
801 | _guard '^-*' 'channel name' | |
802 | return | |
803 | fi | |
804 | ||
805 | # Append the name and info of one channel at a time | |
806 | local domain_xml domain prop | |
807 | local channel_xml channel_name channel_status channel_erl_mode | |
808 | local -a channel_names channel_infos | |
809 | local -i channel_count domain_index channel_index | |
810 | ||
811 | # For each tracing domain | |
812 | for domain_index in {1..$domain_count}; do | |
813 | # Get tracing domain XML node | |
814 | domain_xml=$(__lttng_xmllint_xpath $session_xml "//*[local-name()='domain'][$domain_index]") | |
815 | ||
816 | if (($? != 0)); then | |
817 | continue | |
818 | fi | |
819 | ||
820 | # Get tracing domain type | |
821 | domain=$(__lttng_xmllint_xpath $domain_xml '/*/*[local-name()="type"]/text()') | |
822 | ||
823 | if (($? != 0)); then | |
824 | continue | |
825 | fi | |
826 | ||
827 | # Skip unexpected tracing domains | |
828 | if [[ $domain = KERNEL ]]; then | |
829 | if __lttng_user_domain_opt_is_set; then | |
830 | # Skip unexpected Linux kernel tracing domain | |
831 | continue | |
832 | fi | |
833 | ||
834 | domain='Linux kernel' | |
835 | fi | |
836 | ||
837 | if [[ $domain = UST ]]; then | |
838 | if __lttng_kernel_domain_opt_is_set; then | |
839 | # Skip unexpected user space tracing domain | |
840 | continue | |
841 | fi | |
842 | ||
843 | domain='user space' | |
844 | fi | |
845 | ||
846 | # Count channels within tracing domain | |
847 | channel_count=$(__lttng_xmllint_xpath $domain_xml 'count(//*[local-name()="channel"])') | |
848 | ||
849 | if (($? != 0 || channel_count == 0)); then | |
850 | continue | |
851 | fi | |
852 | ||
853 | # For each channel | |
854 | for channel_index in {1..$channel_count}; do | |
855 | # Get channel XML node | |
856 | channel_xml=$(__lttng_xmllint_xpath $domain_xml "//*[local-name()='channel'][$channel_index]") | |
857 | ||
858 | if (($? != 0)); then | |
859 | continue | |
860 | fi | |
861 | ||
862 | # Get channel name | |
863 | channel_name=$(__lttng_name_prop_from_xml $channel_xml channel) | |
864 | ||
865 | if (($? != 0)); then | |
866 | continue | |
867 | fi | |
868 | ||
869 | # Get channel status | |
870 | channel_status=$(__lttng_enabled_prop_from_xml $channel_xml channel) | |
871 | ||
872 | if (($? != 0)); then | |
873 | continue | |
874 | fi | |
875 | ||
876 | channel_status=$(__lttng_status_from_enabled_prop $channel_status) | |
877 | ||
878 | if [[ $req_status != all && $req_status != $channel_status ]]; then | |
879 | # Skip channel with unexpected status | |
880 | continue | |
881 | fi | |
882 | ||
883 | # Get channel event record loss mode | |
884 | channel_erl_mode=$(__lttng_xmllint_xpath $channel_xml '//*[local-name()="attributes"]/*[local-name()="overwrite_mode"]/text()') | |
885 | ||
886 | if (($? != 0)); then | |
887 | continue | |
888 | fi | |
889 | ||
890 | if [[ $channel_erl_mode = DISCARD ]]; then | |
891 | channel_erl_mode=discard | |
892 | elif [[ $channel_erl_mode = OVERWRITE ]]; then | |
893 | channel_erl_mode=overwrite | |
894 | fi | |
895 | ||
896 | channel_names+=("$channel_name") | |
897 | channel_infos+=("$channel_status, $domain, $channel_erl_mode mode") | |
898 | done | |
899 | done | |
900 | ||
901 | # No channels: show message | |
902 | if (($#channel_names == 0)); then | |
903 | _guard '^-*' 'channel name' | |
904 | return | |
905 | fi | |
906 | ||
907 | # Compute maximum channel info length | |
908 | local channel_info | |
909 | local -i max_info_len=0 len | |
910 | ||
911 | for channel_info in $channel_infos; do | |
912 | len=$#channel_info | |
913 | ||
914 | if ((len > max_info_len)); then | |
915 | max_info_len=$len | |
916 | fi | |
917 | done | |
918 | ||
919 | # Compute maximum channel name length | |
920 | local -i max_name_len=0 | |
921 | ||
922 | for channel_name in $channel_names; do | |
923 | len=$#channel_name | |
924 | ||
925 | if ((len > max_name_len)); then | |
926 | max_name_len=$len | |
927 | fi | |
928 | done | |
929 | ||
930 | # Some room for the longest info string, two spaces, and two brackets | |
931 | local -ir max_possible_name_len=$((COLUMNS - max_info_len - 5)) | |
932 | ||
933 | if ((max_name_len > max_possible_name_len)); then | |
934 | # Clamp | |
935 | max_name_len=$max_possible_name_len | |
936 | fi | |
937 | ||
938 | # Create the dislay strings (name, status, tracing domain, mode) | |
939 | local -a disps | |
940 | ||
941 | for channel_index in {1..${#channel_names}}; do | |
942 | disps+=("${(r:$max_name_len:: :)channel_names[$channel_index]} [$channel_infos[$channel_index]]") | |
943 | done | |
944 | ||
945 | # Add completions | |
946 | local expl | |
947 | ||
948 | if __lttng_style_is_verbose channel channels; then | |
949 | # Verbose mode (list with infos). | |
950 | # | |
951 | # Using `-2` as Linux kernel and user space channels may have the | |
952 | # same name, but we want to show the different infos. | |
953 | _wanted -C channel channels expl 'channel name' \ | |
954 | compadd "$@" -2 -d disps -l -a channel_names | |
955 | else | |
956 | # Just the channel names, no duplicates | |
957 | _wanted -C channel channels expl 'channel name' \ | |
958 | compadd "$@" -a channel_names | |
959 | fi | |
960 | } | |
961 | ||
962 | # Add completions for instrumentation point names. | |
963 | # | |
964 | # This function relies on the tracing domain options of `$opt_args` and | |
965 | # `$opt_args[ip---syscall]` to restrict the offered completions. | |
966 | __lttng_complete_ip_name() { | |
967 | local msg | |
968 | local -a list_opts | |
969 | ||
970 | if __lttng_kernel_domain_opt_is_set; then | |
971 | list_opts=(-k) | |
972 | ||
973 | if (($+opt_args[ip---syscall])); then | |
974 | msg='system call name (no `sys_` prefix)' | |
975 | list_opts+=(--syscall) | |
976 | else | |
977 | msg='Linux kernel tracepoint name' | |
978 | fi | |
979 | elif __lttng_user_domain_opt_is_set; then | |
980 | msg='user space tracepoint name' | |
981 | list_opts=(-u) | |
982 | elif __lttng_jul_domain_opt_is_set; then | |
983 | msg='`java.util.logging` logger name' | |
984 | list_opts=(-j) | |
985 | elif __lttng_log4j_domain_opt_is_set; then | |
e46c0fbb | 986 | msg='Apache Log4j 1.x logger name' |
76bcac58 | 987 | list_opts=(-l) |
e46c0fbb MJ |
988 | elif __lttng_log4j2_domain_opt_is_set; then |
989 | msg='Apache Log4j 2 logger name' | |
990 | list_opts=(-L) | |
76bcac58 PP |
991 | elif __lttng_python_domain_opt_is_set; then |
992 | msg='Python logger name' | |
993 | list_opts=(-p) | |
994 | else | |
995 | # No tracing domain option | |
996 | _guard '^-*' 'instrumentation point or recording event rule name' | |
997 | return | |
998 | fi | |
999 | ||
1000 | # Get XML list of available instrumentation point names | |
1001 | local list_xml | |
1002 | ||
1003 | list_xml=$(__lttng_mi_run $msg list $list_opts) | |
1004 | ||
1005 | if (($? != 0)); then | |
1006 | return 1 | |
1007 | fi | |
1008 | ||
1009 | # Convert to one instrumentation point name per line | |
1010 | local ip_names | |
1011 | ||
1012 | ip_names=$(__lttng_xmllint_xpath $list_xml '//*[local-name()="event"]//*[local-name()="name"]/text()') | |
1013 | ||
1014 | if (($? != 0)) || [[ -z $ip_names ]]; then | |
1015 | # `xmllint` error or no instrumentation points | |
1016 | _guard '^-*' $msg | |
1017 | return | |
1018 | fi | |
1019 | ||
1020 | local ip_name | |
1021 | local -a items | |
1022 | ||
1023 | while read -r ip_name; do | |
1024 | if [[ -z $ip_name ]]; then | |
1025 | continue | |
1026 | fi | |
1027 | ||
1028 | items+=($ip_name) | |
1029 | done <<< $ip_names | |
1030 | ||
1031 | # Add completions | |
1032 | local expl | |
1033 | ||
1034 | _wanted instrumentation-points expl $msg compadd "$@" -a items | |
1035 | } | |
1036 | ||
1037 | # Adds completions for the arguments of the `add-context` command. | |
1038 | __lttng_complete_add_context_cmd() { | |
1039 | local specs=( | |
1040 | $help_opt_specs | |
1041 | '(- : *)--list[list the available context field types]' | |
1042 | '(--list -s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name inactive all' | |
1043 | '(--list -c --channel)'{-c+,--channel=}'[select a specific channel]: : __lttng_complete_channel_name enabled opt' | |
1044 | '(--list)*'{-t+,--type=}'[add a context field to be recorded]: : __lttng_complete_context_type' | |
1045 | + '(domain)' | |
1046 | '(--list)'{-k,--kernel}'[select the Linux kernel tracing domain]' | |
1047 | '(--list)'{-u,--userspace}'[select the user space tracing domain]' | |
1048 | ) | |
1049 | ||
1050 | # The Java tracing domain options require LTTng-tools ≥ 2.8 (for | |
1051 | # application-specific context field types). | |
1052 | if ((minor_version >= 8)); then | |
1053 | specs+=( | |
1054 | '(--list)'{-j,--jul}'[select the `java.util.logging` tracing domain]' | |
e46c0fbb MJ |
1055 | '(--list)'{-l,--log4j}'[select the Apache Log4j 1.x tracing domain]' |
1056 | '(--list)'{-L,--log4j2}'[select the Apache Log4j 2 tracing domain]' | |
1057 | ) | |
1058 | fi | |
1059 | ||
1060 | if ((minor_version >= 14)); then | |
1061 | specs+=( | |
1062 | '(--list)'{-L,--log4j2}'[select the Apache Log4j 2 tracing domain]' | |
76bcac58 PP |
1063 | ) |
1064 | fi | |
1065 | ||
1066 | # Add completions | |
1067 | __lttng_arguments $specs | |
1068 | } | |
1069 | ||
1070 | # Adds completions for log level names. | |
1071 | # | |
1072 | # This function relies on the tracing domain options of `$opt_args` to | |
1073 | # restrict the offered completions. | |
1074 | __lttng_complete_log_level() { | |
1075 | local -a log_levels | |
1076 | ||
1077 | # Fill the `log_levels` array depending on the tracing domain option | |
1078 | if __lttng_user_domain_opt_is_set; then | |
1079 | log_levels=( | |
1080 | EMERG | |
1081 | ALERT | |
1082 | CRIT | |
1083 | ERR | |
1084 | WARNING | |
1085 | NOTICE | |
1086 | INFO | |
1087 | DEBUG_SYSTEM | |
1088 | DEBUG_PROGRAM | |
1089 | DEBUG_PROCESS | |
1090 | DEBUG_MODULE | |
1091 | DEBUG_UNIT | |
1092 | DEBUG_FUNCTION | |
1093 | DEBUG_LINE | |
1094 | DEBUG | |
1095 | ) | |
1096 | elif __lttng_jul_domain_opt_is_set; then | |
1097 | log_levels=( | |
1098 | OFF | |
1099 | SEVERE | |
1100 | WARNING | |
1101 | INFO | |
1102 | CONFIG | |
1103 | FINE | |
1104 | FINER | |
1105 | FINEST | |
1106 | ALL | |
1107 | ) | |
1108 | elif __lttng_log4j_domain_opt_is_set; then | |
1109 | log_levels=( | |
1110 | OFF | |
1111 | FATAL | |
1112 | ERROR | |
1113 | WARN | |
1114 | INFO | |
1115 | DEBUG | |
1116 | TRACE | |
1117 | ALL | |
1118 | ) | |
e46c0fbb MJ |
1119 | elif __lttng_log4j2_domain_opt_is_set; then |
1120 | log_levels=( | |
1121 | OFF | |
1122 | FATAL | |
1123 | ERROR | |
1124 | WARN | |
1125 | INFO | |
1126 | DEBUG | |
1127 | TRACE | |
1128 | ALL | |
1129 | ) | |
76bcac58 PP |
1130 | elif __lttng_python_domain_opt_is_set; then |
1131 | log_levels=( | |
1132 | CRITICAL | |
1133 | ERROR | |
1134 | WARNING | |
1135 | INFO | |
1136 | DEBUG | |
1137 | NOTSET | |
1138 | ) | |
1139 | else | |
1140 | # No tracing domain option | |
1141 | _guard '^-*' 'log level name' | |
1142 | fi | |
1143 | ||
1144 | # Add completions | |
1145 | local expl | |
1146 | ||
1147 | _wanted log-levels expl 'log level name' compadd -a log_levels | |
1148 | } | |
1149 | ||
1150 | # Adds completions for a trigger condition type. | |
1151 | __lttng_complete_trigger_condition_type() { | |
1152 | local -r types=( | |
1153 | 'event-rule-matches:an event rule matches an event' | |
1154 | ) | |
1155 | ||
1156 | # Add completions | |
1157 | local expl | |
1158 | ||
1159 | _describe 'trigger condition type' types | |
1160 | } | |
1161 | ||
1162 | # Adds completions for a trigger action type. | |
1163 | __lttng_complete_trigger_action_type() { | |
1164 | local -r types=( | |
1165 | 'notify:send a notification through the notification mechanism' | |
1166 | 'start-session:start a recording session' | |
1167 | 'stop-session:stop a recording session' | |
1168 | 'rotate-session:archive the current trace chunk of a recording session' | |
1169 | 'snapshot-session:take a recording session snapshot' | |
1170 | ) | |
1171 | ||
1172 | # Add completions | |
1173 | local expl | |
1174 | ||
1175 | _describe 'trigger action type' types | |
1176 | } | |
1177 | ||
1178 | # Adds completions for the arguments of the `add-trigger` command. | |
1179 | # | |
1180 | # Note that those completions are incomplete, in that: | |
1181 | # | |
1182 | # • A valid event rule specification, as per lttng-event-rule(7), | |
1183 | # must follow `--condition=event-rule-matches`. | |
1184 | # | |
1185 | # • `--capture` options are possible within an `event-rule-matches` | |
1186 | # condition specifier. | |
1187 | # | |
1188 | # • The `--rate-policy` option and other arguments, sometimes mandatory, | |
1189 | # are possible within an action specifier. | |
1190 | # | |
1191 | # Having full completion for condition and action specifiers require | |
1192 | # more Zsh magic as _arguments(), like most command-line argument | |
1193 | # parsers, doesn't take option positions into account. | |
1194 | __lttng_complete_add_trigger_cmd() { | |
1195 | local -r specs=( | |
1196 | $help_opt_specs | |
1197 | '(-n --name)'{-n+,--name=}'[set the trigger name]:new trigger name:' | |
1198 | '--owner-uid=[add the trigger as another Unix user]: : __lttng_complete_uid' | |
1199 | '--condition=[set the condition type and arguments]: : __lttng_complete_trigger_condition_type' | |
1200 | '*--action=[set the action type and arguments]: : __lttng_complete_trigger_action_type' | |
1201 | ) | |
1202 | ||
1203 | # Add completions | |
1204 | __lttng_arguments $specs | |
1205 | } | |
1206 | ||
1207 | # Adds completions for the arguments of the `clear` command. | |
1208 | __lttng_complete_clear_cmd() { | |
1209 | local -r specs=( | |
1210 | $help_opt_specs | |
1211 | '(-a --all):: : __lttng_complete_session_name all all' | |
1212 | '(1 -a --all)'{-a,--all}'[clear all recording sessions]' | |
1213 | ) | |
1214 | ||
1215 | # Add completions | |
1216 | __lttng_arguments $specs | |
1217 | } | |
1218 | ||
1219 | # Adds completions for the arguments of the `create` command. | |
1220 | __lttng_complete_create_cmd() { | |
1221 | local specs=( | |
1222 | $help_opt_specs | |
1223 | ':: :_guard "^-*" "new recording session name"' | |
1224 | '(-C --ctrl-url output)'{-C+,--ctrl-url=}'[set the control URL]:control URL:' | |
1225 | '(-D --data-url output)'{-D+,--data-url=}'[set the trace data output URL]:trace data output URL:' | |
1226 | ) | |
1227 | ||
79d885cf | 1228 | # The `--shm-path` option requires LTTng-tools ≥ 2.7 |
76bcac58 PP |
1229 | if ((minor_version >= 7)); then |
1230 | specs+=( | |
1231 | '--shm-path=[write shared memory files to a specific directory]:shared memory file directory:_files -/' | |
1232 | ) | |
1233 | fi | |
1234 | ||
1235 | # Add the remaining option groups | |
1236 | specs+=( | |
1237 | + '(output)' | |
1238 | '(-D --data-url -C --ctrl-url --live)--no-output[disable trace data output]' | |
1239 | '(-D --data-url -C --ctrl-url --live)'{-o+,--output=}'[set the local trace data output directory]:trace data output directory:_files -/' | |
1240 | '(-D --data-url -C --ctrl-url)'{-U+,--set-url=}'[set the trace data output and control URL]:trace data output and control URL:' | |
1241 | + '(mode)' | |
1242 | '(-o --output --no-output)--live=[create an LTTng live recording session]:live timer period (µs):' | |
1243 | '--snapshot[create a snapshot recording session]' | |
1244 | ) | |
1245 | ||
1246 | # Add completions | |
1247 | __lttng_arguments $specs | |
1248 | } | |
1249 | ||
1250 | # Adds completions for the arguments of the `destroy` command. | |
1251 | __lttng_complete_destroy_cmd() { | |
1252 | local specs=( | |
1253 | $help_opt_specs | |
1254 | '(-a --all):: : __lttng_complete_session_name all all' | |
1255 | '(1 -a --all)'{-a,--all}'[destroy all recording sessions]' | |
1256 | ) | |
1257 | ||
1258 | # The `--no-wait` option requires LTTng-tools ≥ 2.8 | |
1259 | if ((minor_version >= 8)); then | |
1260 | specs+=( | |
1261 | '(-n --no-wait)'{-n,--no-wait}'[exit immediately]' | |
1262 | ) | |
1263 | fi | |
1264 | ||
1265 | # Add completions | |
1266 | __lttng_arguments $specs | |
1267 | } | |
1268 | ||
1269 | # Adds completions for the arguments of the `disable-channel` command. | |
1270 | __lttng_complete_disable_channel_cmd() { | |
1271 | local -r specs=( | |
1272 | $help_opt_specs | |
1273 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1274 | ': : _sequence __lttng_complete_channel_name enabled opt' | |
1275 | + '(domain)' | |
1276 | {-k,--kernel}'[select the Linux kernel tracing domain]' | |
1277 | {-u,--userspace}'[select the user space tracing domain]' | |
1278 | ) | |
1279 | ||
1280 | # Add completions | |
1281 | __lttng_arguments $specs | |
1282 | } | |
1283 | ||
1284 | # Prints the XML tracing domain name value depending on the tracing | |
1285 | # domain option (in `$opt_args`), or prints nothing and returns 1 when | |
1286 | # not available. | |
1287 | __lttng_xml_domain_name_from_opt() { | |
1288 | if __lttng_kernel_domain_opt_is_set; then | |
1289 | echo -n KERNEL | |
1290 | elif __lttng_user_domain_opt_is_set; then | |
1291 | echo -n UST | |
1292 | elif __lttng_jul_domain_opt_is_set; then | |
1293 | echo -n JUL | |
1294 | elif __lttng_log4j_domain_opt_is_set; then | |
1295 | echo -n LOG4J | |
e46c0fbb MJ |
1296 | elif __lttng_log4j2_domain_opt_is_set; then |
1297 | echo -n LOG4J2 | |
76bcac58 PP |
1298 | elif __lttng_python_domain_opt_is_set; then |
1299 | echo -n PYTHON | |
1300 | else | |
1301 | return 1 | |
1302 | fi | |
1303 | } | |
1304 | ||
1305 | # Prints the XML instrumentation point type value depending on the | |
1306 | # instrumentation point option (in `$opt_args`). | |
1307 | __lttng_xml_ip_type_from_opt() { | |
1308 | if (($+opt_args[--syscall] || $+opt_args[ip---syscall])); then | |
1309 | echo -n SYSCALL | |
1310 | elif (($+opt_args[--probe] || $+opt_args[ip---probe])); then | |
1311 | echo -n PROBE | |
1312 | elif (($+opt_args[--function] || $+opt_args[ip---function])); then | |
1313 | echo -n FUNCTION | |
1314 | else | |
1315 | echo -n TRACEPOINT | |
1316 | fi | |
1317 | } | |
1318 | ||
1319 | # Adds completions for an old, enabled recording event rule name | |
1320 | # condition (for the `disable-event` command). | |
1321 | __lttng_complete_old_enabled_er_name_cond() { | |
1322 | local -r msg='recording event rule name condition' | |
1323 | ||
1324 | # Find the recording session name to use | |
1325 | local session_name | |
1326 | ||
1327 | if (($+opt_args[-s])); then | |
1328 | session_name=$opt_args[-s] | |
1329 | elif (($+opt_args[--session])); then | |
1330 | session_name=$opt_args[--session] | |
1331 | else | |
1332 | # Fall back to current recording session | |
1333 | session_name=$(__lttng_cur_session_name) | |
1334 | ||
1335 | if (($? != 0)); then | |
1336 | _guard '^-*' $msg | |
1337 | fi | |
1338 | fi | |
1339 | ||
1340 | # Find the channel name to use (`channel0` is the default name) | |
1341 | local channel_name=channel0 | |
1342 | ||
1343 | if (($+opt_args[-c])); then | |
1344 | channel_name=$opt_args[-c] | |
1345 | elif (($+opt_args[--channel])); then | |
1346 | channel_name=$opt_args[--channel] | |
1347 | fi | |
1348 | ||
1349 | # Create tracing domain XPath part | |
1350 | local domain_xpath | |
1351 | local xml_domain_val | |
1352 | ||
1353 | xml_domain_val=$(__lttng_xml_domain_name_from_opt) | |
1354 | ||
1355 | if (($? == 0)); then | |
1356 | domain_xpath="*[local-name() = 'domain'][*[local-name() = 'type'] = '$xml_domain_val']//" | |
1357 | fi | |
1358 | ||
1359 | # Create channel XPath part | |
1360 | local -r channel_xpath="*[local-name() = 'channel'][*[local-name() = 'name'] = '$channel_name']//" | |
1361 | ||
1362 | # Create instrumentation point type XPath part | |
1363 | local -r xml_ip_type_val=$(__lttng_xml_ip_type_from_opt) | |
1364 | local -r ip_type_xpath="[*[local-name() = 'type'] = '$xml_ip_type_val']" | |
1365 | ||
1366 | # Get XML document (detailed recording session) | |
1367 | local session_xml | |
1368 | ||
1369 | session_xml=$(__lttng_session_xml $msg $session_name) | |
1370 | ||
1371 | if (($? != 0)); then | |
1372 | return 1 | |
1373 | fi | |
1374 | ||
1375 | # Convert to one recording event rule name per line | |
1376 | local lines | |
1377 | ||
1378 | lines=$(__lttng_xmllint_xpath $session_xml "//$domain_xpath${channel_xpath}*[local-name() = 'event']${ip_type_xpath}[*[local-name() = 'enabled'] = 'true']/*[local-name() = 'name']/text()") | |
1379 | ||
1380 | if (($? != 0)); then | |
1381 | _guard '^-*' $msg | |
1382 | return | |
1383 | fi | |
1384 | ||
1385 | local -a er_names | |
1386 | ||
1387 | while read -r line; do | |
1388 | if [[ -z ${line// } ]]; then | |
1389 | # Skip empty line | |
1390 | continue | |
1391 | fi | |
1392 | ||
1393 | er_names+=$line | |
1394 | done <<< $lines | |
1395 | ||
1396 | # Add completions | |
1397 | local expl | |
1398 | ||
1399 | _wanted -C event events expl $msg compadd "$@" -a er_names | |
1400 | } | |
1401 | ||
1402 | # Adds completions for the arguments of the `disable-event` command. | |
1403 | __lttng_complete_disable_event_cmd() { | |
1404 | local -r kernel_ip_opt_excl=(--syscall --probe --function) | |
1405 | local specs=( | |
1406 | $help_opt_specs | |
1407 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1408 | '(-c --channel)'{-c+,--channel=}'[select a specific channel]: : __lttng_complete_channel_name all opt' | |
1409 | + '(names)' | |
1410 | {-a,--all-events}'[disable all recording event rules]' | |
1411 | ': :_sequence __lttng_complete_old_enabled_er_name_cond' | |
1412 | + '(domain)' | |
1413 | {-k,--kernel}'[select the Linux kernel tracing domain]' | |
1414 | "($kernel_ip_opt_excl)"{-u,--userspace}'[select the user space tracing domain]' | |
1415 | "($kernel_ip_opt_excl)"{-j,--jul}'[select the `java.util.logging` tracing domain]' | |
1416 | ) | |
1417 | ||
1418 | # Add tracing domain option specifications based on the minor version | |
1419 | # of LTTng-tools. | |
1420 | if ((minor_version >= 6)); then | |
1421 | specs+=( | |
e46c0fbb MJ |
1422 | "($kernel_ip_opt_excl)"{-l,--log4j}'[select the Apache Log4j 1.x tracing domain]' |
1423 | ) | |
1424 | fi | |
1425 | ||
1426 | if ((minor_version >= 14)); then | |
1427 | specs+=( | |
1428 | "($kernel_ip_opt_excl)"{-L,--log4j2}'[select the Apache Log4j 2 tracing domain]' | |
76bcac58 PP |
1429 | ) |
1430 | fi | |
1431 | ||
1432 | if ((minor_version >= 7)); then | |
1433 | specs+=( | |
1434 | "($kernel_ip_opt_excl)"{-p,--python}'[select the Python tracing domain]' | |
1435 | ) | |
1436 | fi | |
1437 | ||
1438 | # Add instrumentation point type option specifications based on the | |
1439 | # minor version of LTTng-tools. | |
1440 | if ((minor_version >= 6)); then | |
1441 | specs+=( | |
1442 | + '(ip)' | |
1443 | "($non_kernel_domain_opt_excl)--syscall[disable recording ER matching Linux system call events]" | |
1444 | ) | |
1445 | fi | |
1446 | ||
1447 | if ((minor_version >= 7)); then | |
1448 | specs+=( | |
1449 | '--tracepoint[disable recording ER matching tracepoint events]' | |
1450 | "($non_kernel_domain_opt_excl)--probe[disable recording ER matching kprobe events]" | |
1451 | "($non_kernel_domain_opt_excl)--function[disable recording ER matching kretprobe events]" | |
1452 | ) | |
1453 | fi | |
1454 | ||
1455 | # Add completions | |
1456 | __lttng_arguments $specs | |
1457 | } | |
1458 | ||
1459 | # Adds completions for the arguments of the `disable-rotation` command. | |
1460 | __lttng_complete_disable_rotation_cmd() { | |
1461 | local -r specs=( | |
1462 | $help_opt_specs | |
1463 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1464 | '--timer[disable the periodic rotation schedule]' | |
1465 | '--size[disable the size-based rotation schedule]' | |
1466 | ) | |
1467 | ||
1468 | __lttng_arguments $specs | |
1469 | } | |
1470 | ||
1471 | # Adds completions for a channel output type (`mmap` and, possibly, | |
1472 | # `splice`) (for the `--output` option of the `enable-channel` command). | |
1473 | # | |
1474 | # This function replaces the argument field of the current context with | |
1475 | # `output-opt`. | |
1476 | # | |
1477 | # This function relies on the user space tracing domain options of | |
1478 | # `$opt_args` to restrict the offered completions. Without the user | |
1479 | # space tracing domain option, this function adds the `splice` | |
1480 | # completion too. | |
1481 | __lttng_complete_channel_output_type() { | |
1482 | local output_types=(mmap) | |
1483 | ||
1484 | if ! __lttng_user_domain_opt_is_set; then | |
1485 | # Linux kernel tracing domain or none | |
1486 | output_types+=(splice) | |
1487 | fi | |
1488 | ||
1489 | local expl | |
1490 | ||
1491 | _wanted -C 'output-opt' values expl 'output type' compadd -a output_types | |
1492 | } | |
1493 | ||
1494 | # Adds completions for the non-option argument of the `enable-channel` | |
1495 | # command. | |
1496 | # | |
1497 | # This function either, depending on the keys of `$opt_args`: | |
1498 | # | |
1499 | # At least one creation option: | |
1500 | # Shows a message to enter the new channel name. | |
1501 | # | |
1502 | # Otherwise: | |
1503 | # Adds completions for a comma-separated list of known channel names | |
1504 | # using __lttng_complete_channel_name(). | |
1505 | __lttng_complete_enable_channel_cmd_names() { | |
1506 | local key | |
1507 | local -r enable_opts=( | |
1508 | -s --session | |
1509 | domain---kernel domain--k | |
1510 | domain---userspace domain--u | |
1511 | ) | |
1512 | ||
1513 | # For each key of `$opt_args` | |
1514 | for key in "${(@k)opt_args}"; do | |
1515 | if (($enable_opts[(Ie)$key])); then | |
1516 | # Enabling option exists: skip | |
1517 | continue | |
1518 | fi | |
1519 | ||
1520 | # Creation option exists: single name | |
1521 | _guard '^-*' 'new channel name' | |
1522 | return | |
1523 | done | |
1524 | ||
1525 | # Comma-separated list of existing channel names | |
1526 | _sequence __lttng_complete_channel_name disabled opt | |
1527 | } | |
1528 | ||
1529 | # Adds completions for the arguments of the `enable-channel` command. | |
1530 | __lttng_complete_enable_channel_cmd() { | |
1531 | local specs=( | |
1532 | $help_opt_specs | |
1533 | '--switch-timer=[set the switch timer period]:switch timer period (µs):' | |
1534 | '--read-timer=[set the read timer period]:read timer period (µs):' | |
1535 | '--subbuf-size=[set the size of each sub-buffer]:sub-buffer size (bytes; `k`/`M`/`G` suffixes supported):' | |
1536 | '--num-subbuf=[set the number of sub-buffers per ring buffer]:sub-buffer count:' | |
1537 | '--tracefile-size=[set the maximum size of each trace file]:trace file size (bytes; `k`/`M`/`G` suffixes supported):' | |
1538 | '--tracefile-count=[set the maximum number of trace files]:maximum trace file count:' | |
1539 | '--output=[set the output type]: : __lttng_complete_channel_output_type' | |
1540 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1541 | ': : __lttng_complete_enable_channel_cmd_names' | |
1542 | ) | |
1543 | ||
1544 | # The `--blocking-timeout` and `--monitor-timer` options require | |
1545 | # LTTng-tools ≥ 2.10. | |
1546 | if ((minor_version >= 10)); then | |
1547 | specs+=( | |
1548 | '(--kernel --overwrite --buffers-global)--blocking-timeout=[set the blocking timeout]:blocking timeout (µs):' | |
1549 | '--monitor-timer=[set the monitor timer period]:monitor timer period (µs):' | |
1550 | ) | |
1551 | fi | |
1552 | ||
1553 | # Add the remaining option groups | |
1554 | specs+=( | |
1555 | + '(domain)' | |
1556 | '(--blocking-timeout --buffers-uid --buffers-pid)'{-k,--kernel}'[select the Linux kernel tracing domain]' | |
1557 | '(--buffers-global)'{-u,--userspace}'[select the user space tracing domain]' | |
1558 | + '(loss-mode)' | |
1559 | '--discard[discard event records with no available sub-buffer]' | |
1560 | '(--blocking-timeout)--overwrite[overwrite oldest sub-buffer with no available sub-buffer]' | |
1561 | + '(buffering)' | |
1562 | '(-k --kernel)--buffers-uid[use per-user ring buffers]' | |
1563 | '(-k --kernel)--buffers-pid[use per-process ring buffers]' | |
1564 | '(-u --userspace --blocking-timeout)--buffers-global[use global ring buffers]' | |
1565 | ) | |
1566 | ||
1567 | # Add completions | |
1568 | __lttng_arguments $specs | |
1569 | } | |
1570 | ||
1571 | # Adds completions for the arguments of the `enable-event` command. | |
1572 | __lttng_complete_enable_event_cmd() { | |
1573 | local -r kernel_opts_excl=( | |
1574 | -k --kernel | |
1575 | --syscall | |
1576 | --probe | |
1577 | --userspace-probe | |
1578 | --function | |
1579 | ) | |
1580 | local -r non_kernel_opts_excl=( | |
1581 | $non_kernel_domain_opt_excl | |
1582 | -x --exclude | |
1583 | log-level | |
1584 | ) | |
1585 | local -r exclude_opt_excl=( | |
1586 | $kernel_opts_excl | |
1587 | -j --jul | |
1588 | -l --log4j | |
e46c0fbb | 1589 | -L --log4j2 |
76bcac58 PP |
1590 | -p --python |
1591 | -x --exclude | |
1592 | ) | |
1593 | local ip_specs=( | |
1594 | '--tracepoint[only match LTTng tracepoint events]' | |
1595 | "($non_kernel_opts_excl)--syscall[only match Linux system call events]" | |
1596 | "($non_kernel_opts_excl)--probe=[only match kprobe events]:kprobe location:" | |
1597 | "($non_kernel_opts_excl)--function=[only match kretprobe events]:kretprobe location:" | |
1598 | ) | |
1599 | local domain_specs=( | |
1600 | "($non_kernel_opts_excl)"{-k,--kernel}'[select the Linux kernel tracing domain]' | |
1601 | "($kernel_opts_excl)"{-u,--userspace}'[select the user space tracing domain]' | |
1602 | "($kernel_opts_excl -x --exclude)"{-j,--jul}'[select the `java.util.logging` tracing domain]' | |
1603 | ) | |
1604 | ||
e46c0fbb | 1605 | # The Apache Log4j tracing domain options require LTTng-tools ≥ 2.6 |
76bcac58 PP |
1606 | if ((minor_version >= 6)); then |
1607 | domain_specs+=( | |
e46c0fbb MJ |
1608 | "($kernel_opts_excl -x --exclude)"{-l,--log4j}'[select the Apache Log4j 1.x tracing domain]' |
1609 | ) | |
1610 | fi | |
1611 | ||
1612 | # The Apache Log4j tracing domain options require LTTng-tools ≥ 2.14 | |
1613 | if ((minor_version >= 14)); then | |
1614 | domain_specs+=( | |
1615 | "($kernel_opts_excl -x --exclude)"{-L,--log4j2}'[select the Apache Log4j 2 tracing domain]' | |
76bcac58 PP |
1616 | ) |
1617 | fi | |
1618 | ||
1619 | # The Python tracing domain options require LTTng-tools 2.7 | |
1620 | if ((minor_version >= 7)); then | |
1621 | domain_specs+=( | |
1622 | "($kernel_opts_excl -x --exclude)"{-p,--python}'[select the Python tracing domain]' | |
1623 | ) | |
1624 | fi | |
1625 | ||
1626 | # The Linux user space probe instrumentation options require LTTng-tools 2.11 | |
1627 | if ((minor_version >= 11)); then | |
1628 | ip_specs+=( | |
1629 | "($non_kernel_opts_excl)--userspace-probe=[only match Linux user space probe events]:user space probe location:" | |
1630 | ) | |
1631 | fi | |
1632 | ||
1633 | # Add completions. | |
1634 | # | |
1635 | # There's no way, based on the command-line arguments, to distinguish | |
1636 | # between creating a new recording event rule and enabling an | |
1637 | # existing, disabled recording event rule here. | |
1638 | # | |
1639 | # For example, given this: | |
1640 | # | |
1641 | # $ lttng enable-event --kernel --syscall <TAB> | |
1642 | # | |
1643 | # At this point, the user might want the list of existing, disabled | |
1644 | # kernel system call recording event rule names (current recording | |
1645 | # session, default channel name), or the full list of available system | |
1646 | # call instrumentation point names. | |
1647 | # | |
1648 | # This function makes the arbitrary choice to provide the available | |
1649 | # instrumentation point names (__lttng_complete_ip_name()) because, | |
1650 | # interactively, it seems to be more common/useful than disabling | |
1651 | # existing recording event rules. | |
1652 | local -r specs=( | |
1653 | $help_opt_specs | |
1654 | '(--probe --userspace-probe --function -f --filter)'{-f+,--filter=}'[only match events which satisfy an expression]:filter expression:' | |
1655 | "($exclude_opt_excl)"{-x+,--exclude=}'[exclude event name patterns]:comma-separated list of patterns:' | |
1656 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1657 | '(-c --channel)'{-c+,--channel=}'[select a specific channel]: : __lttng_complete_channel_name all opt' | |
1658 | + '(log-level)' | |
1659 | "($kernel_opts_excl)--loglevel=[only match events with specific log levels]: : __lttng_complete_log_level" | |
1660 | "($kernel_opts_excl)--loglevel-only=[only match events with an exact log level]: : __lttng_complete_log_level" | |
1661 | + '(names)' | |
1662 | {-a,--all}'[match events regardless of their name]' | |
1663 | ': :_sequence __lttng_complete_ip_name' | |
1664 | + '(ip)' $ip_specs | |
1665 | + '(domain)' $domain_specs | |
1666 | ) | |
1667 | ||
1668 | __lttng_arguments $specs | |
1669 | } | |
1670 | ||
1671 | # Adds completions for the arguments of the `enable-rotation` command. | |
1672 | __lttng_complete_enable_rotation_cmd() { | |
1673 | local -r specs=( | |
1674 | $help_opt_specs | |
1675 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1676 | '--timer=[rotate periodically]:period (µs; `ms`/`s`/`m`/`h` suffixes supported):' | |
1677 | '--size=[rotate based on flushed size of current trace chunk]:size (bytes; `k`/`M`/`G` suffixes supported):' | |
1678 | ) | |
1679 | ||
1680 | # Add completions | |
1681 | __lttng_arguments $specs | |
1682 | } | |
1683 | ||
1684 | # Adds completions for the arguments of the `help` command. | |
1685 | __lttng_complete_help_cmd() { | |
1686 | local -r specs=( | |
1687 | $help_opt_specs | |
1688 | ': : __lttng_complete_cmd_name' | |
1689 | ) | |
1690 | ||
1691 | # Add completions | |
1692 | __lttng_arguments $specs | |
1693 | } | |
1694 | ||
1695 | # Adds completions for the arguments of the `list` command. | |
1696 | __lttng_complete_list_cmd() { | |
1697 | local -r domain_opt_excl=( | |
1698 | -d --domain | |
1699 | -f --fields | |
1700 | -c --channel | |
1701 | -k --kernel | |
1702 | -u --userspace | |
1703 | -j --jul | |
1704 | -l --log4j | |
e46c0fbb | 1705 | -L --log4j2 |
76bcac58 PP |
1706 | -p --python |
1707 | --syscall | |
1708 | ) | |
1709 | local specs=( | |
1710 | $help_opt_specs | |
1711 | '(-d --domain -f --fields --syscall -c --channel 1)'{-f,--fields}'[show instrumentation point fields]' | |
1712 | "($domain_opt_excl)"{-d,--domain}'[show tracing domains with at least one channel]' | |
1713 | '(-d --domain -f --fields --syscall -c --channel)'{-c+,--channel=}'[list the objects of a specific channel]: : __lttng_complete_channel_name all arg' | |
1714 | '(-d --domain -f --fields --syscall):recording session name: __lttng_complete_session_name all all' | |
1715 | '(-d --domain -k --kernel)'{-k,--kernel}'[list Linux kernel tracing domain objects]' | |
1716 | '(-d --domain -u --userspace)'{-u,--userspace}'[list user space tracing domain objects]' | |
1717 | '(-d --domain -j --jul)'{-j,--jul}'[list `java.util.logging` tracing domain objects]' | |
1718 | ) | |
1719 | ||
e46c0fbb | 1720 | # The Apache Log4j 1.x tracing domain and `--syscall` options require |
76bcac58 PP |
1721 | # LTTng-tools ≥ 2.6. |
1722 | if ((minor_version >= 6)); then | |
1723 | specs+=( | |
e46c0fbb | 1724 | '(-d --domain -l --log4j)'{-l,--log4j}'[list Apache Log4j 1.x tracing domain objects]' |
76bcac58 PP |
1725 | '(-d --domain)--syscall[list Linux kernel system calls]' |
1726 | ) | |
1727 | fi | |
1728 | ||
e46c0fbb MJ |
1729 | # The Apache Log4j 2 tracing domain requires LTTng-tools ≥ 2.14. |
1730 | if ((minor_version >= 14)); then | |
1731 | specs+=( | |
1732 | '(-d --domain -L --log4j2)'{-L,--log4j2}'[list Apache Log4j 2 tracing domain objects]' | |
1733 | ) | |
1734 | fi | |
1735 | ||
76bcac58 PP |
1736 | # The Python tracing domain options require LTTng-tools 2.7 |
1737 | if ((minor_version >= 7)); then | |
1738 | specs+=( | |
1739 | '(-d --domain -p --python)'{-p,--python}'[list Python tracing domain objects]' | |
1740 | ) | |
1741 | fi | |
1742 | ||
1743 | # Add completions | |
1744 | __lttng_arguments $specs | |
1745 | } | |
1746 | ||
1747 | # Adds completions for the arguments of the `list-triggers` command. | |
1748 | __lttng_complete_list_triggers_cmd() { | |
1749 | __lttng_arguments $help_opt_specs | |
1750 | } | |
1751 | ||
1752 | # Adds completions for the arguments of the `load` command. | |
1753 | __lttng_complete_load_cmd() { | |
1754 | local specs=( | |
1755 | $help_opt_specs | |
1756 | '(-f --force)'{-f,--force}'[overwrite existing recording sessions]' | |
1757 | '(-i --input-path)'{-i+,--input-path=}'[load recording session configurations from a specific path]:recording session configuration path:_files' | |
1758 | '(-a --all --override-name 1)'{-a,--all}'[load all recording session configurations]' | |
1759 | '(-a --all):recording session configuration name:_guard "^-*" "recording session name"' | |
1760 | ) | |
1761 | ||
1762 | if ((minor_version >= 9)); then | |
1763 | specs+=( | |
1764 | '--override-url=[override the loaded recording session output URL]:output URL:' | |
1765 | '(-a --all)--override-name=[override the loaded recording session name]:recording session name:' | |
1766 | ) | |
1767 | fi | |
1768 | ||
1769 | # Add completions | |
1770 | __lttng_arguments $specs | |
1771 | } | |
1772 | ||
1773 | # Adds completions for the arguments of the `metadata` command | |
1774 | # (deprecated). | |
1775 | __lttng_complete_metadata_cmd() { | |
1776 | local -r specs=( | |
1777 | $help_opt_specs | |
1778 | ':action:(regenerate)' | |
1779 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1780 | ) | |
1781 | ||
1782 | # Add completions | |
1783 | __lttng_arguments $specs | |
1784 | } | |
1785 | ||
1786 | # Adds completions for the arguments of the `regenerate` command. | |
1787 | __lttng_complete_regenerate_cmd() { | |
1788 | local -r specs=( | |
1789 | $help_opt_specs | |
1790 | ':trace data type:(metadata statedump)' | |
1791 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1792 | ) | |
1793 | ||
1794 | # Add completions | |
1795 | __lttng_arguments $specs | |
1796 | } | |
1797 | ||
1798 | # Adds completions for the arguments of the `remove-trigger` command. | |
1799 | __lttng_complete_remove_trigger_cmd() { | |
1800 | local -r specs=( | |
1801 | $help_opt_specs | |
1802 | '--owner-uid=[remove the trigger as another Unix user]: : __lttng_complete_uid' | |
1803 | ': : __lttng_complete_trigger_name' | |
1804 | ) | |
1805 | ||
1806 | # Add completions | |
1807 | __lttng_arguments $specs | |
1808 | } | |
1809 | ||
1810 | # Adds completions for the arguments of the `rotate` command. | |
1811 | __lttng_complete_rotate_cmd() { | |
1812 | local -r specs=( | |
1813 | $help_opt_specs | |
1814 | '(-n --no-wait)'{-n,--no-wait}'[exit immediately]' | |
1815 | ': : __lttng_complete_session_name all all' | |
1816 | ) | |
1817 | ||
1818 | # Add completions | |
1819 | __lttng_arguments $specs | |
1820 | } | |
1821 | ||
1822 | # Adds completions for the arguments of the `save` command. | |
1823 | __lttng_complete_save_cmd() { | |
1824 | local -r specs=( | |
1825 | $help_opt_specs | |
1826 | '(-f --force)'{-f,--force}'[overwrite existing recording session configuration files]' | |
1827 | '(-o --output-path)'{-o+,--output-path=}'[save recording session configuration files to a specific directory]:recording session configuration directory:_files -/' | |
1828 | '(-a --all 1)'{-a,--all}'[save all recording session configurations]' | |
1829 | '(-a --all): : __lttng_complete_session_name all all' | |
1830 | ) | |
1831 | ||
1832 | # Add completions | |
1833 | __lttng_arguments $specs | |
1834 | } | |
1835 | ||
1836 | # Adds completions for the arguments of the `set-session` command. | |
1837 | __lttng_complete_set_session_cmd() { | |
1838 | local -r specs=( | |
1839 | $help_opt_specs | |
1840 | ': : __lttng_complete_session_name all all' | |
1841 | ) | |
1842 | ||
1843 | # Add completions | |
1844 | __lttng_arguments $specs | |
1845 | } | |
1846 | ||
1847 | # Adds completions for the arguments of the `snapshot` command. | |
1848 | __lttng_complete_snapshot_cmd() { | |
1849 | local specs=( | |
1850 | $help_opt_specs | |
1851 | '(-): : __lttng_complete_snapshot_action_name' \ | |
1852 | '(-)*:: :->action-args' \ | |
1853 | ) | |
1854 | ||
1855 | # Add action name completions | |
1856 | local curcontext=$curcontext state state_descr line | |
1857 | local -A opt_args | |
1858 | ||
1859 | _arguments -C -s -W : $specs | |
1860 | ||
1861 | if (($? == 0)); then | |
1862 | # Completions added: we're done | |
1863 | return | |
1864 | fi | |
1865 | ||
1866 | # Add action-specific completions | |
1867 | local -r common_session_specs=( | |
1868 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all snapshot' | |
1869 | ) | |
1870 | local -r common_output_specs=( | |
1871 | '(-m --max-size)'{-m+,--max-size=}'[set the maximum total size of all snapshot files]:maximum size (bytes; `k`/`M`/`G` suffixes supported):' | |
1872 | '(-n --name)'{-n+,--name=}'[set the snapshot output name]:snapshot output name:' | |
1873 | '(1 -C --ctrl-url output)'{-C+,--ctrl-url=}'[set the control URL]:control URL:' | |
1874 | '(1 -D --data-url output)'{-D+,--data-url=}'[set the trace data output URL]:trace data output URL:' | |
1875 | '(-C --ctrl-url -D --data-url): :_guard "^-*" "snapshot output URL"' | |
1876 | ) | |
1877 | ||
1878 | if [[ $state[1] = action-args ]]; then | |
1879 | # Add completions for the arguments of the specific snapshot action | |
1880 | curcontext=${curcontext%:*:*}:lttng-snapshot-$line[1]: | |
1881 | ||
1882 | case $line[1] in | |
1883 | add-output | record) | |
1884 | specs=($common_session_specs $common_output_specs);; | |
1885 | del-output) | |
1886 | specs=($common_session_specs ':snapshot output index:(1)');; | |
1887 | list-output) | |
1888 | specs=($common_session_specs);; | |
1889 | *) | |
1890 | _message "unknown snapshot action \`$line[1]\`" | |
1891 | return 1 | |
1892 | ;; | |
1893 | esac | |
1894 | ||
1895 | # Add completions | |
1896 | __lttng_arguments $specs | |
1897 | return | |
1898 | fi | |
1899 | ||
1900 | return 1 | |
1901 | } | |
1902 | ||
1903 | # Adds completions for the arguments of the `start` command. | |
1904 | __lttng_complete_start_cmd() { | |
1905 | local -r specs=( | |
1906 | $help_opt_specs | |
1907 | ': : __lttng_complete_session_name inactive all' | |
1908 | ) | |
1909 | ||
1910 | # Add completions | |
1911 | __lttng_arguments $specs | |
1912 | } | |
1913 | ||
1914 | # Adds completions for the arguments of the `stop` command. | |
1915 | __lttng_complete_stop_cmd() { | |
1916 | local -r specs=( | |
1917 | $help_opt_specs | |
1918 | '(-n --no-wait)'{-n,--no-wait}'[exit immediately]' | |
1919 | ': : __lttng_complete_session_name active all' | |
1920 | ) | |
1921 | ||
1922 | # Add completions | |
1923 | __lttng_arguments $specs | |
1924 | } | |
1925 | ||
1926 | # Adds completions for the arguments of the `status` command. | |
1927 | __lttng_complete_status_cmd() { | |
1928 | __lttng_arguments $help_opt_specs | |
1929 | } | |
1930 | ||
1931 | # Adds completions for the arguments of the `track` command. | |
1932 | __lttng_complete_track_cmd() { | |
1933 | local specs=( | |
1934 | $help_opt_specs | |
1935 | '(-s --session)'{-s+,--session=}'[select a specific recording session]: : __lttng_complete_session_name all all' | |
1936 | '(-a --all)'{-a,--all}'[add all possible values to the selected inclusion sets]' | |
1937 | '(-p --pid)'{-p+,--pid=}'[add values to the process ID inclusion set]:process ID(s):_sequence _pids' | |
1938 | ) | |
1939 | ||
1940 | # Virtual PID and user/group inclusion sets require LTTng-tools ≥ 2.12 | |
1941 | if ((minor_version >= 12)); then | |
1942 | specs+=( | |
1943 | '--vpid=[add values to the virtual process ID inclusion set]:virtual process ID(s):_sequence _pids' | |
1944 | '(-u --userspace)--uid=[add values to the user ID inclusion set]:user(s):_sequence _users' | |
1945 | '--vuid=[add values to the virtual user ID inclusion set]:virtual user(s):_sequence _users' | |
1946 | '(-u --userspace)--gid=[add values to the group ID inclusion set]:group(s):_sequence _groups' | |
1947 | '--vgid=[add values to the virtual group ID inclusion set]:virtual group(s):_sequence _groups' | |
1948 | ) | |
1949 | fi | |
1950 | ||
1951 | # Append tracing domain specifications | |
1952 | specs+=( | |
1953 | + '(domain)' | |
1954 | {-k,--kernel}'[select the Linux kernel tracing domain]' | |
1955 | "(--uid --gid)"{-u,--userspace}'[select the user space tracing domain]' | |
1956 | ) | |
1957 | ||
1958 | # Add completions | |
1959 | __lttng_arguments $specs | |
1960 | } | |
1961 | ||
1962 | # Adds completions for the arguments of the `untrack` command. | |
1963 | __lttng_complete_untrack_cmd() { | |
1964 | # As of LTTng-tools 2.13, the `track` and `untrack` commands expect | |
1965 | # the same arguments. | |
1966 | __lttng_complete_track_cmd | |
1967 | } | |
1968 | ||
1969 | # Adds completions for the arguments of the `version` command. | |
1970 | __lttng_complete_version_cmd() { | |
1971 | __lttng_arguments $help_opt_specs | |
1972 | } | |
1973 | ||
1974 | # Adds completions for the arguments of the `view` command. | |
1975 | __lttng_complete_view_cmd() { | |
1976 | local -r specs=( | |
1977 | $help_opt_specs | |
1978 | '(-e --viewer)'{-e+,--viewer=}'[set the trace reader path]:trace reader path:_files' | |
1979 | '(-t --trace-path): : __lttng_complete_session_name all all' | |
1980 | '(1 -t --trace-path)'{-t+,--trace-path=}'[set the trace directory to pass to the reader]:trace directory:_files -/' | |
1981 | ) | |
1982 | ||
1983 | # Add completions | |
1984 | __lttng_arguments $specs | |
1985 | } | |
1986 | ||
1987 | # Add completions for the specific `lttng` command named `$line[1]`. | |
1988 | __lttng_complete_cmd() { | |
1989 | # An lttng(1) command: replace `lttng` with `lttng-$line[1]` (for | |
1990 | # example, `lttng-add-trigger`). | |
1991 | curcontext=${curcontext%:*:*}:lttng-$line[1]: | |
1992 | ||
1993 | # Keep the tracing group: we need to execute `lttng` for some | |
1994 | # completions and use the required tracing group to connect to the | |
1995 | # same session daemon. | |
1996 | # | |
1997 | # The default tracing group is `tracing`. | |
1998 | local tracing_group=tracing | |
1999 | ||
2000 | if (($+opt_args[-g])); then | |
2001 | tracing_group=$opt_args[-g] | |
2002 | elif (($+opt_args[--group])); then | |
2003 | tracing_group=$opt_args[--group] | |
2004 | fi | |
2005 | ||
2006 | # Add command completions: dispatch to a dedicated function | |
2007 | local -r func_name=__lttng_complete_${line[1]//-/_}_cmd | |
2008 | ||
2009 | if ! typeset -f $func_name >/dev/null; then | |
2010 | _message "unknown command \`$line[1]\`" | |
2011 | return 1 | |
2012 | fi | |
2013 | ||
2014 | local -A opt_args | |
2015 | ||
2016 | $func_name | |
2017 | } | |
2018 | ||
2019 | # Save program name | |
2020 | local -r prog_name=$words[1] | |
2021 | ||
2022 | # First, set the `minor_version` variable to the minor version of | |
2023 | # LTTng-tools. Some features depend on a specific version and this | |
2024 | # completion function supports many versions from LTTng-tools 2.5. | |
2025 | local -i minor_version | |
2026 | ||
2027 | __lttng_set_minor_version | |
2028 | ||
2029 | # Exit now with LTTng-tools < 2.5 or LTTng-tools > 2.14 | |
2030 | local -r ignore_version_limit=${LTTNG_ZSH_COMP_IGNORE_VERSION_LIMIT:-0} | |
2031 | ||
2032 | if ((minor_version < 5 || (minor_version > 14 && !ignore_version_limit))); then | |
2033 | _message "completion not available for LTTng-tools 2.$minor_version; please update the completion files or set \`LTTNG_ZSH_COMP_IGNORE_VERSION_LIMIT=1\`" | |
2034 | return 1 | |
2035 | fi | |
2036 | ||
2037 | # Common help option specifications | |
2038 | local -r help_opt_specs=( | |
2039 | '(- : *)'{-h,--help}'[show help]' | |
2040 | ) | |
2041 | ||
2042 | # Common non Linux kernel tracing domain option exclusions | |
e46c0fbb | 2043 | local -r non_kernel_domain_opt_excl=(-u --userspace -j --jul -l --log4j -L --log4j2 -p --python) |
76bcac58 PP |
2044 | |
2045 | # General option specifications | |
2046 | local gen_opt_specs=( | |
2047 | $help_opt_specs | |
2048 | '(- : *)--list-commands[list the available commands and quit]' | |
2049 | '--relayd-path=[set the relay daemon path]:relay daemon path:_files -g \*lttng-relayd' | |
2050 | '--group=[set the tracing group]:tracing group:_groups' | |
2051 | '(-q --quiet)*'{-v,--verbose}'[increase verbosity]' | |
2052 | '(-q --quiet -v --verbose)'{-q,--quiet}'[suppress all messages, including warnings and errors]' | |
2053 | '(- : *)'{-V,--version}'[show version and quit]' | |
2054 | ) | |
2055 | ||
2056 | # MI output requires LTTng-tools ≥ 2.6 | |
2057 | if ((minor_version >= 6)); then | |
2058 | gen_opt_specs+=( | |
2059 | '(-m --mi)'{-m+,--mi=}'[use the machine interface output]:machine interface type:(xml)' | |
2060 | ) | |
2061 | fi | |
2062 | ||
2063 | # Append session daemon option specifications | |
2064 | gen_opt_specs+=( | |
2065 | + '(sessiond)' | |
2066 | {-n,--no-sessiond}'[do not spawn a session daemon]' | |
2067 | '--sessiond-path=[set the session daemon path]:session daemon path:_files -g \*lttng-sessiond' | |
2068 | ) | |
2069 | ||
2070 | # Add general option and command name completions | |
2071 | local curcontext=$curcontext state state_descr line | |
2072 | local -A opt_args | |
2073 | ||
2074 | _arguments -C -s -W : \ | |
2075 | '(-): : __lttng_complete_cmd_name' \ | |
2076 | '(-)*:: :->cmd-args' \ | |
2077 | $gen_opt_specs | |
2078 | ||
2079 | local -ir main_ret=$? | |
2080 | ||
2081 | if ((main_ret == 0)); then | |
2082 | # Completions added: we're done | |
2083 | return | |
2084 | fi | |
2085 | ||
2086 | if [[ $state[1] = cmd-args ]]; then | |
2087 | # Add completions for the arguments of the specific command | |
2088 | __lttng_complete_cmd | |
2089 | return | |
2090 | fi | |
2091 | ||
2092 | return $main_ret |