Merge pull request #614 from robertbaldyga/redesign-standby

Redesign failover standby API
This commit is contained in:
Robert Baldyga 2022-01-04 14:07:05 +01:00 committed by GitHub
commit c6644116ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 396 additions and 303 deletions

View File

@ -93,8 +93,8 @@ struct ocf_cache_info {
uint32_t metadata_end_offset;
/*!< LBA offset where metadata ends (in 4KiB blocks) */
bool failover_detached;
/*!< true if cache drive detached for failover */
bool standby_detached;
/*!< true if cache volume detached in standby mode */
};
/**

View File

@ -141,9 +141,9 @@ typedef enum {
OCF_ERR_CACHE_STANDBY,
/** Operation invalid with cache drive atatched in failover standby */
OCF_ERR_FAILOVER_ATTACHED,
OCF_ERR_STANDBY_ATTACHED,
OCF_ERR_MAX = OCF_ERR_FAILOVER_ATTACHED,
OCF_ERR_MAX = OCF_ERR_STANDBY_ATTACHED,
} ocf_error_t;
#endif /* __OCF_ERR_H__ */

View File

@ -529,52 +529,108 @@ void ocf_mngt_cache_load(ocf_cache_t cache,
ocf_mngt_cache_load_end_t cmpl, void *priv);
/**
* @brief Completion callback of cache bind operation
* @brief Completion callback of cache standby attach operation
*
* @param[in] cache Cache handle
* @param[in] priv Callback context
* @param[in] error Error code (zero on success)
*/
typedef void (*ocf_mngt_cache_bind_end_t)(ocf_cache_t cache,
typedef void (*ocf_mngt_cache_standby_attach_end_t)(ocf_cache_t cache,
void *priv, int error);
/**
* @brief Initiate failover standby
* @brief Attach caching device to cache instance in failover standby mode
*
* @param[in] cache Cache handle
* @param[in] cfg Caching device configuration
* @param[in] cmpl Completion callback
* @param[in] priv Completion callback context
*/
void ocf_mngt_cache_standby(ocf_cache_t cache,
void ocf_mngt_cache_standby_attach(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
ocf_mngt_cache_bind_end_t cmpl, void *priv);
ocf_mngt_cache_standby_attach_end_t cmpl, void *priv);
typedef void (*ocf_mngt_cache_failover_detach_end_t)(void *priv, int error);
void ocf_mngt_cache_failover_detach(ocf_cache_t cache,
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv);
/**
* @brief Completion callback of cache activate operation
* @brief Completion callback of cache standby load operation
*
* @param[in] cache Cache handle
* @param[in] priv Callback context
* @param[in] error Error code (zero on success)
*/
typedef void (*ocf_mngt_cache_activate_end_t)(ocf_cache_t cache,
typedef void (*ocf_mngt_cache_standby_load_end_t)(ocf_cache_t cache,
void *priv, int error);
/**
* @brief Activate cache instance
* @brief Load cache instance in failover standby mode
*
* @param[in] cache Cache handle
* @param[in] cfg Caching device configuration
* @param[in] cmpl Completion callback
* @param[in] priv Completion callback context
*/
void ocf_mngt_cache_activate(ocf_cache_t cache,
struct ocf_mngt_cache_device_config *cfg,
ocf_mngt_cache_activate_end_t cmpl, void *priv);
void ocf_mngt_cache_standby_load(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
ocf_mngt_cache_standby_load_end_t cmpl, void *priv);
/**
* @brief Completion callback of cache standby detach operation
*
* @param[in] cache Cache handle
* @param[in] priv Callback context
* @param[in] error Error code (zero on success)
*/
typedef void (*ocf_mngt_cache_standby_detach_end_t)(void *priv, int error);
/**
* @brief Detach cache volume from cache in standby mode
*
* @param[in] cache Cache handle
* @param[in] cmpl Completion callback
* @param[in] priv Completion callback context
*/
void ocf_mngt_cache_standby_detach(ocf_cache_t cache,
ocf_mngt_cache_standby_detach_end_t cmpl, void *priv);
/**
* @brief Cache standby activate configuration
*/
struct ocf_mngt_cache_standby_activate_config {
/**
* @brief Cache device configuration - must be the first field
*/
struct ocf_mngt_cache_device_config device;
/**
* @brief Automatically open core volumes when activating cache
*
* If set to false, cache load will not attempt to open core volumes,
* and so cores will be marked "inactive" unless their volumes were
* earlier added to the core pool. In such case user will be expected
* to add cores later using function ocf_mngt_cache_add_core().
*/
bool open_cores;
};
/**
* @brief Completion callback of standby cache activate operation
*
* @param[in] cache Cache handle
* @param[in] priv Callback context
* @param[in] error Error code (zero on success)
*/
typedef void (*ocf_mngt_cache_standby_activate_end_t)(ocf_cache_t cache,
void *priv, int error);
/**
* @brief Activate standby cache instance
*
* @param[in] cache Cache handle
* @param[in] cfg Caching device configuration
* @param[in] cmpl Completion callback
* @param[in] priv Completion callback context
*/
void ocf_mngt_cache_standby_activate(ocf_cache_t cache,
struct ocf_mngt_cache_standby_activate_config *cfg,
ocf_mngt_cache_standby_activate_end_t cmpl, void *priv);
/* Adding and removing cores */

View File

@ -1171,79 +1171,6 @@ void ocf_metadata_load_all(ocf_cache_t cache,
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_load_unsafe_finish(ocf_pipeline_t pipeline,
void *priv, int error)
{
struct ocf_metadata_context *context = priv;
ocf_cache_t cache = context->cache;
if (error) {
ocf_cache_log(cache, log_err, "Metadata read FAILURE\n");
ocf_metadata_error(cache);
goto out;
}
ocf_cache_log(cache, log_info, "Done loading cache state\n");
out:
context->cmpl(context->priv, error);
ocf_pipeline_destroy(pipeline);
}
struct ocf_pipeline_arg ocf_metadata_load_unsafe_args[] = {
OCF_PL_ARG_INT(metadata_segment_sb_config),
OCF_PL_ARG_INT(metadata_segment_sb_runtime),
OCF_PL_ARG_INT(metadata_segment_part_config),
OCF_PL_ARG_INT(metadata_segment_part_runtime),
OCF_PL_ARG_INT(metadata_segment_core_config),
OCF_PL_ARG_INT(metadata_segment_core_runtime),
OCF_PL_ARG_INT(metadata_segment_core_uuid),
OCF_PL_ARG_INT(metadata_segment_cleaning),
OCF_PL_ARG_INT(metadata_segment_lru),
OCF_PL_ARG_INT(metadata_segment_collision),
OCF_PL_ARG_INT(metadata_segment_list_info),
OCF_PL_ARG_INT(metadata_segment_hash),
OCF_PL_ARG_TERMINATOR(),
};
struct ocf_pipeline_properties ocf_metadata_load_unsafe_pipeline_props = {
.priv_size = sizeof(struct ocf_metadata_context),
.finish = ocf_metadata_load_unsafe_finish,
.steps = {
OCF_PL_STEP_FOREACH(ocf_metadata_load_segment,
ocf_metadata_load_unsafe_args),
OCF_PL_STEP_TERMINATOR(),
},
};
/*
* Load metadata unsafe
*/
void ocf_metadata_load_unsafe(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv)
{
struct ocf_metadata_context *context;
ocf_pipeline_t pipeline;
int result;
OCF_DEBUG_TRACE(cache);
result = ocf_pipeline_create(&pipeline, cache,
&ocf_metadata_load_unsafe_pipeline_props);
if (result)
OCF_CMPL_RET(priv, result);
context = ocf_pipeline_get_priv(pipeline);
context->cmpl = cmpl;
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_load_recovery_legacy_finish(
ocf_pipeline_t pipeline, void *priv, int error)
{

View File

@ -165,16 +165,6 @@ void ocf_metadata_flush_do_asynch(struct ocf_cache *cache,
void ocf_metadata_load_all(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
/**
* @brief Load metadata unsafe
*
* @param cache - Cache instance
* @param cmpl - Completion callback
* @param priv - Completion context
*/
void ocf_metadata_load_unsafe(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
/**
* @brief Load metadata required for recovery procedure
*

View File

@ -71,8 +71,8 @@ static void ocf_metadata_generic_complete(void *priv, int error)
OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, error);
}
static void ocf_metadata_check_crc_skip(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg, bool skip_on_dirty_shutdown)
void ocf_metadata_check_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_metadata_context *context = priv;
int segment_id = ocf_pipeline_arg_get_int(arg);
@ -80,47 +80,20 @@ static void ocf_metadata_check_crc_skip(ocf_pipeline_t pipeline,
ocf_cache_t cache = context->cache;
uint32_t crc;
uint32_t superblock_crc;
bool clean_shutdown;
clean_shutdown = ocf_metadata_superblock_get_clean_shutdown(
segment->superblock);
if (!clean_shutdown && skip_on_dirty_shutdown)
OCF_PL_NEXT_RET(pipeline);
crc = ocf_metadata_raw_checksum(cache, segment->raw);
superblock_crc = ocf_metadata_superblock_get_checksum(segment->superblock,
segment_id);
if (crc != superblock_crc) {
/* Checksum does not match */
if (!clean_shutdown) {
ocf_cache_log(cache, log_warn,
"Loading %s WARNING, invalid checksum\n",
ocf_metadata_segment_names[segment_id]);
} else {
ocf_cache_log(cache, log_err,
"Loading %s ERROR, invalid checksum\n",
ocf_metadata_segment_names[segment_id]);
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
}
}
ocf_pipeline_next(pipeline);
}
void ocf_metadata_check_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
ocf_metadata_check_crc_skip(pipeline, priv, arg, false);
}
void ocf_metadata_check_crc_if_clean(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
ocf_metadata_check_crc_skip(pipeline, priv, arg, true);
}
void ocf_metadata_calculate_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{

View File

@ -27,9 +27,6 @@ int ocf_metadata_segment_init(
void ocf_metadata_segment_destroy(struct ocf_cache *cache,
struct ocf_metadata_segment *self);
void ocf_metadata_check_crc_if_clean(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);
void ocf_metadata_check_crc(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg);

View File

@ -216,18 +216,14 @@ struct ocf_pipeline_arg ocf_metadata_load_sb_load_segment_args[] = {
};
struct ocf_pipeline_arg ocf_metadata_load_sb_check_crc_args[] = {
OCF_PL_ARG_INT(metadata_segment_sb_runtime),
OCF_PL_ARG_INT(metadata_segment_part_config),
OCF_PL_ARG_INT(metadata_segment_part_runtime),
OCF_PL_ARG_INT(metadata_segment_core_config),
OCF_PL_ARG_INT(metadata_segment_core_uuid),
OCF_PL_ARG_TERMINATOR(),
};
struct ocf_pipeline_arg ocf_metadata_load_sb_check_crc_args_clean[] = {
OCF_PL_ARG_INT(metadata_segment_sb_runtime),
OCF_PL_ARG_INT(metadata_segment_part_runtime),
OCF_PL_ARG_TERMINATOR(),
};
struct ocf_pipeline_properties ocf_metadata_load_sb_pipeline_props = {
.priv_size = sizeof(struct ocf_metadata_context),
.finish = ocf_metadata_load_superblock_finish,
@ -239,8 +235,6 @@ struct ocf_pipeline_properties ocf_metadata_load_sb_pipeline_props = {
OCF_PL_STEP(ocf_metadata_check_crc_sb_config),
OCF_PL_STEP_FOREACH(ocf_metadata_check_crc,
ocf_metadata_load_sb_check_crc_args),
OCF_PL_STEP_FOREACH(ocf_metadata_check_crc_if_clean,
ocf_metadata_load_sb_check_crc_args_clean),
OCF_PL_STEP(ocf_metadata_load_superblock_post),
OCF_PL_STEP_TERMINATOR(),
},
@ -287,6 +281,78 @@ void ocf_metadata_load_superblock(ocf_cache_t cache, ocf_metadata_end_t cmpl,
ocf_pipeline_next(pipeline);
}
struct ocf_pipeline_arg ocf_metadata_load_sb_recov_load_segment_args[] = {
OCF_PL_ARG_INT(metadata_segment_sb_config),
OCF_PL_ARG_INT(metadata_segment_part_config),
OCF_PL_ARG_INT(metadata_segment_core_config),
OCF_PL_ARG_INT(metadata_segment_core_uuid),
OCF_PL_ARG_TERMINATOR(),
};
struct ocf_pipeline_arg ocf_metadata_load_sb_recov_check_crc_args[] = {
OCF_PL_ARG_INT(metadata_segment_part_config),
OCF_PL_ARG_INT(metadata_segment_core_config),
OCF_PL_ARG_INT(metadata_segment_core_uuid),
OCF_PL_ARG_TERMINATOR(),
};
struct ocf_pipeline_properties ocf_metadata_load_sb_recov_pipeline_props = {
.priv_size = sizeof(struct ocf_metadata_context),
.finish = ocf_metadata_load_superblock_finish,
.steps = {
OCF_PL_STEP_FOREACH(ocf_metadata_store_segment,
ocf_metadata_load_sb_store_segment_args),
OCF_PL_STEP_FOREACH(ocf_metadata_load_segment,
ocf_metadata_load_sb_recov_load_segment_args),
OCF_PL_STEP(ocf_metadata_check_crc_sb_config),
OCF_PL_STEP_FOREACH(ocf_metadata_check_crc,
ocf_metadata_load_sb_recov_check_crc_args),
OCF_PL_STEP(ocf_metadata_load_superblock_post),
OCF_PL_STEP_TERMINATOR(),
},
};
/*
* Super Block - Recovery load
*/
void ocf_metadata_load_superblock_recovery(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv)
{
struct ocf_metadata_context *context;
ocf_pipeline_t pipeline;
struct ocf_metadata_ctrl *ctrl;
struct ocf_superblock_config *sb_config;
struct ocf_superblock_runtime *sb_runtime;
int result;
OCF_DEBUG_TRACE(cache);
/* TODO: get ctrl from args rather than from cache */
ctrl = cache->metadata.priv;
ENV_BUG_ON(!ctrl);
sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config);
ENV_BUG_ON(!sb_config);
sb_runtime = METADATA_MEM_POOL(ctrl, metadata_segment_sb_runtime);
ENV_BUG_ON(!sb_runtime);
result = ocf_pipeline_create(&pipeline, cache,
&ocf_metadata_load_sb_recov_pipeline_props);
if (result)
OCF_CMPL_RET(priv, result);
context = ocf_pipeline_get_priv(pipeline);
context->cmpl = cmpl;
context->priv = priv;
context->pipeline = pipeline;
context->cache = cache;
context->ctrl = cache->metadata.priv;
ocf_pipeline_next(pipeline);
}
static void ocf_metadata_flush_superblock_prepare(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{

View File

@ -75,6 +75,9 @@ void ocf_metadata_set_shutdown_status(ocf_cache_t cache,
void ocf_metadata_load_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
void ocf_metadata_load_superblock_recovery(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);
void ocf_metadata_flush_superblock(ocf_cache_t cache,
ocf_metadata_end_t cmpl, void *priv);

View File

@ -215,19 +215,12 @@ static void __init_parts_attached(ocf_cache_t cache)
ocf_lru_init(cache, &cache->free);
}
static void __populate_free_unsafe(ocf_cache_t cache)
{
uint64_t free_clines = ocf_metadata_collision_table_entries(cache);
ocf_lru_populate(cache, free_clines, false);
}
static void __populate_free_safe(ocf_cache_t cache)
static void __populate_free(ocf_cache_t cache)
{
uint64_t free_clines = ocf_metadata_collision_table_entries(cache) -
ocf_get_cache_occupancy(cache);
ocf_lru_populate(cache, free_clines, true);
ocf_lru_populate(cache, free_clines);
}
static ocf_error_t __init_cleaning_policy(ocf_cache_t cache)
@ -316,7 +309,7 @@ static ocf_error_t init_attached_data_structures(ocf_cache_t cache)
ocf_metadata_init_hash_table(cache);
ocf_metadata_init_collision(cache);
__init_parts_attached(cache);
__populate_free_safe(cache);
__populate_free(cache);
result = __init_cleaning_policy(cache);
if (result) {
@ -502,7 +495,7 @@ static void _recovery_reset_cline_metadata(struct ocf_cache *cache,
ocf_cleaning_init_cache_block(cache, cline);
}
static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache, bool initialized)
static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache)
{
ocf_cache_line_t cline;
ocf_core_id_t core_id;
@ -519,7 +512,6 @@ static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache, bool initialized)
OCF_COND_RESCHED(step, 128);
ocf_metadata_get_core_info(cache, cline, &core_id, &core_line);
if (!initialized)
metadata_clear_dirty_if_invalid(cache, cline);
any_valid = metadata_clear_valid_if_clean(cache, cline);
@ -538,12 +530,7 @@ static void _ocf_mngt_rebuild_metadata(ocf_cache_t cache, bool initialized)
static void _ocf_mngt_recovery_rebuild_metadata(ocf_cache_t cache)
{
_ocf_mngt_rebuild_metadata(cache, false);
}
static void _ocf_mngt_bind_rebuild_metadata(ocf_cache_t cache)
{
_ocf_mngt_rebuild_metadata(cache, true);
_ocf_mngt_rebuild_metadata(cache);
}
static inline ocf_error_t _ocf_init_cleaning_policy(ocf_cache_t cache,
@ -572,7 +559,7 @@ static void _ocf_mngt_load_post_metadata_load(ocf_pipeline_t pipeline,
if (context->metadata.shutdown_status != ocf_metadata_clean_shutdown) {
_ocf_mngt_recovery_rebuild_metadata(cache);
__populate_free_safe(cache);
__populate_free(cache);
}
result = _ocf_init_cleaning_policy(cache, cache->cleaner.policy,
@ -584,7 +571,7 @@ static void _ocf_mngt_load_post_metadata_load(ocf_pipeline_t pipeline,
ocf_pipeline_next(pipeline);
}
void _ocf_mngt_load_init_instance_complete(void *priv, int error)
void _ocf_mngt_load_metadata_complete(void *priv, int error)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
@ -601,43 +588,44 @@ void _ocf_mngt_load_init_instance_complete(void *priv, int error)
/**
* handle load variant
*/
static void _ocf_mngt_load_init_instance_clean_load(
struct ocf_cache_attach_context *context)
static void _ocf_mngt_load_metadata_clean(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_metadata_load_all(cache,
_ocf_mngt_load_init_instance_complete, context);
_ocf_mngt_load_metadata_complete, context);
}
/**
* handle recovery variant
*/
static void _ocf_mngt_load_init_instance_recovery(
struct ocf_cache_attach_context *context)
static void _ocf_mngt_load_metadata_recovery(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
init_attached_data_structures_recovery(cache, true);
ocf_cache_log(cache, log_info, "Initiating recovery sequence...\n");
ocf_metadata_load_recovery(cache,
_ocf_mngt_load_init_instance_complete, context);
_ocf_mngt_load_metadata_complete, context);
}
static void _ocf_mngt_load_init_instance(ocf_pipeline_t pipeline,
static void _ocf_mngt_load_metadata(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown) {
_ocf_mngt_load_init_instance_clean_load(context);
_ocf_mngt_load_metadata_clean(pipeline, priv, arg);
} else {
ocf_cache_log(cache, log_warn,
"ERROR: Cache device did not shut down properly!\n");
_ocf_mngt_load_init_instance_recovery(context);
init_attached_data_structures_recovery(cache, true);
ocf_cache_log(cache, log_info, "Initiating recovery sequence...\n");
_ocf_mngt_load_metadata_recovery(pipeline, priv, arg);
}
}
@ -1443,8 +1431,13 @@ static void _ocf_mngt_load_superblock(ocf_pipeline_t pipeline,
ocf_cache_t cache = context->cache;
ocf_cache_log(cache, log_info, "Loading cache state...\n");
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown) {
ocf_metadata_load_superblock(cache,
_ocf_mngt_load_superblock_complete, context);
} else {
ocf_metadata_load_superblock_recovery(cache,
_ocf_mngt_load_superblock_complete, context);
}
}
static void _ocf_mngt_init_cleaner(ocf_pipeline_t pipeline,
@ -1717,7 +1710,7 @@ struct ocf_pipeline_properties _ocf_mngt_cache_load_pipeline_properties = {
OCF_PL_STEP(_ocf_mngt_init_cleaner),
OCF_PL_STEP(_ocf_mngt_init_promotion),
OCF_PL_STEP(_ocf_mngt_load_add_cores),
OCF_PL_STEP(_ocf_mngt_load_init_instance),
OCF_PL_STEP(_ocf_mngt_load_metadata),
OCF_PL_STEP(_ocf_mngt_load_post_metadata_load),
OCF_PL_STEP(_ocf_mngt_attach_flush_metadata),
OCF_PL_STEP(_ocf_mngt_attach_shutdown_status),
@ -2022,21 +2015,6 @@ static void _ocf_mngt_init_cache_front_volume(ocf_pipeline_t pipeline,
ocf_pipeline_next(context->pipeline);
}
static void _ocf_mngt_load_unsafe_complete(void *priv, int error)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
if (error) {
ocf_cache_log(cache, log_err,
"ERROR: Cannot load metadata\n");
OCF_PL_FINISH_RET(context->pipeline,
-OCF_ERR_START_CACHE_FAIL);
}
ocf_pipeline_next(context->pipeline);
}
static void _ocf_mngt_standby_init_properties(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
@ -2053,18 +2031,7 @@ static void _ocf_mngt_standby_init_properties(ocf_pipeline_t pipeline,
ocf_pipeline_next(pipeline);
}
static void _ocf_mngt_load_metadata_unsafe(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_cache_log(cache, log_info, "Loading cache state...\n");
ocf_metadata_load_unsafe(cache,
_ocf_mngt_load_unsafe_complete, context);
}
static void _ocf_mngt_bind_preapre_mempool(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_preapre_mempool(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
@ -2078,15 +2045,36 @@ static void _ocf_mngt_bind_preapre_mempool(ocf_pipeline_t pipeline,
OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, result);
}
static void _ocf_mngt_bind_init_attached_structures(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_init_structures_attach(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
init_attached_data_structures_recovery(cache, true);
__populate_free(cache);
ocf_pipeline_next(pipeline);
}
static void _ocf_mngt_standby_init_structures_load(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
init_attached_data_structures_recovery(cache, false);
ocf_pipeline_next(pipeline);
}
static void _ocf_mngt_standby_init_pio_concurrency(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
int result;
init_attached_data_structures_recovery(cache, false);
result = ocf_pio_concurrency_init(&cache->standby.concurrency, cache);
if (!result)
context->flags.pio_concurrency = true;
@ -2094,19 +2082,19 @@ static void _ocf_mngt_bind_init_attached_structures(ocf_pipeline_t pipeline,
OCF_PL_NEXT_ON_SUCCESS_RET(context->pipeline, result);
}
static void _ocf_mngt_bind_recovery_unsafe(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_recovery(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
ocf_cache_t cache = context->cache;
_ocf_mngt_bind_rebuild_metadata(cache);
__populate_free_unsafe(cache);
_ocf_mngt_recovery_rebuild_metadata(cache);
__populate_free(cache);
ocf_pipeline_next(pipeline);
}
static void _ocf_mngt_bind_init_cleaning(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_init_cleaning(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
@ -2122,7 +2110,7 @@ static void _ocf_mngt_bind_init_cleaning(ocf_pipeline_t pipeline,
ocf_pipeline_next(pipeline);
}
static void _ocf_mngt_bind_post_init(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_post_init(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_attach_context *context = priv;
@ -2133,7 +2121,33 @@ static void _ocf_mngt_bind_post_init(ocf_pipeline_t pipeline,
ocf_pipeline_next(pipeline);
}
struct ocf_pipeline_properties _ocf_mngt_cache_standby_pipeline_properties = {
struct ocf_pipeline_properties _ocf_mngt_cache_standby_attach_pipeline_properties = {
.priv_size = sizeof(struct ocf_cache_attach_context),
.finish = _ocf_mngt_cache_attach_finish,
.steps = {
OCF_PL_STEP(_ocf_mngt_copy_uuid_data),
OCF_PL_STEP(_ocf_mngt_init_attached_nonpersistent),
OCF_PL_STEP(_ocf_mngt_attach_cache_device),
OCF_PL_STEP(_ocf_mngt_attach_read_properties),
OCF_PL_STEP(_ocf_mngt_standby_init_properties),
OCF_PL_STEP(_ocf_mngt_init_cache_front_volume),
OCF_PL_STEP(_ocf_mngt_attach_check_ram),
OCF_PL_STEP(_ocf_mngt_attach_prepare_metadata),
OCF_PL_STEP(_ocf_mngt_test_volume),
OCF_PL_STEP(_ocf_mngt_init_cleaner),
OCF_PL_STEP(_ocf_mngt_standby_init_structures_attach),
OCF_PL_STEP(_ocf_mngt_standby_init_cleaning),
OCF_PL_STEP(_ocf_mngt_standby_preapre_mempool),
OCF_PL_STEP(_ocf_mngt_standby_init_pio_concurrency),
OCF_PL_STEP(_ocf_mngt_attach_flush_metadata),
OCF_PL_STEP(_ocf_mngt_attach_discard),
OCF_PL_STEP(_ocf_mngt_attach_flush),
OCF_PL_STEP(_ocf_mngt_standby_post_init),
OCF_PL_STEP_TERMINATOR(),
},
};
struct ocf_pipeline_properties _ocf_mngt_cache_standby_load_pipeline_properties = {
.priv_size = sizeof(struct ocf_cache_attach_context),
.finish = _ocf_mngt_cache_attach_finish,
.steps = {
@ -2145,40 +2159,42 @@ struct ocf_pipeline_properties _ocf_mngt_cache_standby_pipeline_properties = {
OCF_PL_STEP(_ocf_mngt_attach_check_ram),
OCF_PL_STEP(_ocf_mngt_test_volume),
OCF_PL_STEP(_ocf_mngt_attach_prepare_metadata),
OCF_PL_STEP(_ocf_mngt_load_metadata_unsafe),
OCF_PL_STEP(_ocf_mngt_bind_preapre_mempool),
OCF_PL_STEP(_ocf_mngt_bind_init_attached_structures),
OCF_PL_STEP(_ocf_mngt_bind_recovery_unsafe),
OCF_PL_STEP(_ocf_mngt_load_superblock),
OCF_PL_STEP(_ocf_mngt_load_metadata_recovery),
OCF_PL_STEP(_ocf_mngt_init_cleaner),
OCF_PL_STEP(_ocf_mngt_bind_init_cleaning),
OCF_PL_STEP(_ocf_mngt_bind_post_init),
OCF_PL_STEP(_ocf_mngt_standby_init_structures_load),
OCF_PL_STEP(_ocf_mngt_standby_init_cleaning),
OCF_PL_STEP(_ocf_mngt_standby_preapre_mempool),
OCF_PL_STEP(_ocf_mngt_standby_init_pio_concurrency),
OCF_PL_STEP(_ocf_mngt_standby_recovery),
OCF_PL_STEP(_ocf_mngt_standby_post_init),
OCF_PL_STEP_TERMINATOR(),
},
};
struct ocf_cache_failover_detach_context {
struct ocf_cache_standby_detach_context {
ocf_pipeline_t pipeline;
ocf_cache_t cache;
ocf_mngt_cache_failover_detach_end_t cmpl;
ocf_mngt_cache_standby_detach_end_t cmpl;
void *priv;
};
static void _ocf_mngt_failover_detach_wait_metadata_io_finish(void *priv)
static void _ocf_mngt_standby_detach_wait_metadata_io_finish(void *priv)
{
struct ocf_cache_failover_detach_context *context = priv;
struct ocf_cache_standby_detach_context *context = priv;
ocf_pipeline_next(context->pipeline);
}
static void _ocf_mngt_failover_detach_wait_metadata_io(ocf_pipeline_t pipeline,
static void _ocf_mngt_standby_detach_wait_metadata_io(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_failover_detach_context *context = priv;
struct ocf_cache_standby_detach_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_refcnt_freeze(&cache->refcnt.metadata);
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
_ocf_mngt_failover_detach_wait_metadata_io_finish, context);
_ocf_mngt_standby_detach_wait_metadata_io_finish, context);
}
static void _ocf_mngt_activate_set_cache_device(ocf_pipeline_t pipeline,
@ -2509,7 +2525,7 @@ ocf_mngt_cache_stop_standby_pipeline_properties = {
},
};
static void _ocf_mngt_cache_standby(ocf_cache_t cache,
static void _ocf_mngt_cache_standby_attach(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
{
@ -2518,7 +2534,7 @@ static void _ocf_mngt_cache_standby(ocf_cache_t cache,
int result;
result = ocf_pipeline_create(&pipeline, cache,
&_ocf_mngt_cache_standby_pipeline_properties);
&_ocf_mngt_cache_standby_attach_pipeline_properties);
if (result)
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
@ -2542,10 +2558,43 @@ static void _ocf_mngt_cache_standby(ocf_cache_t cache,
OCF_PL_NEXT_RET(pipeline);
}
static void _ocf_mngt_failover_detach_close_volume(ocf_pipeline_t pipeline,
static void _ocf_mngt_cache_standby_load(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
{
struct ocf_cache_attach_context *context;
ocf_pipeline_t pipeline;
int result;
result = ocf_pipeline_create(&pipeline, cache,
&_ocf_mngt_cache_standby_load_pipeline_properties);
if (result)
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
result = ocf_pipeline_create(&cache->stop_pipeline, cache,
&ocf_mngt_cache_stop_standby_pipeline_properties);
if (result) {
ocf_pipeline_destroy(pipeline);
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_NO_MEM);
}
context = ocf_pipeline_get_priv(pipeline);
context->cmpl = cmpl;
context->priv1 = priv1;
context->priv2 = priv2;
context->pipeline = pipeline;
context->cache = cache;
context->cfg = *cfg;
OCF_PL_NEXT_RET(pipeline);
}
static void _ocf_mngt_standby_detach_close_volume(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_cache_failover_detach_context *context = priv;
struct ocf_cache_standby_detach_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_volume_close(&cache->device->volume);
@ -2554,10 +2603,10 @@ static void _ocf_mngt_failover_detach_close_volume(ocf_pipeline_t pipeline,
ocf_pipeline_next(pipeline);
}
static void ocf_mngt_cache_failover_detach_finish(ocf_pipeline_t pipeline,
static void ocf_mngt_cache_standby_detach_finish(ocf_pipeline_t pipeline,
void *priv, int error)
{
struct ocf_cache_failover_detach_context *context = priv;
struct ocf_cache_standby_detach_context *context = priv;
context->cmpl(context->priv, error);
@ -2565,25 +2614,25 @@ static void ocf_mngt_cache_failover_detach_finish(ocf_pipeline_t pipeline,
}
struct ocf_pipeline_properties
_ocf_mngt_cache_failover_detach_pipeline_properties = {
.priv_size = sizeof(struct ocf_cache_failover_detach_context),
.finish = ocf_mngt_cache_failover_detach_finish,
_ocf_mngt_cache_standby_detach_pipeline_properties = {
.priv_size = sizeof(struct ocf_cache_standby_detach_context),
.finish = ocf_mngt_cache_standby_detach_finish,
.steps = {
OCF_PL_STEP(_ocf_mngt_failover_detach_wait_metadata_io),
OCF_PL_STEP(_ocf_mngt_failover_detach_close_volume),
OCF_PL_STEP(_ocf_mngt_standby_detach_wait_metadata_io),
OCF_PL_STEP(_ocf_mngt_standby_detach_close_volume),
OCF_PL_STEP_TERMINATOR(),
},
};
void _ocf_mngt_cache_failover_detach(ocf_cache_t cache,
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv)
void _ocf_mngt_cache_standby_detach(ocf_cache_t cache,
ocf_mngt_cache_standby_detach_end_t cmpl, void *priv)
{
struct ocf_cache_failover_detach_context *context;
struct ocf_cache_standby_detach_context *context;
ocf_pipeline_t pipeline;
int result;
result = ocf_pipeline_create(&pipeline, cache,
&_ocf_mngt_cache_failover_detach_pipeline_properties);
&_ocf_mngt_cache_standby_detach_pipeline_properties);
if (result)
OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM);
@ -2598,9 +2647,8 @@ void _ocf_mngt_cache_failover_detach(ocf_cache_t cache,
OCF_PL_NEXT_RET(pipeline);
}
static void _ocf_mngt_cache_activate(ocf_cache_t cache,
struct ocf_mngt_cache_device_config *device_cfg,
static void _ocf_mngt_cache_standby_activate(ocf_cache_t cache,
struct ocf_mngt_cache_standby_activate_config *cfg,
_ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2)
{
struct ocf_cache_attach_context *context;
@ -2611,7 +2659,7 @@ static void _ocf_mngt_cache_activate(ocf_cache_t cache,
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
if (!ocf_refcnt_frozen(&cache->refcnt.metadata))
OCF_CMPL_RET(cache, priv1, priv2, OCF_ERR_FAILOVER_ATTACHED);
OCF_CMPL_RET(cache, priv1, priv2, OCF_ERR_STANDBY_ATTACHED);
result = ocf_pipeline_create(&pipeline, cache,
&_ocf_mngt_cache_activate_pipeline_properties);
@ -2626,13 +2674,12 @@ static void _ocf_mngt_cache_activate(ocf_cache_t cache,
context->pipeline = pipeline;
context->cache = cache;
context->cfg.device = *device_cfg;
context->cfg.device = cfg->device;
context->cfg.cache_line_size = cache->metadata.line_size;
context->cfg.open_cores = true;
context->cfg.open_cores = cfg->open_cores;
context->cfg.force = false;
context->cfg.discard_on_start = false;
OCF_PL_NEXT_RET(pipeline);
}
@ -2898,23 +2945,23 @@ void ocf_mngt_cache_load(ocf_cache_t cache,
_ocf_mngt_cache_load(cache, cfg, _ocf_mngt_cache_load_complete, cmpl, priv);
}
static void _ocf_mngt_cache_standby_complete(ocf_cache_t cache, void *priv1,
void *priv2, int error)
static void _ocf_mngt_cache_standby_attach_complete(ocf_cache_t cache,
void *priv1, void *priv2, int error)
{
ocf_mngt_cache_bind_end_t cmpl = priv1;
ocf_mngt_cache_standby_attach_end_t cmpl = priv1;
if (error)
OCF_CMPL_RET(cache, priv2, error);
_ocf_mngt_cache_set_standby(cache);
ocf_cache_log(cache, log_info, "Successfully bound\n");
ocf_cache_log(cache, log_info, "Successfully attached standby cache\n");
OCF_CMPL_RET(cache, priv2, 0);
}
void ocf_mngt_cache_standby(ocf_cache_t cache,
void ocf_mngt_cache_standby_attach(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
ocf_mngt_cache_bind_end_t cmpl, void *priv)
ocf_mngt_cache_standby_attach_end_t cmpl, void *priv)
{
int result;
@ -2924,14 +2971,52 @@ void ocf_mngt_cache_standby(ocf_cache_t cache,
if (!cache->mngt_queue)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
/* Bind is not allowed in volatile metadata mode */
/* Standby is not allowed in volatile metadata mode */
if (cache->metadata.is_volatile)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
/* Bind is not allowed with 'force' flag on */
result = _ocf_mngt_cache_validate_attach_cfg(cfg);
if (result)
OCF_CMPL_RET(cache, priv, result);
_ocf_mngt_cache_standby_attach(cache, cfg,
_ocf_mngt_cache_standby_attach_complete, cmpl, priv);
}
static void _ocf_mngt_cache_standby_load_complete(ocf_cache_t cache,
void *priv1, void *priv2, int error)
{
ocf_mngt_cache_standby_attach_end_t cmpl = priv1;
if (error)
OCF_CMPL_RET(cache, priv2, error);
_ocf_mngt_cache_set_standby(cache);
ocf_cache_log(cache, log_info, "Successfully loaded standby cache\n");
OCF_CMPL_RET(cache, priv2, 0);
}
void ocf_mngt_cache_standby_load(ocf_cache_t cache,
struct ocf_mngt_cache_attach_config *cfg,
ocf_mngt_cache_standby_load_end_t cmpl, void *priv)
{
int result;
OCF_CHECK_NULL(cache);
OCF_CHECK_NULL(cfg);
if (!cache->mngt_queue)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
/* Standby is not allowed in volatile metadata mode */
if (cache->metadata.is_volatile)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
/* Standby load is not allowed with 'force' flag on */
if (cfg->force) {
ocf_cache_log(cache, log_err, "Using 'force' flag is forbidden "
"for bind operation.");
"for standby load operation.");
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
}
@ -2939,14 +3024,31 @@ void ocf_mngt_cache_standby(ocf_cache_t cache,
if (result)
OCF_CMPL_RET(cache, priv, result);
_ocf_mngt_cache_standby(cache, cfg, _ocf_mngt_cache_standby_complete,
cmpl, priv);
_ocf_mngt_cache_standby_load(cache, cfg,
_ocf_mngt_cache_standby_load_complete, cmpl, priv);
}
static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
void *priv2, int error)
void ocf_mngt_cache_standby_detach(ocf_cache_t cache,
ocf_mngt_cache_standby_detach_end_t cmpl, void *priv)
{
ocf_mngt_cache_activate_end_t cmpl = priv1;
OCF_CHECK_NULL(cache);
if (!cache->mngt_queue)
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
if (!ocf_cache_is_standby(cache))
OCF_CMPL_RET(priv, -OCF_ERR_CACHE_EXIST);
if (ocf_refcnt_frozen(&cache->refcnt.metadata))
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
_ocf_mngt_cache_standby_detach(cache, cmpl, priv);
}
static void _ocf_mngt_cache_standby_activate_complete(ocf_cache_t cache,
void *priv1, void *priv2, int error)
{
ocf_mngt_cache_standby_activate_end_t cmpl = priv1;
if (error)
OCF_CMPL_RET(cache, priv2, error);
@ -2960,26 +3062,9 @@ static void _ocf_mngt_cache_activate_complete(ocf_cache_t cache, void *priv1,
OCF_CMPL_RET(cache, priv2, 0);
}
void ocf_mngt_cache_failover_detach(ocf_cache_t cache,
ocf_mngt_cache_failover_detach_end_t cmpl, void *priv)
{
OCF_CHECK_NULL(cache);
if (!cache->mngt_queue)
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
if (!ocf_cache_is_standby(cache))
OCF_CMPL_RET(priv, -OCF_ERR_CACHE_EXIST);
if (ocf_refcnt_frozen(&cache->refcnt.metadata))
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
_ocf_mngt_cache_failover_detach(cache, cmpl, priv);
}
void ocf_mngt_cache_activate(ocf_cache_t cache,
struct ocf_mngt_cache_device_config *cfg,
ocf_mngt_cache_activate_end_t cmpl, void *priv)
void ocf_mngt_cache_standby_activate(ocf_cache_t cache,
struct ocf_mngt_cache_standby_activate_config *cfg,
ocf_mngt_cache_standby_activate_end_t cmpl, void *priv)
{
OCF_CHECK_NULL(cache);
OCF_CHECK_NULL(cfg);
@ -2987,10 +3072,11 @@ void ocf_mngt_cache_activate(ocf_cache_t cache,
if (!cache->mngt_queue)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
if (_ocf_mngt_cache_validate_device_cfg(cfg))
if (_ocf_mngt_cache_validate_device_cfg(&cfg->device))
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
_ocf_mngt_cache_activate(cache, cfg, _ocf_mngt_cache_activate_complete,
_ocf_mngt_cache_standby_activate(cache, cfg,
_ocf_mngt_cache_standby_activate_complete,
cmpl, priv);
}

View File

@ -108,9 +108,9 @@ int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info)
_ocf_stats_zero(&info->inactive);
info->attached = ocf_cache_is_device_attached(cache);
info->failover_detached = ocf_cache_is_standby(cache) &&
info->standby_detached = ocf_cache_is_standby(cache) &&
ocf_refcnt_frozen(&cache->refcnt.metadata);
if (info->attached && !info->failover_detached) {
if (info->attached && !info->standby_detached) {
info->volume_type = ocf_ctx_get_volume_type_id(cache->owner,
cache->device->volume.type);
info->size = cache->conf_meta->cachelines;

View File

@ -891,8 +891,7 @@ static ocf_cache_line_t next_phys_invalid(ocf_cache_t cache,
}
/* put invalid cachelines on freelist partition lru list */
void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines,
bool safe)
void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines)
{
ocf_cache_line_t phys, cline;
ocf_cache_line_t collision_table_entries =
@ -906,10 +905,7 @@ void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines,
for (i = 0; i < num_free_clines; i++) {
/* find first invalid cacheline */
phys = next_phys_invalid(cache, phys);
if (safe)
ENV_BUG_ON(phys == collision_table_entries);
else if (phys == collision_table_entries)
break;
cline = ocf_metadata_map_phy2lg(cache, phys);
++phys;
@ -925,7 +921,7 @@ void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines,
/* we should have reached the last invalid cache line */
phys = next_phys_invalid(cache, phys);
ENV_BUG_ON(safe && phys != collision_table_entries);
ENV_BUG_ON(phys != collision_table_entries);
env_atomic_set(&cache->free.runtime->curr_size, i);
}

View File

@ -31,8 +31,7 @@ void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part,
void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
struct ocf_part *src_upart, struct ocf_part *dst_upart);
uint32_t ocf_lru_num_free(ocf_cache_t cache);
void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines,
bool safe);
void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines);
struct ocf_lru_list *ocf_lru_get_list(struct ocf_part *part,
uint32_t lru_idx, bool clean);
void ocf_lru_remove_locked(ocf_cache_t cache, struct ocf_lru_list *list,

View File

@ -53,7 +53,7 @@ class OcfErrorCode(IntEnum):
OCF_ERR_METADATA_LAYOUT_MISMATCH = auto()
OCF_ERR_CACHE_LINE_SIZE_MISMATCH = auto()
OCF_ERR_CACHE_STANDBY = auto()
OCF_ERR_FAILOVER_ATTACHED = auto()
OCF_ERR_STANDBY_ATTACHED = auto()
class OcfCompletion: