From f5e590c8f24988fd3bdfff96da37948083b695d8 Mon Sep 17 00:00:00 2001 From: Sebastian Basierski Date: Wed, 10 Jan 2018 11:03:39 +0100 Subject: [PATCH] bdev: Added functions allowing logical volume store rename. Change-Id: Ief1f809308fbde2e696c60d3ce79c0720cb3e2ff Signed-off-by: Sebastian Basierski Reviewed-on: https://review.gerrithub.io/398934 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp Reviewed-by: Tomasz Zawadzki --- include/spdk/lvol.h | 11 +++ include/spdk_internal/lvolstore.h | 3 + lib/bdev/lvol/vbdev_lvol.c | 47 +++++++++ lib/bdev/lvol/vbdev_lvol.h | 11 +++ lib/bdev/lvol/vbdev_lvol_rpc.c | 76 +++++++++++++++ lib/lvol/lvol.c | 96 ++++++++++++++++++ scripts/rpc.py | 5 + scripts/rpc/lvol.py | 8 ++ .../lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c | 77 ++++++++++++++- test/unit/lib/lvol/lvol.c/lvol_ut.c | 97 +++++++++++++++++-- 10 files changed, 424 insertions(+), 7 deletions(-) diff --git a/include/spdk/lvol.h b/include/spdk/lvol.h index 991d63e6e..ee6c3d96d 100644 --- a/include/spdk/lvol.h +++ b/include/spdk/lvol.h @@ -113,6 +113,17 @@ typedef void (*spdk_lvol_op_complete)(void *cb_arg, int lvolerrno); 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); +/** + * \brief Renames given lvolstore. + * + * \param lvs Pointer to lvolstore + * \param new_name New name of lvs + * \param cb_fn Completion callback + * \param cb_arg Completion callback custom arguments + */ +void spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name, + spdk_lvs_op_complete cb_fn, void *cb_arg); + /** * \brief Unloads lvolstore * diff --git a/include/spdk_internal/lvolstore.h b/include/spdk_internal/lvolstore.h index 3292d5e2a..4642b30df 100644 --- a/include/spdk_internal/lvolstore.h +++ b/include/spdk_internal/lvolstore.h @@ -45,6 +45,8 @@ struct spdk_lvs_req { spdk_lvs_op_complete cb_fn; void *cb_arg; + struct spdk_lvol_store *lvol_store; + int lvserrno; }; struct spdk_lvol_req { @@ -89,6 +91,7 @@ struct spdk_lvol_store { bool on_list; TAILQ_ENTRY(spdk_lvol_store) link; char name[SPDK_LVS_NAME_MAX]; + char new_name[SPDK_LVS_NAME_MAX]; }; struct spdk_lvol { diff --git a/lib/bdev/lvol/vbdev_lvol.c b/lib/bdev/lvol/vbdev_lvol.c index 435dbeb27..bf8f48aac 100644 --- a/lib/bdev/lvol/vbdev_lvol.c +++ b/lib/bdev/lvol/vbdev_lvol.c @@ -252,6 +252,53 @@ vbdev_lvs_create(struct spdk_bdev *base_bdev, const char *name, uint32_t cluster return 0; } +static void +_vbdev_lvs_rename_cb(void *cb_arg, int lvserrno) +{ + struct spdk_lvs_req *req = cb_arg; + struct spdk_lvol *tmp; + + if (lvserrno != 0) { + SPDK_INFOLOG(SPDK_LOG_VBDEV_LVOL, "Lvol store rename failed\n"); + } else { + TAILQ_FOREACH(tmp, &req->lvol_store->lvols, link) { + /* We have to pass current lvol name, since only lvs name changed */ + _vbdev_lvol_change_bdev_alias(tmp, tmp->name); + } + } + + req->cb_fn(req->cb_arg, lvserrno); + free(req); +} + +void +vbdev_lvs_rename(struct spdk_lvol_store *lvs, const char *new_lvs_name, + spdk_lvs_op_complete cb_fn, void *cb_arg) +{ + struct lvol_store_bdev *lvs_bdev; + + struct spdk_lvs_req *req; + + lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); + if (!lvs_bdev) { + SPDK_ERRLOG("No such lvol store found\n"); + cb_fn(cb_arg, -ENODEV); + return; + } + + req = calloc(1, sizeof(*req)); + if (!req) { + SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n"); + cb_fn(cb_arg, -ENOMEM); + return; + } + req->cb_fn = cb_fn; + req->cb_arg = cb_arg; + req->lvol_store = lvs; + + spdk_lvs_rename(lvs, new_lvs_name, _vbdev_lvs_rename_cb, req); +} + static void _vbdev_lvs_remove_cb(void *cb_arg, int lvserrno) { diff --git a/lib/bdev/lvol/vbdev_lvol.h b/lib/bdev/lvol/vbdev_lvol.h index c86d13dcc..93fd7cb1c 100644 --- a/lib/bdev/lvol/vbdev_lvol.h +++ b/lib/bdev/lvol/vbdev_lvol.h @@ -60,6 +60,17 @@ int vbdev_lvol_resize(char *name, size_t sz, spdk_lvol_op_complete cb_fn, void * void vbdev_lvol_rename(struct spdk_lvol *lvol, const char *new_lvol_name, spdk_lvol_op_complete cb_fn, void *cb_arg); +/** + * \brief Renames given lvolstore. + * + * \param lvs Pointer to lvolstore + * \param new_name New name of lvs + * \param cb_fn Completion callback + * \param cb_arg Completion callback custom arguments + */ +void vbdev_lvs_rename(struct spdk_lvol_store *lvs, const char *new_lvs_name, + spdk_lvs_op_complete cb_fn, void *cb_arg); + /** * \brief Search for handle lvolstore * \param uuid_str UUID of lvolstore diff --git a/lib/bdev/lvol/vbdev_lvol_rpc.c b/lib/bdev/lvol/vbdev_lvol_rpc.c index 9f6866ae2..fba323a18 100644 --- a/lib/bdev/lvol/vbdev_lvol_rpc.c +++ b/lib/bdev/lvol/vbdev_lvol_rpc.c @@ -168,6 +168,82 @@ invalid: } SPDK_RPC_REGISTER("construct_lvol_store", spdk_rpc_construct_lvol_store) +struct rpc_rename_lvol_store { + char *old_name; + char *new_name; +}; + +static void +free_rpc_rename_lvol_store(struct rpc_rename_lvol_store *req) +{ + free(req->old_name); + free(req->new_name); +} + +static const struct spdk_json_object_decoder rpc_rename_lvol_store_decoders[] = { + {"old_name", offsetof(struct rpc_rename_lvol_store, old_name), spdk_json_decode_string}, + {"new_name", offsetof(struct rpc_rename_lvol_store, new_name), spdk_json_decode_string}, +}; + +static void +_spdk_rpc_rename_lvol_store_cb(void *cb_arg, int lvserrno) +{ + struct spdk_json_write_ctx *w; + struct spdk_jsonrpc_request *request = cb_arg; + + if (lvserrno != 0) { + goto invalid; + } + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + return; + +invalid: + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + spdk_strerror(-lvserrno)); +} + +static void +spdk_rpc_rename_lvol_store(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_rename_lvol_store req = {}; + struct spdk_lvol_store *lvs; + int rc; + + if (spdk_json_decode_object(params, rpc_rename_lvol_store_decoders, + SPDK_COUNTOF(rpc_rename_lvol_store_decoders), + &req)) { + SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); + rc = -EINVAL; + goto invalid; + } + + lvs = vbdev_get_lvol_store_by_name(req.old_name); + if (lvs == NULL) { + SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "no lvs existing for given name\n"); + rc = -ENOENT; + goto invalid; + } + + vbdev_lvs_rename(lvs, req.new_name, _spdk_rpc_rename_lvol_store_cb, request); + + free_rpc_rename_lvol_store(&req); + + return; + +invalid: + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc)); + free_rpc_rename_lvol_store(&req); +} +SPDK_RPC_REGISTER("rename_lvol_store", spdk_rpc_rename_lvol_store) + struct rpc_destroy_lvol_store { char *uuid; char *lvs_name; diff --git a/lib/lvol/lvol.c b/lib/lvol/lvol.c index a2235d851..6442b5a2c 100644 --- a/lib/lvol/lvol.c +++ b/lib/lvol/lvol.c @@ -622,6 +622,102 @@ spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o, return 0; } +static void +_spdk_lvs_rename_cb(void *cb_arg, int lvolerrno) +{ + struct spdk_lvs_req *req = cb_arg; + + if (lvolerrno != 0) { + req->lvserrno = lvolerrno; + } + if (req->lvserrno != 0) { + SPDK_ERRLOG("Lvol store rename operation failed\n"); + /* Lvs renaming failed, so we should 'clear' new_name. + * Otherwise it could cause a failure on the next attepmt to change the name to 'new_name' */ + strncpy(req->lvol_store->new_name, req->lvol_store->name, SPDK_LVS_NAME_MAX); + } else { + /* Update lvs name with new_name */ + strncpy(req->lvol_store->name, req->lvol_store->new_name, SPDK_LVS_NAME_MAX); + } + + req->cb_fn(req->cb_arg, req->lvserrno); + free(req); +} + +static void +_spdk_lvs_rename_sync_cb(void *cb_arg, int lvolerrno) +{ + struct spdk_lvs_req *req = cb_arg; + struct spdk_blob *blob = req->lvol_store->super_blob; + + if (lvolerrno < 0) { + req->lvserrno = lvolerrno; + } + + spdk_blob_close(blob, _spdk_lvs_rename_cb, req); +} + +static void +_spdk_lvs_rename_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) +{ + struct spdk_lvs_req *req = cb_arg; + int rc; + + if (lvolerrno < 0) { + _spdk_lvs_rename_cb(cb_arg, lvolerrno); + return; + } + + rc = spdk_blob_set_xattr(blob, "name", req->lvol_store->new_name, + strlen(req->lvol_store->new_name) + 1); + if (rc < 0) { + req->lvserrno = rc; + _spdk_lvs_rename_sync_cb(req, rc); + return; + } + + req->lvol_store->super_blob = blob; + + spdk_blob_sync_md(blob, _spdk_lvs_rename_sync_cb, req); +} + +void +spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name, + spdk_lvs_op_complete cb_fn, void *cb_arg) +{ + struct spdk_lvs_req *req; + struct spdk_lvol_store *tmp; + + /* Check if new name is current lvs name. + * If so, return success immediately */ + if (strncmp(lvs->name, new_name, SPDK_LVS_NAME_MAX) == 0) { + cb_fn(cb_arg, 0); + return; + } + + /* Check if new or new_name is already used in other lvs */ + TAILQ_FOREACH(tmp, &g_lvol_stores, link) { + if (!strncmp(new_name, tmp->name, SPDK_LVS_NAME_MAX) || + !strncmp(new_name, tmp->new_name, SPDK_LVS_NAME_MAX)) { + cb_fn(cb_arg, -EEXIST); + return; + } + } + + req = calloc(1, sizeof(*req)); + if (!req) { + SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); + cb_fn(cb_arg, -ENOMEM); + return; + } + strncpy(lvs->new_name, new_name, SPDK_LVS_NAME_MAX); + req->lvol_store = lvs; + req->cb_fn = cb_fn; + req->cb_arg = cb_arg; + + spdk_bs_open_blob(lvs->blobstore, lvs->super_blob_id, _spdk_lvs_rename_open_cb, req); +} + static void _lvs_unload_cb(void *cb_arg, int lvserrno) { diff --git a/scripts/rpc.py b/scripts/rpc.py index 829ac9bfe..597ec50bd 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -275,6 +275,11 @@ if __name__ == "__main__": p.add_argument('-c', '--cluster-sz', help='size of cluster (in bytes)', type=int, required=False) p.set_defaults(func=rpc.lvol.construct_lvol_store) + p = subparsers.add_parser('rename_lvol_store', help='Change logical volume store name') + p.add_argument('old_name', help='old name') + p.add_argument('new_name', help='new name') + p.set_defaults(func=rpc.lvol.rename_lvol_store) + p = subparsers.add_parser('construct_lvol_bdev', help='Add a bdev with an logical volume backend') p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) p.add_argument('-l', '--lvs_name', help='lvol store name', required=False) diff --git a/scripts/rpc/lvol.py b/scripts/rpc/lvol.py index 801caeb29..9ee0fe81b 100755 --- a/scripts/rpc/lvol.py +++ b/scripts/rpc/lvol.py @@ -8,6 +8,14 @@ def construct_lvol_store(args): print_array(args.client.call('construct_lvol_store', params)) +def rename_lvol_store(args): + params = { + 'old_name': args.old_name, + 'new_name': args.new_name + } + args.client.call('rename_lvol_store', params) + + def construct_lvol_bdev(args): num_bytes = (args.size * 1024 * 1024) params = {'lvol_name': args.lvol_name, 'size': num_bytes} diff --git a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c index 432b6875f..ef37ad8d6 100644 --- a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c +++ b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c @@ -59,6 +59,7 @@ bool lvol_store_initialize_cb_fail = false; bool lvol_already_opened = false; bool g_examine_done = false; bool g_bdev_alias_already_exists = false; +bool g_lvs_with_name_already_exists = false; int spdk_bdev_alias_add(struct spdk_bdev *bdev, const char *alias) @@ -107,6 +108,20 @@ spdk_bdev_unregister_done(struct spdk_bdev *bdev, int bdeverrno) { } +void +spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name, + spdk_lvs_op_complete cb_fn, void *cb_arg) +{ + if (g_lvs_with_name_already_exists) { + g_lvolerrno = -EEXIST; + } else { + strncpy(lvs->name, new_name, SPDK_LVS_NAME_MAX); + g_lvolerrno = 0; + } + + cb_fn(cb_arg, g_lvolerrno); +} + void spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name, spdk_lvol_op_complete cb_fn, void *cb_arg) @@ -248,6 +263,8 @@ spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o, lvs = calloc(1, sizeof(*lvs)); SPDK_CU_ASSERT_FATAL(lvs != NULL); TAILQ_INIT(&lvs->lvols); + uuid_generate_time(lvs->uuid); + strncpy(lvs->name, o->name, SPDK_LVS_NAME_MAX); lvs->bs_dev = bs_dev; error = 0; } @@ -1137,6 +1154,63 @@ ut_vbdev_lvol_submit_request(void) free(g_base_bdev); } +static void +ut_lvs_rename(void) +{ + int rc = 0; + int sz = 10; + struct spdk_lvol_store *lvs; + struct spdk_bs_dev *b_bdev; + + /* Lvol store is succesfully created */ + rc = vbdev_lvs_create(&g_bdev, "old_lvs_name", 0, lvol_store_op_with_handle_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); + CU_ASSERT(g_bs_dev != NULL); + b_bdev = g_bs_dev; + + g_bs_dev = NULL; + lvs = g_lvol_store; + g_lvol_store = NULL; + + g_base_bdev = calloc(1, sizeof(*g_base_bdev)); + SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); + + /* Successfully create lvol, which should be destroyed with lvs later */ + g_lvolerrno = -1; + rc = vbdev_lvol_create(lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvolerrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol != NULL); + + /* Trying to rename lvs with lvols created */ + vbdev_lvs_rename(lvs, "new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == 0); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + CU_ASSERT_STRING_EQUAL(TAILQ_FIRST(&g_lvol->bdev->aliases)->alias, "new_lvs_name/lvol"); + + /* Trying to rename lvs with name already used by another lvs */ + /* This is a bdev_lvol test, so g_lvs_with_name_already_exists simulates + * existing lvs with name 'another_new_lvs_name' and this name in fact is not compared */ + g_lvs_with_name_already_exists = true; + vbdev_lvs_rename(lvs, "another_new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == -EEXIST); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + CU_ASSERT_STRING_EQUAL(TAILQ_FIRST(&g_lvol->bdev->aliases)->alias, "new_lvs_name/lvol"); + g_lvs_with_name_already_exists = false; + + /* Unload lvol store */ + g_lvol_store = lvs; + g_bs_dev = b_bdev; + vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == 0); + CU_ASSERT(g_lvol_store == NULL); + + free(g_base_bdev->name); + free(g_base_bdev); +} + int main(int argc, char **argv) { CU_pSuite suite = NULL; @@ -1165,7 +1239,8 @@ int main(int argc, char **argv) CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL || CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL || CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL || - CU_add_test(suite, "ut_lvol_rename", ut_lvol_rename) == NULL + CU_add_test(suite, "ut_lvol_rename", ut_lvol_rename) == NULL || + CU_add_test(suite, "ut_lvs_rename", ut_lvs_rename) == NULL ) { CU_cleanup_registry(); return CU_get_error(); diff --git a/test/unit/lib/lvol/lvol.c/lvol_ut.c b/test/unit/lib/lvol/lvol.c/lvol_ut.c index 0b5d1e346..617a924f1 100644 --- a/test/unit/lib/lvol/lvol.c/lvol_ut.c +++ b/test/unit/lib/lvol/lvol.c/lvol_ut.c @@ -72,6 +72,7 @@ int g_lvolerrno; int g_lvserrno; int g_close_super_status; int g_resize_rc; +bool g_lvs_rename_blob_open_error = false; struct spdk_lvol_store *g_lvol_store; struct spdk_lvol *g_lvol; spdk_blob_id g_blobid = 1; @@ -343,11 +344,13 @@ spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, { struct spdk_blob *blob; - TAILQ_FOREACH(blob, &bs->blobs, link) { - if (blob->id == blobid) { - blob->ref++; - cb_fn(cb_arg, blob, blob->open_status); - return; + if (!g_lvs_rename_blob_open_error) { + TAILQ_FOREACH(blob, &bs->blobs, link) { + if (blob->id == blobid) { + blob->ref++; + cb_fn(cb_arg, blob, blob->open_status); + return; + } } } @@ -1433,6 +1436,87 @@ lvol_rename(void) spdk_free_thread(); } +static void +lvs_rename(void) +{ + struct lvol_ut_bs_dev dev; + struct spdk_lvs_opts opts; + struct spdk_lvol_store *lvs, *lvs2; + int rc = 0; + + init_dev(&dev); + + spdk_allocate_thread(_lvol_send_msg, NULL, NULL, NULL, NULL); + + spdk_lvs_opts_init(&opts); + strncpy(opts.name, "lvs", SPDK_LVS_NAME_MAX); + g_lvserrno = -1; + g_lvol_store = NULL; + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); + lvs = g_lvol_store; + + spdk_lvs_opts_init(&opts); + strncpy(opts.name, "unimportant_lvs_name", SPDK_LVS_NAME_MAX); + g_lvserrno = -1; + g_lvol_store = NULL; + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); + lvs2 = g_lvol_store; + + /* Trying to rename lvs with new name */ + spdk_lvs_rename(lvs, "new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == 0); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + + /* Trying to rename lvs with name lvs already has */ + spdk_lvs_rename(lvs, "new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == 0); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + + /* Trying to rename lvs with name already existing */ + spdk_lvs_rename(lvs2, "new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == -EEXIST); + CU_ASSERT_STRING_EQUAL(lvs2->name, "unimportant_lvs_name"); + + /* Trying to rename lvs with another rename process started with the same name */ + /* Simulate renaming process in progress */ + strncpy(lvs2->new_name, "another_new_lvs_name", SPDK_LVS_NAME_MAX); + CU_ASSERT_STRING_EQUAL(lvs2->new_name, "another_new_lvs_name"); + /* Start second process */ + spdk_lvs_rename(lvs, "another_new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno == -EEXIST); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + /* reverting lvs2 new name to proper value */ + strncpy(lvs2->new_name, "unimportant_lvs_name", SPDK_LVS_NAME_MAX); + CU_ASSERT_STRING_EQUAL(lvs2->new_name, "unimportant_lvs_name"); + + /* Simulate error while lvs rename */ + g_lvs_rename_blob_open_error = true; + spdk_lvs_rename(lvs, "complete_new_lvs_name", lvol_store_op_complete, NULL); + CU_ASSERT(g_lvserrno != 0); + CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); + CU_ASSERT_STRING_EQUAL(lvs->new_name, "new_lvs_name"); + g_lvs_rename_blob_open_error = false; + + g_lvserrno = -1; + rc = spdk_lvs_destroy(lvs, lvol_store_op_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + g_lvol_store = NULL; + + g_lvserrno = -1; + rc = spdk_lvs_destroy(lvs2, lvol_store_op_complete, NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_lvserrno == 0); + g_lvol_store = NULL; + + spdk_free_thread(); +} static void lvol_refcnt(void) { struct lvol_ut_bs_dev dev; @@ -1582,7 +1666,8 @@ int main(int argc, char **argv) CU_add_test(suite, "lvol_refcnt", lvol_refcnt) == NULL || CU_add_test(suite, "lvol_names", lvol_names) == NULL || CU_add_test(suite, "lvol_create_thin_provisioned", lvol_create_thin_provisioned) == NULL || - CU_add_test(suite, "lvol_rename", lvol_rename) == NULL + CU_add_test(suite, "lvol_rename", lvol_rename) == NULL || + CU_add_test(suite, "lvs_rename", lvs_rename) == NULL ) { CU_cleanup_registry(); return CU_get_error();