Merge pull request #649 from arutk/zero-md-old-meta
Zero metadata if on-disk version differs from current
This commit is contained in:
commit
af664f9917
@ -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_HEADER) "Is cache,Clean Shutdown,Cache dirty\n");
|
||||||
|
|
||||||
fprintf(intermediate_file[1], TAG(TABLE_ROW));
|
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",
|
fprintf(intermediate_file[1], "yes,%s,%s\n",
|
||||||
cmd_info.clean_shutdown ? "yes" : "no",
|
cmd_info.clean_shutdown ? "yes" : "no",
|
||||||
cmd_info.cache_dirty ? "yes" : "no");
|
cmd_info.cache_dirty ? "yes" : "no");
|
||||||
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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[] = {
|
||||||
|
@ -1012,11 +1012,17 @@ static void cache_mngt_metadata_probe_end(void *priv, int error,
|
|||||||
|
|
||||||
*context->result = 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->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;
|
*context->result = 0;
|
||||||
} else if (error == 0) {
|
} else if (error == 0) {
|
||||||
cmd_info->is_cache_device = true;
|
cmd_info->is_cache_device = true;
|
||||||
|
cmd_info->metadata_compatible = true;
|
||||||
cmd_info->clean_shutdown = status->clean_shutdown;
|
cmd_info->clean_shutdown = status->clean_shutdown;
|
||||||
cmd_info->cache_dirty = status->cache_dirty;
|
cmd_info->cache_dirty = status->cache_dirty;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,12 @@ struct kcas_core_pool_remove {
|
|||||||
|
|
||||||
struct kcas_cache_check_device {
|
struct kcas_cache_check_device {
|
||||||
char path_name[MAX_STR_LEN]; /**< path to a 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 clean_shutdown;
|
||||||
bool cache_dirty;
|
bool cache_dirty;
|
||||||
bool format_atomic;
|
bool format_atomic;
|
||||||
|
@ -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
|
uses 520 bytes LBA allowing to write cache data and metadata in a single
|
||||||
request (atomically).
|
request (atomically).
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B --zero-metadata
|
||||||
|
Remove metadata from previously used cache device.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B -H, --help
|
.B -H, --help
|
||||||
Print 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
|
Defines output format for printed IO class configuration. It can be either
|
||||||
\fBtable\fR (default) or \fBcsv\fR.
|
\fBtable\fR (default) or \fBcsv\fR.
|
||||||
|
|
||||||
|
.SH Options that are valid with --zero-metadata are:
|
||||||
|
.TP
|
||||||
|
.B -d, --device <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.
|
.SH Command --help (-H) does not accept any options.
|
||||||
.BR
|
.BR
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user