From 68b68db9c0ca1823754409b74e8287147c106d7d Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Thu, 21 Jan 2021 14:31:00 -0600 Subject: [PATCH 1/3] Zero metadata if on-disk version differs from current Kernel adapter now returns is_cache_device=1 and newly added metadata_compatible=0 in case of metadata detected with differing version (instead of is_cache_device = 0). This allows zero-superblock command to recognize old cache instance and clear it. casadm --script --check-cache-device still returns 'Is cache'='no' in this case, as this layer only cares about metadata in current version to be able to detect dirty datas tatus. Signed-off-by: Adam Rutkowski --- casadm/cas_lib.c | 2 +- modules/cas_cache/layer_cache_management.c | 8 +++++++- modules/include/cas_ioctl_codes.h | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/casadm/cas_lib.c b/casadm/cas_lib.c index 57f7ea3..88867f4 100644 --- a/casadm/cas_lib.c +++ b/casadm/cas_lib.c @@ -2894,7 +2894,7 @@ int check_cache_device(const char *device_path) fprintf(intermediate_file[1], TAG(TABLE_HEADER) "Is cache,Clean Shutdown,Cache dirty\n"); fprintf(intermediate_file[1], TAG(TABLE_ROW)); - if (cmd_info.is_cache_device) { + if (cmd_info.is_cache_device && cmd_info.metadata_compatible) { fprintf(intermediate_file[1], "yes,%s,%s\n", cmd_info.clean_shutdown ? "yes" : "no", cmd_info.cache_dirty ? "yes" : "no"); diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index cde4ad3..b6e4097 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -1012,11 +1012,17 @@ static void cache_mngt_metadata_probe_end(void *priv, int error, *context->result = error; - if (error == -OCF_ERR_NO_METADATA || error == -OCF_ERR_METADATA_VER) { + if (error == -OCF_ERR_NO_METADATA) { cmd_info->is_cache_device = false; + cmd_info->metadata_compatible = false; + *context->result = 0; + } else if (error == -OCF_ERR_METADATA_VER) { + cmd_info->is_cache_device = true; + cmd_info->metadata_compatible = false; *context->result = 0; } else if (error == 0) { cmd_info->is_cache_device = true; + cmd_info->metadata_compatible = true; cmd_info->clean_shutdown = status->clean_shutdown; cmd_info->cache_dirty = status->cache_dirty; } diff --git a/modules/include/cas_ioctl_codes.h b/modules/include/cas_ioctl_codes.h index 923aecb..ad772ff 100644 --- a/modules/include/cas_ioctl_codes.h +++ b/modules/include/cas_ioctl_codes.h @@ -314,7 +314,12 @@ struct kcas_core_pool_remove { struct kcas_cache_check_device { char path_name[MAX_STR_LEN]; /**< path to a device */ - bool is_cache_device; + bool is_cache_device; /* OCF metadata detected */ + + /* following bool flags are defined is_cache_device == 1 */ + bool metadata_compatible; /* OCF metadata is in current version */ + + /* following bool flags are defined iff is_metadata_compatible == 1 */ bool clean_shutdown; bool cache_dirty; bool format_atomic; From 4c98949cacc98e55b83ac9df0f4f9a03d8ad26cd Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Thu, 21 Jan 2021 15:30:26 -0600 Subject: [PATCH 2/3] Add force option to zero-metadata Force option is used to enforce metadata erasure despite dirty data, metadata mistmatch and/or dirty shutdown. Signed-off-by: Adam Rutkowski --- casadm/cas_lib.c | 34 +++++++++++++++++++++++++++++++++- casadm/cas_lib.h | 4 +++- casadm/cas_main.c | 10 +++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/casadm/cas_lib.c b/casadm/cas_lib.c index 88867f4..b2119a7 100644 --- a/casadm/cas_lib.c +++ b/casadm/cas_lib.c @@ -2909,7 +2909,8 @@ int check_cache_device(const char *device_path) return SUCCESS; } -int zero_md(const char *cache_device){ +int zero_md(const char *cache_device, bool force) +{ struct kcas_cache_check_device cmd_info = {}; char zero_page[4096] = {0}; int fd = 0; @@ -2937,6 +2938,37 @@ int zero_md(const char *cache_device){ return FAILURE; } + if (!cmd_info.metadata_compatible) { + if (!force) { + cas_printf(LOG_ERR, "Unable to determine whether cache contains dirty data due to metadata mismatch.\n" + "Clearing metadata might result in loss of dirty data. In order to inspect cache content\n" + "please load cache instance using matching OpenCAS version. Alternatively, if you wish to clear\n" + "metadata anyway, please use '--force' option.\n"); + return FAILURE; + } else { + cas_printf(LOG_WARNING, "Clearing metadata with unknown version - potential loss of dirty data.\n"); + } + } else if (!cmd_info.clean_shutdown) { + if (!force) { + cas_printf(LOG_ERR, "Cache instance did not shut down cleanly. It might contain dirty data. \n" + "Clearing metadata might result in loss of dirty data. Please recover cache instance\n" + "by loading it and flush dirty data in order to preserve then on the core device.\n" + "Alternatively, if you wish to clear metadata anyway, please use '--force' option. \n"); + return FAILURE; + } else { + cas_printf(LOG_WARNING, "Clearing metadata after dirty shutdown - potential loss of dirty data.\n"); + } + } else if (cmd_info.cache_dirty) { + if (!force) { + cas_printf(LOG_ERR, "Cache instance contains dirty data. Clearing metadata will result in loss of dirty data.\n" + "Please load cache instance and flush dirty data in order to preserve them on the core device.\n" + "Alternatively, if you wish to clear metadata anyway, please use '--force' option. \n"); + return FAILURE; + } else { + cas_printf(LOG_WARNING, "Clearing metadata for dirty pages - dirty cache data is being discarded. \n"); + } + } + fd = open(cache_device, O_WRONLY | O_SYNC | O_EXCL); if (fd < 0) { cas_printf(LOG_ERR, "Error while opening '%s'exclusively. This can be due to\n" diff --git a/casadm/cas_lib.h b/casadm/cas_lib.h index 19161e9..5bf3d34 100644 --- a/casadm/cas_lib.h +++ b/casadm/cas_lib.h @@ -266,9 +266,11 @@ int validate_str_metadata_mode(const char* s); * @brief clear metadata * * @param[in] cache_device device to which zeroing cache's metadata applies + * @param[in] force enforce metadata erasure despite dirty data, metadata + * mistmatch and/or dirty shutdown * @return 0 if succeed, 1 if failed */ -int zero_md(const char *cache_device); +int zero_md(const char *cache_device, bool force); /** * @brief calculate flush progress diff --git a/casadm/cas_main.c b/casadm/cas_main.c index e30e7e7..61f5cc2 100644 --- a/casadm/cas_main.c +++ b/casadm/cas_main.c @@ -1832,12 +1832,15 @@ static int handle_help(); struct { const char *device; + bool force; } static zero_params = { - .device = "" + .device = "", + .force = false }; static cli_option zero_options[] = { {'d', "device", "Path to device on which metadata would be cleared", 1, "DEVICE", CLI_OPTION_REQUIRED}, + {'f', "force", "Ignore potential dirty data on cache device"}, {0} }; @@ -1848,7 +1851,8 @@ int zero_handle_option(char *opt, const char **arg) if(validate_device_name(arg[0]) == FAILURE) return FAILURE; zero_params.device = arg[0]; - + } else if (!strcmp(opt, "force")){ + zero_params.force = 1; } else { return FAILURE; } @@ -1872,7 +1876,7 @@ int handle_zero() return FAILURE; } - return zero_md(zero_params.device); + return zero_md(zero_params.device, zero_params.force); } static cli_command cas_commands[] = { From b0ba347ee7aae392ce4e0098a4d97e36b7915cd9 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Thu, 21 Jan 2021 15:56:04 -0600 Subject: [PATCH 3/3] man entry for --zero-metadata command Signed-off-by: Adam Rutkowski --- utils/casadm.8 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utils/casadm.8 b/utils/casadm.8 index 2bb4ff1..555649a 100644 --- a/utils/casadm.8 +++ b/utils/casadm.8 @@ -154,6 +154,10 @@ Atomic mode exploits extended NVMe metadata features. In this mode namespace uses 520 bytes LBA allowing to write cache data and metadata in a single request (atomically). +.TP +.B --zero-metadata +Remove metadata from previously used cache device. + .TP .B -H, --help Print help. @@ -586,6 +590,15 @@ Identifier of cache instance <1-16384>. Defines output format for printed IO class configuration. It can be either \fBtable\fR (default) or \fBcsv\fR. +.SH Options that are valid with --zero-metadata are: +.TP +.B -d, --device +Path to block device containing Open CAS metadata. + +.TP +.B -f, --force +Ignore potential dirty data on cache device. + .SH Command --help (-H) does not accept any options. .BR