From 1c4c551ba837145db3dac105d4087354018e13e4 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Sun, 18 Dec 2016 22:14:13 -0700 Subject: [PATCH] Fix bash completion script The bash completion script has never worked correctly for me. After reviewing the code, it didn't seem to make too much sense to me either. Thus, I've rewrote parts of it so that it works. I've also done a _quick_ audit of all the main commands to make sure they have the correct arguments available. --- completions/bash-nvme-completion.sh | 288 +++++++++++++++++----------- 1 file changed, 172 insertions(+), 116 deletions(-) diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh index 6770f34..da16f0e 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -2,41 +2,98 @@ # (unfortunately, bash won't let me add descriptions to cmds) # Kelly Kaoudis kelly.n.kaoudis at intel.com, Aug. 2015 -_cmds="admin-passthru attach-ns compare create-ns delete-ns detach-ns error-log flush format fw-activate fw-download fw-log get-feature get-log get-ns-id help id-ctrl id-ns io-passthru list-ctrl list-ns read resv-acquire resv-register resv-release resv-report security-recv security-send set-feature show-regs smart-log smart-log-add write" +_cmds="list id-ctrl id-ns list-ns create-ns delete-ns \ + attach-ns detach-ns list-ctrl get-ns-id get-log \ + fw-log smart-log smart-log-add error-log \ + get_feature set-feature format fw-activate \ + fw-download admin-passthru io-passthru security-send \ + security-recv resv-acquire resv-register resv-release \ + resv-report dsm flush compare read write write-zeroes \ + write-uncor reset subsystem-reset show-regs discover \ + connect-all connect disconnect version help \ + intel lnvm memblaze" + +nvme_list_opts () { + local opts="" + local compargs="" + + local nonopt_args=0 + for (( i=0; i < ${#words[@]}-1; i++ )); do + if [[ ${words[i]} != -* ]]; then + let nonopt_args+=1 + fi + done + + if [ $nonopt_args -eq 2 ]; then + opts="/dev/nvme* " + fi -_nvme_list_opts () { - local opts="/dev/nvme*" + opts+=" " case "$1" in - "io-passthru") - opts+=" --opcode= -o --flags= -f --rsvd= -R --namespace-id= -n --data-len= -l --metadata-len= -m --timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 --cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 --cdw15= -9 --input-file= -i --raw-binary= -b --show-command -s --dry-run -d --read -r --write -w" - ;; - "admin-passthru") - opts+=" --opcode= -o --flags= -f --rsvd= -R --namespace-id= -n --data-len= -l --metadata-len= -m --timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 --cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 --cdw15= -9 --input-file= -i --raw-binary= -b --show-command -s --dry-run -d --read -r --write -w" - ;; - "attach-ns") - opts+=" --namespace-id= -n --controllers= -c" + "list") + opts="" + ;; + "id-ctrl") + opts+=" --raw-binary -b --human-readable -H \ + --vendor-specific -v --output-format= -o" + ;; + "id-ns") + opts+=" --namespace-id= -n --raw-binary -b \ + --human-readable -H --vendor-specific -v \ + --force -f --output-format= -o" ;; - "compare") - opts+=" --start-block= -s --block-count= -c --metadata-size= -y --data-size= -z --data= -d --prinfo= -p --app-tag-mask= -m --app-tag= -a --limited-retry -l --force-unit-access -f" + "list-ns") + opts+=" --namespace-id= -n --al -a" ;; "create-ns") - opts+=" --nsze= -s --ncap= -c --flbas= -f --dps= -d --nmic= -n" + opts+=" --nsze= -s --ncap= -c --flbas= -f \ + --dps= -d --nmic= -n" ;; "delete-ns") opts+=" -namespace-id= -n" ;; + "attach-ns") + opts+=" --namespace-id= -n --controllers= -c" + ;; "detach-ns") opts+=" --namespace-id= -n --controllers= -c" ;; + "list-ctrl") + opts+=" --namespace-id= -n --cntid= -c" + ;; + "get-ns-id") + ;; + "get-log") + opts+=" --log-id= -i --log-len= -l --namespace-id= -n \ + --raw-binary= -b" + ;; + "fw-log") + opts+=" --raw-binary -b --output-format= -o" + ;; + "smart-log") + opts+=" --namespace-id= -n --raw-binary -b \ + --output-format= -o" + ;; + "smart-log-add") + opts+=" --namespace-id= -n --raw-binary -b" + ;; "error-log") - opts+=" --namespace-id= -n --raw-binary -b --log-entries= -e" + opts+=" --namespace-id= -n --raw-binary -b --log-entries= -e \ + --output-format= -o" ;; - "flush") - opts+=" --namespace-id= -n" + "get-feature") + opts+=" --namespace-id= -n --feature-id= -f --sel= -s \ + --data-len= -l --cdw11= --raw-binary -b \ + --human-readable -H" + ;; + "set-feature") + opts+=" --namespace-id= -n --feature-id= -f --value= -v \ + --data-len= -l -data= -d --value= --save -s" ;; "format") - opts+=" --namespace-id= -n --lbaf= -l --ses= -s --pil= -p --pi= -i --ms= -m" + opts+=" --namespace-id= -n --timeout= -t --lbaf= -l \ + --ses= -s --pil= -p -pi= -i --ms= -m --reset -r" ;; "fw-activate") opts+=" --action= -a --slot= -s" @@ -44,136 +101,135 @@ _nvme_list_opts () { "fw-download") opts+=" --fw= -f --xfer= -x --offset= -o" ;; - "fw-log") - opts+=" --raw-binary -b" + "admin-passthru") + opts+=" --opcode= -o --flags= -f --prefil= -p --rsvd= -R \ + --namespace-id= -n --data-len= -l --metadata-len= -m \ + --timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 \ + --cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 \ + --cdw15= -9 --input-file= -i --raw-binary= -b \ + --show-command -s --dry-run -d --read -r --write -w" ;; - "get-feature") - opts+=" --namespace-id= -n --feature-id= -f --sel= -s --data-len= -l --cdw11= --raw-binary -b" + "io-passthru") + opts+=" --opcode= -o --flags= -f --prefill= -p --rsvd= -R \ + --namespace-id= -n --data-len= -l --metadata-len= -m \ + --timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 \ + --cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 \ + --cdw15= -9 --input-file= -i --raw-binary= -b \ + --show-command -s --dry-run -d --read -r --write -w" ;; - "get-log") - opts+=" --log-id= -i --log-len= -l --namespace-id= -n --raw-binary= -b" + "security-send") + opts+=" --namespace-id= -n --file= -f --nssf= -N --secp= -p \ + --spsp= -s --tl= -t" ;; - "get-ns-id") + "security-recv") + opts+=" --namespace-id= -n --size= -x --secp= -p --spsp= -s \ + --al= -t --raw-binary -b" ;; - "help") - opts=$_cmds + "resv-acquire") + opts+=" --namespace-id= -n --crkey= -c --prkey= -p \ + --rtype= -t --racqa= -a --iekey= -i" ;; - "id-ctrl") - opts+=" --raw-binary -b --human-readable -H --vendor-specific -v" + "resv-register") + opts+=" --namespace-id= -n --crkey= -c --nrkey= -k \ + --rrega= -r --cptpl= -p --iekey -i" ;; - "id-ns") - opts+=" --namespace-id= -n --raw-binary -b --human-readable -H --vendor-specific -v" + "resv-release") + opts+=" --namespace-id= -n --crkey -c --rtype= -t \ + --rrela= -a --iekey -i" ;; - "list-ctrl") - opts+=" --namespace-id= -n --cntid= -c" + "resv-report") + opts+=" --namespace-id= -n --numd= -d --raw-binary= -b \ + --output-format= -o" ;; - "list-ns") + "dsm") + opts+=" --namespace-id= -n --ctx-attrs= -a --blocks= -b\ + -slbs= -s --ad -d --idw -w --idr -r --cdw11= -c" + ;; + "flush") opts+=" --namespace-id= -n" ;; + "compare") + opts+=" --start-block= -s --block-count= -c --data-size= -z \ + --metadata-size= -y --ref-tag= -r --data= -d \ + --metadata= -M --prinfo= -p --app-tag-mask= -m \ + --app-tag= -a --limited-retry -l \ + --force-unit-access -f --show-command -v \ + --dry-run -w --latency -t" + ;; "read") - opts+=" --start-block= -s --block-count= -c --data-size= -z --metadata-size= -y --ref-tag= -r --data= -d --prinfo= -p --app-tag-mask= -m --app-tag= -a --limited-retry -l --latency -t --force-unit-access -f" + opts+=" --start-block= -s --block-count= -c --data-size= -z \ + --metadata-size= -y --ref-tag= -r --data= -d \ + --metadata= -M --prinfo= -p --app-tag-mask= -m \ + --app-tag= -a --limited-retry -l \ + --force-unit-access -f --show-command -v \ + --dry-run -w --latency -t" ;; - "resv-acquire") - opts+=" --namespace-id= -n --prkey= -p --rtype= -t --racqa= -a --iekey= -i" + "write") + opts+=" --start-block= -s --block-count= -c --data-size= -z \ + --metadata-size= -y --ref-tag= -r --data= -d \ + --metadata= -M --prinfo= -p --app-tag-mask= -m \ + --app-tag= -a --limited-retry -l \ + --force-unit-access -f --show-command -v \ + --dry-run -w --latency -t" ;; - "resv-register") - opts+=" --namespace-id= -n --crkey= -c --nrkey= -k --cptpl= -p --rrega= -a --iekey -i" + "write-zeros") + opts+=" --namespace-id= -n --start-block= -s \ + --block-count= -c --limited-retry -l \ + --force-unit-access -f --prinfo= -p --ref-tag= -r \ + --app-tag-mask= -m --app-tag= -a" ;; - "resv-release") - opts+=" --namespace-id= -n --rtype= -t --rrela= -a --iekey -i" + "write-uncor") + opts+=" --namespace-id= -n --start-block= -s \ + --block-count= -c" ;; - "resv-report") - opts+=" --namespace-id= -n --numd= -d --raw-binary= -b" + "reset") + opts+="" ;; - "security-recv") - opts+=" --secp= -p --spsp= -s --size= -x --al= -a --raw-binary -b" + "subsystem-reset") + opts+="" ;; - "security-send") - opts+=" --file= -f --secp= -p --spsp= -s --tl= -t" + "show-regs") + opts+=" --human-readable -H" ;; - "set-feature") - opts+=" --namespace-id= -n --feature-id= -f --data-len= -l --data= -d --value=" + "discover") + opts+=" --transport= -t -traddr= -a -trsvcid= -s \ + --hostnqn= -q --raw= -r" ;; - "show-regs") + "connect-all") + opts+=" --transport= -t --traddr= -a --trsvcid= -s + --hostnqn= -q --raw= -r" ;; - "smart-log") - opts+=" --namespace-id= -n --raw-binary -b" + "connect") + opts+=" --transport= -t --nqn= -n --traddr= -a --trsvcid -s \ + --hostnqn= -q --nr-io-queues= -i --keep-alive-tmo -k \ + --reconnect-delay -r" ;; - "smart-log-add") - opts+=" --namespace-id= -n --raw-binary -b" + "disconnect") + opts+=" --nqn -n --device -d" ;; - "write") - opts+=" --start-block= -s --block-count= -c --data-size= -z --metadata-size= -y --ref-tag= -r --data= -d --prinfo= -p --app-tag-mask= -m --app-tag= -a --limited-retry -l --latency -t --force-unit-access -f" + "version") + opts+="" + ;; + "help") + opts=$_cmds ;; esac - COMPREPLY+=( $( compgen -W "$opts" -- $cur ) ) - return 0 -} - -## print the reduced sub-command match list in -## a sane way ## -_compile_matches () { - local matches=$1 - local tab_idx=0 - local this=${matches[$tab_idx]} - - while :; do - local key=`read -r -n 1` - case $key in - '\t') - echo -en "\033[${#this}D" - (($tab_idx++)) - this=${matches[$tab_idx]} - printf '%s' "$this" - ;; - *) - match_to_stop_on=$this - break - ;; - esac - done -} + opts+=" -h --help" -## reduce the full list of NVMe sub-commands to stuff starting with what -## already is part of the current token ## -_match_on_cur () { - local cmds - read -a cmds <<<$_cmds + COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) ) - declare -a matches - - local match_to_stop_on - - for cmd in ${cmds[@]}; do - if [[ "${cmd}" =~ ^"${cur}" ]]; then - matches+=("${cmd}") - - if [[ ${#matches} -lt 2 ]]; then - COMPREPLY=($(compgen -W "$cmd" -- $cur ) ) - fi - fi - done - - if [[ ${#matches} -ge 2 ]]; then - _compile_matches $matches - COMPREPLY=( $(compgen -W "$match_to_stop_on" -- $cur ) ) - fi + return 0 } _nvme_subcmds () { - local prev cur words - - words=$(_get_comp_words_by_ref words) - cur=$(_get_cword) - prev=$(_get_pword) + local cur prev words cword + _init_completion || return - if [[ "$_cmds" =~ "$prev" ]]; then - _nvme_list_opts $prev - elif [[ " \r\n\t\v\e" =~ "$cur" ]]; then - _match_on_cur $cur - else + if [[ ${#words[*]} -lt 3 ]]; then COMPREPLY+=( $(compgen -W "$_cmds" -- $cur ) ) + else + nvme_list_opts ${words[1]} $prev fi return 0 -- 2.49.0