bdev/compress: add RPC to list orphaned comp bdevs

The previous patch in this series introduced the notion of an
orphan comp bdev which is available only for deletion due to
a missing PMEM file.  This RPC allows applications to list
orphaned comp bdevs as they will not show up with get_bdevs
because they are not registered bdevs.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: I431f9cdebd4e5ae6068308639cb41d6c52f7309b
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465812
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
paul luse 2019-08-20 13:12:59 -04:00 committed by Jim Harris
parent 09824fa0e7
commit 68e7da44ec
7 changed files with 166 additions and 0 deletions

View File

@ -33,6 +33,12 @@ connections is moving to a more dynamic model.
The `bdev_delay_update_latency` has been added to allow users to update
a latency value for a given delay bdev.
### compress bdev
A new RPC `bdev_compress_get_orphans` has been added to list compress bdevs
that were not loaded due to a missing pm metadata file. In this state they
can only be deleted.
## v19.07:
### ftl

View File

@ -172,6 +172,12 @@ compression vbdev will not be available.
`rpc.py bdev_compress_delete COMP_LVS/myLvol`
To list compression volumes that are only available for deletion because their PMEM file
was missing use the following. The name parameter is optional and if not included will list
all volumes, if used it will return the name or an error that the device does not exist.
`rpc.py bdev_compress_get_orphans --name COMP_Nvme0n1`
# Crypto Virtual Bdev Module {#bdev_config_crypto}
The crypto virtual bdev module can be configured to provide at rest data encryption

View File

@ -883,6 +883,45 @@ delete_vol_unload_cb(void *cb_arg, int reduce_errno)
}
}
const char *
compress_get_name(const struct vbdev_compress *comp_bdev)
{
return comp_bdev->comp_bdev.name;
}
struct vbdev_compress *
compress_bdev_first(void)
{
struct vbdev_compress *comp_bdev;
comp_bdev = TAILQ_FIRST(&g_vbdev_comp);
return comp_bdev;
}
struct vbdev_compress *
compress_bdev_next(struct vbdev_compress *prev)
{
struct vbdev_compress *comp_bdev;
comp_bdev = TAILQ_NEXT(prev, link);
return comp_bdev;
}
bool
compress_has_orphan(const char *name)
{
struct vbdev_compress *comp_bdev;
TAILQ_FOREACH(comp_bdev, &g_vbdev_comp, link) {
if (comp_bdev->orphaned && strcmp(name, comp_bdev->comp_bdev.name) == 0) {
return true;
}
}
return false;
}
/* Called after we've unregistered following a hot remove callback.
* Our finish entry point will be called next.
*/

View File

@ -38,6 +38,37 @@
#include "spdk/bdev.h"
/**
* Get the first compression bdev.
*
* \return the first compression bdev.
*/
struct vbdev_compress *compress_bdev_first(void);
/**
* Get the next compression bdev.
*
* \param prev previous compression bdev.
* \return the next compression bdev.
*/
struct vbdev_compress *compress_bdev_next(struct vbdev_compress *prev);
/**
* Test to see if a compression bdev orphan exists.
*
* \param name The name of the compression bdev.
* \return true if found, false if not.
*/
bool compress_has_orphan(const char *name);
/**
* Get the name of a compression bdev.
*
* \param comp_bdev The compression bdev.
* \return the name of the compression bdev.
*/
const char *compress_get_name(const struct vbdev_compress *comp_bdev);
enum compress_pmd {
COMPRESS_PMD_AUTO = 0,
COMPRESS_PMD_QAT_ONLY,

View File

@ -37,6 +37,67 @@
#include "spdk/string.h"
#include "spdk_internal/log.h"
struct rpc_bdev_compress_get_orphans {
char *name;
};
static void
free_rpc_bdev_compress_get_orphans(struct rpc_bdev_compress_get_orphans *r)
{
free(r->name);
}
static const struct spdk_json_object_decoder rpc_bdev_compress_get_orphans_decoders[] = {
{"name", offsetof(struct rpc_bdev_compress_get_orphans, name), spdk_json_decode_string, true},
};
static void
spdk_rpc_bdev_compress_get_orphans(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_compress_get_orphans req = {};
struct spdk_json_write_ctx *w;
struct vbdev_compress *comp_bdev;
bool found = false;
if (params && spdk_json_decode_object(params, rpc_bdev_compress_get_orphans_decoders,
SPDK_COUNTOF(rpc_bdev_compress_get_orphans_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
free_rpc_bdev_compress_get_orphans(&req);
return;
}
if (req.name) {
if (compress_has_orphan(req.name) == false) {
spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
free_rpc_bdev_compress_get_orphans(&req);
return;
}
found = true;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
if (found) {
spdk_json_write_string(w, req.name);
} else {
for (comp_bdev = compress_bdev_first(); comp_bdev != NULL;
comp_bdev = compress_bdev_next(comp_bdev)) {
if (compress_has_orphan(compress_get_name(comp_bdev))) {
spdk_json_write_string(w, compress_get_name(comp_bdev));
}
}
}
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
free_rpc_bdev_compress_get_orphans(&req);
}
SPDK_RPC_REGISTER("bdev_compress_get_orphans", spdk_rpc_bdev_compress_get_orphans, SPDK_RPC_RUNTIME)
struct rpc_set_compress_pmd {
enum compress_pmd pmd;
};

View File

@ -161,6 +161,14 @@ if __name__ == "__main__":
p.add_argument('-p', '--pmd', type=int, help='0 = auto-select, 1= QAT only, 2 = ISAL only')
p.set_defaults(func=set_compress_pmd)
def bdev_compress_get_orphans(args):
print_dict(rpc.bdev.bdev_compress_get_orphans(args.client,
name=args.name))
p = subparsers.add_parser(
'bdev_compress_get_orphans', help='Display list of orphaned compress bdevs.')
p.add_argument('-b', '--name', help="Name of a comp bdev. Example: COMP_Nvme0n1", required=False)
p.set_defaults(func=bdev_compress_get_orphans)
def bdev_crypto_create(args):
print_json(rpc.bdev.bdev_crypto_create(args.client,
base_bdev_name=args.base_bdev_name,

View File

@ -56,6 +56,21 @@ def set_compress_pmd(client, pmd):
return client.call('set_compress_pmd', params)
def bdev_compress_get_orphans(client, name=None):
"""Get a list of comp bdevs that do not have a pmem file (aka orphaned).
Args:
name: comp bdev name to query (optional; if omitted, query all comp bdevs)
Returns:
List of comp bdev names.
"""
params = {}
if name:
params['name'] = name
return client.call('bdev_compress_get_orphans', params)
@deprecated_alias('construct_crypto_bdev')
def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd, key):
"""Construct a crypto virtual block device.