]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
add bash and zsh autocompletion files and readme
authorkaoudis <kaoudis@colorado.edu>
Mon, 3 Aug 2015 19:13:17 +0000 (13:13 -0600)
committerkaoudis <kaoudis@colorado.edu>
Mon, 3 Aug 2015 20:27:32 +0000 (14:27 -0600)
completions/README [new file with mode: 0644]
completions/_nvme [new file with mode: 0644]
completions/bash-nvme-completion.sh [new file with mode: 0644]

diff --git a/completions/README b/completions/README
new file mode 100644 (file)
index 0000000..9fe51b5
--- /dev/null
@@ -0,0 +1,120 @@
+Kelly Kaoudis, kelly.n.kaoudis at intel.com, June 2015
+
+Setting Up NVMe Tab Autocompletion for bash or zsh
+==================================================
+
+If your working shell is bash...
+--------------------------------
+the following gets bash autocompletion to behave properly
+#echo "bind 'set show-all-if-ambiguous on'" >> ~/.bashrc
+#echo "bind 'set show-all-if-unmodified on'" >> ~/.bashrc
+#echo "bind 'set completion-ignore-case on'" >> ~/.bashrc
+#echo "bind 'set completion-map-case on'" >> ~/.bashrc
+
+add NVMe autocompletion script to your autocompletes directory
+#cp `pwd`/bash-nvme-completion.sh /etc/bash_completion.d/nvme
+
+make sure this bash knows where everything is
+#source /etc/bash_completion.d/nvme && source ~/.bashrc
+
+you should be able to autocomplete with the nvme utility now
+(double TABs still apply)! If autocompleting has disappeared,
+just re-source nvme and .bashrc. To see a full list of auto-completable
+NVMe commands, type "nvme help " and hit TAB.
+
+You may also need to uncomment the "enable bash completion in interactive
+shells" part of /etc/bash.bashrc, which hopefully looks somehting like:
+
+if [ -f /usr/share/bash-completion/bash_completion ]; then
+       . /usr/share/bash-completion/bash_completion
+elif [ -f /etc/bash_completion ]; then
+       . /etc/bash_completion
+fi
+
+(don't bother with the shopt part, your Bash version might not support shopt).
+
+Bash footnote: for bash vers >= 4.2, it appears to be the case that
+menu-complete **no longer works.** If the bash dev folks ever re-patch this,
+try binding TAB to menu-complete to cycle through the NVMe subcommand matches
+on whatever you typed.
+
+if your working shell is zsh...
+-------------------------------
+create the zsh completions directory if you don't have it
+#if [ ! -e "~/.zsh" ]; then
+#      mkdir ~/.zsh
+#      mkdir ~/.zsh/completion
+#fi
+
+#cp `pwd`/_nvme ~/.zsh/completion/_nvme
+
+add compinit if you don't have it in your .zshrc
+#echo "autoload -Uz compinit && compinit" >> ~/.zshrc
+
+add nvme autocompletions to your .zshrc
+#echo "# source for tab autocompletions" >> ~/.zshrc
+#echo "fpath=(~/.zsh/completion $fpath)" >> ~/.zshrc
+#echo "source ~/.zsh/completion/_nvme" >> ~/.zshrc
+
+make sure this zsh knows where everything is
+#source ~/.zsh/completion/_nvme && source ~/.zshrc
+
+You should be able to autocomplete with the nvme utility now (single TAB press
+should get you a completion with descriptions -- sadly, bash doesn't support
+descriptions within completions). If autocompletes disappear, just re-source
+_nvme and .zshrc. Also, make sure your .zshrc is ordered correctly: we want to
+source _nvme before updating our fpath. Both of these should occur before
+compinit is loaded.
+
+Updating NVMe Tab Autocompletions
+=================================
+
+zsh
+---
+
+Add your new command to the _cmds array in the following format:
+
+'command:short-form description'
+
+Add a case to the zsh case statement for autocompletion of subopts
+in the following format (as seen in _nvme):
+
+(bar)
+       local _list_of_subopts
+       _list_of_subopts=(
+       /dev/nvme':supply a device to use (required)'
+       --foo':do something cool'
+       -f':alias of --foo'
+       )
+
+       _arguments '*:: :->subcmds'
+       _describe -t commands "nvme bar options" _list_of_subopts
+       ;;
+
+All zsh autocompletion built-ins start with _, and so should anything
+internal to your autocompletes. _arguments and _describe are built-ins.
+The '*:: :->subcmds' bit describes the format in which we want our
+options to be displayed (don't change this, unless you like pain.)
+_describe -t adds our list of options to the data structure associated with
+our command `bar'.
+
+Add the name of your command to the (help) case as well.
+
+Update your ~/.zsh/completion/_nvme with your new changes and re-source as needed.
+
+bash
+----
+
+Add the name of your command to _cmds in bash_nvme_completion.sh. Add a case to
+_nvme_list_opts in the following format:
+
+"bar")
+opts+="--foo= -f --baz= -b"
+;;
+
+Update your /etc/bash_completion.d/nvme version, and re-source things as needed.
+
+TO DO
+-----
+Automatically generate man pages and autocompletions for new NVMe commands, possibly
+with kerneldoc.
diff --git a/completions/_nvme b/completions/_nvme
new file mode 100644 (file)
index 0000000..e076232
--- /dev/null
@@ -0,0 +1,659 @@
+#compdef _nvme nvme
+
+# zsh completions for the nvme command-line interface,
+# very loosely based on git and adb command completion
+# Kelly Kaoudis kelly.n.kaoudis at intel.com, June 2015
+
+_nvme () {
+       local -a _cmds
+       _cmds=(
+       'id-ctrl:display information about the controller'
+       'id-ns:display information about the namespace'
+       'list-ns:identify all namespace(s) attached'
+       'create-ns:create a new namespace before attachment'
+       'delete-ns:delete a detached namespace'
+       'attach-ns:attach namespace to controller'
+       'detach-ns:detach namespace from controller'
+       'list-ctrl:identify all controller(s) attached'
+       'get-ns-id:get namespace id of opened block device'
+       'get-log:retrieve any log in raw format'
+       'fw-log:retrieve fw log'
+       'smart-log:retrieve SMART log'
+       'smart-log-add:retrieve additional SMART log'
+       'error-log:retrieve error log'
+       'get-feature:display a controller feature'
+       'set-feature:set a controller feature and show results'
+       'format:apply new block format to namespace'
+       'fw-activate:activate a firmware on the device'
+       'fw-download:download a firmware to the device'
+       'admin-passthru:submit a passthrough IOCTL'
+       'io-passthru:submit a passthrough IOCTL'
+       'security-send:send security/secure data to controller'
+       'security-recv:ask for security/secure data from controller'
+       'resv-acquire:acquire reservation on a namespace'
+       'resv-register:register reservation on a namespace'
+       'resv-release:release reservation on a namespace'
+       'resv-report:report reservation on a namespace'
+       'flush:submit a flush'
+       'compare:compare data on device to data elsewhere'
+       'read:submit a read command'
+       'write:submit a write command'
+       'show-regs:shows the controller registers; requires admin character device'
+       'help:print brief descriptions of all nvme commands'
+       )
+
+       local expl
+
+       _arguments '*:: :->subcmds' && return 0
+
+       if (( CURRENT == 1 )); then
+               _describe -t commands "nvme subcommands" _cmds
+               return
+       else
+               case ${words[CURRENT-1]} in
+               (id-ctrl)
+                       local _idctrl
+                       _idctrl=(
+                       /dev/nvme':supply a device to use (required)'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias of --raw-binary'
+                       --human-readable':show infos in readable format'
+                       -H':alias of --human-readable'
+                       --vendor-specific':also dump binary vendor infos'
+                       -v':alias of --vendor-specific'
+                       )
+
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme id-ctrl options" _idctrl
+                       ;;
+               (id-ns)
+                       local _idns
+                       _idns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':show infos for namespace <nsid>'
+                       -n':alias of --namespace-id'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias of --raw-binary'
+                       --human-readable':show infos in readable format'
+                       -H':alias of --human-readable'
+                       --vendor-specific':also dump binary vendor infos'
+                       -v':alias of --vendor-specific'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme id-ns options" _idns
+                       ;;
+               (list-ns)
+                       local _listns
+                       _listns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':start namespace infos listing with this nsid'
+                       -n':alias of --namespace-id'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme list-ns options" _listns
+                       ;;
+               (create-ns)
+                       local _createns
+                       _createns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --nsze=':namespace size to create'
+                       -s':alias of --nsze'
+                       --ncap=':namespace capacity'
+                       -c':alias of --ncap'
+                       --flbas=':FLBA size'
+                       -f':alias of --flbas'
+                       --dps=':data protection?'
+                       -d':alias of --dps'
+                       --nmic=':multipath and sharing'
+                       -n':alias of --nmic'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme create-ns options" _createns
+                       ;;
+               (delete-ns)
+                       local _deletens
+                       _deletens=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':namespace to delete'
+                       -n':alias of --namespace-id'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme delete-ns options" _deletens
+                       ;;
+               (attach-ns)
+                       local _attachns
+                       _attachns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':namespace to attach to the controller'
+                       -n':alias of --namespace-id'
+                       --controllers=':if a device is not provided, supply a comma-sep list of controllers'
+                       -c':alias of --controllers'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme attach-ns options" _attachns
+                       ;;
+               (detach-ns)
+                       local _detachns
+                       _detachns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':namespace to detach from controller'
+                       -n':alias of --namespace-id'
+                       --controllers=':if a device is not provided, supply a comma-sep list of controllers'
+                       -c':alias of --controllers'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme detach-ns options" _detachns
+                       ;;
+               (list-ctrl)
+                       local _listctrl
+                       _listctrl=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':show controllers attached to this namespace'
+                       -n':alias of --namespace-id'
+                       --cntid=':start the list with this controller'
+                       -c':alias of --cntid'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme list-ctrl options" _listctrl
+                       ;;
+               (get-ns-id)
+                       local _getnsid
+                       _getnsid=(
+                       /dev/nvme':supply a device to use (required)'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme get-ns-id options" _getnsid
+                       ;;
+               (get-log)
+                       local _getlog
+                       _getlog=(
+                       /dev/nvme':supply a device to use (required)'
+                       --log-id=':requested log number'
+                       -i':alias of --log-id'
+                       --log-len=':number of bytes to show for requested log'
+                       -l':alias of --log-len'
+                       --namespace-id=':get log specific to <nsid> if namespace logs are supported'
+                       -n':alias of --namespace-id'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias of --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme get-log options" _getlog
+                       ;;
+               (fw-log)
+                       local _fwlog
+                       _fwlog=(
+                       /dev/nvme':supply a device to use (required)'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias of --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme fw-log options" _fwlog
+                       ;;
+               (smart-log)
+                       local _smartlog
+                       _smartlog=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':get SMART log specific to <nsid> if namespace logs are supported'
+                       -n':alias to --namespace-id'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias to --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme smart-log options" _smartlog
+                       ;;
+               (smart-log-add)
+                       local _add
+                       _add=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':get additional SMART log specific to <nsid> if namespace logs supported'
+                       -n':alias to --namespace-id'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias to --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme smart-log-add options" _add
+                       ;;
+               (error-log)
+                       local _errlog
+                       _errlog=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':get log specific to <nsid> if namespace logs are supported'
+                       -n':alias to --namespace-id'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias to --raw-binary'
+                       --log-entries=':request n >= 1 log entries'
+                       -e':alias to --log-entries'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme error-log options" _errlog
+                       ;;
+               (get-feature)
+                       local _getf
+                       _getf=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':get feature specific to <nsid>'
+                       -n':alias to --namespace-id'
+                       --feature-id=':hexadecimal name of feature to examine (required)'
+                       -f':alias to --feature-id'
+                       --sel=':select from 0 - current, 1 - default, 2 - saved, 3 - supported'
+                       -s':alias to --sel'
+                       --data-len=':buffer len for returned LBA Type Range or host identifier data'
+                       -l':alias for --data-len'
+                       --cdw11=':dword 11 value, used for interrupt vector configuration only'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias to --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme get-feature options" _getf
+                       ;;
+               (set-feature)
+                       local _setf
+                       _setf=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':feature is specific to <nsid>'
+                       -n':alias to --namespace-id'
+                       --feature-id=':hexadecimal name of feature to set (required)'
+                       -f':alias to --feature-id'
+                       --data-len=':buffer length, only used for LBA Type Range or host identifier data'
+                       -l':alias for --data-len'
+                       --data=':data file for LBA Type Range or host identifier buffer (defaults to stdin)'
+                       -d':alias to --data'
+                       --value=':new value of feature (required)'
+                       -v'alias to --value'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme set-feature options" _setf
+                       ;;
+               (format)
+                       local _format
+                       _format=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':<nsid> of namespace to format (required)'
+                       -n':alias of --namespace-id'
+                       --lbaf=':LBA format to apply to namespace (required)'
+                       -l':alias of --lbaf'
+                       --ses=':secure erase? 0 - no-op (default), 1 - user-data erase, 2 - cryptographic erase'
+                       -s':alias of --ses'
+                       --pil=':location of protection information? 0 - end, 1 - start'
+                       -p':alias of --pil'
+                       --pi=':protection information? 0 - off, 1 - Type 1 on, 2 - Type 2 on, 3 - Type 3 on'
+                       -i':alias of --pi'
+                       --ms=':extended format? 0 - off (metadata in separate buffer), 1 - on (extended LBA used)'
+                       -m':alias of --ms'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme format options" _format
+                       ;;
+               (fw-activate)
+                       local _fwact
+                       _fwact=(
+                       /dev/nvme':supply a device to use (required)'
+                       --action=':activation action (required)? 0 - replace fw without activating, 1 - replace with activation, 2 - replace with activation at next reset'
+                       -a':alias of --action'
+                       --slot=':firmware slot to activate'
+                       -s':alias of --slot'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme fw-activate options" _fwact
+                       ;;
+               (fw-download)
+                       local _fwd
+                       _fwd=(
+                       /dev/nvme':supply a device to use (required)'
+                       --fw=':firmware file to download (required)'
+                       -f':alias of --fw'
+                       --xfer=':limit on chunk-size of transfer (if device has download size limit)'
+                       -x':alias of --xfer'
+                       --offset=':starting offset, in dwords (defaults to 0, only useful if download is split across multiple files)'
+                       -o':alias of --offset'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme fw-download options" _fwd
+                       ;;
+               (admin-passthru)
+                       local _admin
+                       _admin=(
+                       /dev/nvme':supply a device to use (required)'
+                       --opcode=':hexadecimal opcode to send (required)'
+                       -o':alias of --opcode'
+                       --flags=':command flags'
+                       -f':alias of --flags'
+                       --rsvd=':value for reserved field'
+                       -R':alias of --rsvd'
+                       --namespace-id=':value for nsid'
+                       -n':alias of --namespace-id'
+                       --data-len=':length for data buffer'
+                       -l':alias of --data-len'
+                       --metadata-len=':length for metadata buffer'
+                       -m':alias of --metadata-len'
+                       --timeout=':value for timeout'
+                       -t':alias of --timeout'
+                       --cdw2=':value for command dword 2'
+                       -2':alias for --cdw2'
+                       --cdw3=':value for command dword 3'
+                       -3':alias for --cdw3'
+                       --cdw10=':value for command dword 10'
+                       -4':alias for --cdw10'
+                       --cdw11=':value for command dword 11'
+                       -5':alias for --cdw11'
+                       --cdw12=':value for command dword 12'
+                       -6':alias for --cdw12'
+                       --cdw13=':value for command dword 13'
+                       -7':alias for --cdw13'
+                       --cdw14=':value for command dword 14'
+                       -8':alias for command dword 14'
+                       --cdw15=':value for command dword 15'
+                       -9':alias for command dword 15'
+                       --input-file=':defaults to stdin; input for write (send direction)'
+                       -i':alias for --input-file'
+                       --raw-binary':dump output in binary format'
+                       -b':alias for --raw-binary'
+                       --show-command':simply print command instead of sending it to <device>'
+                       -s':alias for --show-command'
+                       --dry-run':alias for --show-command'
+                       -d':alias for --show-command'
+                       --read':set dataflow direction to receive'
+                       -r':alias for --read'
+                       --write':set dataflow direction to send'
+                       -w':alias for --write'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme admin-passthru options" _admin
+                       ;;
+               (io-passthru)
+                       local _io
+                       _io=(
+                       /dev/nvme':supply a device to use (required)'
+                       --opcode=':hexadecimal opcode to send (required)'
+                       -o':alias of --opcode'
+                       --flags=':command flags'
+                       -f':alias of --flags'
+                       --rsvd=':value for reserved field'
+                       -R':alias of --rsvd'
+                       --namespace-id=':value for nsid'
+                       -n':alias of --namespace-id'
+                       --data-len=':length for data buffer'
+                       -l':alias of --data-len'
+                       --metadata-len=':length for metadata buffer'
+                       -m':alias of --metadata-len'
+                       --timeout=':value for timeout'
+                       -t':alias of --timeout'
+                       --cdw2=':value for command dword 2'
+                       -2':alias for --cdw2'
+                       --cdw3=':value for command dword 3'
+                       -3':alias for --cdw3'
+                       --cdw10=':value for command dword 10'
+                       -4':alias for --cdw10'
+                       --cdw11=':value for command dword 11'
+                       -5':alias for --cdw11'
+                       --cdw12=':value for command dword 12'
+                       -6':alias for --cdw12'
+                       --cdw13=':value for command dword 13'
+                       -7':alias for --cdw13'
+                       --cdw14=':value for command dword 14'
+                       -8':alias for command dword 14'
+                       --cdw15=':value for command dword 15'
+                       -9':alias for command dword 15'
+                       --input-file=':defaults to stdin; input for write (send direction)'
+                       -i':alias for --input-file'
+                       --raw-binary':dump output in binary format'
+                       -b':alias for --raw-binary'
+                       --show-command':simply print command instead of sending it to <device>'
+                       -s':alias for --show-command'
+                       --dry-run':alias for --show-command'
+                       -d':alias for --show-command'
+                       --read':set dataflow direction to receive'
+                       -r':alias for --read'
+                       --write':set dataflow direction to send'
+                       -w':alias for --write'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme io-passthru options" _io
+                       ;;
+               (security-send)
+                       local _ssend
+                       _ssend=(
+                       /dev/nvme':supply a device to use (required)'
+                       --file=':payload'
+                       -f':alias for --file'
+                       --secp=':security protocol as defined in SPC-4'
+                       -p':alias for --secp'
+                       --spsp=':send security-protocol-specific data as defined in SPC-4'
+                       -s':alias for --spsp'
+                       --tl=':transfer length as defined in SPC-4'
+                       -t':alias for --tl'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme security-send options" _ssend
+                       ;;
+               (security-recv)
+                       local _srecv
+                       _srecv=(
+                       /dev/nvme':supply a device to use (required)'
+                       --secp=':security protocol as defined in SPC-4'
+                       -p':alias for --secp'
+                       --spsp=':send security-protocol-specific data as defined in SPC-4'
+                       -s':alias for --spsp'
+                       --size=':size of buffer (prints to stdout on successful recv)'
+                       -x':alias for --size'
+                       --al=':allocation length as defined in SPC-4'
+                       -a':alias for --al'
+                       --raw-binary':dump output in binary format'
+                       -b':alias for --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme security-recv options" _srecv
+                       ;;
+               (resv-acquire)
+                       local _acq
+                       _acq=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':<nsid> of namespace to try to reserve (required)'
+                       -n':alias for --namespace-id'
+                       --prkey=':pre-empt reservation key'
+                       -p':alias for --prkey'
+                       --rtype=':hexadecimal reservation type'
+                       -t':alias for --rtype'
+                       --racqa=':reservation acquiry action'
+                       -a':alias for --racqa'
+                       --iekey=':ignore existing reservation key'
+                       -i':alias for --iekey'
+                       --crkey':current reservation key'
+                       -c':alias for --crkey'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme resv-acquire options" _acq
+                       ;;
+               (resv-release)
+                       local _rel
+                       _rel=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':nsid'
+                       -n':alias of --namespace-id'
+                       --rtype=':hexadecimal reservation type'
+                       -t':alias of --rtype'
+                       --rrela=':reservation release action'
+                       -a':alias of --rrela'
+                       --iekey':ignore existing reservation key'
+                       -i':alias of --iekey'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme resv-release options" _rel
+                       ;;
+               (resv-report)
+                       local _rep
+                       _rep=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':nsid'
+                       -n':alias of --namespace-id'
+                       --numd=':number of dwords of reservation status to xfer'
+                       -d':alias of --numd'
+                       --raw-binary':dump output in binary format'
+                       -b':alias of --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme resv-report options" _rep
+                       ;;
+               (resv-register)
+                       local _reg
+                       _reg=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':nsid'
+                       -n':alias of --namespace-id'
+                       --crkey=':current reservation key'
+                       -c'alias of --crkey'
+                       --nrkey=':new reservation key'
+                       -k':alias of --nrkey'
+                       --cptpl=':change persistence through power loss setting'
+                       -p':alias for --cptpl'
+                       --rrega=':reservation registration action to perform'
+                       -a':alias for --rrega'
+                       --iekey':ignore existing reservation key'
+                       -i':alias for --iekey'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme resv-register options" _reg
+                       ;;
+               (flush)
+                       local _flush
+                       _flush=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':nsid'
+                       -n':alias of --namespace-id'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme flush options" _flush
+                       ;;
+               (compare)
+                       local _comp
+                       _comp=(
+                       /dev/nvme':supply a device to use (required)'
+                       --start-block=':begin compare at this 64-bit LBA on device'
+                       -s':alias of --start-block'
+                       --block-count=':number of logical blocks on device to compare to local data'
+                       -c':alias of --block-count'
+                       --metadata-size=':number of bytes of metadata to compare'
+                       -y':alias of --metadata-size'
+                       --data-size=':size of local data buffer in bytes'
+                       -z':alias of --data-size'
+                       --data=':local data file to compare to blocks on device'
+                       -d':alias of --data'
+                       --prinfo=':protection information action and check field'
+                       -p':alias of --prinfo'
+                       --app-tag-mask=':application tag mask (for end to end PI)'
+                       -m':alias of --app-tag-mask'
+                       --app-tag=':application tag (for end to end PI)'
+                       -a':alias of --app-tag'
+                       --limited-retry':if included, controller should try less hard to retrieve data from media (if not included, all available data recovery means used)'
+                       -l':alias of --limited-retry'
+                       --force-unit-access':if included, the data shall be read from non-volatile media'
+                       -f':alias of --force-unit access'
+                       --show-command':show command instead of sending to device'
+                       -v':alias of --show-command'
+                       --dry-run':show command instead of sending to device'
+                       -w':alias of --show-command'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme compare options" _comp
+                       ;;
+               (read)
+                       local _read
+                       _read=(
+                       /dev/nvme':supply a device to use (required)'
+                       --start-block=':64-bit address of the first logical block to be read'
+                       -s':alias of --start-block'
+                       --block-count=':number of logical blocks on device to read'
+                       -c':alias of --block-count'
+                       --data-size=':size of data to be read'
+                       -z':alias of --data-size'
+                       --metadata-size=':size of metadata to be read'
+                       -y':alias of --metadata-size'
+                       --ref-tag=':reference tag (for end to end PI)'
+                       -r':alias of --ref-tag'
+                       --data=':file into which data should be read (defaults to stdout)'
+                       -d':alias of --data'
+                       --prinfo=':protection information and check field'
+                       -p':alias of --prinfo'
+                       --app-tag-mask=':application tag mask (for end to end PI)'
+                       -m':alias of --app-tag-mask'
+                       --app-tag=':application tag (for end to end PI)'
+                       -a':alias of --app-tag'
+                       --limited-retry=':if included, controller should try less hard to retrieve data from media (if not included, all available data-recovery means used)'
+                       -l':alias of --limited-retry'
+                       --latency':latency statistics will be output following read'
+                       -t':alias of --latency'
+                       --force-unit-access':data read shall be returned from nonvolatile media before command completion is indicated'
+                       -f':alias of --force-unit-access'
+                       --show-command':show command instead of sending to device'
+                       -v':alias of --show-command'
+                       --dry-run':show command instead of sending to device'
+                       -w':alias of --show-command'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme read options" _read
+                       ;;
+               (write)
+                       local _wr
+                       _wr=(
+                       /dev/nvme':supply a device to use (required)'
+                       --start-block=':64-bit address of the first logical block to be written'
+                       -s':alias of --start-block'
+                       --block-count=':number of logical blocks on device to write'
+                       -c':alias of --block-count'
+                       --data-size=':size of data to be written'
+                       -z':alias of --data-size'
+                       --metadata-size=':size of metadata to be written'
+                       -y':alias of --metadata-size'
+                       --ref-tag=':reference tag (for end to end PI)'
+                       -r':alias of --ref-tag'
+                       --data=':file from which data should be written to device (defaults to stdin)'
+                       -d':alias of --data'
+                       --prinfo=':protection information and check field'
+                       -p':alias of --prinfo'
+                       --app-tag-mask=':application tag mask (for end to end PI)'
+                       -m':alias of --app-tag-mask'
+                       --app-tag=':application tag (for end to end PI)'
+                       -a':alias of --app-tag'
+                       --limited-retry=':if included, controller should try less hard to send data to media (if not included, all available data-recovery means used)'
+                       -l':alias of --limited-retry'
+                       --latency':latency statistics will be output following write'
+                       -t':alias of --latency'
+                       --force-unit-access':data shall be written to nonvolatile media before command completion is indicated'
+                       -f':alias of --force-unit-access'
+                       --show-command':show command instead of sending to device'
+                       -v':alias of --show-command'
+                       --dry-run':show command instead of sending to device'
+                       -w':alias of --show-command'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme write options" _wr
+                       ;;
+               (show-regs)
+                       local _shor
+                       _shor=(
+                       /dev/nvme':supply a device to use (required)'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme show-regs options" _shor
+                       ;;
+               (help)
+                       local _h
+                       _h=( 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 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 flush compare read write show-regs
+                          )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h
+                       ;;
+               (*)
+                       _files
+                       ;;
+               esac
+               return
+       fi
+
+       _files
+}
diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh
new file mode 100644 (file)
index 0000000..1a8613e
--- /dev/null
@@ -0,0 +1,184 @@
+#!/usr/bin/env bash
+
+# bash tab completion for the nvme command line utility
+# (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"
+
+_nvme_list_opts () {
+       local opts="/dev/nvme*"
+
+       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"
+                       ;;
+               "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"
+                       ;;
+               "create-ns")
+               opts+=" --nsze= -s --ncap= -c --flbas= -f --dps= -d --nmic= -n"
+                       ;;
+               "delete-ns")
+               opts+=" -namespace-id= -n"
+                       ;;
+               "detach-ns")
+               opts+=" --namespace-id= -n --controllers= -c"
+                       ;;
+               "error-log")
+               opts+=" --namespace-id= -n --raw-binary -b --log-entries= -e"
+                       ;;
+               "flush")
+               opts+=" --namespace-id= -n"
+                       ;;
+               "format")
+               opts+=" --namespace-id= -n --lbaf= -l --ses= -s --pil= -p --pi= -i --ms= -m"
+                       ;;
+               "fw-activate")
+               opts+=" --action= -a --slot= -s"
+                       ;;
+               "fw-download")
+               opts+=" --fw= -f --xfer= -x --offset= -o"
+                       ;;
+               "fw-log")
+               opts+=" --raw-binary -b"
+                       ;;
+               "get-feature")
+               opts+=" --namespace-id= -n --feature-id= -f --sel= -s --data-len= -l --cdw11= --raw-binary -b"
+                       ;;
+               "get-log")
+               opts+=" --log-id= -i --log-len= -l --namespace-id= -n --raw-binary= -b"
+                       ;;
+               "get-ns-id")
+                       ;;
+               "help")
+               opts=$_cmds
+                       ;;
+               "id-ctrl")
+               opts+=" --raw-binary -b --human-readable -H --vendor-specific -v"
+                       ;;
+               "id-ns")
+               opts+=" --namespace-id= -n --raw-binary -b --human-readable -H --vendor-specific -v"
+                       ;;
+               "list-ctrl")
+               opts+=" --namespace-id= -n --cntid= -c"
+                       ;;
+               "list-ns")
+               opts+=" --namespace-id= -n"
+                       ;;
+               "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"
+                       ;;
+               "resv-acquire")
+               opts+=" --namespace-id= -n --prkey= -p --rtype= -t --racqa= -a --iekey= -i"
+                       ;;
+               "resv-register")
+               opts+=" --namespace-id= -n --crkey= -c --nrkey= -k --cptpl= -p --rrega= -a --iekey -i"
+                       ;;
+               "resv-release")
+               opts+=" --namespace-id= -n --rtype= -t --rrela= -a --iekey -i"
+                       ;;
+               "resv-report")
+               opts+=" --namespace-id= -n --numd= -d --raw-binary= -b"
+                       ;;
+               "security-recv")
+               opts+=" --secp= -p --spsp= -s --size= -x --al= -a --raw-binary -b"
+                       ;;
+               "security-send")
+               opts+=" --file= -f --secp= -p --spsp= -s --tl= -t"
+                       ;;
+               "set-feature")
+               opts+=" --namespace-id= -n --feature-id= -f --data-len= -l --data= -d --value="
+                       ;;
+               "show-regs")
+                       ;;
+               "smart-log")
+               opts+=" --namespace-id= -n --raw-binary -b"
+                       ;;
+               "smart-log-add")
+               opts+=" --namespace-id= -n --raw-binary -b"
+                       ;;
+               "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"
+                       ;;
+       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
+}
+
+## 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
+
+       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
+}
+
+_nvme_subcmds () {
+       local prev cur words
+
+       words=$(_get_comp_words_by_ref words)
+       cur=$(_get_cword)
+       prev=$(_get_pword)
+
+       if [[ "$_cmds" =~ "$prev" ]]; then
+               _nvme_list_opts $prev
+       elif [[ " \r\n\t\v\e" =~ "$cur" ]]; then
+               _match_on_cur $cur
+       else
+               COMPREPLY+=( $(compgen -W "$_cmds" -- $cur ) )
+       fi
+
+       return 0
+}
+
+complete -o default -F _nvme_subcmds nvme