Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions src/mngt/ocf_mngt_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1319,19 +1319,24 @@ static void _ocf_mngt_attach_read_properties_end(void *priv, int error,
{
struct ocf_cache_attach_context *context = priv;

if (error != -OCF_ERR_NO_METADATA) {
if (!error) {
/*
* To prevent silent metadata overriding, return error if old
* metadata was detected when attempting to attach cache.
*/
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_METADATA_FOUND);
}
switch (error) {
case -OCF_ERR_NO_METADATA:
/* No metadata exists on the device */
OCF_PL_NEXT_RET(context->pipeline);
case 0:
case -OCF_ERR_METADATA_VER:
case -OCF_ERR_ADAPTER_MISMATCH:
case -OCF_ERR_ADAPTER_VER:
case -OCF_ERR_BLOCK_MODE_MISMATCH:
/*
* To prevent silent metadata overriding, return error if old
* metadata was detected when attempting to attach cache - also
* if it was created by incompatible OCF or adapter version.
*/
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_METADATA_FOUND);
default:
OCF_PL_FINISH_RET(context->pipeline, error);
}

/* No metadata exists on the device */
OCF_PL_NEXT_RET(context->pipeline);
}

static void _ocf_mngt_load_read_properties_end(void *priv, int error,
Expand Down
29 changes: 29 additions & 0 deletions tests/functional/tests/management/test_attach_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
CacheLineSize,
SeqCutOffPolicy,
OcfError,
OcfErrorCode,
)
from pyocf.types.volume import RamVolume
from pyocf.types.volume_core import CoreVolume
Expand Down Expand Up @@ -135,6 +136,34 @@ def test_detach_cache_zero_superblock(pyocf_ctx):
cache.stop()


def test_attach_cache_incompatible_metadata_version(pyocf_ctx):
"""Check if attaching a device holding metadata of a different version
without --force option reports that metadata was found.
"""
cache_device = RamVolume(Size.from_MiB(50))
cache = Cache.start_on_device(cache_device)
cache.stop()

# metadata_version follows clean_shutdown, dirty_flushed, padding and magic
version_offset = 8
version = int.from_bytes(
cache_device.data[version_offset : version_offset + 4], "little"
)
cache_device.data[version_offset : version_offset + 4] = (version ^ 0x0100).to_bytes(
4, "little"
)

cache = Cache(owner=pyocf_ctx)
cache.start_cache()

with pytest.raises(OcfError) as ex:
cache.attach_device(cache_device, force=False)
assert ex.value.error_code == OcfErrorCode.OCF_ERR_METADATA_FOUND

cache.attach_device(cache_device, force=True)
cache.stop()


def test_reattach_preserves_policy_params(pyocf_ctx):
"""Check if cleaning, promotion and prefetch policy parameters set before
detach are preserved after the cache device is attached again.
Expand Down
Loading