bdev/error: add option to provide UUID for error bdev

Make sure UUID can be passed to error bdev type during
its creation.

Change-Id: I80b9c1b938a464c0cc8c61f871ae2044d8e09dfd
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17107
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
This commit is contained in:
Krzysztof Karas 2023-03-06 15:25:36 +01:00 committed by David Ko
parent c64d7ad06f
commit ba77879e01
6 changed files with 49 additions and 12 deletions

View File

@ -5208,6 +5208,7 @@ Construct error bdev.
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
base_name | Required | string | Base bdev name
uuid | Optional | string | UUID for this bdev
#### Example

View File

@ -21,6 +21,7 @@
struct spdk_vbdev_error_config {
char *base_bdev;
struct spdk_uuid uuid;
TAILQ_ENTRY(spdk_vbdev_error_config) tailq;
};
@ -54,7 +55,7 @@ static void vbdev_error_fini(void);
static void vbdev_error_examine(struct spdk_bdev *bdev);
static int vbdev_error_config_json(struct spdk_json_write_ctx *w);
static int vbdev_error_config_add(const char *base_bdev_name);
static int vbdev_error_config_add(const char *base_bdev_name, const struct spdk_uuid *uuid);
static int vbdev_error_config_remove(const char *base_bdev_name);
static struct spdk_bdev_module error_if = {
@ -314,11 +315,11 @@ vbdev_error_base_bdev_hotremove_cb(void *_part_base)
}
static int
_vbdev_error_create(const char *base_bdev_name)
_vbdev_error_create(const char *base_bdev_name, const struct spdk_uuid *uuid)
{
struct spdk_bdev_part_base *base = NULL;
struct error_disk *disk = NULL;
struct spdk_bdev *base_bdev;
struct spdk_bdev *base_bdev, *bdev;
char *name;
int rc;
@ -351,6 +352,11 @@ _vbdev_error_create(const char *base_bdev_name)
return -ENOMEM;
}
if (uuid) {
bdev = spdk_bdev_part_get_bdev(&disk->part);
spdk_uuid_copy(&bdev->uuid, uuid);
}
rc = spdk_bdev_part_construct(&disk->part, base, name, 0, base_bdev->blockcnt,
"Error Injection Disk");
free(name);
@ -368,18 +374,18 @@ _vbdev_error_create(const char *base_bdev_name)
}
int
vbdev_error_create(const char *base_bdev_name)
vbdev_error_create(const char *base_bdev_name, const struct spdk_uuid *uuid)
{
int rc;
rc = vbdev_error_config_add(base_bdev_name);
rc = vbdev_error_config_add(base_bdev_name, uuid);
if (rc != 0) {
SPDK_ERRLOG("Adding config for ErrorInjection bdev %s failed (rc=%d)\n",
base_bdev_name, rc);
return rc;
}
rc = _vbdev_error_create(base_bdev_name);
rc = _vbdev_error_create(base_bdev_name, uuid);
if (rc == -ENODEV) {
rc = 0;
} else if (rc != 0) {
@ -429,7 +435,7 @@ vbdev_error_config_find_by_base_name(const char *base_bdev_name)
}
static int
vbdev_error_config_add(const char *base_bdev_name)
vbdev_error_config_add(const char *base_bdev_name, const struct spdk_uuid *uuid)
{
struct spdk_vbdev_error_config *cfg;
@ -453,6 +459,10 @@ vbdev_error_config_add(const char *base_bdev_name)
return -ENOMEM;
}
if (uuid) {
spdk_uuid_copy(&cfg->uuid, uuid);
}
TAILQ_INSERT_TAIL(&g_error_config, cfg, tailq);
return 0;
@ -494,7 +504,7 @@ vbdev_error_examine(struct spdk_bdev *bdev)
cfg = vbdev_error_config_find_by_base_name(bdev->name);
if (cfg != NULL) {
rc = _vbdev_error_create(bdev->name);
rc = _vbdev_error_create(bdev->name, &cfg->uuid);
if (rc != 0) {
SPDK_ERRLOG("could not create error vbdev for bdev %s at examine\n",
bdev->name);
@ -508,6 +518,7 @@ static int
vbdev_error_config_json(struct spdk_json_write_ctx *w)
{
struct spdk_vbdev_error_config *cfg;
char uuid_str[SPDK_UUID_STRING_LEN];
TAILQ_FOREACH(cfg, &g_error_config, tailq) {
spdk_json_write_object_begin(w);
@ -515,6 +526,10 @@ vbdev_error_config_json(struct spdk_json_write_ctx *w)
spdk_json_write_named_string(w, "method", "bdev_error_create");
spdk_json_write_named_object_begin(w, "params");
spdk_json_write_named_string(w, "base_name", cfg->base_bdev);
if (!spdk_mem_all_zero(&cfg->uuid, sizeof(struct spdk_uuid))) {
spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &cfg->uuid);
spdk_json_write_named_string(w, "uuid", uuid_str);
}
spdk_json_write_object_end(w);
spdk_json_write_object_end(w);

View File

@ -8,6 +8,7 @@
#include "spdk/stdinc.h"
#include "spdk/bdev.h"
#include "spdk/uuid.h"
enum vbdev_error_type {
VBDEV_IO_FAILURE = 1,
@ -21,9 +22,10 @@ typedef void (*spdk_delete_error_complete)(void *cb_arg, int bdeverrno);
* Create a vbdev on the base bdev to inject error into it.
*
* \param base_bdev_name Name of the base bdev.
* \param uuid Optional UUID to assign to the bdev.
* \return 0 on success or negative on failure.
*/
int vbdev_error_create(const char *base_bdev_name);
int vbdev_error_create(const char *base_bdev_name, const struct spdk_uuid *uuid);
/**
* Delete vbdev used to inject errors.

View File

@ -57,16 +57,19 @@ rpc_error_bdev_decode_error_type(const struct spdk_json_val *val, void *out)
struct rpc_bdev_error_create {
char *base_name;
char *uuid;
};
static void
free_rpc_bdev_error_create(struct rpc_bdev_error_create *req)
{
free(req->base_name);
free(req->uuid);
}
static const struct spdk_json_object_decoder rpc_bdev_error_create_decoders[] = {
{"base_name", offsetof(struct rpc_bdev_error_create, base_name), spdk_json_decode_string},
{"uuid", offsetof(struct rpc_bdev_error_create, uuid), spdk_json_decode_string, true},
};
static void
@ -74,6 +77,8 @@ rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_error_create req = {};
struct spdk_uuid *uuid = NULL;
struct spdk_uuid decoded_uuid;
int rc = 0;
if (spdk_json_decode_object(params, rpc_bdev_error_create_decoders,
@ -85,7 +90,16 @@ rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
goto cleanup;
}
rc = vbdev_error_create(req.base_name);
if (req.uuid) {
if (spdk_uuid_parse(&decoded_uuid, req.uuid)) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Failed to parse bdev UUID");
goto cleanup;
}
uuid = &decoded_uuid;
}
rc = vbdev_error_create(req.base_name, uuid);
if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;

View File

@ -1152,13 +1152,16 @@ def bdev_rbd_resize(client, name, new_size):
return client.call('bdev_rbd_resize', params)
def bdev_error_create(client, base_name):
def bdev_error_create(client, base_name, uuid=None):
"""Construct an error injection block device.
Args:
base_name: base bdev name
uuid: UUID for this bdev (optional)
"""
params = {'base_name': base_name}
if uuid is not None:
params['uuid'] = uuid
return client.call('bdev_error_create', params)

View File

@ -1069,10 +1069,12 @@ if __name__ == "__main__":
def bdev_error_create(args):
print_json(rpc.bdev.bdev_error_create(args.client,
base_name=args.base_name))
base_name=args.base_name,
uuid=args.uuid))
p = subparsers.add_parser('bdev_error_create', help='Add bdev with error injection backend')
p.add_argument('base_name', help='base bdev name')
p.add_argument('--uuid', help='UUID for this bdev', required=False)
p.set_defaults(func=bdev_error_create)
def bdev_error_delete(args):