lvol: updated documentation.

Signed-off-by: Piotr Pelplinski <piotr.pelplinski@intel.com>
Change-Id: I566a4d277ac1595fa7b4d630df52301a9abeec49
Reviewed-on: https://review.gerrithub.io/381629
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Piotr Pelplinski 2017-10-06 09:27:23 +02:00 committed by Daniel Verkamp
parent 9d17cbdd23
commit d17345183e
3 changed files with 190 additions and 23 deletions

View File

@ -113,7 +113,7 @@ specify an output file handle (stdout or stderr, for example).
Logical volumes library built on top of SPDK blobstore has been added.
It is possible to create logical volumes on top of other devices using RPC.
See the [logical volumes](http://www.spdk.io/doc/lvolstore.html) documentation for more information.
See the [logical volumes](http://www.spdk.io/doc/logical_volumes.html) documentation for more information.
### Persistent Memory

View File

@ -1,28 +1,81 @@
# Logical volume store {#lvolstore}
# Logical Volumes Introduction {#logical_volumes}
A logical volume store is an SPDK blobstore with a special super blob denoting the blobstore.
This super blob is to different from SPDK blobstores used for BlobFS.
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.
# Logical volume {#lvol}
# Terminology {#lvol_terminology}
A logical volume is an SPDK blob created from an lvolstore.
## Logical volume store {#lvs}
An lvol is uniquely identified by its blob ID and the UUID of the lvolstore from which it was created.
* Shorthand: lvolstore, lvs
* Type name: struct spdk_lvol_store
# Logical volume block device {#vdev_lvol}
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.
Representation of an SPDK block device (spdk_bdev) with an lvol implementation. A logical volume block device translates generic SPDK block device I/O (spdk_bdev_io) operations into the equivalent SPDK blob operations.
## Logical volume {#lvol}
# RPC overview
There are few logical volumes specific calls.
* Shorthand: lvol
* Type name: struct spdk_lvol
- construct_lvol_store bdev_name
Constructs lvolstore on specified bdev
- destroy_lvol_store bdev_name
Destroy lvolstore on specified bdev
- construct_lvol_bdev uuid size
Constructs lvol bdev on lvolstore specified by uuid with specified size
- resize_lvol_bdev bdev_name size
Resizes specified lvol bdev
A logical volume is implemented as an SPDK blob created from an lvolstore. An lvol is uniquely identified by its lvol ID and lvolstore UUID from which it was created.
Note that destroying lvol store requires using call destroy_lvol_store, while deleting single lvol requires using delete_bdev rpc call.
## Logical volume block device {#lvol_bdev}
* Shorthand: lvol_bdev
* Type name: struct spdk_lvol_bdev
Representation of an SPDK block device (spdk_bdev) with an lvol implementation.
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 ID and lvolstore UUID gives lvol_bdev name in a form "uuid/lvolid". block_size of the created bdev is always 4096, due to blobstore page size. Cluster_size is configurable by parameter. By default it is 1GiB.
Size of the new bdev will be rounded up to nearest multiple of cluster_size.
# Configuring Logical Volumes
There is no static configuration available for logical volumes. All configuration is done trough RPC. Information about logical volumes is kept on block devices.
# RPC overview {#lvol_rpc}
RPC regarding lvolstore:
```
construct_lvol_store [-h] [-c CLUSTER_SZ] base_name
Constructs lvolstore on specified bdev. During construction bdev is unmapped
at initialization and all data is erased. Then original bdev is claimed by
SPDK, but no additional spdk bdevs are created.
Returns uuid of created lvolstore.
Optional paramters:
-h show help
-c CLUSTER_SZ Specifies the size of cluster. By default its 1GB.
destroy_lvol_store [-h] uuid
Destroy lvolstore on specified bdev. Removes lvolstore along with lvols on
it. Note that destroying lvolstore requires using this call, while deleting
single lvol requires using delete_bdev rpc call.
optional arguments:
-h, --help show help
get_lvol_stores [-h]
Display current logical volume store list
optional arguments:
-h, --help show help
```
RPC regarding lvol and spdk bdev:
```
construct_lvol_bdev [-h] uuid size
Creates lvol with specified size on lvolstore specified by its uuid.
Then constructs spdk bdev on top of that lvol and presents it as spdk bdev.
Returns the name of new spdk bdev
get_bdevs [-h] [-b NAME]
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
delete_bdev [-h] bdev_name
Deletes spdk bdev
optional arguments:
-h, --help show help
```
# Restrictions
- Unmap is not supported.
- Nesting logical volumes on each other is not supported.
- Resizing lvol bdev is experimental. Code is present but not used.

View File

@ -49,33 +49,147 @@ struct spdk_lvol;
#define SPDK_LVS_NAME_MAX 64
#define SPDK_LVOL_NAME_MAX 64
/**
* Parameters for lvolstore initialization.
*/
struct spdk_lvs_opts {
uint32_t cluster_sz;
char name[SPDK_LVS_NAME_MAX];
};
/* Initialize an spdk_lvs_opts structure to the default logical volume store option values. */
/**
* \brief Initialize an spdk_lvs_opts structure to the defaults.
* \param opts
*/
void spdk_lvs_opts_init(struct spdk_lvs_opts *opts);
/**
* \brief Callback definition for lvolstore operations, including handle to lvs
* \param cb_arg Custom arguments
* \param lvol_store Handle to lvol_store or NULL when lvserrno is set
* \param lvserrno Error
*/
typedef void (*spdk_lvs_op_with_handle_complete)(void *cb_arg, struct spdk_lvol_store *lvol_store,
int lvserrno);
/**
* \brief Callback definition for lvolstore operations without handle
* \param cb_arg Custom arguments
* \param lvserrno Error
*/
typedef void (*spdk_lvs_op_complete)(void *cb_arg, int lvserrno);
typedef void (*spdk_lvol_op_complete)(void *cb_arg, int lvolerrno);
/**
* \brief Callback definition for lvol operations with handle to lvol
* \param cb_arg Custom arguments
* \param lvol Handle to lvol or NULL when lvserrno is set
* \param lvolerrno Error
*/
typedef void (*spdk_lvol_op_with_handle_complete)(void *cb_arg, struct spdk_lvol *lvol,
int lvolerrno);
/**
* \brief Callback definition for lvol operations without handle to lvol
* \param cb_arg Custom arguments
* \param lvolerrno Error
*/
typedef void (*spdk_lvol_op_complete)(void *cb_arg, int lvolerrno);
/**
* \brief Initialize lvolstore on given bs_bdev.
*
* bs_dev can be created on bdev by using spdk_bdev_create_bs_dev()
* Refer to blobstore documention for more details.
*
* \param o Options for lvolstore
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
* \return error
*/
int spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg);
int spdk_lvs_unload(struct spdk_lvol_store *lvol_store, spdk_lvs_op_complete cb_fn, void *cb_arg);
/**
* \brief Unloads lvolstore
*
* All lvols have to be closed beforehand, when doing unload.
*
* \param lvol_store Handle to lvolstore
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
* \return error
*/
int spdk_lvs_unload(struct spdk_lvol_store *lvol_store,
spdk_lvs_op_complete cb_fn, void *cb_arg);
/**
* \brief Destroy lvolstore
*
* All lvols have to be closed beforehand, when doing destroy.
*
* \param lvol_store Handle to lvolstore
* \param umap_device When set to true, unmaps whole lvolstore, otherwise writes zeros in first block
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
* \return error
*/
int spdk_lvs_destroy(struct spdk_lvol_store *lvol_store, bool unmap_device,
spdk_lvs_op_complete cb_fn, void *cb_arg);
/**
* \brief Create lvol on given lvolstore with specified size
* \param lvs Handle to lvolstore
* \param sz size of lvol in bytes
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
* \return error
*/
int spdk_lvol_create(struct spdk_lvol_store *lvs, char *name, uint64_t sz,
spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);
/**
* \brief Closes lvol and removes information about lvol from its lvolstore.
* \param lvol Handle to lvol
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
*/
void spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg);
/**
* \brief Closes lvol, but information is kept on lvolstore.
* \param lvol Handle to lvol
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
*/
void spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg);
/**
* \brief Return IO channel of bdev associated with specified lvol.
* \param lvol Handle to lvol
* \return IO channel
*/
struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol);
/**
* \brief Search for handle to lvolstore bdev
* \param lvs_orig Handle to spdk_lvol_store
* \return Handle to lvol_store_bdev or NULL if not found.
*/
struct lvol_store_bdev *vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig);
/**
* \brief Search for handle to lvol
* \param name Name of bdev
* \return Handle to spdk_lvol or NULL if not found.
*/
struct spdk_lvol *vbdev_get_lvol_by_name(const char *name);
/**
* \brief Search for handle lvolstore
* \param uuid UUID of lvolstore
* \return Handle to spdk_lvol_store or NULL if not found.
*/
struct spdk_lvol_store *vbdev_get_lvol_store_by_uuid(uuid_t uuid);
void spdk_lvs_load(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn,
void *cb_arg);