pyocf: replicated volume
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
parent
dcf3129ff8
commit
d2164e4ffd
92
tests/functional/pyocf/types/volume_replicated.py
Normal file
92
tests/functional/pyocf/types/volume_replicated.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#
|
||||||
|
# Copyright(c) 2022 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
from threading import Lock
|
||||||
|
from .volume import Volume, VOLUME_POISON
|
||||||
|
from .io import Io, IoDir
|
||||||
|
from ctypes import cast, c_void_p, CFUNCTYPE, c_int, POINTER, memmove, sizeof, pointer
|
||||||
|
|
||||||
|
|
||||||
|
class ReplicatedVolume(Volume):
|
||||||
|
def __init__(self, primary: Volume, secondary: Volume, uuid=None):
|
||||||
|
super().__init__(uuid)
|
||||||
|
self.primary = primary
|
||||||
|
self.secondary = secondary
|
||||||
|
|
||||||
|
if secondary.get_max_io_size() < primary.get_max_io_size():
|
||||||
|
raise Exception("secondary volume max io size too small")
|
||||||
|
if secondary.get_length() < primary.get_length():
|
||||||
|
raise Exception("secondary volume size too small")
|
||||||
|
|
||||||
|
def do_open(self):
|
||||||
|
ret = self.primary.do_open()
|
||||||
|
if ret:
|
||||||
|
return ret
|
||||||
|
ret = self.secondary.do_open()
|
||||||
|
if ret:
|
||||||
|
self.primary.close()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.primary.close()
|
||||||
|
self.secondary.close()
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
return self.primary.get_length()
|
||||||
|
|
||||||
|
def get_max_io_size(self):
|
||||||
|
return self.primary.get_max_io_size()
|
||||||
|
|
||||||
|
def _prepare_io(self, io):
|
||||||
|
original_cb = Io.END()
|
||||||
|
pointer(original_cb)[0] = io.contents._end
|
||||||
|
lock = Lock()
|
||||||
|
error = 0
|
||||||
|
io_remaining = 2
|
||||||
|
|
||||||
|
@CFUNCTYPE(None, c_void_p, c_int)
|
||||||
|
def cb(io, err):
|
||||||
|
nonlocal io_remaining
|
||||||
|
nonlocal error
|
||||||
|
nonlocal original_cb
|
||||||
|
nonlocal lock
|
||||||
|
io = cast(io, POINTER(Io))
|
||||||
|
|
||||||
|
with lock:
|
||||||
|
if err:
|
||||||
|
error = err
|
||||||
|
io_remaining -= 1
|
||||||
|
finished = True if io_remaining == 0 else False
|
||||||
|
if finished:
|
||||||
|
io.contents._end = original_cb
|
||||||
|
original_cb(io, error)
|
||||||
|
|
||||||
|
io.contents._end = cb
|
||||||
|
|
||||||
|
def do_submit_io(self, io):
|
||||||
|
if io.contents._dir == IoDir.WRITE:
|
||||||
|
self._prepare_io(io)
|
||||||
|
self.primary.submit_io(io)
|
||||||
|
self.secondary.submit_io(io)
|
||||||
|
else:
|
||||||
|
# for read just pass through down to primary
|
||||||
|
# with original completion
|
||||||
|
self.primary.submit_io(io)
|
||||||
|
|
||||||
|
def do_submit_flush(self, flush):
|
||||||
|
self._prepare_io(flush)
|
||||||
|
self.primary.submit_flush(flush)
|
||||||
|
self.secondary.submit_flush(flush)
|
||||||
|
|
||||||
|
def do_submit_discard(self, discard):
|
||||||
|
self._prepare_io(discard)
|
||||||
|
self.primary.submit_discard(discard)
|
||||||
|
self.secondary.submit_discard(discard)
|
||||||
|
|
||||||
|
def dump(self, offset=0, size=0, ignore=VOLUME_POISON, **kwargs):
|
||||||
|
self.primary.dump()
|
||||||
|
|
||||||
|
def md5(self):
|
||||||
|
return self.primary.md5()
|
@ -11,6 +11,7 @@ import gc
|
|||||||
sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
|
sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
|
||||||
from pyocf.types.logger import LogLevel, DefaultLogger, BufferLogger
|
from pyocf.types.logger import LogLevel, DefaultLogger, BufferLogger
|
||||||
from pyocf.types.volume import RamVolume, ErrorDevice
|
from pyocf.types.volume import RamVolume, ErrorDevice
|
||||||
|
from pyocf.types.volume_replicated import ReplicatedVolume
|
||||||
from pyocf.types.ctx import OcfCtx
|
from pyocf.types.ctx import OcfCtx
|
||||||
|
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ def pyocf_ctx():
|
|||||||
c = OcfCtx.with_defaults(DefaultLogger(LogLevel.WARN))
|
c = OcfCtx.with_defaults(DefaultLogger(LogLevel.WARN))
|
||||||
c.register_volume_type(RamVolume)
|
c.register_volume_type(RamVolume)
|
||||||
c.register_volume_type(ErrorDevice)
|
c.register_volume_type(ErrorDevice)
|
||||||
|
c.register_volume_type(ReplicatedVolume)
|
||||||
yield c
|
yield c
|
||||||
c.exit()
|
c.exit()
|
||||||
gc.collect()
|
gc.collect()
|
||||||
@ -34,6 +36,7 @@ def pyocf_ctx_log_buffer():
|
|||||||
c = OcfCtx.with_defaults(logger)
|
c = OcfCtx.with_defaults(logger)
|
||||||
c.register_volume_type(RamVolume)
|
c.register_volume_type(RamVolume)
|
||||||
c.register_volume_type(ErrorDevice)
|
c.register_volume_type(ErrorDevice)
|
||||||
|
c.register_volume_type(ReplicatedVolume)
|
||||||
yield logger
|
yield logger
|
||||||
c.exit()
|
c.exit()
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
Loading…
Reference in New Issue
Block a user