From 99c8c05f3f989fe2cdfdfad13f452fdbe35f2afa Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Thu, 9 Dec 2021 23:03:32 +0100 Subject: [PATCH 1/3] Introduce flapping of metadata config sections This feature provides double buffering of config sections to prevent situation when power failure during metadata flush leads to partially updated metadata. Flapping mechanism makes it always possible to perform graceful rollback to previous config metadata content in such situation. Signed-off-by: Robert Baldyga --- src/metadata/metadata.c | 36 +++++++++++++++++++++- src/metadata/metadata_raw.c | 38 ++++++++++++++++------- src/metadata/metadata_raw.h | 21 ++++++++----- src/metadata/metadata_raw_dynamic.c | 39 +++++++++++++++++++----- src/metadata/metadata_raw_dynamic.h | 4 +-- src/metadata/metadata_raw_volatile.c | 4 +-- src/metadata/metadata_raw_volatile.h | 4 +-- src/metadata/metadata_segment.c | 26 +++++++++++----- src/metadata/metadata_superblock.c | 45 ++++++++++++++++++++-------- src/metadata/metadata_superblock.h | 8 +++++ 10 files changed, 172 insertions(+), 53 deletions(-) diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 5037021..6e01e76 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -187,6 +187,34 @@ static int64_t ocf_metadata_get_element_size( return size; } +/* + * Check if particular metadata type supports flapping + */ +static bool ocf_metadata_is_flapped( + enum ocf_metadata_segment_id type) +{ + switch (type) { + case metadata_segment_part_config: + case metadata_segment_core_config: + case metadata_segment_core_uuid: + return true; + + case metadata_segment_sb_config: + case metadata_segment_sb_runtime: + case metadata_segment_reserved: + case metadata_segment_part_runtime: + case metadata_segment_core_runtime: + case metadata_segment_cleaning: + case metadata_segment_lru: + case metadata_segment_collision: + case metadata_segment_list_info: + case metadata_segment_hash: + default: + return false; + + } +} + /* * Metadata calculation exception handling. * @@ -484,6 +512,9 @@ static struct ocf_metadata_ctrl *ocf_metadata_ctrl_init( = ocf_metadata_get_element_size(i, 0); raw->entries_in_page = PAGE_SIZE / raw->entry_size; + /* Setup flapping support */ + raw->flapping = ocf_metadata_is_flapped(i); + /* Setup number of entries */ raw->entries = ocf_metadata_get_entries(i, 0); @@ -675,6 +706,9 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, raw->entry_size = ocf_metadata_get_element_size(i, line_size); raw->entries_in_page = PAGE_SIZE / raw->entry_size; + + /* Setup flapping support */ + raw->flapping = ocf_metadata_is_flapped(i); } if (0 != ocf_metadata_calculate_metadata_size(cache, ctrl, line_size)) { @@ -1009,7 +1043,7 @@ void ocf_metadata_flush_collision(ocf_cache_t cache, ctrl = cache->metadata.priv; raw = &ctrl->raw_desc[metadata_segment_collision]; - ocf_metadata_raw_flush_all(cache, raw, cmpl, priv); + ocf_metadata_raw_flush_all(cache, raw, cmpl, priv, 0); } /* diff --git a/src/metadata/metadata_raw.c b/src/metadata/metadata_raw.c index 99a532b..3276443 100644 --- a/src/metadata/metadata_raw.c +++ b/src/metadata/metadata_raw.c @@ -33,13 +33,24 @@ /******************************************************************************* * Common RAW Implementation ******************************************************************************/ + +static uint32_t _raw_ram_segment_size_on_ssd(struct ocf_metadata_raw *raw) +{ + const size_t alignment = 128 * KiB / PAGE_SIZE; + + return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; +} + /* * Check if page is valid for specified RAW descriptor */ static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) { + uint32_t size = _raw_ram_segment_size_on_ssd(raw) * + (raw->flapping ? 2 : 1); + ENV_BUG_ON(page < raw->ssd_pages_offset); - ENV_BUG_ON(page >= (raw->ssd_pages_offset + raw->ssd_pages)); + ENV_BUG_ON(page >= (raw->ssd_pages_offset + size)); return true; } @@ -144,9 +155,9 @@ static size_t _raw_ram_size_of(ocf_cache_t cache, struct ocf_metadata_raw *raw) */ static uint32_t _raw_ram_size_on_ssd(struct ocf_metadata_raw *raw) { - const size_t alignment = 128 * KiB / PAGE_SIZE; + size_t flapping_factor = raw->flapping ? 2 : 1; - return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; + return _raw_ram_segment_size_on_ssd(raw) * flapping_factor; } /* @@ -226,6 +237,7 @@ static int _raw_ram_update(ocf_cache_t cache, struct _raw_ram_load_all_context { struct ocf_metadata_raw *raw; + uint64_t ssd_pages_offset; ocf_metadata_end_t cmpl; void *priv; }; @@ -240,7 +252,7 @@ static int _raw_ram_load_all_drain(ocf_cache_t cache, struct ocf_metadata_raw *raw = context->raw; return _raw_ram_drain_page(cache, raw, data, - page - raw->ssd_pages_offset); + page - context->ssd_pages_offset); } static void _raw_ram_load_all_complete(ocf_cache_t cache, @@ -256,11 +268,12 @@ static void _raw_ram_load_all_complete(ocf_cache_t cache, * RAM Implementation - Load all metadata elements from SSD */ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { struct _raw_ram_load_all_context *context; int result; + ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -270,9 +283,11 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; + context->ssd_pages_offset = raw->ssd_pages_offset + + _raw_ram_segment_size_on_ssd(raw) * flapping_idx; result = metadata_io_read_i_asynch(cache, cache->mngt_queue, context, - raw->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->ssd_pages, 0, _raw_ram_load_all_drain, _raw_ram_load_all_complete); if (result) _raw_ram_load_all_complete(cache, context, result); @@ -280,6 +295,7 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, struct _raw_ram_flush_all_context { struct ocf_metadata_raw *raw; + uint64_t ssd_pages_offset; ocf_metadata_end_t cmpl; void *priv; }; @@ -299,7 +315,7 @@ static int _raw_ram_flush_all_fill(ocf_cache_t cache, ENV_BUG_ON(!_raw_ssd_page_is_valid(raw, page)); ENV_BUG_ON(size > PAGE_SIZE); - raw_page = page - raw->ssd_pages_offset; + raw_page = page - context->ssd_pages_offset; line = raw_page * raw->entries_in_page; OCF_DEBUG_PARAM(cache, "Line = %u, Page = %u", line, raw_page); @@ -328,11 +344,11 @@ static void _raw_ram_flush_all_complete(ocf_cache_t cache, * RAM Implementation - Flush all elements */ static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { struct _raw_ram_flush_all_context *context; int result; - + ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -342,9 +358,11 @@ static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; + context->ssd_pages_offset = raw->ssd_pages_offset + + _raw_ram_segment_size_on_ssd(raw) * flapping_idx; result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context, - raw->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->ssd_pages, 0, _raw_ram_flush_all_fill, _raw_ram_flush_all_complete, raw->mio_conc); if (result) diff --git a/src/metadata/metadata_raw.h b/src/metadata/metadata_raw.h index b63512c..b016dee 100644 --- a/src/metadata/metadata_raw.h +++ b/src/metadata/metadata_raw.h @@ -69,6 +69,7 @@ struct ocf_metadata_raw { uint32_t entry_size; /*!< Size of particular entry */ uint32_t entries_in_page; /*!< Numbers of entries in one page*/ uint64_t entries; /*!< Numbers of entries */ + bool flapping; /* !< Supports flapping */ /** * @name Location on cache device description @@ -129,10 +130,12 @@ struct raw_iface { ctx_data_t *data, uint64_t page, uint64_t count); void (*load_all)(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, + unsigned flapping_idx); void (*flush_all)(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, + unsigned flapping_idx); void (*flush_mark)(ocf_cache_t cache, struct ocf_request *req, uint32_t map_idx, int to_state, uint8_t start, @@ -269,12 +272,13 @@ static inline int ocf_metadata_raw_update(ocf_cache_t cache, * @param raw - RAW descriptor * @param cmpl - Completion callback * @param priv - Completion callback context + * @param flapping_idx - Index of flapping segment version */ static inline void ocf_metadata_raw_load_all(ocf_cache_t cache, - struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + struct ocf_metadata_raw *raw, ocf_metadata_end_t cmpl, + void *priv, unsigned flapping_idx) { - raw->iface->load_all(cache, raw, cmpl, priv); + raw->iface->load_all(cache, raw, cmpl, priv, flapping_idx); } /** @@ -284,12 +288,13 @@ static inline void ocf_metadata_raw_load_all(ocf_cache_t cache, * @param raw - RAW descriptor * @param cmpl - Completion callback * @param priv - Completion callback context + * @param flapping_idx - Index of flapping segment version */ static inline void ocf_metadata_raw_flush_all(ocf_cache_t cache, - struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + struct ocf_metadata_raw *raw, ocf_metadata_end_t cmpl, + void *priv, unsigned flapping_idx) { - raw->iface->flush_all(cache, raw, cmpl, priv); + raw->iface->flush_all(cache, raw, cmpl, priv, flapping_idx); } diff --git a/src/metadata/metadata_raw_dynamic.c b/src/metadata/metadata_raw_dynamic.c index a776384..50002ae 100644 --- a/src/metadata/metadata_raw_dynamic.c +++ b/src/metadata/metadata_raw_dynamic.c @@ -36,10 +36,21 @@ /* * Check if page is valid for specified RAW descriptor */ + +uint32_t raw_dynamic_segment_size_on_ssd(struct ocf_metadata_raw *raw) +{ + const size_t alignment = 128 * KiB / PAGE_SIZE; + + return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; +} + static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) { + uint32_t size = raw_dynamic_segment_size_on_ssd(raw) * + (raw->flapping ? 2 : 1); + ENV_BUG_ON(page < raw->ssd_pages_offset); - ENV_BUG_ON(page >= (raw->ssd_pages_offset + raw->ssd_pages)); + ENV_BUG_ON(page >= (raw->ssd_pages_offset + size)); return true; } @@ -212,9 +223,9 @@ size_t raw_dynamic_size_of(ocf_cache_t cache, */ uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw) { - const size_t alignment = 128 * KiB / PAGE_SIZE; + size_t flapping_factor = raw->flapping ? 2 : 1; - return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; + return raw_dynamic_segment_size_on_ssd(raw) * flapping_factor; } /* @@ -337,6 +348,7 @@ int raw_dynamic_update(ocf_cache_t cache, struct raw_dynamic_load_all_context { struct ocf_metadata_raw *raw; + unsigned flapping_idx; struct ocf_request *req; ocf_cache_t cache; struct ocf_io *io; @@ -388,14 +400,19 @@ static int raw_dynamic_load_all_read(struct ocf_request *req) { struct raw_dynamic_load_all_context *context = req->priv; struct ocf_metadata_raw *raw = context->raw; + uint64_t ssd_pages_offset; uint64_t count; int result; + ssd_pages_offset = raw->ssd_pages_offset + + raw_dynamic_segment_size_on_ssd(raw) * + context->flapping_idx; + count = metadata_io_size(context->i_page, raw->ssd_pages); /* Allocate IO */ context->io = ocf_new_cache_io(context->cache, req->io_queue, - PAGES_TO_BYTES(raw->ssd_pages_offset + context->i_page), + PAGES_TO_BYTES(ssd_pages_offset + context->i_page), PAGES_TO_BYTES(count), OCF_READ, 0, 0); if (!context->io) { @@ -453,11 +470,12 @@ static int raw_dynamic_load_all_update(struct ocf_request *req) } void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { struct raw_dynamic_load_all_context *context; int result; + ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vzalloc(sizeof(*context)); @@ -465,6 +483,7 @@ void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM); context->raw = raw; + context->flapping_idx = flapping_idx; context->cache = cache; context->cmpl = cmpl; context->priv = priv; @@ -509,6 +528,7 @@ err_data: struct raw_dynamic_flush_all_context { struct ocf_metadata_raw *raw; + uint64_t ssd_pages_offset; ocf_metadata_end_t cmpl; void *priv; }; @@ -526,7 +546,7 @@ static int raw_dynamic_flush_all_fill(ocf_cache_t cache, ENV_BUG_ON(!_raw_ssd_page_is_valid(raw, page)); - raw_page = page - raw->ssd_pages_offset; + raw_page = page - context->ssd_pages_offset; if (ctrl->pages[raw_page]) { OCF_DEBUG_PARAM(cache, "Page = %u", raw_page); @@ -555,11 +575,12 @@ static void raw_dynamic_flush_all_complete(ocf_cache_t cache, } void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { struct raw_dynamic_flush_all_context *context; int result; + ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -569,9 +590,11 @@ void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; + context->ssd_pages_offset = raw->ssd_pages_offset + + raw_dynamic_segment_size_on_ssd(raw) * flapping_idx; result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context, - raw->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->ssd_pages, 0, raw_dynamic_flush_all_fill, raw_dynamic_flush_all_complete, raw->mio_conc); diff --git a/src/metadata/metadata_raw_dynamic.h b/src/metadata/metadata_raw_dynamic.h index b83298a..f64d0f7 100644 --- a/src/metadata/metadata_raw_dynamic.h +++ b/src/metadata/metadata_raw_dynamic.h @@ -65,14 +65,14 @@ int raw_dynamic_update(ocf_cache_t cache, * from cache device */ void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); /* * RAW DYNAMIC - Flush all metadata of this RAW metadata container * to cache device */ void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); /* * RAW DYNAMIC - Mark specified entry to be flushed diff --git a/src/metadata/metadata_raw_volatile.c b/src/metadata/metadata_raw_volatile.c index 82129fb..a7b4e15 100644 --- a/src/metadata/metadata_raw_volatile.c +++ b/src/metadata/metadata_raw_volatile.c @@ -41,7 +41,7 @@ int raw_volatile_update(ocf_cache_t cache, * RAW volatile Implementation - Load all metadata elements from SSD */ void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { cmpl(priv, -OCF_ERR_NOT_SUPP); } @@ -50,7 +50,7 @@ void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, * RAM Implementation - Flush all elements */ void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv) + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) { cmpl(priv, 0); } diff --git a/src/metadata/metadata_raw_volatile.h b/src/metadata/metadata_raw_volatile.h index f3a37de..fe3a71e 100644 --- a/src/metadata/metadata_raw_volatile.h +++ b/src/metadata/metadata_raw_volatile.h @@ -28,13 +28,13 @@ int raw_volatile_update(ocf_cache_t cache, * RAW volatile Implementation - Load all metadata elements from SSD */ void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); /* * RAW volatile Implementation - Flush all elements */ void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, - ocf_metadata_end_t cmpl, void *priv); + ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); /* * RAM RAW volatile Implementation - Mark to Flush diff --git a/src/metadata/metadata_segment.c b/src/metadata/metadata_segment.c index bd7d58d..0253e68 100644 --- a/src/metadata/metadata_segment.c +++ b/src/metadata/metadata_segment.c @@ -138,22 +138,32 @@ void ocf_metadata_flush_segment(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_metadata_context *context = priv; - int segment = ocf_pipeline_arg_get_int(arg); - struct ocf_metadata_ctrl *ctrl = context->ctrl; + int segment_id = ocf_pipeline_arg_get_int(arg); + struct ocf_metadata_segment *segment = context->ctrl->segment[segment_id]; ocf_cache_t cache = context->cache; + unsigned next_flapping_idx = + ocf_metadata_superblock_get_next_flapping_idx( + segment->superblock); - ocf_metadata_raw_flush_all(cache, &ctrl->raw_desc[segment], - ocf_metadata_generic_complete, context); + next_flapping_idx = segment->raw->flapping ? next_flapping_idx : 0; + + ocf_metadata_raw_flush_all(cache, segment->raw, + ocf_metadata_generic_complete, context, + next_flapping_idx); } void ocf_metadata_load_segment(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_metadata_context *context = priv; - int segment = ocf_pipeline_arg_get_int(arg); - struct ocf_metadata_ctrl *ctrl = context->ctrl; + int segment_id = ocf_pipeline_arg_get_int(arg); + struct ocf_metadata_segment *segment = context->ctrl->segment[segment_id]; ocf_cache_t cache = context->cache; + unsigned flapping_idx = ocf_metadata_superblock_get_flapping_idx( + segment->superblock); - ocf_metadata_raw_load_all(cache, &ctrl->raw_desc[segment], - ocf_metadata_generic_complete, context); + flapping_idx = segment->raw->flapping ? flapping_idx : 0; + + ocf_metadata_raw_load_all(cache, segment->raw, + ocf_metadata_generic_complete, context, flapping_idx); } diff --git a/src/metadata/metadata_superblock.c b/src/metadata/metadata_superblock.c index da5d656..a75bce0 100644 --- a/src/metadata/metadata_superblock.c +++ b/src/metadata/metadata_superblock.c @@ -325,11 +325,21 @@ static void ocf_metadata_flush_superblock_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_metadata_context *context = priv; + struct ocf_metadata_ctrl *ctrl; + struct ocf_superblock_config *sb_config; ocf_cache_t cache = context->cache; - if (error) + if (error) { ocf_metadata_error(cache); + goto end; + } + ctrl = context->ctrl; + sb_config = METADATA_MEM_POOL(ctrl, metadata_segment_sb_config); + + sb_config->flapping_idx = (sb_config->flapping_idx + 1) % 2; + +end: context->cmpl(context->priv, error); ocf_pipeline_destroy(pipeline); } @@ -357,15 +367,7 @@ static void ocf_metadata_flush_disk(ocf_pipeline_t pipeline, ocf_metadata_flush_disk_end, context); } -struct ocf_pipeline_arg ocf_metadata_flush_sb_calculate_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_arg ocf_metadata_flush_sb_flush_segment_args[] = { - OCF_PL_ARG_INT(metadata_segment_sb_config), +struct ocf_pipeline_arg ocf_metadata_flush_sb_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), @@ -379,9 +381,12 @@ struct ocf_pipeline_properties ocf_metadata_flush_sb_pipeline_props = { OCF_PL_STEP(ocf_metadata_flush_superblock_prepare), OCF_PL_STEP(ocf_metadata_calculate_crc_sb_config), OCF_PL_STEP_FOREACH(ocf_metadata_calculate_crc, - ocf_metadata_flush_sb_calculate_crc_args), + ocf_metadata_flush_sb_args), OCF_PL_STEP_FOREACH(ocf_metadata_flush_segment, - ocf_metadata_flush_sb_flush_segment_args), + ocf_metadata_flush_sb_args), + OCF_PL_STEP(ocf_metadata_flush_disk), + OCF_PL_STEP_ARG_INT(ocf_metadata_flush_segment, + metadata_segment_sb_config), OCF_PL_STEP(ocf_metadata_flush_disk), OCF_PL_STEP_TERMINATOR(), }, @@ -484,6 +489,22 @@ bool ocf_metadata_superblock_get_clean_shutdown( return sb->config->clean_shutdown; } +unsigned ocf_metadata_superblock_get_flapping_idx( + struct ocf_metadata_segment *self) +{ + struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self); + + return sb->config->flapping_idx; +} + +unsigned ocf_metadata_superblock_get_next_flapping_idx( + struct ocf_metadata_segment *self) +{ + struct ocf_metadata_superblock *sb = _ocf_segment_to_sb(self); + + return (sb->config->flapping_idx + 1) % 2; +} + int ocf_metadata_validate_superblock(ocf_ctx_t ctx, struct ocf_superblock_config *superblock) { diff --git a/src/metadata/metadata_superblock.h b/src/metadata/metadata_superblock.h index 87528f5..30f55a4 100644 --- a/src/metadata/metadata_superblock.h +++ b/src/metadata/metadata_superblock.h @@ -29,6 +29,8 @@ struct ocf_superblock_config { uint32_t metadata_version; + unsigned flapping_idx; + /* Currently set cache mode */ ocf_cache_mode_t cache_mode; @@ -97,6 +99,12 @@ void ocf_metadata_superblock_set_checksum( bool ocf_metadata_superblock_get_clean_shutdown( struct ocf_metadata_segment *self); +unsigned ocf_metadata_superblock_get_flapping_idx( + struct ocf_metadata_segment *self); + +unsigned ocf_metadata_superblock_get_next_flapping_idx( + struct ocf_metadata_segment *self); + int ocf_metadata_validate_superblock(ocf_ctx_t ctx, struct ocf_superblock_config *superblock); From 98cb9bff706520238583525387b20821390269d9 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 13 Dec 2021 15:57:25 +0100 Subject: [PATCH 2/3] pyocf: Use bigger cache device size in tests As amount of fixed size metadata allocated by OCF grows, we need to adjust test to not try to start cache on device that is too small. Signed-off-by: Robert Baldyga --- tests/functional/tests/basic/test_pyocf.py | 12 ++--- .../functional/tests/engine/test_io_flags.py | 4 +- tests/functional/tests/engine/test_pp.py | 16 +++---- tests/functional/tests/engine/test_read.py | 4 +- .../tests/eviction/test_eviction.py | 12 ++--- .../tests/flush/test_flush_after_mngmt.py | 4 +- .../tests/management/test_add_remove.py | 22 +++++----- .../tests/management/test_attach_cache.py | 4 +- .../tests/management/test_change_params.py | 8 ++-- .../tests/management/test_start_stop.py | 24 +++++----- .../tests/security/test_management_fuzzy.py | 44 +++++++++---------- .../security/test_management_start_fuzzy.py | 4 +- .../tests/security/test_negative_io.py | 2 +- .../tests/security/test_secure_erase.py | 4 +- 14 files changed, 82 insertions(+), 82 deletions(-) diff --git a/tests/functional/tests/basic/test_pyocf.py b/tests/functional/tests/basic/test_pyocf.py index a1530c8..7eacbaa 100644 --- a/tests/functional/tests/basic/test_pyocf.py +++ b/tests/functional/tests/basic/test_pyocf.py @@ -20,8 +20,8 @@ def test_ctx_fixture(pyocf_ctx): def test_simple_wt_write(pyocf_ctx): - cache_device = Volume(S.from_MiB(30)) - core_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) + core_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) core = Core.using_device(core_device) @@ -52,21 +52,21 @@ def test_simple_wt_write(pyocf_ctx): def test_start_corrupted_metadata_lba(pyocf_ctx): - cache_device = ErrorDevice(S.from_MiB(30), error_sectors=set([0])) + cache_device = ErrorDevice(S.from_MiB(50), error_sectors=set([0])) with pytest.raises(OcfError, match="OCF_ERR_WRITE_CACHE"): cache = Cache.start_on_device(cache_device) def test_load_cache_no_preexisting_data(pyocf_ctx): - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) with pytest.raises(OcfError, match="OCF_ERR_NO_METADATA"): cache = Cache.load_from_device(cache_device) def test_load_cache(pyocf_ctx): - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) cache.stop() @@ -75,7 +75,7 @@ def test_load_cache(pyocf_ctx): def test_load_cache_recovery(pyocf_ctx): - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) diff --git a/tests/functional/tests/engine/test_io_flags.py b/tests/functional/tests/engine/test_io_flags.py index 5b76ade..8f7d22f 100644 --- a/tests/functional/tests/engine/test_io_flags.py +++ b/tests/functional/tests/engine/test_io_flags.py @@ -84,8 +84,8 @@ def test_io_flags(pyocf_ctx, cache_mode): data = bytes(block_size) - cache_device = FlagsValVolume(Size.from_MiB(30), flags) - core_device = FlagsValVolume(Size.from_MiB(30), flags) + cache_device = FlagsValVolume(Size.from_MiB(50), flags) + core_device = FlagsValVolume(Size.from_MiB(50), flags) cache = Cache.start_on_device(cache_device, cache_mode=cache_mode) core = Core.using_device(core_device) diff --git a/tests/functional/tests/engine/test_pp.py b/tests/functional/tests/engine/test_pp.py index b73f124..c9dde8d 100644 --- a/tests/functional/tests/engine/test_pp.py +++ b/tests/functional/tests/engine/test_pp.py @@ -26,8 +26,8 @@ def test_init_nhit(pyocf_ctx, promotion_policy): * verify that promotion policy type is properly reflected in stats """ - cache_device = Volume(Size.from_MiB(30)) - core_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) + core_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device(cache_device, promotion_policy=promotion_policy) core = Core.using_device(core_device) @@ -53,8 +53,8 @@ def test_change_to_nhit_and_back_io_in_flight(pyocf_ctx): """ # Step 1 - cache_device = Volume(Size.from_MiB(30)) - core_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) + core_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device(cache_device) core = Core.using_device(core_device) @@ -177,8 +177,8 @@ def test_promoted_after_hits_various_thresholds( """ # Step 1 - cache_device = Volume(Size.from_MiB(30)) - core_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) + core_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device(cache_device, promotion_policy=PromotionPolicy.NHIT) core = Core.using_device(core_device) @@ -260,8 +260,8 @@ def test_partial_hit_promotion(pyocf_ctx): """ # Step 1 - cache_device = Volume(Size.from_MiB(30)) - core_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) + core_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device(cache_device) core = Core.using_device(core_device) diff --git a/tests/functional/tests/engine/test_read.py b/tests/functional/tests/engine/test_read.py index d875f4b..48c2e59 100644 --- a/tests/functional/tests/engine/test_read.py +++ b/tests/functional/tests/engine/test_read.py @@ -259,8 +259,8 @@ def test_read_data_consistency(pyocf_ctx, cacheline_size, cache_mode, rand_seed) result_b = bytes(WORKSET_SIZE) - cache_device = Volume(Size.from_MiB(30)) - core_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) + core_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=CacheMode.WO, cache_line_size=cacheline_size diff --git a/tests/functional/tests/eviction/test_eviction.py b/tests/functional/tests/eviction/test_eviction.py index 539b358..d2cc1e8 100644 --- a/tests/functional/tests/eviction/test_eviction.py +++ b/tests/functional/tests/eviction/test_eviction.py @@ -24,7 +24,7 @@ logger = logging.getLogger(__name__) @pytest.mark.parametrize("mode", [CacheMode.WT]) def test_eviction_two_cores(pyocf_ctx, mode: CacheMode, cls: CacheLineSize): """Test if eviction works correctly when remapping cachelines between distinct cores.""" - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) core_device1 = Volume(Size.from_MiB(40)) core_device2 = Volume(Size.from_MiB(40)) @@ -52,9 +52,9 @@ def test_eviction_two_cores(pyocf_ctx, mode: CacheMode, cls: CacheLineSize): @pytest.mark.parametrize("mode", [CacheMode.WT, CacheMode.WB, CacheMode.WO]) def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLineSize): """Test if eviction does not occur when IO greater than cache size is submitted.""" - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) - core_device = Volume(Size.from_MiB(5)) + core_device = Volume(Size.from_MiB(200)) cache = Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls) cache_size = cache.get_stats()["conf"]["size"] core_exported = Core.using_device(core_device) @@ -74,10 +74,10 @@ def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLin ), "Occupancy after first IO" prev_writes_to_core = stats["block"]["core_volume_wr"]["value"] - # Anything below 5 MiB is a valid size (less than core device size) + # Anything below 200 MiB is a valid size (less than core device size) # Writing over cache size (to the offset above first io) in this case should go # directly to core and shouldn't trigger eviction - io_size_bigger_than_cache = Size.from_MiB(2) + io_size_bigger_than_cache = Size.from_MiB(100) io_offset = valid_io_size test_data = Data(io_size_bigger_than_cache) send_io(core_exported, test_data, io_offset) @@ -106,7 +106,7 @@ def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLin @pytest.mark.parametrize("cls", CacheLineSize) def test_evict_overflown_pinned(pyocf_ctx, cls: CacheLineSize): """ Verify if overflown pinned ioclass is evicted """ - cache_device = Volume(Size.from_MiB(35)) + cache_device = Volume(Size.from_MiB(50)) core_device = Volume(Size.from_MiB(100)) cache = Cache.start_on_device( cache_device, cache_mode=CacheMode.WT, cache_line_size=cls diff --git a/tests/functional/tests/flush/test_flush_after_mngmt.py b/tests/functional/tests/flush/test_flush_after_mngmt.py index 3cb03b3..e9aa185 100644 --- a/tests/functional/tests/flush/test_flush_after_mngmt.py +++ b/tests/functional/tests/flush/test_flush_after_mngmt.py @@ -75,8 +75,8 @@ def test_flush_after_mngmt(pyocf_ctx): data = bytes(block_size) - cache_device = FlushValVolume(Size.from_MiB(30)) - core_device = FlushValVolume(Size.from_MiB(30)) + cache_device = FlushValVolume(Size.from_MiB(50)) + core_device = FlushValVolume(Size.from_MiB(50)) # after start cache VC must be cleared cache = Cache.start_on_device(cache_device, cache_mode=CacheMode.WT) diff --git a/tests/functional/tests/management/test_add_remove.py b/tests/functional/tests/management/test_add_remove.py index d5e2dd0..d071989 100644 --- a/tests/functional/tests/management/test_add_remove.py +++ b/tests/functional/tests/management/test_add_remove.py @@ -19,7 +19,7 @@ from pyocf.types.shared import OcfError, OcfCompletion, CacheLineSize @pytest.mark.parametrize("cls", CacheLineSize) def test_adding_core(pyocf_ctx, cache_mode, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cache_mode, cache_line_size=cls ) @@ -44,7 +44,7 @@ def test_adding_core(pyocf_ctx, cache_mode, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_removing_core(pyocf_ctx, cache_mode, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cache_mode, cache_line_size=cls ) @@ -68,7 +68,7 @@ def test_removing_core(pyocf_ctx, cache_mode, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_remove_dirty_no_flush(pyocf_ctx, cache_mode, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cache_mode, cache_line_size=cls ) @@ -90,7 +90,7 @@ def test_remove_dirty_no_flush(pyocf_ctx, cache_mode, cls): def test_30add_remove(pyocf_ctx): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) # Create core device @@ -111,7 +111,7 @@ def test_30add_remove(pyocf_ctx): def test_10add_remove_with_io(pyocf_ctx): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) # Create core device @@ -143,7 +143,7 @@ def test_10add_remove_with_io(pyocf_ctx): def test_add_remove_30core(pyocf_ctx): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device) core_devices = [] core_amount = 30 @@ -176,7 +176,7 @@ def test_adding_to_random_cache(pyocf_ctx): # Create 5 cache devices for i in range(0, cache_amount): - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, name=f"cache{i}") cache_devices.append(cache) @@ -202,7 +202,7 @@ def test_adding_to_random_cache(pyocf_ctx): @pytest.mark.parametrize("cls", CacheLineSize) def test_adding_core_twice(pyocf_ctx, cache_mode, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cache_mode, cache_line_size=cls ) @@ -227,13 +227,13 @@ def test_adding_core_twice(pyocf_ctx, cache_mode, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_adding_core_already_used(pyocf_ctx, cache_mode, cls): # Start first cache device - cache_device1 = Volume(S.from_MiB(30)) + cache_device1 = Volume(S.from_MiB(50)) cache1 = Cache.start_on_device( cache_device1, cache_mode=cache_mode, cache_line_size=cls, name="cache1" ) # Start second cache device - cache_device2 = Volume(S.from_MiB(30)) + cache_device2 = Volume(S.from_MiB(50)) cache2 = Cache.start_on_device( cache_device2, cache_mode=cache_mode, cache_line_size=cls, name="cache2" ) @@ -261,7 +261,7 @@ def test_adding_core_already_used(pyocf_ctx, cache_mode, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_add_remove_incrementally(pyocf_ctx, cache_mode, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cache_mode, cache_line_size=cls ) diff --git a/tests/functional/tests/management/test_attach_cache.py b/tests/functional/tests/management/test_attach_cache.py index 8150b3b..6915ee7 100644 --- a/tests/functional/tests/management/test_attach_cache.py +++ b/tests/functional/tests/management/test_attach_cache.py @@ -35,7 +35,7 @@ logger = logging.getLogger(__name__) @pytest.mark.parametrize("cls", CacheLineSize) @pytest.mark.parametrize("mode", [CacheMode.WB, CacheMode.WT, CacheMode.WO]) -@pytest.mark.parametrize("new_cache_size", [25, 45]) +@pytest.mark.parametrize("new_cache_size", [80, 120]) def test_attach_different_size( pyocf_ctx, new_cache_size, mode: CacheMode, cls: CacheLineSize ): @@ -43,7 +43,7 @@ def test_attach_different_size( attach cache with different size and trigger IO. Verify if occupancy thresold is respected with both original and new cache device. """ - cache_device = Volume(Size.from_MiB(35)) + cache_device = Volume(Size.from_MiB(100)) core_device = Volume(Size.from_MiB(100)) cache = Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls) core = Core.using_device(core_device) diff --git a/tests/functional/tests/management/test_change_params.py b/tests/functional/tests/management/test_change_params.py index 7f32bb1..40b6847 100644 --- a/tests/functional/tests/management/test_change_params.py +++ b/tests/functional/tests/management/test_change_params.py @@ -17,7 +17,7 @@ from pyocf.types.shared import CacheLineSize @pytest.mark.parametrize("cls", CacheLineSize) def test_change_cache_mode(pyocf_ctx, from_cm, to_cm, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=from_cm, cache_line_size=cls ) @@ -32,7 +32,7 @@ def test_change_cache_mode(pyocf_ctx, from_cm, to_cm, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_change_cleaning_policy(pyocf_ctx, cm, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, cache_line_size=cls ) @@ -57,7 +57,7 @@ def test_change_cleaning_policy(pyocf_ctx, cm, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_cache_change_seq_cut_off_policy(pyocf_ctx, cm, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, cache_line_size=cls ) @@ -96,7 +96,7 @@ def test_cache_change_seq_cut_off_policy(pyocf_ctx, cm, cls): @pytest.mark.parametrize("cls", CacheLineSize) def test_core_change_seq_cut_off_policy(pyocf_ctx, cm, cls): # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, cache_line_size=cls ) diff --git a/tests/functional/tests/management/test_start_stop.py b/tests/functional/tests/management/test_start_stop.py index bfe4c26..2d2b765 100644 --- a/tests/functional/tests/management/test_start_stop.py +++ b/tests/functional/tests/management/test_start_stop.py @@ -26,7 +26,7 @@ def test_start_check_default(pyocf_ctx): """Test if default values are correct after start. """ - cache_device = Volume(Size.from_MiB(40)) + cache_device = Volume(Size.from_MiB(50)) core_device = Volume(Size.from_MiB(10)) cache = Cache.start_on_device(cache_device) @@ -50,7 +50,7 @@ def test_start_write_first_and_check_mode(pyocf_ctx, mode: CacheMode, cls: Cache After start check proper cache mode behaviour, starting with write operation. """ - cache_device = Volume(Size.from_MiB(40)) + cache_device = Volume(Size.from_MiB(50)) core_device = Volume(Size.from_MiB(10)) cache = Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls) core_exported = Core.using_device(core_device) @@ -88,7 +88,7 @@ def test_start_read_first_and_check_mode(pyocf_ctx, mode: CacheMode, cls: CacheL After start check proper cache mode behaviour, starting with read operation. """ - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) core_device = Volume(Size.from_MiB(5)) cache = Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls) core_exported = Core.using_device(core_device) @@ -131,7 +131,7 @@ def test_start_params(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, layout: Me Check if cache starts without errors. If possible check whether cache reports properly set parameters. """ - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) queue_size = randrange(60000, 2**32) unblock_size = randrange(1, queue_size) volatile_metadata = randrange(2) == 1 @@ -169,7 +169,7 @@ def test_stop(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, with_flush: bool): Check if cache is stopped properly in different modes with or without preceding flush operation. """ - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) core_device = Volume(Size.from_MiB(5)) cache = Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls) core_exported = Core.using_device(core_device) @@ -204,7 +204,7 @@ def test_start_stop_multiple(pyocf_ctx): caches = [] caches_no = randrange(6, 11) for i in range(1, caches_no): - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) cache_name = f"cache{i}" cache_mode = CacheMode(randrange(0, len(CacheMode))) size = 4096 * 2**randrange(0, len(CacheLineSize)) @@ -236,7 +236,7 @@ def test_100_start_stop(pyocf_ctx): """ for i in range(1, 101): - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) cache_name = f"cache{i}" cache_mode = CacheMode(randrange(0, len(CacheMode))) size = 4096 * 2**randrange(0, len(CacheLineSize)) @@ -271,7 +271,7 @@ def test_start_stop_incrementally(pyocf_ctx): while run: if add: for i in range(0, randrange(3, 5) if increase else randrange(1, 3)): - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) cache_name = f"cache{next(counter)}" cache_mode = CacheMode(randrange(0, len(CacheMode))) size = 4096 * 2**randrange(0, len(CacheLineSize)) @@ -311,8 +311,8 @@ def test_start_cache_same_id(pyocf_ctx, mode, cls): Check that OCF does not allow for 2 caches to be started with the same cache_name """ - cache_device1 = Volume(Size.from_MiB(20)) - cache_device2 = Volume(Size.from_MiB(20)) + cache_device1 = Volume(Size.from_MiB(50)) + cache_device2 = Volume(Size.from_MiB(50)) cache_name = "cache" cache = Cache.start_on_device(cache_device1, cache_mode=mode, @@ -342,7 +342,7 @@ def test_start_cache_huge_device(pyocf_ctx_log_buffer, cls): def submit_io(self, io): io.contents._end(io, 0) - cache_device = HugeDevice(Size.from_MiB(20)) + cache_device = HugeDevice(Size.from_MiB(50)) with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"): cache = Cache.start_on_device(cache_device, cache_line_size=cls, metadata_volatile=True) @@ -360,7 +360,7 @@ def test_start_cache_same_device(pyocf_ctx, mode, cls): Check that OCF does not allow for 2 caches using the same cache device to be started """ - cache_device = Volume(Size.from_MiB(20)) + cache_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=mode, cache_line_size=cls, name="cache1" ) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index dbe3950..0abff54 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -41,7 +41,7 @@ def test_neg_change_cache_mode(pyocf_ctx, cm, cls): :param cls: cache line size we start with """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Change cache mode to invalid one and check if failed @@ -65,7 +65,7 @@ def test_neg_set_cleaning_policy(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Set cleaning policy to invalid one and check if failed @@ -90,7 +90,7 @@ def test_neg_attach_cls(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache(owner=cache_device.owner, cache_mode=cm, cache_line_size=cls) cache.start_cache() @@ -115,7 +115,7 @@ def test_neg_cache_set_seq_cut_off_policy(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create 2 core devices @@ -149,7 +149,7 @@ def test_neg_cache_set_seq_cut_off_promotion(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create 2 core devices @@ -185,7 +185,7 @@ def test_neg_core_set_seq_cut_off_promotion(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create core device @@ -218,7 +218,7 @@ def test_neg_cache_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create 2 core devices @@ -254,7 +254,7 @@ def test_neg_core_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create core device @@ -287,7 +287,7 @@ def test_neg_core_set_seq_cut_off_policy(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Create core device @@ -318,7 +318,7 @@ def test_neg_set_alru_param(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Change invalid alru param and check if failed @@ -355,7 +355,7 @@ def test_neg_set_alru_param_value(pyocf_ctx, cm, cls, param): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) cache.set_cleaning_policy(CleaningPolicy.ALRU) @@ -382,7 +382,7 @@ def test_neg_set_acp_param(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Change invalid acp param and check if failed @@ -415,7 +415,7 @@ def test_neg_set_acp_param_value(pyocf_ctx, cm, cls, param): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) cache.set_cleaning_policy(CleaningPolicy.ACP) @@ -442,7 +442,7 @@ def test_neg_set_promotion_policy(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Change to invalid promotion policy and check if failed @@ -466,7 +466,7 @@ def test_neg_set_nhit_promotion_policy_param(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, @@ -496,7 +496,7 @@ def test_neg_set_nhit_promotion_policy_param_trigger(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, @@ -528,7 +528,7 @@ def test_neg_set_nhit_promotion_policy_param_threshold(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=cm, @@ -559,7 +559,7 @@ def test_neg_set_ioclass_max_size(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Set invalid max size and check if failed @@ -589,7 +589,7 @@ def test_neg_set_ioclass_priority(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Set invalid priority and check if failed @@ -619,7 +619,7 @@ def test_neg_set_ioclass_cache_mode(pyocf_ctx, cm, cls): :return: """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) # Set invalid cache mode and check if failed @@ -644,7 +644,7 @@ def test_neg_set_ioclass_name(pyocf_ctx): invalid_chars += [",", '"'] # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=CacheMode.WT, cache_line_size=CacheLineSize.LINE_4KiB ) @@ -669,7 +669,7 @@ def test_neg_set_ioclass_name_len(pyocf_ctx): """ # Start cache device - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device( cache_device, cache_mode=CacheMode.WT, cache_line_size=CacheLineSize.LINE_4KiB ) diff --git a/tests/functional/tests/security/test_management_start_fuzzy.py b/tests/functional/tests/security/test_management_start_fuzzy.py index 11a8764..2af5e91 100644 --- a/tests/functional/tests/security/test_management_start_fuzzy.py +++ b/tests/functional/tests/security/test_management_start_fuzzy.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) def try_start_cache(**config): - cache_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) cache = Cache.start_on_device(cache_device, **config) cache.stop() @@ -58,7 +58,7 @@ def test_fuzzy_start_name(pyocf_ctx, string_randomize, cm, cls): :param cm: cache mode value to start cache with :param cls: cache line size value to start cache with """ - cache_device = Volume(Size.from_MiB(30)) + cache_device = Volume(Size.from_MiB(50)) incorrect_values = [''] try: cache = Cache.start_on_device(cache_device, name=string_randomize, cache_mode=cm, diff --git a/tests/functional/tests/security/test_negative_io.py b/tests/functional/tests/security/test_negative_io.py index 2eefc16..3d1e3bb 100644 --- a/tests/functional/tests/security/test_negative_io.py +++ b/tests/functional/tests/security/test_negative_io.py @@ -182,7 +182,7 @@ def test_neg_io_direction(pyocf_ctx, c_int_randomize): assert completion.results["err"] != 0 -def prepare_cache_and_core(core_size: Size, cache_size: Size = Size.from_MiB(20)): +def prepare_cache_and_core(core_size: Size, cache_size: Size = Size.from_MiB(50)): cache_device = Volume(cache_size) core_device = Volume(core_size) diff --git a/tests/functional/tests/security/test_secure_erase.py b/tests/functional/tests/security/test_secure_erase.py index 181bd92..8123f6c 100644 --- a/tests/functional/tests/security/test_secure_erase.py +++ b/tests/functional/tests/security/test_secure_erase.py @@ -77,7 +77,7 @@ def test_secure_erase_simple_io_read_misses(cache_mode): ctx.register_volume_type(Volume) - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=cache_mode) core_device = Volume(S.from_MiB(50)) @@ -170,7 +170,7 @@ def test_secure_erase_simple_io_cleaning(): ctx.register_volume_type(Volume) - cache_device = Volume(S.from_MiB(30)) + cache_device = Volume(S.from_MiB(50)) cache = Cache.start_on_device(cache_device, cache_mode=CacheMode.WB) core_device = Volume(S.from_MiB(100)) From df9a9f272280011b71eaec9aed1a9a3f82e33e5c Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 15 Dec 2021 12:26:09 +0100 Subject: [PATCH 3/3] Read superblock sections from cache volume during activate Because of metadata flapping it is much more complicated to capture those sections in flight in standby mode, so we read them directly from the cache volume during the activate. Signed-off-by: Robert Baldyga --- src/concurrency/ocf_pio_concurrency.c | 5 +---- src/metadata/metadata_passive_update.c | 3 --- src/mngt/ocf_mngt_cache.c | 23 ++++++----------------- 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/concurrency/ocf_pio_concurrency.c b/src/concurrency/ocf_pio_concurrency.c index 854572f..c30490e 100644 --- a/src/concurrency/ocf_pio_concurrency.c +++ b/src/concurrency/ocf_pio_concurrency.c @@ -18,7 +18,7 @@ struct pio_ctx { uint64_t first_entry; uint64_t begin; uint64_t end; - } segments[5]; + } segments[2]; }; #define OUT_OF_RANGE -1 @@ -181,9 +181,6 @@ int ocf_pio_concurrency_init(struct ocf_alock **self, ocf_cache_t cache) uint32_t pages_to_alloc = 0; enum ocf_metadata_segment_id update_segments[] = { metadata_segment_sb_config, - metadata_segment_part_config, - metadata_segment_core_config, - metadata_segment_core_uuid, metadata_segment_collision, }; int i; diff --git a/src/metadata/metadata_passive_update.c b/src/metadata/metadata_passive_update.c index 207627a..282a62c 100644 --- a/src/metadata/metadata_passive_update.c +++ b/src/metadata/metadata_passive_update.c @@ -234,9 +234,6 @@ static int passive_io_resume(struct ocf_request *req) ocf_cache_line_t cache_etries = ocf_metadata_collision_table_entries(cache); enum ocf_metadata_segment_id update_segments[] = { metadata_segment_sb_config, - metadata_segment_part_config, - metadata_segment_core_config, - metadata_segment_core_uuid, metadata_segment_collision, }; int i; diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 0e33906..1584109 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -2216,19 +2216,17 @@ static void _ocf_mngt_activate_set_cache_device(ocf_pipeline_t pipeline, ocf_pipeline_next(pipeline); } -static void _ocf_mngt_activate_check_superblock_complete(void *priv, int error) +static void _ocf_mngt_activate_check_superblock(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; - if (error) - OCF_PL_FINISH_RET(context->pipeline, error); - result = ocf_metadata_validate_superblock(cache->owner, cache->conf_meta); if (result) - OCF_PL_FINISH_RET(context->pipeline, result); + OCF_PL_FINISH_RET(pipeline, result); if (cache->conf_meta->metadata_layout != cache->metadata.layout) { ocf_cache_log(cache, log_err, "Failed to activate standby instance: " @@ -2244,17 +2242,7 @@ static void _ocf_mngt_activate_check_superblock_complete(void *priv, int error) -OCF_ERR_CACHE_LINE_SIZE_MISMATCH); } - ocf_pipeline_next(context->pipeline); -} - -static void _ocf_mngt_activate_check_superblock(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_sb_crc_recovery(cache, - _ocf_mngt_activate_check_superblock_complete, context); + ocf_pipeline_next(pipeline); } static void _ocf_mngt_activate_compare_superblock_end( @@ -2378,8 +2366,9 @@ struct ocf_pipeline_properties _ocf_mngt_cache_activate_pipeline_properties = { .steps = { OCF_PL_STEP(_ocf_mngt_copy_uuid_data), OCF_PL_STEP(_ocf_mngt_activate_set_cache_device), - OCF_PL_STEP(_ocf_mngt_activate_check_superblock), OCF_PL_STEP(_ocf_mngt_activate_compare_superblock), + OCF_PL_STEP(_ocf_mngt_load_superblock), + OCF_PL_STEP(_ocf_mngt_activate_check_superblock), OCF_PL_STEP(_ocf_mngt_activate_init_properties), OCF_PL_STEP(_ocf_mngt_test_volume), OCF_PL_STEP(_ocf_mngt_init_promotion),