From 2bfd9c6a9b0d9ee5b547a31ba97be74b09ac3afc Mon Sep 17 00:00:00 2001 From: Samuel Merritt Date: Thu, 15 Feb 2018 15:42:09 -0800 Subject: [PATCH] Make DB replicators ignore non-partition directories If a cluster operator has some tooling that makes directories in /srv/node//accounts, then the account replicator will treat those directories as partition dirs and may remove empty subdirectories contained therein. This wastes time and confuses the operator. This commit makes DB replicators skip partition directories whose names don't look like positive integers. This doesn't completely avoid the problem since an operator can still use an all-digit name, but it will skip directories like "tmp21945". Change-Id: I8d6682915a555f537fc0ce8c39c3d52c99ff3056 --- swift/common/db_replicator.py | 14 +++++++++++++- test/unit/common/test_db_replicator.py | 8 +++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/swift/common/db_replicator.py b/swift/common/db_replicator.py index a28f8b0e62..e25ac9124a 100644 --- a/swift/common/db_replicator.py +++ b/swift/common/db_replicator.py @@ -69,6 +69,17 @@ def quarantine_db(object_file, server_type): renamer(object_dir, quarantine_dir, fsync=False) +def looks_like_partition(dir_name): + """ + True if the directory name is a valid partition number, False otherwise. + """ + try: + part = int(dir_name) + return part >= 0 + except ValueError: + return False + + def roundrobin_datadirs(datadirs): """ Generator to walk the data dirs in a round robin manner, evenly @@ -81,7 +92,8 @@ def roundrobin_datadirs(datadirs): """ def walk_datadir(datadir, node_id): - partitions = os.listdir(datadir) + partitions = [pd for pd in os.listdir(datadir) + if looks_like_partition(pd)] random.shuffle(partitions) for partition in partitions: part_dir = os.path.join(datadir, partition) diff --git a/test/unit/common/test_db_replicator.py b/test/unit/common/test_db_replicator.py index a1e818cef1..66a07ac1e1 100644 --- a/test/unit/common/test_db_replicator.py +++ b/test/unit/common/test_db_replicator.py @@ -1266,9 +1266,11 @@ class TestDBReplicator(unittest.TestCase): return [] path = path[len('/srv/node/sdx/containers'):] if path == '': - return ['123', '456', '789', '9999'] + return ['123', '456', '789', '9999', "-5", "not-a-partition"] # 456 will pretend to be a file # 9999 will be an empty partition with no contents + # -5 and not-a-partition were created by something outside + # Swift elif path == '/123': return ['abc', 'def.db'] # def.db will pretend to be a file elif path == '/123/abc': @@ -1292,6 +1294,10 @@ class TestDBReplicator(unittest.TestCase): 'weird2'] # weird2 will pretend to be a dir, if asked elif path == '9999': return [] + elif path == 'not-a-partition': + raise Exception("shouldn't look in not-a-partition") + elif path == '-5': + raise Exception("shouldn't look in -5") return [] def _isdir(path):