pyocf: unique volume ops for each volume class
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
parent
7cb9523d8c
commit
2672f5460a
@ -66,10 +66,9 @@ class VolumeProperties(Structure):
|
|||||||
("_caps", VolumeCaps),
|
("_caps", VolumeCaps),
|
||||||
("_io_ops", IoOps),
|
("_io_ops", IoOps),
|
||||||
("_deinit", c_char_p),
|
("_deinit", c_char_p),
|
||||||
("_ops", VolumeOps),
|
("_ops_", VolumeOps),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class VolumeIoPriv(Structure):
|
class VolumeIoPriv(Structure):
|
||||||
_fields_ = [("_data", c_void_p), ("_offset", c_uint64)]
|
_fields_ = [("_data", c_void_p), ("_offset", c_uint64)]
|
||||||
|
|
||||||
@ -80,21 +79,96 @@ VOLUME_POISON = 0x13
|
|||||||
class Volume:
|
class Volume:
|
||||||
_instances_ = weakref.WeakValueDictionary()
|
_instances_ = weakref.WeakValueDictionary()
|
||||||
_uuid_ = weakref.WeakValueDictionary()
|
_uuid_ = weakref.WeakValueDictionary()
|
||||||
|
_ops_ = {}
|
||||||
|
_props_ = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_ops(cls):
|
def get_ops(cls):
|
||||||
cls.ops = VolumeOps(
|
if cls in Volume._ops_:
|
||||||
_submit_io=cls._submit_io,
|
return Volume._ops_[cls]
|
||||||
_submit_flush=cls._submit_flush,
|
|
||||||
_submit_metadata=cls._submit_metadata,
|
@VolumeOps.SUBMIT_IO
|
||||||
_submit_discard=cls._submit_discard,
|
def _submit_io(io):
|
||||||
_submit_write_zeroes=cls._submit_write_zeroes,
|
io_structure = cast(io, POINTER(Io))
|
||||||
_open=cls._open,
|
volume = Volume.get_instance(
|
||||||
_close=cls._close,
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
_get_max_io_size=cls._get_max_io_size,
|
)
|
||||||
_get_length=cls._get_length,
|
|
||||||
|
volume.submit_io(io_structure)
|
||||||
|
|
||||||
|
@VolumeOps.SUBMIT_FLUSH
|
||||||
|
def _submit_flush(flush):
|
||||||
|
io_structure = cast(flush, POINTER(Io))
|
||||||
|
volume = Volume.get_instance(
|
||||||
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
|
)
|
||||||
|
|
||||||
|
volume.submit_flush(io_structure)
|
||||||
|
|
||||||
|
@VolumeOps.SUBMIT_METADATA
|
||||||
|
def _submit_metadata(meta):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@VolumeOps.SUBMIT_DISCARD
|
||||||
|
def _submit_discard(discard):
|
||||||
|
io_structure = cast(discard, POINTER(Io))
|
||||||
|
volume = Volume.get_instance(
|
||||||
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
|
)
|
||||||
|
|
||||||
|
volume.submit_discard(io_structure)
|
||||||
|
|
||||||
|
@VolumeOps.SUBMIT_WRITE_ZEROES
|
||||||
|
def _submit_write_zeroes(write_zeroes):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@VolumeOps.OPEN
|
||||||
|
def _open(ref):
|
||||||
|
uuid_ptr = cast(
|
||||||
|
OcfLib.getInstance().ocf_volume_get_uuid(ref), POINTER(Uuid)
|
||||||
|
)
|
||||||
|
uuid = str(uuid_ptr.contents._data, encoding="ascii")
|
||||||
|
try:
|
||||||
|
volume = Volume.get_by_uuid(uuid)
|
||||||
|
except: # noqa E722 TODO:Investigate whether this really should be so broad
|
||||||
|
print("Tried to access unallocated volume {}".format(uuid))
|
||||||
|
print("{}".format(Volume._uuid_))
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if volume.opened:
|
||||||
|
return -OcfErrorCode.OCF_ERR_NOT_OPEN_EXC
|
||||||
|
|
||||||
|
Volume._instances_[ref] = volume
|
||||||
|
|
||||||
|
return volume.do_open()
|
||||||
|
|
||||||
|
@VolumeOps.CLOSE
|
||||||
|
def _close(ref):
|
||||||
|
volume = Volume.get_instance(ref)
|
||||||
|
volume.close()
|
||||||
|
volume.opened = False
|
||||||
|
|
||||||
|
@VolumeOps.GET_MAX_IO_SIZE
|
||||||
|
def _get_max_io_size(ref):
|
||||||
|
return Volume.get_instance(ref).get_max_io_size()
|
||||||
|
|
||||||
|
@VolumeOps.GET_LENGTH
|
||||||
|
def _get_length(ref):
|
||||||
|
return Volume.get_instance(ref).get_length()
|
||||||
|
|
||||||
|
Volume._ops_[cls] = VolumeOps(
|
||||||
|
_submit_io=_submit_io,
|
||||||
|
_submit_flush=_submit_flush,
|
||||||
|
_submit_metadata=_submit_metadata,
|
||||||
|
_submit_discard=_submit_discard,
|
||||||
|
_submit_write_zeroes=_submit_write_zeroes,
|
||||||
|
_open=_open,
|
||||||
|
_close=_close,
|
||||||
|
_get_max_io_size=_get_max_io_size,
|
||||||
|
_get_length=_get_length,
|
||||||
)
|
)
|
||||||
return cls.ops
|
|
||||||
|
return Volume._ops_[cls]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_io_ops(cls):
|
def get_io_ops(cls):
|
||||||
@ -102,16 +176,19 @@ class Volume:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_props(cls):
|
def get_props(cls):
|
||||||
cls.props = VolumeProperties(
|
if cls in Volume._props_:
|
||||||
|
return Volume._props_[cls]
|
||||||
|
|
||||||
|
Volume._props_[cls] = VolumeProperties(
|
||||||
_name=str(cls.__name__).encode("ascii"),
|
_name=str(cls.__name__).encode("ascii"),
|
||||||
_io_priv_size=sizeof(VolumeIoPriv),
|
_io_priv_size=sizeof(VolumeIoPriv),
|
||||||
_volume_priv_size=0,
|
_volume_priv_size=0,
|
||||||
_caps=VolumeCaps(_atomic_writes=0),
|
_caps=VolumeCaps(_atomic_writes=0),
|
||||||
_ops=cls.get_ops(),
|
_ops_=cls.get_ops(),
|
||||||
_io_ops=cls.get_io_ops(),
|
_io_ops=cls.get_io_ops(),
|
||||||
_deinit=0,
|
_deinit=0,
|
||||||
)
|
)
|
||||||
return cls.props
|
return Volume._props_[cls]
|
||||||
|
|
||||||
def get_copy(self):
|
def get_copy(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -128,84 +205,6 @@ class Volume:
|
|||||||
def get_by_uuid(cls, uuid):
|
def get_by_uuid(cls, uuid):
|
||||||
return cls._uuid_[uuid]
|
return cls._uuid_[uuid]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.SUBMIT_IO
|
|
||||||
def _submit_io(io):
|
|
||||||
io_structure = cast(io, POINTER(Io))
|
|
||||||
volume = Volume.get_instance(
|
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
|
||||||
)
|
|
||||||
|
|
||||||
volume.submit_io(io_structure)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.SUBMIT_FLUSH
|
|
||||||
def _submit_flush(flush):
|
|
||||||
io_structure = cast(flush, POINTER(Io))
|
|
||||||
volume = Volume.get_instance(
|
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
|
||||||
)
|
|
||||||
|
|
||||||
volume.submit_flush(io_structure)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.SUBMIT_METADATA
|
|
||||||
def _submit_metadata(meta):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.SUBMIT_DISCARD
|
|
||||||
def _submit_discard(discard):
|
|
||||||
io_structure = cast(discard, POINTER(Io))
|
|
||||||
volume = Volume.get_instance(
|
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
|
||||||
)
|
|
||||||
|
|
||||||
volume.submit_discard(io_structure)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.SUBMIT_WRITE_ZEROES
|
|
||||||
def _submit_write_zeroes(write_zeroes):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@CFUNCTYPE(c_int, c_void_p)
|
|
||||||
def _open(ref):
|
|
||||||
uuid_ptr = cast(
|
|
||||||
OcfLib.getInstance().ocf_volume_get_uuid(ref), POINTER(Uuid)
|
|
||||||
)
|
|
||||||
uuid = str(uuid_ptr.contents._data, encoding="ascii")
|
|
||||||
try:
|
|
||||||
volume = Volume.get_by_uuid(uuid)
|
|
||||||
except: # noqa E722 TODO:Investigate whether this really should be so broad
|
|
||||||
print("Tried to access unallocated volume {}".format(uuid))
|
|
||||||
print("{}".format(Volume._uuid_))
|
|
||||||
return -1
|
|
||||||
|
|
||||||
if volume.opened:
|
|
||||||
return -OcfErrorCode.OCF_ERR_NOT_OPEN_EXC
|
|
||||||
|
|
||||||
Volume._instances_[ref] = volume
|
|
||||||
|
|
||||||
return volume.do_open()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.CLOSE
|
|
||||||
def _close(ref):
|
|
||||||
volume = Volume.get_instance(ref)
|
|
||||||
volume.close()
|
|
||||||
volume.opened = False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.GET_MAX_IO_SIZE
|
|
||||||
def _get_max_io_size(ref):
|
|
||||||
return Volume.get_instance(ref).get_max_io_size()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@VolumeOps.GET_LENGTH
|
|
||||||
def _get_length(ref):
|
|
||||||
return Volume.get_instance(ref).get_length()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@IoOps.SET_DATA
|
@IoOps.SET_DATA
|
||||||
def _io_set_data(io, data, offset):
|
def _io_set_data(io, data, offset):
|
||||||
|
@ -21,6 +21,7 @@ from pyocf.types.cache import (
|
|||||||
Backfill
|
Backfill
|
||||||
)
|
)
|
||||||
from pyocf.types.core import Core
|
from pyocf.types.core import Core
|
||||||
|
from pyocf.types.ctx import OcfCtx
|
||||||
from pyocf.types.data import Data
|
from pyocf.types.data import Data
|
||||||
from pyocf.types.io import IoDir
|
from pyocf.types.io import IoDir
|
||||||
from pyocf.types.shared import OcfError, OcfCompletion, CacheLineSize, SeqCutOffPolicy
|
from pyocf.types.shared import OcfError, OcfCompletion, CacheLineSize, SeqCutOffPolicy
|
||||||
@ -349,6 +350,8 @@ def test_start_cache_huge_device(pyocf_ctx_log_buffer, cls):
|
|||||||
def submit_io(self, io):
|
def submit_io(self, io):
|
||||||
io.contents._end(io, 0)
|
io.contents._end(io, 0)
|
||||||
|
|
||||||
|
OcfCtx.get_default().register_volume_type(HugeDevice)
|
||||||
|
|
||||||
cache_device = HugeDevice()
|
cache_device = HugeDevice()
|
||||||
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"):
|
||||||
|
Loading…
Reference in New Issue
Block a user