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:
parent
cf72664c2c
commit
c7144decf8
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user