pyocf: extend error volume capabilities

Adding option to
1. inject error based on I/O number
2. arm/disarm error injection for easier testing

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2021-12-14 23:06:24 +01:00
parent cf72664c2c
commit c7144decf8

View File

@ -305,12 +305,7 @@ class Volume(Structure):
if size == 0: if size == 0:
size = int(self.size) - int(offset) size = int(self.size) - int(offset)
print_buffer( print_buffer(self._storage, size, ignore=ignore, **kwargs)
self._storage,
size,
ignore=ignore,
**kwargs
)
def md5(self): def md5(self):
m = md5() m = md5()
@ -319,20 +314,62 @@ class Volume(Structure):
class ErrorDevice(Volume): class ErrorDevice(Volume):
def __init__(self, size, error_sectors: set = None, uuid=None): def __init__(
self,
size,
error_sectors: set = None,
error_seq_no: dict = None,
armed=True,
uuid=None,
):
super().__init__(size, uuid) super().__init__(size, uuid)
self.error_sectors = error_sectors or set() self.error_sectors = error_sectors
self.error_seq_no = error_seq_no
self.armed = armed
self.io_seq_no = {IoDir.WRITE: 0, IoDir.READ: 0}
self.error = False
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 submit_io(self, io):
if io.contents._addr in self.error_sectors: if not self.armed:
super().submit_io(io)
return
direction = IoDir(io.contents._dir)
seq_no_match = (
self.error_seq_no is not None
and direction in self.error_seq_no
and self.error_seq_no[direction] <= self.io_seq_no[direction]
)
sector_match = (
self.error_sectors is not None and io.contents._addr in self.error_sectors
)
self.io_seq_no[direction] += 1
error = True
if self.error_seq_no is not None and not seq_no_match:
error = False
if self.error_sectors is not None and not sector_match:
error = False
if error:
self.error = True
io.contents._end(io, -5) io.contents._end(io, -5)
self.stats["errors"][io.contents._dir] += 1 self.stats["errors"][direction] += 1
else: else:
super().submit_io(io) super().submit_io(io)
def arm(self):
self.armed = True
def disarm(self):
self.armed = False
def error_triggered(self):
return self.error
def reset_stats(self): def reset_stats(self):
super().reset_stats() super().reset_stats()
self.stats["errors"] = {IoDir.WRITE: 0, IoDir.READ: 0} self.stats["errors"] = {IoDir.WRITE: 0, IoDir.READ: 0}