bdev/error: Add config of error vbdev when the base bdev of it doesn't exist
Currently construct_error_bdev() fails if the base bdev doesn't exist. This patch add configuration of the error vbdev for the base bdev instead, and the configuration will be parsed at examine() when the base bdev is created. This will improve the usability of error injection for bdev and will be usable for the upcoming JSON config file. Change-Id: I550b7f6c74fd8ab6cbd424a192f12a0c0099028e Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/403914 Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
070e72eda7
commit
22b8b92275
@ -82,6 +82,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_remove(const char *base_bdev_name);
|
||||
|
||||
static struct spdk_bdev_module error_if = {
|
||||
@ -259,8 +260,8 @@ spdk_vbdev_error_base_bdev_hotremove_cb(void *_base_bdev)
|
||||
spdk_bdev_part_base_hotremove(_base_bdev, &g_error_disks);
|
||||
}
|
||||
|
||||
int
|
||||
spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
static int
|
||||
_spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
{
|
||||
struct spdk_bdev_part_base *base = NULL;
|
||||
struct error_disk *disk = NULL;
|
||||
@ -280,14 +281,14 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
sizeof(struct error_channel), NULL, NULL);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("could not construct part base for bdev %s\n", spdk_bdev_get_name(base_bdev));
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
disk = calloc(1, sizeof(*disk));
|
||||
if (!disk) {
|
||||
SPDK_ERRLOG("Memory allocation failure\n");
|
||||
spdk_error_free_base(base);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
name = spdk_sprintf_alloc("EE_%s", spdk_bdev_get_name(base_bdev));
|
||||
@ -295,7 +296,7 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
SPDK_ERRLOG("name allocation failure\n");
|
||||
spdk_error_free_base(base);
|
||||
free(disk);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = spdk_bdev_part_construct(&disk->part, base, name, 0, base_bdev->blockcnt,
|
||||
@ -305,7 +306,7 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
/* spdk_bdev_part_construct will free name on failure */
|
||||
spdk_error_free_base(base);
|
||||
free(disk);
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
TAILQ_INIT(&disk->pending_ios);
|
||||
@ -313,6 +314,34 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_vbdev_error_create(const char *base_bdev_name)
|
||||
{
|
||||
int rc;
|
||||
struct spdk_bdev *base_bdev;
|
||||
|
||||
rc = vbdev_error_config_add(base_bdev_name);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("Adding config for ErrorInjection bdev %s failed (rc=%d)\n",
|
||||
base_bdev_name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
base_bdev = spdk_bdev_get_by_name(base_bdev_name);
|
||||
if (!base_bdev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = _spdk_vbdev_error_create(base_bdev);
|
||||
if (rc != 0) {
|
||||
vbdev_error_config_remove(base_bdev_name);
|
||||
SPDK_ERRLOG("Could not create ErrorInjection bdev %s (rc=%d)\n",
|
||||
base_bdev_name, rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
vbdev_error_clear_config(void)
|
||||
{
|
||||
@ -339,6 +368,36 @@ vbdev_error_config_find_by_base_name(const char *base_bdev_name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
vbdev_error_config_add(const char *base_bdev_name)
|
||||
{
|
||||
struct spdk_vbdev_error_config *cfg;
|
||||
|
||||
cfg = vbdev_error_config_find_by_base_name(base_bdev_name);
|
||||
if (cfg) {
|
||||
SPDK_ERRLOG("vbdev_error_config for bdev %s already exists\n",
|
||||
base_bdev_name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
cfg = calloc(1, sizeof(*cfg));
|
||||
if (!cfg) {
|
||||
SPDK_ERRLOG("calloc() failed for vbdev_error_config\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cfg->base_bdev = strdup(base_bdev_name);
|
||||
if (!cfg->base_bdev) {
|
||||
free(cfg);
|
||||
SPDK_ERRLOG("strdup() failed for base_bdev_name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&g_error_config, cfg, tailq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vbdev_error_config_remove(const char *base_bdev_name)
|
||||
{
|
||||
@ -419,9 +478,10 @@ vbdev_error_examine(struct spdk_bdev *bdev)
|
||||
|
||||
cfg = vbdev_error_config_find_by_base_name(bdev->name);
|
||||
if (cfg != NULL) {
|
||||
rc = spdk_vbdev_error_create(bdev);
|
||||
rc = _spdk_vbdev_error_create(bdev);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("could not create error vbdev for bdev %s\n", bdev->name);
|
||||
SPDK_ERRLOG("could not create error vbdev for bdev %s at examine\n",
|
||||
bdev->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,22 @@ enum vbdev_error_type {
|
||||
VBDEV_IO_PENDING,
|
||||
};
|
||||
|
||||
int spdk_vbdev_error_create(struct spdk_bdev *base_bdev);
|
||||
/**
|
||||
* Create a vbdev on the base bdev to inject error into it.
|
||||
*
|
||||
* \param base_bdev_name Name of the base bdev.
|
||||
* \return 0 on success or negative on failure.
|
||||
*/
|
||||
int spdk_vbdev_error_create(const char *base_bdev_name);
|
||||
|
||||
/**
|
||||
* Inject error to the base bdev. Users can specify which IO type error is injected,
|
||||
* what type of error is injected, and how many errors are injected.
|
||||
*
|
||||
* \param name Name of the base bdev into which error is injected.
|
||||
* \param io_type IO type into which error is injected.
|
||||
* \param error_num Count of injected errors
|
||||
*/
|
||||
int spdk_vbdev_inject_error(char *name, uint32_t io_type, uint32_t error_type,
|
||||
uint32_t error_num);
|
||||
|
||||
|
@ -92,7 +92,6 @@ spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_request *request,
|
||||
{
|
||||
struct rpc_construct_error_bdev req = {};
|
||||
struct spdk_json_write_ctx *w;
|
||||
struct spdk_bdev *base_bdev;
|
||||
|
||||
if (spdk_json_decode_object(params, rpc_construct_error_bdev_decoders,
|
||||
SPDK_COUNTOF(rpc_construct_error_bdev_decoders),
|
||||
@ -101,13 +100,7 @@ spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_request *request,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
base_bdev = spdk_bdev_get_by_name(req.base_name);
|
||||
if (!base_bdev) {
|
||||
SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", req.base_name);
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (spdk_vbdev_error_create(base_bdev)) {
|
||||
if (spdk_vbdev_error_create(req.base_name)) {
|
||||
SPDK_ERRLOG("Could not create ErrorInjection bdev %s\n", req.base_name);
|
||||
goto invalid;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user