diff options
author | David Goetz <david.goetz@rackspace.com> | 2011-08-31 15:17:26 +0000 |
---|---|---|
committer | Tarmac <> | 2011-08-31 15:17:26 +0000 |
commit | b0651fde1e7e027887990195e9e810625b4be967 (patch) | |
tree | 44a81c26ca01a12cc661a65fe781ce5361be3303 | |
parent | 418b57b729a74e2795fd7997c8be7a2c9965d925 (diff) | |
parent | fc4f6feb8f769aac8f62afb6fdedac86262c2c26 (diff) | |
download | swift-b0651fde1e7e027887990195e9e810625b4be967.tar.gz |
Fix for object auditor. It doesn't close files that are quarantined for certain reasons, zero byte files for one, which will cause it to eventually crash due to keeping too many files open. Thanks David Kranz for finding / reporting this!!
-rw-r--r-- | swift/obj/auditor.py | 51 | ||||
-rw-r--r-- | test/unit/obj/test_auditor.py | 20 |
2 files changed, 47 insertions, 24 deletions
diff --git a/swift/obj/auditor.py b/swift/obj/auditor.py index a512f3d67..50b8c2a1e 100644 --- a/swift/obj/auditor.py +++ b/swift/obj/auditor.py @@ -134,31 +134,34 @@ class AuditorWorker(object): df = object_server.DiskFile(self.devices, device, partition, account, container, obj, self.logger, keep_data_fp=True) - if df.data_file is None: - # file is deleted, we found the tombstone - return try: - obj_size = df.get_data_file_size() - except DiskFileError, e: - raise AuditException(str(e)) - except DiskFileNotExist: - return - if self.zero_byte_only_at_fps and obj_size: - self.passes += 1 - return - for chunk in df: - self.bytes_running_time = ratelimit_sleep( - self.bytes_running_time, self.max_bytes_per_second, - incr_by=len(chunk)) - self.bytes_processed += len(chunk) - self.total_bytes_processed += len(chunk) - df.close() - if df.quarantined_dir: - self.quarantines += 1 - self.logger.error( - _("ERROR Object %(path)s failed audit and will be " - "quarantined: ETag and file's md5 do not match"), - {'path': path}) + if df.data_file is None: + # file is deleted, we found the tombstone + return + try: + obj_size = df.get_data_file_size() + except DiskFileError, e: + raise AuditException(str(e)) + except DiskFileNotExist: + return + if self.zero_byte_only_at_fps and obj_size: + self.passes += 1 + return + for chunk in df: + self.bytes_running_time = ratelimit_sleep( + self.bytes_running_time, self.max_bytes_per_second, + incr_by=len(chunk)) + self.bytes_processed += len(chunk) + self.total_bytes_processed += len(chunk) + df.close() + if df.quarantined_dir: + self.quarantines += 1 + self.logger.error( + _("ERROR Object %(path)s failed audit and will be " + "quarantined: ETag and file's md5 do not match"), + {'path': path}) + finally: + df.close(verify_file=False) except AuditException, err: self.quarantines += 1 self.logger.error(_('ERROR Object %(obj)s failed audit and will ' diff --git a/test/unit/obj/test_auditor.py b/test/unit/obj/test_auditor.py index 0aa05bcce..cc08c2cd6 100644 --- a/test/unit/obj/test_auditor.py +++ b/test/unit/obj/test_auditor.py @@ -315,6 +315,26 @@ class TestAuditor(unittest.TestCase): my_auditor._sleep() self.assertEquals(round(time.time() - start, 2), 0.01) + def test_object_run_fast_track_zero_check_closed(self): + rat = [False] + + class FakeFile(DiskFile): + + def close(self, verify_file=True): + rat[0] = True + DiskFile.close(self, verify_file=verify_file) + self.setup_bad_zero_byte() + was_df = object_server.DiskFile + try: + object_server.DiskFile = FakeFile + self.auditor.run_once(zero_byte_fps=50) + quarantine_path = os.path.join(self.devices, + 'sda', 'quarantined', 'objects') + self.assertTrue(os.path.isdir(quarantine_path)) + self.assertTrue(rat[0]) + finally: + object_server.DiskFile = was_df + def test_run_forever(self): class StopForever(Exception): |