bdev: Added bdev aliases list.

Added aliases list to bdev struct.
Added 2 API calls to add and remove aliases.
Added test for adding and removing aliases.

Change-Id: I1815aec8c02cfa398b2d1de41577197315665fdc
Signed-off-by: Sebastian Basierski <sebastianx.basierski@intel.com>
Reviewed-on: https://review.gerrithub.io/390200
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Sebastian Basierski 2017-11-29 16:13:17 +01:00 committed by Daniel Verkamp
parent 4ee8322439
commit b9afa3c732
3 changed files with 173 additions and 4 deletions

View File

@ -182,6 +182,11 @@ enum spdk_bdev_io_status {
SPDK_BDEV_IO_STATUS_SUCCESS = 1,
};
struct spdk_bdev_alias {
char *alias;
TAILQ_ENTRY(spdk_bdev_alias) tailq;
};
struct spdk_bdev {
/** User context passed in by the backend */
void *ctxt;
@ -189,6 +194,9 @@ struct spdk_bdev {
/** Unique name for this block device. */
char *name;
/** Unique aliases for this block device. */
TAILQ_HEAD(spdk_bdev_aliases_list, spdk_bdev_alias) aliases;
/** Unique product name for this kind of block device. */
char *product_name;
@ -396,6 +404,31 @@ int spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *d
struct spdk_bdev_module_if *module);
void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev);
/**
* Add alias to block device names list.
* Aliases can be add only to registered bdev.
*
* \param bdev Block device to query.
* \param alias Alias to be added to list.
*
* Return codes
* \return 0 on success
* \return -EEXIST if alias already exists as name or alias on any bdev
* \return -ENOMEM if memory cannot be allocated to store alias
* \return -EINVAL if passed alias is empty
*/
int spdk_bdev_alias_add(struct spdk_bdev *bdev, const char *alias);
/**
* Removes name from block device names list.
*
* \param bdev Block device to query.
* \param alias Alias to be deleted from list.
* \return 0 on success
* \return -ENOENT if alias does not exists
*/
int spdk_bdev_alias_del(struct spdk_bdev *bdev, const char *alias);
/**
* Allocate a buffer for given bdev_io. Allocation will happen
* only if the bdev_io has no assigned SGL yet. The buffer will be

View File

@ -237,12 +237,20 @@ spdk_bdev_next_leaf(struct spdk_bdev *prev)
struct spdk_bdev *
spdk_bdev_get_by_name(const char *bdev_name)
{
struct spdk_bdev_alias *tmp;
struct spdk_bdev *bdev = spdk_bdev_first();
while (bdev != NULL) {
if (strcmp(bdev_name, bdev->name) == 0) {
return bdev;
}
TAILQ_FOREACH(tmp, &bdev->aliases, tailq) {
if (strcmp(bdev_name, tmp->alias) == 0) {
return bdev;
}
}
bdev = spdk_bdev_next(bdev);
}
@ -942,6 +950,58 @@ spdk_bdev_channel_destroy(void *io_device, void *ctx_buf)
assert(ch->io_outstanding == 0);
}
int
spdk_bdev_alias_add(struct spdk_bdev *bdev, const char *alias)
{
struct spdk_bdev_alias *tmp;
if (alias == NULL) {
SPDK_ERRLOG("Empty alias passed\n");
return -EINVAL;
}
if (spdk_bdev_get_by_name(alias)) {
SPDK_ERRLOG("Bdev name/alias: %s already exists\n", alias);
return -EEXIST;
}
tmp = calloc(1, sizeof(*tmp));
if (tmp == NULL) {
SPDK_ERRLOG("Unable to allocate alias\n");
return -ENOMEM;
}
tmp->alias = strdup(alias);
if (tmp->alias == NULL) {
free(tmp);
SPDK_ERRLOG("Unable to allocate alias\n");
return -ENOMEM;
}
TAILQ_INSERT_TAIL(&bdev->aliases, tmp, tailq);
return 0;
}
int
spdk_bdev_alias_del(struct spdk_bdev *bdev, const char *alias)
{
struct spdk_bdev_alias *tmp;
TAILQ_FOREACH(tmp, &bdev->aliases, tailq) {
if (strcmp(alias, tmp->alias) == 0) {
TAILQ_REMOVE(&bdev->aliases, tmp, tailq);
free(tmp->alias);
free(tmp);
return 0;
}
}
SPDK_INFOLOG(SPDK_LOG_BDEV, "Alias %s does not exists\n", alias);
return -ENOENT;
}
struct spdk_io_channel *
spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
{
@ -1917,6 +1977,8 @@ _spdk_bdev_register(struct spdk_bdev *bdev)
TAILQ_INIT(&bdev->vbdevs);
TAILQ_INIT(&bdev->base_bdevs);
TAILQ_INIT(&bdev->aliases);
bdev->reset_in_progress = NULL;
spdk_io_device_register(bdev, spdk_bdev_channel_create, spdk_bdev_channel_destroy,

View File

@ -83,6 +83,7 @@ static struct spdk_bdev *
allocate_bdev(char *name)
{
struct spdk_bdev *bdev;
int rc;
bdev = calloc(1, sizeof(*bdev));
SPDK_CU_ASSERT_FATAL(bdev != NULL);
@ -91,7 +92,8 @@ allocate_bdev(char *name)
bdev->fn_table = &fn_table;
bdev->module = SPDK_GET_BDEV_MODULE(bdev_ut);
spdk_bdev_register(bdev);
rc = spdk_bdev_register(bdev);
CU_ASSERT(rc == 0);
CU_ASSERT(TAILQ_EMPTY(&bdev->base_bdevs));
CU_ASSERT(TAILQ_EMPTY(&bdev->vbdevs));
@ -103,6 +105,7 @@ allocate_vbdev(char *name, struct spdk_bdev *base1, struct spdk_bdev *base2)
{
struct spdk_bdev *bdev;
struct spdk_bdev *array[2];
int rc;
bdev = calloc(1, sizeof(*bdev));
SPDK_CU_ASSERT_FATAL(bdev != NULL);
@ -117,7 +120,8 @@ allocate_vbdev(char *name, struct spdk_bdev *base1, struct spdk_bdev *base2)
array[0] = base1;
array[1] = base2;
spdk_vbdev_register(bdev, array, base2 == NULL ? 1 : 2);
rc = spdk_vbdev_register(bdev, array, base2 == NULL ? 1 : 2);
CU_ASSERT(rc == 0);
CU_ASSERT(!TAILQ_EMPTY(&bdev->base_bdevs));
CU_ASSERT(TAILQ_EMPTY(&bdev->vbdevs));
@ -333,6 +337,7 @@ part_test(void)
struct spdk_bdev_part part1, part2;
struct spdk_bdev bdev_base = {};
SPDK_BDEV_PART_TAILQ tailq = TAILQ_HEAD_INITIALIZER(tailq);
int rc;
base = calloc(1, sizeof(*base));
SPDK_CU_ASSERT_FATAL(base != NULL);
@ -340,7 +345,8 @@ part_test(void)
bdev_base.name = "base";
bdev_base.fn_table = &base_fn_table;
bdev_base.module = SPDK_GET_BDEV_MODULE(bdev_ut);
spdk_bdev_register(&bdev_base);
rc = spdk_bdev_register(&bdev_base);
CU_ASSERT(rc == 0);
spdk_bdev_part_base_construct(base, &bdev_base, NULL, SPDK_GET_BDEV_MODULE(vbdev_ut),
&part_fn_table, &tailq, __base_free, 0, NULL, NULL);
@ -359,6 +365,73 @@ part_test(void)
spdk_bdev_unregister(&bdev_base, NULL, NULL);
}
static void
alias_add_del_test(void)
{
struct spdk_bdev *bdev[2];
int rc;
/* Creating and registering bdevs */
bdev[0] = allocate_bdev("bdev0");
SPDK_CU_ASSERT_FATAL(bdev[0] != 0);
bdev[1] = allocate_bdev("bdev1");
SPDK_CU_ASSERT_FATAL(bdev[1] != 0);
/*
* Trying adding an alias identical to name.
* Alias is identical to name, so it can not be added to aliases list
*/
rc = spdk_bdev_alias_add(bdev[0], bdev[0]->name);
CU_ASSERT(rc == -EEXIST);
/*
* Trying to add empty alias,
* this one should fail
*/
rc = spdk_bdev_alias_add(bdev[0], NULL);
CU_ASSERT(rc == -EINVAL);
/* Trying adding same alias to two different registered bdevs */
/* Alias is used first time, so this one should pass */
rc = spdk_bdev_alias_add(bdev[0], "proper alias 0");
CU_ASSERT(rc == 0);
/* Alias was added to another bdev, so this one should fail */
rc = spdk_bdev_alias_add(bdev[1], "proper alias 0");
CU_ASSERT(rc == -EEXIST);
/* Alias is used first time, so this one should pass */
rc = spdk_bdev_alias_add(bdev[1], "proper alias 1");
CU_ASSERT(rc == 0);
/* Trying removing an alias from registered bdevs */
/* Alias is not on a bdev aliases list, so this one should fail */
rc = spdk_bdev_alias_del(bdev[0], "not existing");
CU_ASSERT(rc == -ENOENT);
/* Alias is present on a bdev aliases list, so this one should pass */
rc = spdk_bdev_alias_del(bdev[0], "proper alias 0");
CU_ASSERT(rc == 0);
/* Alias is present on a bdev aliases list, so this one should pass */
rc = spdk_bdev_alias_del(bdev[1], "proper alias 1");
CU_ASSERT(rc == 0);
/* Trying to remove name instead of alias, so this one should fail, name cannot be changed or removed */
rc = spdk_bdev_alias_del(bdev[0], bdev[0]->name);
CU_ASSERT(rc != 0);
/* Unregister and free bdevs */
spdk_bdev_unregister(bdev[0], NULL, NULL);
spdk_bdev_unregister(bdev[1], NULL, NULL);
free(bdev[0]);
free(bdev[1]);
}
int
main(int argc, char **argv)
{
@ -379,7 +452,8 @@ main(int argc, char **argv)
CU_add_test(suite, "bytes_to_blocks_test", bytes_to_blocks_test) == NULL ||
CU_add_test(suite, "io_valid", io_valid_test) == NULL ||
CU_add_test(suite, "open_write", open_write_test) == NULL ||
CU_add_test(suite, "part", part_test) == NULL
CU_add_test(suite, "part", part_test) == NULL ||
CU_add_test(suite, "alias_add_del", alias_add_del_test) == NULL
) {
CU_cleanup_registry();
return CU_get_error();