From 42fe2e9b244cfd754e25465fa9a78916a9814a75 Mon Sep 17 00:00:00 2001 From: Mateusz Kozlowski Date: Wed, 29 May 2019 11:21:02 +0200 Subject: [PATCH] lib/ftl: Add config to construct_ftl rpc for dirty shutdown restore Gives the ability to change behavior of restore after dirty shutdown without recompiling ftl library. User can define if partial recovery or error should be returned after such a scenario. Signed-off-by: Mateusz Kozlowski Change-Id: I6dda40df7b92d6a377957e4a70a3eab91a6ac4a9 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/456185 Tested-by: SPDK CI Jenkins Reviewed-by: Darek Stojaczyk Reviewed-by: Ben Walker Reviewed-by: Konrad Sztyber --- include/spdk/ftl.h | 2 ++ lib/bdev/nvme/bdev_ftl.c | 9 ++++++++- lib/bdev/nvme/bdev_ftl.h | 2 ++ lib/bdev/nvme/bdev_ftl_rpc.c | 6 ++++++ lib/ftl/ftl_core.c | 1 + scripts/rpc.py | 5 ++++- scripts/rpc/bdev.py | 6 ++++-- 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/spdk/ftl.h b/include/spdk/ftl.h index ff9b1cf3d..a4a5ab6ee 100644 --- a/include/spdk/ftl.h +++ b/include/spdk/ftl.h @@ -141,6 +141,8 @@ struct spdk_ftl_attrs { size_t lbk_size; /* Write buffer cache */ struct spdk_bdev_desc *cache_bdev_desc; + /* Allow partial recovery after dirty shutdown */ + bool allow_open_bands; }; struct ftl_module_init_opts { diff --git a/lib/bdev/nvme/bdev_ftl.c b/lib/bdev/nvme/bdev_ftl.c index 32657320d..396c83da1 100644 --- a/lib/bdev/nvme/bdev_ftl.c +++ b/lib/bdev/nvme/bdev_ftl.c @@ -436,6 +436,8 @@ bdev_ftl_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w spdk_json_write_named_string(w, "cache", cache_bdev); } + spdk_json_write_named_bool(w, "allow_open_bands", attrs.allow_open_bands); + spdk_json_write_object_end(w); spdk_json_write_object_end(w); } @@ -749,8 +751,13 @@ bdev_ftl_create(struct spdk_nvme_ctrlr *ctrlr, const struct ftl_bdev_init_opts * struct spdk_bdev *cache_bdev = NULL; struct nvme_bdev_ctrlr *ftl_ctrlr; struct spdk_ftl_dev_init_opts opts = {}; + struct spdk_ftl_conf conf = {}; int rc; + spdk_ftl_conf_init_defaults(&conf); + + conf.allow_open_bands = bdev_opts->allow_open_bands; + ftl_ctrlr = bdev_ftl_add_ctrlr(ctrlr, &bdev_opts->trid); if (!ftl_ctrlr) { spdk_nvme_detach(ctrlr); @@ -804,7 +811,7 @@ bdev_ftl_create(struct spdk_nvme_ctrlr *ctrlr, const struct ftl_bdev_init_opts * opts.uuid = bdev_opts->uuid; opts.name = ftl_bdev->bdev.name; opts.cache_bdev_desc = ftl_bdev->cache_bdev_desc; - opts.conf = NULL; + opts.conf = &conf; /* TODO: set threads based on config */ opts.core_thread = opts.read_thread = spdk_get_thread(); diff --git a/lib/bdev/nvme/bdev_ftl.h b/lib/bdev/nvme/bdev_ftl.h index ad5d91584..cea59cec3 100644 --- a/lib/bdev/nvme/bdev_ftl.h +++ b/lib/bdev/nvme/bdev_ftl.h @@ -64,6 +64,8 @@ struct ftl_bdev_init_opts { uint32_t mode; /* UUID if device is restored from SSD */ struct spdk_uuid uuid; + /* Allow for partial restore after dirty shutdown */ + bool allow_open_bands; }; typedef void (*ftl_bdev_init_fn)(const struct ftl_bdev_info *, void *, int); diff --git a/lib/bdev/nvme/bdev_ftl_rpc.c b/lib/bdev/nvme/bdev_ftl_rpc.c index f4b732674..f9821e696 100644 --- a/lib/bdev/nvme/bdev_ftl_rpc.c +++ b/lib/bdev/nvme/bdev_ftl_rpc.c @@ -46,6 +46,7 @@ struct rpc_construct_ftl { char *punits; char *uuid; char *cache_bdev; + bool allow_open_bands; }; static void @@ -66,6 +67,10 @@ static const struct spdk_json_object_decoder rpc_construct_ftl_decoders[] = { {"punits", offsetof(struct rpc_construct_ftl, punits), spdk_json_decode_string}, {"uuid", offsetof(struct rpc_construct_ftl, uuid), spdk_json_decode_string, true}, {"cache", offsetof(struct rpc_construct_ftl, cache_bdev), spdk_json_decode_string, true}, + { + "allow_open_bands", offsetof(struct rpc_construct_ftl, allow_open_bands), + spdk_json_decode_bool, true + }, }; #define FTL_RANGE_MAX_LENGTH 32 @@ -123,6 +128,7 @@ spdk_rpc_construct_ftl_bdev(struct spdk_jsonrpc_request *request, opts.name = req.name; opts.mode = SPDK_FTL_MODE_CREATE; opts.cache_bdev = req.cache_bdev; + opts.allow_open_bands = req.allow_open_bands; /* Parse trtype */ rc = spdk_nvme_transport_id_parse_trtype(&opts.trid.trtype, req.trtype); diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index 921cc7c90..aba090a9c 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -1643,6 +1643,7 @@ spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *at attrs->lbk_size = FTL_BLOCK_SIZE; attrs->range = dev->range; attrs->cache_bdev_desc = dev->nv_cache.bdev_desc; + attrs->allow_open_bands = dev->conf.allow_open_bands; } static void diff --git a/scripts/rpc.py b/scripts/rpc.py index 676b2a848..e52eb81ae 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -1298,7 +1298,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse traddr=args.traddr, punits=args.punits, uuid=args.uuid, - cache=args.cache)) + cache=args.cache, + allow_open_bands=args.allow_open_bands)) p = subparsers.add_parser('construct_ftl_bdev', help='Add FTL bdev') @@ -1312,6 +1313,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p.add_argument('-u', '--uuid', help='UUID of restored bdev (not applicable when creating new ' 'instance): e.g. b286d19a-0059-4709-abcd-9f7732b1567d (optional)') p.add_argument('-c', '--cache', help='Name of the bdev to be used as a write buffer cache (optional)') + p.add_argument('-o', '--allow_open_bands', help='Restoring after dirty shutdown without cache will' + ' result in partial data recovery, instead of error', action='store_true') p.set_defaults(func=construct_ftl_bdev) def delete_ftl_bdev(args): diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index 7b95a6211..d75ca9d79 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -586,7 +586,7 @@ def destruct_split_vbdev(client, base_bdev): return client.call('destruct_split_vbdev', params) -def construct_ftl_bdev(client, name, trtype, traddr, punits, uuid=None, cache=None): +def construct_ftl_bdev(client, name, trtype, traddr, punits, allow_open_bands, uuid=None, cache=None): """Construct FTL bdev Args: @@ -596,11 +596,13 @@ def construct_ftl_bdev(client, name, trtype, traddr, punits, uuid=None, cache=No punit: parallel unit range uuid: UUID of the device cache: name of the write buffer bdev + allow_open_bands: allow for partial restore after dirty shutdown """ params = {'name': name, 'trtype': trtype, 'traddr': traddr, - 'punits': punits} + 'punits': punits, + 'allow_open_bands': allow_open_bands} if uuid: params['uuid'] = uuid if cache: