pyocf: Extract generic volume logic from RamVolume
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
parent
16f9d58f28
commit
9e13364896
@ -77,65 +77,45 @@ class VolumeIoPriv(Structure):
|
|||||||
VOLUME_POISON = 0x13
|
VOLUME_POISON = 0x13
|
||||||
|
|
||||||
|
|
||||||
class RamVolume():
|
class Volume:
|
||||||
_instances_ = weakref.WeakValueDictionary()
|
_instances_ = weakref.WeakValueDictionary()
|
||||||
_uuid_ = weakref.WeakValueDictionary()
|
_uuid_ = weakref.WeakValueDictionary()
|
||||||
|
|
||||||
props = None
|
@classmethod
|
||||||
|
def get_ops(cls):
|
||||||
|
cls.ops = VolumeOps(
|
||||||
|
_submit_io=cls._submit_io,
|
||||||
|
_submit_flush=cls._submit_flush,
|
||||||
|
_submit_metadata=cls._submit_metadata,
|
||||||
|
_submit_discard=cls._submit_discard,
|
||||||
|
_submit_write_zeroes=cls._submit_write_zeroes,
|
||||||
|
_open=cls._open,
|
||||||
|
_close=cls._close,
|
||||||
|
_get_max_io_size=cls._get_max_io_size,
|
||||||
|
_get_length=cls._get_length,
|
||||||
|
)
|
||||||
|
return cls.ops
|
||||||
|
|
||||||
def __init__(self, size: S, uuid=None):
|
@classmethod
|
||||||
super().__init__()
|
def get_io_ops(cls):
|
||||||
self.size = size
|
return IoOps(_set_data=cls._io_set_data, _get_data=cls._io_get_data)
|
||||||
if uuid:
|
|
||||||
if uuid in type(self)._uuid_:
|
|
||||||
raise Exception(
|
|
||||||
"RamVolume with uuid {} already created".format(uuid)
|
|
||||||
)
|
|
||||||
self.uuid = uuid
|
|
||||||
else:
|
|
||||||
self.uuid = str(id(self))
|
|
||||||
|
|
||||||
type(self)._uuid_[self.uuid] = self
|
|
||||||
|
|
||||||
self.data = create_string_buffer(int(self.size))
|
|
||||||
memset(self.data, VOLUME_POISON, self.size)
|
|
||||||
self.data_ptr = cast(self.data, c_void_p).value
|
|
||||||
|
|
||||||
self.reset_stats()
|
|
||||||
self.opened = False
|
|
||||||
|
|
||||||
def get_copy(self):
|
|
||||||
new_volume = RamVolume(self.size)
|
|
||||||
memmove(new_volume.data, self.data, self.size)
|
|
||||||
return new_volume
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_props(cls):
|
def get_props(cls):
|
||||||
if not cls.props:
|
cls.props = VolumeProperties(
|
||||||
cls.props = 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=VolumeOps(
|
_io_ops=cls.get_io_ops(),
|
||||||
_submit_io=cls._submit_io,
|
_deinit=0,
|
||||||
_submit_flush=cls._submit_flush,
|
)
|
||||||
_submit_metadata=cls._submit_metadata,
|
|
||||||
_submit_discard=cls._submit_discard,
|
|
||||||
_submit_write_zeroes=cls._submit_write_zeroes,
|
|
||||||
_open=cls._open,
|
|
||||||
_close=cls._close,
|
|
||||||
_get_max_io_size=cls._get_max_io_size,
|
|
||||||
_get_length=cls._get_length,
|
|
||||||
),
|
|
||||||
_io_ops=IoOps(
|
|
||||||
_set_data=cls._io_set_data, _get_data=cls._io_get_data
|
|
||||||
),
|
|
||||||
_deinit=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
return cls.props
|
return cls.props
|
||||||
|
|
||||||
|
def get_copy(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_instance(cls, ref):
|
def get_instance(cls, ref):
|
||||||
instance = cls._instances_[ref]
|
instance = cls._instances_[ref]
|
||||||
@ -152,7 +132,7 @@ class RamVolume():
|
|||||||
@VolumeOps.SUBMIT_IO
|
@VolumeOps.SUBMIT_IO
|
||||||
def _submit_io(io):
|
def _submit_io(io):
|
||||||
io_structure = cast(io, POINTER(Io))
|
io_structure = cast(io, POINTER(Io))
|
||||||
volume = RamVolume.get_instance(
|
volume = Volume.get_instance(
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -162,7 +142,7 @@ class RamVolume():
|
|||||||
@VolumeOps.SUBMIT_FLUSH
|
@VolumeOps.SUBMIT_FLUSH
|
||||||
def _submit_flush(flush):
|
def _submit_flush(flush):
|
||||||
io_structure = cast(flush, POINTER(Io))
|
io_structure = cast(flush, POINTER(Io))
|
||||||
volume = RamVolume.get_instance(
|
volume = Volume.get_instance(
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -171,13 +151,13 @@ class RamVolume():
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.SUBMIT_METADATA
|
@VolumeOps.SUBMIT_METADATA
|
||||||
def _submit_metadata(meta):
|
def _submit_metadata(meta):
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.SUBMIT_DISCARD
|
@VolumeOps.SUBMIT_DISCARD
|
||||||
def _submit_discard(discard):
|
def _submit_discard(discard):
|
||||||
io_structure = cast(discard, POINTER(Io))
|
io_structure = cast(discard, POINTER(Io))
|
||||||
volume = RamVolume.get_instance(
|
volume = Volume.get_instance(
|
||||||
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
OcfLib.getInstance().ocf_io_get_volume(io_structure)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -186,7 +166,7 @@ class RamVolume():
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.SUBMIT_WRITE_ZEROES
|
@VolumeOps.SUBMIT_WRITE_ZEROES
|
||||||
def _submit_write_zeroes(write_zeroes):
|
def _submit_write_zeroes(write_zeroes):
|
||||||
pass
|
raise NotImplementedError
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@CFUNCTYPE(c_int, c_void_p)
|
@CFUNCTYPE(c_int, c_void_p)
|
||||||
@ -196,35 +176,35 @@ class RamVolume():
|
|||||||
)
|
)
|
||||||
uuid = str(uuid_ptr.contents._data, encoding="ascii")
|
uuid = str(uuid_ptr.contents._data, encoding="ascii")
|
||||||
try:
|
try:
|
||||||
volume = RamVolume.get_by_uuid(uuid)
|
volume = Volume.get_by_uuid(uuid)
|
||||||
except: # noqa E722 TODO:Investigate whether this really should be so broad
|
except: # noqa E722 TODO:Investigate whether this really should be so broad
|
||||||
print("Tried to access unallocated volume {}".format(uuid))
|
print("Tried to access unallocated volume {}".format(uuid))
|
||||||
print("{}".format(RamVolume._uuid_))
|
print("{}".format(Volume._uuid_))
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
if volume.opened:
|
if volume.opened:
|
||||||
return -OcfErrorCode.OCF_ERR_NOT_OPEN_EXC
|
return -OcfErrorCode.OCF_ERR_NOT_OPEN_EXC
|
||||||
|
|
||||||
RamVolume._instances_[ref] = volume
|
Volume._instances_[ref] = volume
|
||||||
|
|
||||||
return volume.open()
|
return volume.do_open()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.CLOSE
|
@VolumeOps.CLOSE
|
||||||
def _close(ref):
|
def _close(ref):
|
||||||
volume = RamVolume.get_instance(ref)
|
volume = Volume.get_instance(ref)
|
||||||
volume.close()
|
volume.close()
|
||||||
volume.opened = False
|
volume.opened = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.GET_MAX_IO_SIZE
|
@VolumeOps.GET_MAX_IO_SIZE
|
||||||
def _get_max_io_size(ref):
|
def _get_max_io_size(ref):
|
||||||
return RamVolume.get_instance(ref).get_max_io_size()
|
return Volume.get_instance(ref).get_max_io_size()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@VolumeOps.GET_LENGTH
|
@VolumeOps.GET_LENGTH
|
||||||
def _get_length(ref):
|
def _get_length(ref):
|
||||||
return RamVolume.get_instance(ref).get_length()
|
return Volume.get_instance(ref).get_length()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@IoOps.SET_DATA
|
@IoOps.SET_DATA
|
||||||
@ -246,12 +226,76 @@ class RamVolume():
|
|||||||
)
|
)
|
||||||
return io_priv.contents._data
|
return io_priv.contents._data
|
||||||
|
|
||||||
def open(self):
|
def __init__(self, uuid=None):
|
||||||
|
if uuid:
|
||||||
|
if uuid in type(self)._uuid_:
|
||||||
|
raise Exception(
|
||||||
|
"Volume with uuid {} already created".format(uuid)
|
||||||
|
)
|
||||||
|
self.uuid = uuid
|
||||||
|
else:
|
||||||
|
self.uuid = str(id(self))
|
||||||
|
|
||||||
|
type(self)._uuid_[self.uuid] = self
|
||||||
|
|
||||||
|
self.reset_stats()
|
||||||
|
self.opened = False
|
||||||
|
|
||||||
|
def do_open(self):
|
||||||
self.opened = True
|
self.opened = True
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
self.opened = False
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_max_io_size(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def submit_flush(self, flush):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def submit_discard(self, discard):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_stats(self):
|
||||||
|
return self.stats
|
||||||
|
|
||||||
|
def reset_stats(self):
|
||||||
|
self.stats = {IoDir.WRITE: 0, IoDir.READ: 0}
|
||||||
|
|
||||||
|
def inc_stats(self, _dir):
|
||||||
|
self.stats[_dir] += 1
|
||||||
|
|
||||||
|
def submit_io(self, io):
|
||||||
|
volume.inc_stats(IoDir(io.contents._dir))
|
||||||
|
volume.do_submit_io(io)
|
||||||
|
|
||||||
|
def do_submit_io(self, io):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def dump(self, offset=0, size=0, ignore=VOLUME_POISON, **kwargs):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def md5(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
class RamVolume(Volume):
|
||||||
|
props = None
|
||||||
|
|
||||||
|
def __init__(self, size: S, uuid=None):
|
||||||
|
super().__init__(uuid)
|
||||||
|
self.size = size
|
||||||
|
self.data = create_string_buffer(int(self.size))
|
||||||
|
memset(self.data, VOLUME_POISON, self.size)
|
||||||
|
self.data_ptr = cast(self.data, c_void_p).value
|
||||||
|
|
||||||
|
def get_copy(self):
|
||||||
|
new_volume = RamVolume(self.size)
|
||||||
|
memmove(new_volume.data, self.data, self.size)
|
||||||
|
return new_volume
|
||||||
|
|
||||||
def get_length(self):
|
def get_length(self):
|
||||||
return self.size
|
return self.size
|
||||||
@ -277,16 +321,8 @@ class RamVolume():
|
|||||||
except: # noqa E722
|
except: # noqa E722
|
||||||
discard.contents._end(discard, -OcfErrorCode.OCF_ERR_NOT_SUPP)
|
discard.contents._end(discard, -OcfErrorCode.OCF_ERR_NOT_SUPP)
|
||||||
|
|
||||||
def get_stats(self):
|
def do_submit_io(self, io):
|
||||||
return self.stats
|
|
||||||
|
|
||||||
def reset_stats(self):
|
|
||||||
self.stats = {IoDir.WRITE: 0, IoDir.READ: 0}
|
|
||||||
|
|
||||||
def submit_io(self, io):
|
|
||||||
try:
|
try:
|
||||||
self.stats[IoDir(io.contents._dir)] += 1
|
|
||||||
|
|
||||||
io_priv = cast(
|
io_priv = cast(
|
||||||
OcfLib.getInstance().ocf_io_get_priv(io), POINTER(VolumeIoPriv))
|
OcfLib.getInstance().ocf_io_get_priv(io), POINTER(VolumeIoPriv))
|
||||||
offset = io_priv.contents._offset
|
offset = io_priv.contents._offset
|
||||||
@ -341,9 +377,9 @@ class ErrorDevice(RamVolume):
|
|||||||
def set_mapping(self, error_sectors: set):
|
def set_mapping(self, error_sectors: set):
|
||||||
self.error_sectors = error_sectors
|
self.error_sectors = error_sectors
|
||||||
|
|
||||||
def submit_io(self, io):
|
def do_submit_io(self, io):
|
||||||
if not self.armed:
|
if not self.armed:
|
||||||
super().submit_io(io)
|
super().do_submit_io(io)
|
||||||
return
|
return
|
||||||
|
|
||||||
direction = IoDir(io.contents._dir)
|
direction = IoDir(io.contents._dir)
|
||||||
@ -368,7 +404,7 @@ class ErrorDevice(RamVolume):
|
|||||||
io.contents._end(io, -OcfErrorCode.OCF_ERR_IO)
|
io.contents._end(io, -OcfErrorCode.OCF_ERR_IO)
|
||||||
self.stats["errors"][direction] += 1
|
self.stats["errors"][direction] += 1
|
||||||
else:
|
else:
|
||||||
super().submit_io(io)
|
super().do_submit_io(io)
|
||||||
|
|
||||||
def arm(self):
|
def arm(self):
|
||||||
self.armed = True
|
self.armed = True
|
||||||
@ -389,7 +425,7 @@ class TraceDevice(RamVolume):
|
|||||||
super().__init__(size, uuid)
|
super().__init__(size, uuid)
|
||||||
self.trace_fcn = trace_fcn
|
self.trace_fcn = trace_fcn
|
||||||
|
|
||||||
def submit_io(self, io):
|
def do_submit_io(self, io):
|
||||||
submit = True
|
submit = True
|
||||||
|
|
||||||
if self.trace_fcn:
|
if self.trace_fcn:
|
||||||
|
Loading…
Reference in New Issue
Block a user