nvm_cmd¶
NVM command (nvm_cmd_*) -- Ver { major(0), minor(1), patch(5) }
Construct and execute NVM commands
Usage:
nvm_cmd idfy dev_path [-h] [-v]
nvm_cmd rprt_all dev_path [-h] [-v]
nvm_cmd rprt_lun dev_path ch lun [-h] [-v]
nvm_cmd gbbt dev_path ch lun [-h] [-v]
nvm_cmd sbbt dev_path ch lun blk 0xVAL [-h] [-v]
nvm_cmd erase dev_path 0xADDR [0xADDR...] [-h] [-v]
nvm_cmd write dev_path 0xADDR [0xADDR...] [-h] [-v] [-i FILE]
nvm_cmd read dev_path 0xADDR [0xADDR...] [-h] [-v] [-o FILE]
nvm_cmd copy dev_path pugrp punit chunk pugrp punit chunk [-h] [-v]
Options:
-h Print usage
-v Dump CLI state to stdout
-i FILE Path to input file
-o FILE Path to output file
See: http://lightnvm.io/liblightnvm/cli/ for usage examples
Tip
See section Environment Variables for a full list of environment variables modifying command behavior
Device Identification / Geometry¶
For Open-Channel drives, both 1.2 and 2.0, then device identification and geometry information can be quiried like so:
nvm_cmd idfy /dev/nvme0n1
# nvm_cmd_idfy
idfy:
verid: 00000010
verid_minor: 00000000
mccap: 00000000000000000000000000000001
lbaf:
pugrp: 3
punit: 2
chunk: 11
sectr: 13
lgeo:
npugrp: 8
npunit: 4
nchunk: 1474
nsectr: 6144
wrt:
ws_min: 24
ws_opt: 24
mw_cunits: 192
perf:
trdt: 40000
trdm: 80000
twrt: 1900000
twrm: 3700000
tcet: 7000000
tcem: 20000000
Tip
See section nvm_dev for additional device information.
Media State¶
For Open-Channel 1.2 drives then media state can be read and written via the bad-block-table interface. See section nvm_bbt for an elaborate description.
For Open-Channel 2.0 drives, the media state can only read, not written. This is facilitated by the NVMe get-log-page, and in liblightnvm provided via the following nvm_cmd_rprt.
To retrieve the entire state:
nvm_cmd rprt_all /dev/nvme0n1 | head -n 20
# nvm_cmd_rprt: (nil)
rprt:
ndescr: 47168
rprt_descr:
- { slba: 0x0000000000000000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000002000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000004000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000006000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000008000, cnlb: 0x1800, wp: 0x0000000000001800, cs: 0x02, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000000A000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000000C000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000000E000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000010000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000012000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000014000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000016000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000000018000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000001A000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000001C000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000000001E000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
To retrieve the state for a single LUN / parallel unit:
nvm_cmd rprt_lun /dev/nvme0n1 4 2 | head -n 20
# nvm_cmd_rprt: 0x55a52c7c64d0
naddrs: 1
addrs:
- {val: 0x0402000000000000, pugrp: 04, punit: 02, chunk: 0000, sectr: 0000}
rprt:
ndescr: 1474
rprt_descr:
- { slba: 0x0000000012000000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012002000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012004000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012006000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012008000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000001200A000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000001200C000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x000000001200E000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012010000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012012000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012014000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012016000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
- { slba: 0x0000000012018000, cnlb: 0x1800, wp: 0x0000000000000000, cs: 0x01, ct: 0x01, wli: 0x00 }
Submitting IO¶
The nvm_cmd
provides three IO sub-commands which constructs, submits and
waits for completion of a single NVMe command using the OCSSD erase(reset),
write(vector-write), and read(vector-read) command opcodes.
Perform a read command:
nvm_cmd read /dev/nvme0n1 \
0x0402008e00000000 0x0402008e00000001 0x0402008e00000002 0x0402008e00000003
# nvm_cmd_read: {pmode: SNGL}
naddrs: 4
addrs:
- {val: 0x0402008e00000000, pugrp: 04, punit: 02, chunk: 0142, sectr: 0000}
- {val: 0x0402008e00000001, pugrp: 04, punit: 02, chunk: 0142, sectr: 0001}
- {val: 0x0402008e00000002, pugrp: 04, punit: 02, chunk: 0142, sectr: 0002}
- {val: 0x0402008e00000003, pugrp: 04, punit: 02, chunk: 0142, sectr: 0003}
Use the -o FILE
option, to dump the data read from device to file:
nvm_cmd read /dev/nvme0n1 \
0x0402008e00000000 0x0402008e00000001 0x0402008e00000002 0x0402008e00000003 \
0x0402008e00000004 0x0402008e00000005 0x0402008e00000006 0x0402008e00000007 \
-o /tmp/nvm_dump.bin
# nvm_cmd_read: {pmode: SNGL}
naddrs: 8
addrs:
- {val: 0x0402008e00000000, pugrp: 04, punit: 02, chunk: 0142, sectr: 0000}
- {val: 0x0402008e00000001, pugrp: 04, punit: 02, chunk: 0142, sectr: 0001}
- {val: 0x0402008e00000002, pugrp: 04, punit: 02, chunk: 0142, sectr: 0002}
- {val: 0x0402008e00000003, pugrp: 04, punit: 02, chunk: 0142, sectr: 0003}
- {val: 0x0402008e00000004, pugrp: 04, punit: 02, chunk: 0142, sectr: 0004}
- {val: 0x0402008e00000005, pugrp: 04, punit: 02, chunk: 0142, sectr: 0005}
- {val: 0x0402008e00000006, pugrp: 04, punit: 02, chunk: 0142, sectr: 0006}
- {val: 0x0402008e00000007, pugrp: 04, punit: 02, chunk: 0142, sectr: 0007}
Which can then be inspected with for example hexdump
:
hexdump /tmp/nvm_dump.bin -C -n 128
00000000 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 41 42 |MNOPQRSTUVWXYZAB|
00000010 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 |CDEFGHIJKLMNOPQR|
00000020 53 54 55 56 57 58 59 5a 41 42 43 44 45 46 47 48 |STUVWXYZABCDEFGH|
00000030 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 |IJKLMNOPQRSTUVWX|
00000040 59 5a 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e |YZABCDEFGHIJKLMN|
00000050 4f 50 51 52 53 54 55 56 57 58 59 5a 41 42 43 44 |OPQRSTUVWXYZABCD|
00000060 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 |EFGHIJKLMNOPQRST|
00000070 55 56 57 58 59 5a 41 42 43 44 45 46 47 48 49 4a |UVWXYZABCDEFGHIJ|
00000080