Merge "Make rsync ignore it's own temporary files"
This commit is contained in:
commit
346dad2904
@ -229,6 +229,7 @@ class ObjectReplicator(Daemon):
|
||||
'--timeout=%s' % self.rsync_io_timeout,
|
||||
'--contimeout=%s' % self.rsync_io_timeout,
|
||||
'--bwlimit=%s' % self.rsync_bwlimit,
|
||||
'--exclude=.*.%s' % ''.join('[0-9a-zA-Z]' for i in range(6))
|
||||
]
|
||||
if self.rsync_compress and \
|
||||
job['region'] != node['region']:
|
||||
|
@ -19,6 +19,7 @@ from uuid import uuid4
|
||||
import random
|
||||
from hashlib import md5
|
||||
from collections import defaultdict
|
||||
import os
|
||||
|
||||
from swiftclient import client
|
||||
|
||||
@ -82,6 +83,22 @@ class TestObjectHandoff(ReplProbeTest):
|
||||
raise Exception('Direct object GET did not return VERIFY, instead '
|
||||
'it returned: %s' % repr(odata))
|
||||
|
||||
# drop a tempfile in the handoff's datadir, like it might have
|
||||
# had if there was an rsync failure while it was previously a
|
||||
# primary
|
||||
handoff_device_path = self.device_dir('object', another_onode)
|
||||
data_filename = None
|
||||
for root, dirs, files in os.walk(handoff_device_path):
|
||||
for filename in files:
|
||||
if filename.endswith('.data'):
|
||||
data_filename = filename
|
||||
temp_filename = '.%s.6MbL6r' % data_filename
|
||||
temp_filepath = os.path.join(root, temp_filename)
|
||||
if not data_filename:
|
||||
self.fail('Did not find any data files on %r' %
|
||||
handoff_device_path)
|
||||
open(temp_filepath, 'w')
|
||||
|
||||
# Assert container listing (via proxy and directly) has container/obj
|
||||
objs = [o['name'] for o in
|
||||
client.get_container(self.url, self.token, container)[1]]
|
||||
@ -134,6 +151,20 @@ class TestObjectHandoff(ReplProbeTest):
|
||||
raise Exception('Direct object GET did not return VERIFY, instead '
|
||||
'it returned: %s' % repr(odata))
|
||||
|
||||
# and that it does *not* have a temporary rsync dropping!
|
||||
found_data_filename = False
|
||||
primary_device_path = self.device_dir('object', onode)
|
||||
for root, dirs, files in os.walk(primary_device_path):
|
||||
for filename in files:
|
||||
if filename.endswith('.6MbL6r'):
|
||||
self.fail('Found unexpected file %s' %
|
||||
os.path.join(root, filename))
|
||||
if filename == data_filename:
|
||||
found_data_filename = True
|
||||
self.assertTrue(found_data_filename,
|
||||
'Did not find data file %r on %r' % (
|
||||
data_filename, primary_device_path))
|
||||
|
||||
# Assert the handoff server no longer has container/obj
|
||||
try:
|
||||
direct_client.direct_get_object(
|
||||
|
@ -910,6 +910,49 @@ class TestObjectReplicator(unittest.TestCase):
|
||||
jobs = self.replicator.collect_jobs()
|
||||
self.assertEqual(len(jobs), 0)
|
||||
|
||||
def test_replicator_skips_rsync_temp_files(self):
|
||||
# the empty pre-setup dirs aren't that useful to us
|
||||
device_path = os.path.join(self.devices, 'sda')
|
||||
rmtree(device_path, ignore_errors=1)
|
||||
os.mkdir(device_path)
|
||||
# create a real data file to trigger rsync
|
||||
df = self.df_mgr.get_diskfile('sda', '0', 'a', 'c', 'o',
|
||||
policy=POLICIES.legacy)
|
||||
ts = next(self.ts)
|
||||
with df.create() as w:
|
||||
w.write('asdf')
|
||||
w.put({'X-Timestamp': ts.internal})
|
||||
w.commit(ts)
|
||||
# pre-flight and post sync request for both other primaries
|
||||
expected_replicate_requests = 4
|
||||
process_arg_checker = [
|
||||
# (return_code, stdout, <each in capture rsync args>)
|
||||
(0, '', []),
|
||||
(0, '', []),
|
||||
]
|
||||
stub_body = pickle.dumps({})
|
||||
with _mock_process(process_arg_checker) as rsync_log, \
|
||||
mock.patch('swift.obj.replicator.whataremyips',
|
||||
side_effect=_ips), \
|
||||
mocked_http_conn(*[200] * expected_replicate_requests,
|
||||
body=stub_body) as conn_log:
|
||||
self.replicator.replicate()
|
||||
self.assertEqual(['REPLICATE'] * expected_replicate_requests,
|
||||
[r['method'] for r in conn_log.requests])
|
||||
# expect one rsync to each other primary node
|
||||
self.assertEqual(2, len(rsync_log))
|
||||
expected = '--exclude=.*.[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]' \
|
||||
'[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]'
|
||||
for subprocess_info in rsync_log:
|
||||
rsync_args = subprocess_info['rsync_args']
|
||||
for arg in rsync_args:
|
||||
if arg.startswith('--exclude'):
|
||||
self.assertEqual(arg, expected)
|
||||
break
|
||||
else:
|
||||
self.fail('Did not find --exclude argument in %r' %
|
||||
rsync_args)
|
||||
|
||||
def test_replicator_removes_zbf(self):
|
||||
# After running xfs_repair, a partition directory could become a
|
||||
# zero-byte file. If this happens, the replicator should clean it
|
||||
|
Loading…
Reference in New Issue
Block a user