From f25592f3cd76dbe2d14e044b0e402e1760010cb1 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 15 Jun 2021 14:12:59 -0700 Subject: [PATCH] Quarantine on IOErrors while reading Change-Id: I3b89d10096f29652f691428065b9801d57d77ec7 --- swift/obj/diskfile.py | 10 +++++++++- test/unit/obj/test_diskfile.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/swift/obj/diskfile.py b/swift/obj/diskfile.py index a786c800bc..ff6c260bbd 100644 --- a/swift/obj/diskfile.py +++ b/swift/obj/diskfile.py @@ -2063,7 +2063,15 @@ class BaseDiskFileReader(object): self._read_to_eof = False self._init_checks() while True: - chunk = self._fp.read(self._disk_chunk_size) + try: + chunk = self._fp.read(self._disk_chunk_size) + except IOError as e: + if e.errno == errno.EIO: + # Note that if there's no quarantine hook set up, + # this won't raise any exception + self._quarantine(str(e)) + # ... so it's significant that this is not in an else + raise if chunk: self._update_checks(chunk) self._bytes_read += len(chunk) diff --git a/test/unit/obj/test_diskfile.py b/test/unit/obj/test_diskfile.py index 451fb0cb01..12486f15a9 100644 --- a/test/unit/obj/test_diskfile.py +++ b/test/unit/obj/test_diskfile.py @@ -3924,6 +3924,34 @@ class DiskFileMixin(BaseDiskFileTestMixin): reader._obj_size += 1 self.assertRaises(DiskFileQuarantined, b''.join, reader) + def test_disk_file_reader_iter_w_io_error(self): + df, df_data = self._create_test_file(b'1234567890') + + class FakeFp(object): + def __init__(self, buf): + self.pos = 0 + self.buf = buf + + def read(self, sz): + if not self.buf: + raise IOError(5, 'Input/output error') + chunk, self.buf = self.buf, b'' + self.pos += len(chunk) + return chunk + + def close(self): + pass + + def tell(self): + return self.pos + + def raise_dfq(m): + raise DiskFileQuarantined(m) + + reader = df.reader(_quarantine_hook=raise_dfq) + reader._fp = FakeFp(b'1234') + self.assertRaises(DiskFileQuarantined, b''.join, reader) + def test_disk_file_app_iter_corners(self): df, df_data = self._create_test_file(b'1234567890') quarantine_msgs = []