1# Block Device User Guide {#bdev} 2 3# Introduction {#bdev_ug_introduction} 4 5The SPDK block device layer, often simply called *bdev*, is a C library 6intended to be equivalent to the operating system block storage layer that 7often sits immediately above the device drivers in a traditional kernel 8storage stack. Specifically, this library provides the following 9functionality: 10 11* A pluggable module API for implementing block devices that interface with different types of block storage devices. 12* Driver modules for NVMe, malloc (ramdisk), Linux AIO, virtio-scsi, Ceph RBD, Pmem and Vhost-SCSI Initiator and more. 13* An application API for enumerating and claiming SPDK block devices and then performing operations (read, write, unmap, etc.) on those devices. 14* Facilities to stack block devices to create complex I/O pipelines, including logical volume management (lvol) and partition support (GPT). 15* Configuration of block devices via JSON-RPC. 16* Request queueing, timeout, and reset handling. 17* Multiple, lockless queues for sending I/O to block devices. 18 19Bdev module creates abstraction layer that provides common API for all devices. 20User can use available bdev modules or create own module with any type of 21device underneath (please refer to @ref bdev_module for details). SPDK 22provides also vbdev modules which creates block devices on existing bdev. For 23example @ref bdev_ug_logical_volumes or @ref bdev_ug_gpt 24 25# Prerequisites {#bdev_ug_prerequisites} 26 27This guide assumes that you can already build the standard SPDK distribution 28on your platform. The block device layer is a C library with a single public 29header file named bdev.h. All SPDK configuration described in following 30chapters is done by using JSON-RPC commands. SPDK provides a python-based 31command line tool for sending RPC commands located at `scripts/rpc.py`. User 32can list available commands by running this script with `-h` or `--help` flag. 33Additionally user can retrieve currently supported set of RPC commands 34directly from SPDK application by running `scripts/rpc.py get_rpc_methods`. 35Detailed help for each command can be displayed by adding `-h` flag as a 36command parameter. 37 38# General Purpose RPCs {#bdev_ug_general_rpcs} 39 40## get_bdevs {#bdev_ug_get_bdevs} 41 42List of currently available block devices including detailed information about 43them can be get by using `get_bdevs` RPC command. User can add optional 44parameter `name` to get details about specified by that name bdev. 45 46Example response 47 48~~~ 49{ 50 "num_blocks": 32768, 51 "supported_io_types": { 52 "reset": true, 53 "nvme_admin": false, 54 "unmap": true, 55 "read": true, 56 "write_zeroes": true, 57 "write": true, 58 "flush": true, 59 "nvme_io": false 60 }, 61 "driver_specific": {}, 62 "claimed": false, 63 "block_size": 4096, 64 "product_name": "Malloc disk", 65 "name": "Malloc0" 66} 67~~~ 68 69## delete_bdev {#bdev_ug_delete_bdev} 70 71To remove previously created bdev user can use `delete_bdev` RPC command. 72Bdev can be deleted at any time and this will be fully handled by any upper 73layers. As an argument user should provide bdev name. 74 75# NVMe bdev {#bdev_config_nvme} 76 77There are two ways to create block device based on NVMe device in SPDK. First 78way is to connect local PCIe drive and second one is to connect NVMe-oF device. 79In both cases user should use `construct_nvme_bdev` RPC command to achieve that. 80 81Example commands 82 83`rpc.py construct_nvme_bdev -b NVMe1 -t PCIe -a 0000:01:00.0` 84 85This command will create NVMe bdev of physical device in the system. 86 87`rpc.py construct_nvme_bdev -b Nvme0 -t RDMA -a 192.168.100.1 -f IPv4 -s 4420 -n nqn.2016-06.io.spdk:cnode1` 88 89This command will create NVMe bdev of NVMe-oF resource. 90 91# Null {#bdev_config_null} 92 93The SPDK null bdev driver is a dummy block I/O target that discards all writes and returns undefined 94data for reads. It is useful for benchmarking the rest of the bdev I/O stack with minimal block 95device overhead and for testing configurations that can't easily be created with the Malloc bdev. 96To create Null bdev RPC command `construct_null_bdev` should be used. 97 98Example command 99 100`rpc.py construct_null_bdev Null0 8589934592 4096` 101 102This command will create an 8 petabyte `Null0` device with block size 4096. 103 104# Linux AIO bdev {#bdev_config_aio} 105 106The SPDK AIO bdev driver provides SPDK block layer access to Linux kernel block 107devices or a file on a Linux filesystem via Linux AIO. Note that O_DIRECT is 108used and thus bypasses the Linux page cache. This mode is probably as close to 109a typical kernel based target as a user space target can get without using a 110user-space driver. To create AIO bdev RPC command `construct_aio_bdev` should be 111used. 112 113Example commands 114 115`rpc.py construct_aio_bdev /dev/sda aio0` 116 117This command will create `aio0` device from /dev/sda. 118 119`rpc.py construct_aio_bdev /tmp/file file 8192` 120 121This command will create `file` device with block size 8192 from /tmp/file. 122 123# Ceph RBD {#bdev_config_rbd} 124 125The SPDK RBD bdev driver provides SPDK block layer access to Ceph RADOS block 126devices (RBD). Ceph RBD devices are accessed via librbd and librados libraries 127to access the RADOS block device exported by Ceph. To create Ceph bdev RPC 128command `construct_rbd_bdev` should be used. 129 130Example command 131 132`rpc.py construct_rbd_bdev rbd foo 512` 133 134This command will create a bdev that represents the 'foo' image from a pool called 'rbd'. 135 136# GPT (GUID Partition Table) {#bdev_config_gpt} 137 138The GPT virtual bdev driver is enabled by default and does not require any configuration. 139It will automatically detect @ref bdev_ug_gpt_table on any attached bdev and will create 140possibly multiple virtual bdevs. 141 142## SPDK GPT partition table {#bdev_ug_gpt_table} 143The SPDK partition type GUID is `7c5222bd-8f5d-4087-9c00-bf9843c7b58c`. Existing SPDK bdevs 144can be exposed as Linux block devices via NBD and then ca be partitioned with 145standard partitioning tools. After partitioning, the bdevs will need to be deleted and 146attached again fot the GPT bdev module to see any changes. NBD kernel module must be 147loaded first. To create NBD bdev user should use `start_nbd_disk` RPC command. 148 149Example command 150 151`rpc.py start_nbd_disk Malloc0 /dev/nbd0` 152 153This will expose an SPDK bdev `Malloc0` under the `/dev/nbd0` block device. 154 155To remove NBD device user should use `stop_nbd_disk` RPC command. 156 157Example command 158 159`rpc.py stop_nbd_disk /dev/nbd0` 160 161To display full or specified nbd device list user should use `get_nbd_disks` RPC command. 162 163Example command 164 165`rpc.py stop_nbd_disk -n /dev/nbd0` 166 167## Creating a GPT partition table using NBD {#bdev_ug_gpt_create_part} 168 169~~~ 170# Expose bdev Nvme0n1 as kernel block device /dev/nbd0 by JSON-RPC 171rpc.py start_nbd_disk Nvme0n1 /dev/nbd0 172 173# Create GPT partition table. 174parted -s /dev/nbd0 mklabel gpt 175 176# Add a partition consuming 50% of the available space. 177parted -s /dev/nbd0 mkpart MyPartition '0%' '50%' 178 179# Change the partition type to the SPDK GUID. 180# sgdisk is part of the gdisk package. 181sgdisk -t 1:7c5222bd-8f5d-4087-9c00-bf9843c7b58c /dev/nbd0 182 183# Stop the NBD device (stop exporting /dev/nbd0). 184rpc.py stop_nbd_disk /dev/nbd0 185 186# Now Nvme0n1 is configured with a GPT partition table, and 187# the first partition will be automatically exposed as 188# Nvme0n1p1 in SPDK applications. 189~~~ 190 191# Logical volumes {#bdev_ug_logical_volumes} 192 193The Logical Volumes library is a flexible storage space management system. It allows 194creating and managing virtual block devices with variable size on top of other bdevs. 195The SPDK Logical Volume library is built on top of @ref blob. For detailed description 196please refer to @ref lvol. 197 198## Logical volume store {#bdev_ug_lvol_store} 199 200Before creating any logical volumes (lvols), an lvol store has to be created first on 201selected block device. Lvol store is lvols vessel responsible for managing underlying 202bdev space assigment to lvol bdevs and storing metadata. To create lvol store user 203should use using `construct_lvol_store` RPC command. 204 205Example command 206 207`rpc.py construct_lvol_store Malloc2 lvs -c 4096` 208 209This will create lvol store named `lvs` with cluster size 4096, build on top of 210`Malloc2` bdev. In response user will be provided with uuid which is unique lvol store 211identifier. 212 213User can get list of available lvol stores using `get_lvol_stores` RPC command (no 214parameters available). 215 216Example response 217 218~~~ 219{ 220 "uuid": "330a6ab2-f468-11e7-983e-001e67edf35d", 221 "base_bdev": "Malloc2", 222 "free_clusters": 8190, 223 "cluster_size": 8192, 224 "total_data_clusters": 8190, 225 "block_size": 4096, 226 "name": "lvs" 227} 228~~~ 229 230To delete lvol store user should use `destroy_lvol_store` RPC command. 231 232Example commands 233 234`rpc.py destroy_lvol_store -u 330a6ab2-f468-11e7-983e-001e67edf35d` 235 236`rpc.py destroy_lvol_store -l lvs` 237 238## Lvols {#bdev_ug_lvols} 239 240To create lvols on existing lvol store user should use `construct_lvol_bdev` RPC command. 241Each created lvol will be represented by new bdev. 242 243Example commands 244 245`rpc.py construct_lvol_bdev lvol1 25 -l lvs` 246 247`rpc.py construct_lvol_bdev lvol2 25 -u 330a6ab2-f468-11e7-983e-001e67edf35d` 248 249# Pmem {#bdev_config_pmem} 250 251The SPDK pmem bdev driver uses pmemblk pool as the target for block I/O operations. For 252details on Pmem memory please refer to PMDK documentation on http://pmem.io website. 253First, user needs to configure SPDK to include PMDK support: 254 255`configure --with-pmdk` 256 257To create pmemblk pool for use with SPDK user should use `create_pmem_pool` RPC command. 258 259Example command 260 261`rpc.py create_pmem_pool /path/to/pmem_pool 25 4096` 262 263To get information on created pmem pool file user can use `pmem_pool_info` RPC command. 264 265Example command 266 267`rpc.py pmem_pool_info /path/to/pmem_pool` 268 269To remove pmem pool file user can use `delete_pmem_pool` RPC command. 270 271Example command 272 273`rpc.py delete_pmem_pool /path/to/pmem_pool` 274 275To create bdev based on pmemblk pool file user should use `construct_pmem_bdev ` RPC 276command. 277 278Example command 279 280`rpc.py construct_pmem_bdev /path/to/pmem_pool -n pmem` 281 282# Virtio SCSI {#bdev_config_virtio_scsi} 283 284The Virtio-SCSI driver allows creating SPDK block devices from Virtio-SCSI LUNs. 285 286The following command creates a Virtio-SCSI device named `VirtioScsi0` from a vhost-user 287socket `/tmp/vhost.0` exposed directly by SPDK @ref vhost. Optional `vq-count` and 288`vq-size` params specify number of request queues and queue depth to be used. 289 290`rpc.py construct_virtio_user_scsi_bdev /tmp/vhost.0 VirtioScsi0 --vq-count 2 --vq-size 512` 291 292The driver can be also used inside QEMU-based VMs. The following command creates a Virtio 293SCSI device named `VirtioScsi0` from a Virtio PCI device at address `0000:00:01.0`. 294The entire configuration will be read automatically from PCI Configuration Space. It will 295reflect all parameters passed to QEMU's vhost-user-scsi-pci device. 296 297`rpc.py construct_virtio_pci_scsi_bdev 0000:00:01.0 VirtioScsi0` 298 299Each Virtio-SCSI device may export up to 64 block devices named VirtioScsi0t0 ~ VirtioScsi0t63, 300one LUN (LUN0) per SCSI device. The above 2 commands will output names of all exposed bdevs. 301 302Virtio-SCSI devices can be removed with the following command 303 304`rpc.py remove_virtio_scsi_bdev VirtioScsi0` 305 306Removing a Virtio-SCSI device will destroy all its bdevs. 307 308# Virtio Block {#bdev_config_virtio_blk} 309 310The Virtio-Block driver can expose an SPDK bdev from a Virtio-Block device. 311 312Virtio-Block bdevs are constructed the same way as Virtio-SCSI ones. 313 314`rpc.py construct_virtio_user_blk_bdev /tmp/virtio.0 VirtioBlk0 --vq-count 2 --vq-size 512` 315 316`rpc.py construct_virtio_pci_blk_bdev 0000:01:00.0 VirtioBlk1` 317 318Since they export only a single bdev, the Virtio-Block driver doesn't offer additional 319remove/destruct RPC calls. @ref bdev_ug_delete_bdev should be used instead. 320