summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goetz <david.goetz@rackspace.com>2011-08-31 15:17:26 +0000
committerTarmac <>2011-08-31 15:17:26 +0000
commitb0651fde1e7e027887990195e9e810625b4be967 (patch)
tree44a81c26ca01a12cc661a65fe781ce5361be3303
parent418b57b729a74e2795fd7997c8be7a2c9965d925 (diff)
parentfc4f6feb8f769aac8f62afb6fdedac86262c2c26 (diff)
downloadswift-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.py51
-rw-r--r--test/unit/obj/test_auditor.py20
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):