2018-06-05 21:08:48 +00:00
|
|
|
# Logical Volumes {#logical_volumes}
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
The Logical Volumes library is a flexible storage space management system. It provides creating and managing virtual
|
|
|
|
block devices with variable size. The SPDK Logical Volume library is built on top of @ref blob.
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
## Terminology {#lvol_terminology}
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Logical volume store {#lvs}
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2017-10-06 07:27:23 +00:00
|
|
|
* Shorthand: lvolstore, lvs
|
|
|
|
* Type name: struct spdk_lvol_store
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
A logical volume store uses the super blob feature of blobstore to hold uuid (and in future other metadata).
|
|
|
|
Blobstore types are implemented in blobstore itself, and saved on disk. An lvolstore will generate a UUID on
|
|
|
|
creation, so that it can be uniquely identified from other lvolstores.
|
|
|
|
By default when creating lvol store data region is unmapped. Optional --clear-method parameter can be passed
|
|
|
|
on creation to change that behavior to writing zeroes or performing no operation.
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Logical volume {#lvol}
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2017-10-06 07:27:23 +00:00
|
|
|
* Shorthand: lvol
|
|
|
|
* Type name: struct spdk_lvol
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
A logical volume is implemented as an SPDK blob created from an lvolstore. An lvol is uniquely identified by
|
|
|
|
its UUID. Lvol additional can have alias name.
|
2017-07-12 14:58:55 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Logical volume block device {#lvol_bdev}
|
2017-10-06 07:27:23 +00:00
|
|
|
|
|
|
|
* Shorthand: lvol_bdev
|
|
|
|
* Type name: struct spdk_lvol_bdev
|
|
|
|
|
|
|
|
Representation of an SPDK block device (spdk_bdev) with an lvol implementation.
|
2021-07-27 10:05:23 +00:00
|
|
|
A logical volume block device translates generic SPDK block device I/O (spdk_bdev_io) operations into the
|
|
|
|
equivalent SPDK blob operations. Combination of lvol name and lvolstore name gives lvol_bdev alias name in
|
|
|
|
a form "lvs_name/lvol_name". block_size of the created bdev is always 4096, due to blobstore page size.
|
|
|
|
Cluster_size is configurable by parameter. Size of the new bdev will be rounded up to nearest multiple of
|
|
|
|
cluster_size. By default lvol bdevs claim part of lvol store equal to their set size. When thin provision
|
|
|
|
option is enabled, no space is taken from lvol store until data is written to lvol bdev.
|
|
|
|
By default when deleting lvol bdev or resizing down, allocated clusters are unmapped. Optional --clear-method
|
|
|
|
parameter can be passed on creation to change that behavior to writing zeroes or performing no operation.
|
2017-10-06 07:27:23 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Thin provisioning {#lvol_thin_provisioning}
|
2018-06-14 09:40:20 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
Thin provisioned lvols rely on dynamic cluster allocation (e.g. when the first write operation on a cluster is performed), only space
|
|
|
|
required to store data is used and unallocated clusters are obtained from underlying device (e.g. zeroes_dev).
|
2018-06-14 09:40:20 +00:00
|
|
|
|
|
|
|
Sample write operations of thin provisioned blob are shown on the diagram below:
|
|
|
|
|
|
|
|
![Writing clusters to the thin provisioned blob](lvol_thin_provisioning_write.svg)
|
|
|
|
|
|
|
|
Sample read operations and the structure of thin provisioned blob are shown on the diagram below:
|
|
|
|
|
|
|
|
![Reading clusters from thin provisioned blob](lvol_thin_provisioning.svg)
|
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Snapshots and clone {#lvol_snapshots}
|
2018-04-13 13:20:12 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
Logical volumes support snapshots and clones functionality. User may at any given time create snapshot of existing
|
|
|
|
logical volume to save a backup of current volume state. When creating snapshot original volume becomes thin provisioned
|
|
|
|
and saves only incremental differences from its underlying snapshot. This means that every read from unallocated cluster
|
|
|
|
is actually a read from the snapshot and every write to unallocated cluster triggers new cluster allocation and data copy
|
|
|
|
from corresponding cluster in snapshot to the new cluster in logical volume before the actual write occurs.
|
2018-05-30 18:34:31 +00:00
|
|
|
|
|
|
|
The read operation is performed as shown in the diagram below:
|
|
|
|
![Reading cluster from clone](lvol_clone_snapshot_read.svg)
|
|
|
|
|
|
|
|
The write operation is performed as shown in the diagram below:
|
|
|
|
![Writing cluster to the clone](lvol_clone_snapshot_write.svg)
|
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
User may also create clone of existing snapshot that will be thin provisioned and it will behave in the same way as logical volume
|
|
|
|
from which snapshot is created. There is no limit of clones and snapshots that may be created as long as there is enough space on
|
|
|
|
logical volume store. Snapshots are read only. Clones may be created only from snapshots or read only logical volumes.
|
2018-04-13 13:20:12 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
A snapshot can be removed only if there is a single clone on top of it. The relation chain will be updated accordingly.
|
|
|
|
The cluster map of clone and snapshot will be merged and entries for unallocated clusters in the clone will be updated with
|
|
|
|
addresses from the snapshot cluster map. The entire operation modifies metadata only - no data is copied during this process.
|
2019-06-18 12:34:36 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Inflation {#lvol_inflation}
|
2018-05-30 18:35:59 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
Blobs can be inflated to copy data from backing devices (e.g. snapshots) and allocate all remaining clusters. As a result of this
|
|
|
|
operation all dependencies for the blob are removed.
|
2018-05-30 18:35:59 +00:00
|
|
|
|
|
|
|
![Removing backing blob and bdevs relations using inflate call](lvol_inflate_clone_snapshot.svg)
|
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
### Decoupling {#lvol_decoupling}
|
2018-07-16 07:05:01 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
Blobs can be decoupled from their parent blob by copying data from backing devices (e.g. snapshots) for all allocated clusters.
|
|
|
|
Remaining unallocated clusters are kept thin provisioned.
|
|
|
|
Note: When decouple is performed, only single dependency is removed. To remove all dependencies in a chain of blobs depending
|
|
|
|
on each other, multiple calls need to be issued.
|
2018-07-16 07:05:01 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
## Configuring Logical Volumes
|
2017-10-06 07:27:23 +00:00
|
|
|
|
2021-07-27 10:05:23 +00:00
|
|
|
There is no static configuration available for logical volumes. All configuration is done trough RPC. Information about
|
|
|
|
logical volumes is kept on block devices.
|
2017-10-06 07:27:23 +00:00
|
|
|
|
2021-08-02 12:27:54 +00:00
|
|
|
## RPC overview {#lvol_rpc}
|
2017-10-06 07:27:23 +00:00
|
|
|
|
|
|
|
RPC regarding lvolstore:
|
|
|
|
|
2021-08-24 07:04:22 +00:00
|
|
|
```bash
|
2019-08-29 13:31:19 +00:00
|
|
|
bdev_lvol_create_lvstore [-h] [-c CLUSTER_SZ] bdev_name lvs_name
|
2018-04-13 13:20:12 +00:00
|
|
|
Constructs lvolstore on specified bdev with specified name. During
|
|
|
|
construction bdev is unmapped at initialization and all data is
|
|
|
|
erased. Then original bdev is claimed by
|
2017-10-06 07:27:23 +00:00
|
|
|
SPDK, but no additional spdk bdevs are created.
|
|
|
|
Returns uuid of created lvolstore.
|
2018-08-27 08:42:35 +00:00
|
|
|
Optional parameters:
|
2018-04-13 13:20:12 +00:00
|
|
|
-h show help
|
|
|
|
-c CLUSTER_SZ Specifies the size of cluster. By default its 4MiB.
|
2019-02-28 09:57:19 +00:00
|
|
|
--clear-method specify data region clear method "none", "unmap" (default), "write_zeroes"
|
2019-08-29 12:07:56 +00:00
|
|
|
bdev_lvol_delete_lvstore [-h] [-u UUID] [-l LVS_NAME]
|
2017-10-06 07:27:23 +00:00
|
|
|
Destroy lvolstore on specified bdev. Removes lvolstore along with lvols on
|
2018-04-13 13:20:12 +00:00
|
|
|
it. User can identify lvol store by UUID or its name. Note that destroying
|
|
|
|
lvolstore requires using this call, while deleting single lvol requires
|
2019-08-29 10:33:16 +00:00
|
|
|
using bdev_lvol_delete rpc call.
|
2017-10-06 07:27:23 +00:00
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-26 11:54:05 +00:00
|
|
|
bdev_lvol_get_lvstores [-h] [-u UUID] [-l LVS_NAME]
|
2017-10-06 07:27:23 +00:00
|
|
|
Display current logical volume store list
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2018-04-13 13:20:12 +00:00
|
|
|
-u UUID, --uuid UUID show details of specified lvol store
|
|
|
|
-l LVS_NAME, --lvs_name LVS_NAME show details of specified lvol store
|
2019-08-29 13:11:18 +00:00
|
|
|
bdev_lvol_rename_lvstore [-h] old_name new_name
|
2018-04-13 13:20:12 +00:00
|
|
|
Change logical volume store name
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show this help message and exit
|
2017-10-06 07:27:23 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
RPC regarding lvol and spdk bdev:
|
|
|
|
|
2021-08-24 07:04:22 +00:00
|
|
|
```bash
|
2019-08-29 11:01:30 +00:00
|
|
|
bdev_lvol_create [-h] [-u UUID] [-l LVS_NAME] [-t] [-c CLEAR_METHOD] lvol_name size
|
2018-04-13 13:20:12 +00:00
|
|
|
Creates lvol with specified size and name on lvolstore specified by its uuid
|
|
|
|
or name. Then constructs spdk bdev on top of that lvol and presents it as spdk bdev.
|
|
|
|
User may use -t switch to create thin provisioned lvol.
|
2017-10-06 07:27:23 +00:00
|
|
|
Returns the name of new spdk bdev
|
2018-04-13 13:20:12 +00:00
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-01-29 10:23:26 +00:00
|
|
|
-c, --clear-method specify data clusters clear method "none", "unmap" (default), "write_zeroes"
|
2019-09-11 09:29:55 +00:00
|
|
|
bdev_get_bdevs [-h] [-b NAME]
|
2017-10-06 07:27:23 +00:00
|
|
|
User can view created bdevs using this call including those created on top of lvols.
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
|
|
|
-b NAME, --name NAME Name of the block device. Example: Nvme0n1
|
2019-08-29 10:33:16 +00:00
|
|
|
bdev_lvol_delete [-h] bdev_name
|
2019-08-29 11:01:30 +00:00
|
|
|
Deletes a logical volume previously created by bdev_lvol_create.
|
2017-10-06 07:27:23 +00:00
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-29 09:40:39 +00:00
|
|
|
bdev_lvol_snapshot [-h] lvol_name snapshot_name
|
2018-04-13 13:20:12 +00:00
|
|
|
Create a snapshot with snapshot_name of a given lvol bdev.
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-23 09:35:34 +00:00
|
|
|
bdev_lvol_clone [-h] snapshot_name clone_name
|
2018-04-13 13:20:12 +00:00
|
|
|
Create a clone with clone_name of a given lvol snapshot.
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-23 09:57:07 +00:00
|
|
|
bdev_lvol_rename [-h] old_name new_name
|
2018-04-13 13:20:12 +00:00
|
|
|
Change lvol bdev name
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-26 13:06:42 +00:00
|
|
|
bdev_lvol_resize [-h] name size
|
2018-04-13 13:20:12 +00:00
|
|
|
Resize existing lvol bdev
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-26 12:49:31 +00:00
|
|
|
bdev_lvol_set_read_only [-h] name
|
2019-01-15 15:31:05 +00:00
|
|
|
Mark lvol bdev as read only
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-29 09:25:48 +00:00
|
|
|
bdev_lvol_inflate [-h] name
|
2018-05-30 18:35:59 +00:00
|
|
|
Inflate lvol bdev
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2019-08-26 13:35:53 +00:00
|
|
|
bdev_lvol_decouple_parent [-h] name
|
2018-07-16 07:05:01 +00:00
|
|
|
Decouple parent of a logical volume
|
|
|
|
optional arguments:
|
|
|
|
-h, --help show help
|
2017-10-06 07:27:23 +00:00
|
|
|
```
|