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 <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2021-01-21 15:30:26 -06:00
parent 68b68db9c0
commit 4c98949cac
3 changed files with 43 additions and 5 deletions

View File

@ -2909,7 +2909,8 @@ int check_cache_device(const char *device_path)
return SUCCESS; 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 = {}; struct kcas_cache_check_device cmd_info = {};
char zero_page[4096] = {0}; char zero_page[4096] = {0};
int fd = 0; int fd = 0;
@ -2937,6 +2938,37 @@ int zero_md(const char *cache_device){
return FAILURE; 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); fd = open(cache_device, O_WRONLY | O_SYNC | O_EXCL);
if (fd < 0) { if (fd < 0) {
cas_printf(LOG_ERR, "Error while opening '%s'exclusively. This can be due to\n" cas_printf(LOG_ERR, "Error while opening '%s'exclusively. This can be due to\n"

View File

@ -266,9 +266,11 @@ int validate_str_metadata_mode(const char* s);
* @brief clear metadata * @brief clear metadata
* *
* @param[in] cache_device device to which zeroing cache's metadata applies * @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 * @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 * @brief calculate flush progress

View File

@ -1832,12 +1832,15 @@ static int handle_help();
struct { struct {
const char *device; const char *device;
bool force;
} static zero_params = { } static zero_params = {
.device = "" .device = "",
.force = false
}; };
static cli_option zero_options[] = { static cli_option zero_options[] = {
{'d', "device", "Path to device on which metadata would be cleared", 1, "DEVICE", CLI_OPTION_REQUIRED}, {'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} {0}
}; };
@ -1848,7 +1851,8 @@ int zero_handle_option(char *opt, const char **arg)
if(validate_device_name(arg[0]) == FAILURE) if(validate_device_name(arg[0]) == FAILURE)
return FAILURE; return FAILURE;
zero_params.device = arg[0]; zero_params.device = arg[0];
} else if (!strcmp(opt, "force")){
zero_params.force = 1;
} else { } else {
return FAILURE; return FAILURE;
} }
@ -1872,7 +1876,7 @@ int handle_zero()
return FAILURE; return FAILURE;
} }
return zero_md(zero_params.device); return zero_md(zero_params.device, zero_params.force);
} }
static cli_command cas_commands[] = { static cli_command cas_commands[] = {