From adc52ba71e1f84e3a3ea09afcab75c1176d439d0 Mon Sep 17 00:00:00 2001 From: Jan Musial Date: Tue, 21 Jan 2020 15:24:57 +0100 Subject: [PATCH 1/3] Detect cache devices that would overflow ocf_cacheline_t Signed-off-by: Jan Musial --- src/metadata/metadata_hash.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/metadata/metadata_hash.c b/src/metadata/metadata_hash.c index c375807..eccaaf1 100644 --- a/src/metadata/metadata_hash.c +++ b/src/metadata/metadata_hash.c @@ -912,6 +912,7 @@ static int ocf_metadata_hash_init_variable_size(struct ocf_cache *cache, struct ocf_cache_line_settings *settings = (struct ocf_cache_line_settings *)&cache->metadata.settings; ocf_flush_page_synch_t lock_page, unlock_page; + uint64_t device_lines; OCF_DEBUG_TRACE(cache); @@ -919,7 +920,16 @@ static int ocf_metadata_hash_init_variable_size(struct ocf_cache *cache, ctrl = cache->metadata.iface_priv; - ctrl->device_lines = device_size / cache_line_size; + device_lines = device_size / cache_line_size; + if (device_lines >= (ocf_cache_line_t)(-1)){ + /* TODO: This is just a rough check. Most optimal one would be + * located in calculate_metadata_size. */ + ocf_cache_log(cache, log_err, "Device exceeds maximum suported size " + "with this cache line size. Try bigger cache line size."); + return -OCF_ERR_INVAL_CACHE_DEV; + } + + ctrl->device_lines = device_lines; if (settings->size != cache_line_size) /* Re-initialize settings with different cache line size */ From ecbb5cbc1b398cb3eadac63c5af3ea906413972c Mon Sep 17 00:00:00 2001 From: Jan Musial Date: Tue, 21 Jan 2020 13:37:06 +0100 Subject: [PATCH 2/3] Make RAM infinite in POSIX env Since the calculation that's being used right now isn't too acurate anyways, let's just get rid of it, maybe we'll find more memory-related bugs. Signed-off-by: Jan Musial --- env/posix/ocf_env.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env/posix/ocf_env.h b/env/posix/ocf_env.h index dc4952b..d255174 100644 --- a/env/posix/ocf_env.h +++ b/env/posix/ocf_env.h @@ -180,7 +180,7 @@ static inline void env_secure_free(const void *ptr, size_t size) static inline uint64_t env_get_free_memory(void) { - return sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); + return (uint64_t)(-1); } /* ALLOCATOR */ From e5aff609d998aa95d95c6ef04336c151e4421e42 Mon Sep 17 00:00:00 2001 From: Jan Musial Date: Wed, 15 Jan 2020 12:44:12 +0100 Subject: [PATCH 3/3] Add test for huge cache Signed-off-by: Jan Musial --- .../tests/management/test_start_stop.py | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/functional/tests/management/test_start_stop.py b/tests/functional/tests/management/test_start_stop.py index 17d9c67..f455ea1 100644 --- a/tests/functional/tests/management/test_start_stop.py +++ b/tests/functional/tests/management/test_start_stop.py @@ -4,7 +4,7 @@ # import logging -from ctypes import c_int, c_void_p, byref +from ctypes import c_int, c_void_p, byref, c_uint32 from random import randrange from itertools import count @@ -330,6 +330,31 @@ def test_start_cache_same_id(pyocf_ctx, mode, cls): cache.get_stats() +@pytest.mark.parametrize("cls", CacheLineSize) +def test_start_cache_huge_device(pyocf_ctx_log_buffer, cls): + """ + Test whether we can start cache which would overflow ocf_cache_line_t type. + pass_criteria: + - Starting cache on device too big to handle should fail + """ + class HugeDevice(Volume): + def get_length(self): + return Size.from_B((cls * c_uint32(-1).value)) + + def submit_io(self, io): + io.contents._end(io, 0) + + cache_device = HugeDevice(Size.from_MiB(20)) + + with pytest.raises(OcfError, match="OCF_ERR_START_CACHE_FAIL"): + cache = Cache.start_on_device(cache_device, cache_line_size=cls, metadata_volatile=True) + + assert any( + [line.find("exceeds maximum") > 0 for line in pyocf_ctx_log_buffer.get_lines()] + ), "Expected to find log notifying that max size was exceeded" + + + @pytest.mark.parametrize("mode", CacheMode) @pytest.mark.parametrize("cls", CacheLineSize) def test_start_cache_same_device(pyocf_ctx, mode, cls):