Backends#
xNVMe
hides the implementation of operating system interaction from the
user. That is, the implementation of the xnvme_*
C API, is delegated at
runtime to a backend implementation.
Devices are associated with a backend when they are “opened” via a device identifier on the such as:
/dev/nvme0n1
/dev/nvme0ns1
0000:01:00.0
\\.\PhysicalDrive1
The library can inform you which backend is in affect, e.g.:
xnvme info /dev/nvme0n1
xnvme_dev:
xnvme_ident:
trgt: '/dev/nvme0n1'
schm: 'file'
opts: ''
uri: 'file:/dev/nvme0n1'
xnvme_be:
async: {id: 'thr', enabled: 1}
sync: {id: 'nvme_ioctl', enabled: 1}
attr: {name: 'linux', enabled: 1}
xnvme_cmd_opts:
mask: '00000000000000000000000000000001'
iomd: 'SYNC'
payload_data: 'DRV'
payload_meta: 'DRV'
csi: 0x0
nsid: 0x1
ssw: 9
xnvme_geo:
type: XNVME_GEO_CONVENTIONAL
npugrp: 1
npunit: 1
nzone: 1
nsect: 16777216
nbytes: 512
nbytes_oob: 0
tbytes: 8589934592
mdts_nbytes: 65024
lba_nbytes: 512
lba_extended: 0
The valid combinations of interfaces and backends are listed below:
Backends |
||||||
---|---|---|---|---|---|---|
Async interfaces |
|
|
libvfn |
|
|
|
io_uring |
no |
yes |
no |
no |
no |
no |
io_uring_cmd |
no |
yes |
no |
no |
no |
no |
libaio |
no |
yes |
no |
no |
no |
no |
kqueue |
yes |
no |
no |
no |
no |
no |
POSIX aio |
yes |
yes |
no |
no |
no |
yes |
NVMe Driver (vfio-pci) |
no |
no |
yes |
yes |
no |
no |
NVMe Driver (uio-generic) |
no |
no |
no |
yes |
no |
no |
emu |
yes |
yes |
yes |
yes |
yes |
yes |
thrpool |
yes |
yes |
yes |
yes |
yes |
yes |
nil |
yes |
yes |
yes |
yes |
yes |
yes |
xNVMe compatibility#
Command |
Ramdisk |
---|---|
Compare |
✓ |
Copy |
✓ |
Dataset Management |
✗ |
Flush |
✗ |
Read |
✓ |
Verify |
✗ |
Write |
✓ |
Write Uncorrectable |
✗ |
Write Zeroes |
✓ |
Appendix#
[1] http://www.cs.cmu.edu/~riedel/ftp/SIO/API/cmu-cs-96-193.pdf [2] https://www.nextplatform.com/2017/09/11/whats-bad-posix-io/ [3] https://blog.linuxplumbersconf.org/2009/slides/Anthony-Liguori-qemu-block.pdf