From cd7159c69cc8d3de135298c1cb5613bea1397215 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 22 Feb 2022 15:54:24 -0800 Subject: db: Attempt to clean up part dir post replication Change-Id: Id844f47ead7fab47915b6db76c06155b22586efe --- swift/common/db_replicator.py | 20 +++++++++++++------- test/unit/common/test_db_replicator.py | 15 +++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/swift/common/db_replicator.py b/swift/common/db_replicator.py index 9447a802d..47fb58c29 100644 --- a/swift/common/db_replicator.py +++ b/swift/common/db_replicator.py @@ -710,16 +710,22 @@ class Replicator(Daemon): suf_dir = os.path.dirname(hash_dir) with lock_parent_directory(object_file): shutil.rmtree(hash_dir, True) - try: - os.rmdir(suf_dir) - except OSError as err: - if err.errno not in (errno.ENOENT, errno.ENOTEMPTY): - self.logger.exception( - _('ERROR while trying to clean up %s') % suf_dir) - return False self.stats['remove'] += 1 device_name = self.extract_device(object_file) self.logger.increment('removes.' + device_name) + + for parent_dir in (suf_dir, os.path.dirname(suf_dir)): + try: + os.rmdir(parent_dir) + except OSError as err: + if err.errno == errno.ENOTEMPTY: + break + elif err.errno == errno.ENOENT: + continue + else: + self.logger.exception( + 'ERROR while trying to clean up %s', parent_dir) + return False return True def extract_device(self, object_file): diff --git a/test/unit/common/test_db_replicator.py b/test/unit/common/test_db_replicator.py index c5951da21..111b77f70 100644 --- a/test/unit/common/test_db_replicator.py +++ b/test/unit/common/test_db_replicator.py @@ -1066,7 +1066,9 @@ class TestDBReplicator(unittest.TestCase): temp_dir = mkdtemp() try: - temp_suf_dir = os.path.join(temp_dir, '16e') + temp_part_dir = os.path.join(temp_dir, '140') + os.mkdir(temp_part_dir) + temp_suf_dir = os.path.join(temp_part_dir, '16e') os.mkdir(temp_suf_dir) temp_hash_dir = os.path.join(temp_suf_dir, '166e33924a08ede4204871468c11e16e') @@ -1079,6 +1081,7 @@ class TestDBReplicator(unittest.TestCase): # sanity-checks self.assertTrue(os.path.exists(temp_dir)) + self.assertTrue(os.path.exists(temp_part_dir)) self.assertTrue(os.path.exists(temp_suf_dir)) self.assertTrue(os.path.exists(temp_hash_dir)) self.assertTrue(os.path.exists(temp_file.name)) @@ -1090,6 +1093,7 @@ class TestDBReplicator(unittest.TestCase): replicator.delete_db(temp_file) self.assertTrue(os.path.exists(temp_dir)) + self.assertTrue(os.path.exists(temp_part_dir)) self.assertTrue(os.path.exists(temp_suf_dir)) self.assertFalse(os.path.exists(temp_hash_dir)) self.assertFalse(os.path.exists(temp_file.name)) @@ -1103,6 +1107,7 @@ class TestDBReplicator(unittest.TestCase): replicator.delete_db(temp_file2) self.assertTrue(os.path.exists(temp_dir)) + self.assertFalse(os.path.exists(temp_part_dir)) self.assertFalse(os.path.exists(temp_suf_dir)) self.assertFalse(os.path.exists(temp_hash_dir)) self.assertFalse(os.path.exists(temp_file.name)) @@ -2186,13 +2191,7 @@ class TestReplicatorSync(unittest.TestCase): # running replicator will remove the deleted db daemon = self._run_once(node, daemon=daemon) self.assertEqual(1, daemon.stats['remove']) - # we still have a part dir (but it's empty) - suff = os.listdir(os.path.join(part_root, part)) - self.assertEqual(0, len(suff)) - # run it again and there's nothing to do... - daemon = self._run_once(node, daemon=daemon) - self.assertEqual(0, daemon.stats['attempted']) - # but empty part dir is cleaned up! + # which also takes out the empty part dir parts = os.listdir(part_root) self.assertEqual(0, len(parts)) -- cgit v1.2.1