pyocf: cache and core exported object volumes
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
parent
d2164e4ffd
commit
9e88afad62
31
tests/functional/pyocf/types/volume_cache.py
Normal file
31
tests/functional/pyocf/types/volume_cache.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Copyright(c) 2022 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
from ctypes import cast, POINTER
|
||||||
|
|
||||||
|
from .cache import Cache
|
||||||
|
from .io import Io
|
||||||
|
from .io import IoDir
|
||||||
|
from .volume_exp_obj import ExpObjVolume
|
||||||
|
from .volume import Volume
|
||||||
|
|
||||||
|
|
||||||
|
class CacheVolume(ExpObjVolume):
|
||||||
|
def __init__(self, cache, open=False, uuid=None):
|
||||||
|
super().__init__(cache, uuid)
|
||||||
|
self.cache = cache
|
||||||
|
self.lib = cache.owner.lib
|
||||||
|
if open:
|
||||||
|
self.open()
|
||||||
|
|
||||||
|
def md5(self):
|
||||||
|
data = self._read()
|
||||||
|
return data.md5()
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
return Volume.open(
|
||||||
|
self.lib.ocf_cache_get_front_volume(self.cache.handle),
|
||||||
|
self
|
||||||
|
)
|
27
tests/functional/pyocf/types/volume_core.py
Normal file
27
tests/functional/pyocf/types/volume_core.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#
|
||||||
|
# Copyright(c) 2022 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
from .core import Core
|
||||||
|
from .volume_exp_obj import ExpObjVolume
|
||||||
|
from .io import IoDir
|
||||||
|
from .volume import Volume
|
||||||
|
|
||||||
|
|
||||||
|
class CoreVolume(ExpObjVolume):
|
||||||
|
def __init__(self, core, open=False, uuid=None):
|
||||||
|
super().__init__(core, uuid)
|
||||||
|
self.core = core
|
||||||
|
self.lib = core.cache.owner.lib
|
||||||
|
if open:
|
||||||
|
self.open()
|
||||||
|
|
||||||
|
def md5(self):
|
||||||
|
return self.core.exp_obj_md5()
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
return Volume.open(
|
||||||
|
self.lib.ocf_core_get_front_volume(self.core.handle),
|
||||||
|
self
|
||||||
|
)
|
97
tests/functional/pyocf/types/volume_exp_obj.py
Normal file
97
tests/functional/pyocf/types/volume_exp_obj.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#
|
||||||
|
# Copyright(c) 2022 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
from ctypes import c_int, c_void_p, CFUNCTYPE, byref, c_uint32, c_uint64, cast, POINTER
|
||||||
|
|
||||||
|
from ..ocf import OcfLib
|
||||||
|
from .volume import Volume, VOLUME_POISON
|
||||||
|
from pyocf.utils import Size
|
||||||
|
from pyocf.types.data import Data
|
||||||
|
from pyocf.types.io import IoDir, Io
|
||||||
|
from pyocf.types.shared import OcfCompletion
|
||||||
|
|
||||||
|
|
||||||
|
class ExpObjVolume(Volume):
|
||||||
|
def __init__(self, parent, uuid=None):
|
||||||
|
super().__init__(uuid)
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
def __alloc_io(self, addr, _bytes, _dir, _class, _flags):
|
||||||
|
vol = self.parent.get_front_volume()
|
||||||
|
queue = self.parent.get_default_queue() # TODO multiple queues?
|
||||||
|
return vol.new_io(
|
||||||
|
queue, addr, _bytes, _dir, _class, _flags
|
||||||
|
)
|
||||||
|
|
||||||
|
def _alloc_io(self, io):
|
||||||
|
exp_obj_io = self.__alloc_io(
|
||||||
|
io.contents._addr,
|
||||||
|
io.contents._bytes,
|
||||||
|
io.contents._dir,
|
||||||
|
io.contents._class,
|
||||||
|
io.contents._flags,
|
||||||
|
)
|
||||||
|
|
||||||
|
lib = OcfLib.getInstance()
|
||||||
|
cdata = OcfLib.getInstance().ocf_io_get_data(io)
|
||||||
|
OcfLib.getInstance().ocf_io_set_data(byref(exp_obj_io), cdata, 0)
|
||||||
|
|
||||||
|
def cb(error):
|
||||||
|
nonlocal io
|
||||||
|
io = cast(io, POINTER(Io))
|
||||||
|
io.contents._end(io, error)
|
||||||
|
|
||||||
|
exp_obj_io.callback = cb
|
||||||
|
|
||||||
|
return exp_obj_io
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
return Size.from_B(OcfLib.getInstance().ocf_volume_get_length(self.c_vol))
|
||||||
|
|
||||||
|
def get_max_io_size(self):
|
||||||
|
return Size.from_B(OcfLib.getInstance().ocf_volume_get_max_io_size(self.c_vol))
|
||||||
|
|
||||||
|
def do_submit_io(self, io):
|
||||||
|
io = self._alloc_io(io)
|
||||||
|
io.submit()
|
||||||
|
|
||||||
|
def do_submit_flush(self, flush):
|
||||||
|
io = self._alloc_io(flush)
|
||||||
|
io.submit_flush()
|
||||||
|
|
||||||
|
def do_submit_discard(self, discard):
|
||||||
|
io = self._alloc_io(discard)
|
||||||
|
io.submit_discard()
|
||||||
|
|
||||||
|
def _read(self, offset=0, size=0):
|
||||||
|
if size == 0:
|
||||||
|
size = self.get_length().B - offset
|
||||||
|
exp_obj_io = self.__alloc_io(offset, size, IoDir.READ, 0, 0)
|
||||||
|
completion = OcfCompletion([("err", c_int)])
|
||||||
|
exp_obj_io.callback = completion
|
||||||
|
data = Data.from_bytes(bytes(size))
|
||||||
|
exp_obj_io.set_data(data)
|
||||||
|
exp_obj_io.submit()
|
||||||
|
completion.wait()
|
||||||
|
error = completion.results["err"]
|
||||||
|
if error:
|
||||||
|
raise Exception("error reading exported object for dump")
|
||||||
|
return data
|
||||||
|
|
||||||
|
def dump(self, offset=0, size=0, ignore=VOLUME_POISON, **kwargs):
|
||||||
|
data = self._read(offset, size)
|
||||||
|
data.dump(ignore=ifnore, **kwargs)
|
||||||
|
|
||||||
|
def md5(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
lib = OcfLib.getInstance()
|
||||||
|
lib.ocf_volume_get_max_io_size.argtypes = [c_void_p]
|
||||||
|
lib.ocf_volume_get_max_io_size.restype = c_uint32
|
||||||
|
lib.ocf_volume_get_length.argtypes = [c_void_p]
|
||||||
|
lib.ocf_volume_get_length.restype = c_uint64
|
||||||
|
lib.ocf_io_get_data.argtypes = [POINTER(Io)]
|
||||||
|
lib.ocf_io_get_data.restype = c_void_p
|
@ -11,6 +11,8 @@ 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_cache import CacheVolume
|
||||||
|
from pyocf.types.volume_core import CoreVolume
|
||||||
from pyocf.types.volume_replicated import ReplicatedVolume
|
from pyocf.types.volume_replicated import ReplicatedVolume
|
||||||
from pyocf.types.ctx import OcfCtx
|
from pyocf.types.ctx import OcfCtx
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ 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(CacheVolume)
|
||||||
|
c.register_volume_type(CoreVolume)
|
||||||
c.register_volume_type(ReplicatedVolume)
|
c.register_volume_type(ReplicatedVolume)
|
||||||
yield c
|
yield c
|
||||||
c.exit()
|
c.exit()
|
||||||
@ -36,6 +40,8 @@ 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(CacheVolume)
|
||||||
|
c.register_volume_type(CoreVolume)
|
||||||
c.register_volume_type(ReplicatedVolume)
|
c.register_volume_type(ReplicatedVolume)
|
||||||
yield logger
|
yield logger
|
||||||
c.exit()
|
c.exit()
|
||||||
|
Loading…
Reference in New Issue
Block a user