Output account-reaper's logs for PolicyError

By some operational mistakes, policy settings can be inconsistent among
servers of swift cluster. Before this patch, if a policy setting of the
server where account-reaper daemon is running is different from other
servers, reap_object process failed without outputing error logs and
count up remaining objects.

Change-Id: Ic84fef7b49c77f0197f0bec4d41401686114d50e
Related-Bug: 1375384
This commit is contained in:
Daisuke Morita 2014-12-12 10:37:33 +09:00
parent df529a225f
commit 8607833fdd
2 changed files with 46 additions and 2 deletions

View File

@ -31,7 +31,7 @@ from swift.common.ring import Ring
from swift.common.utils import get_logger, whataremyips, ismount, \
config_true_value, Timestamp
from swift.common.daemon import Daemon
from swift.common.storage_policy import POLICIES
from swift.common.storage_policy import POLICIES, PolicyError
class AccountReaper(Daemon):
@ -353,6 +353,10 @@ class AccountReaper(Daemon):
break
try:
policy_index = headers.get('X-Backend-Storage-Policy-Index', 0)
policy = POLICIES.get_by_index(policy_index)
if not policy:
self.logger.error('ERROR: invalid storage policy index: %r'
% policy_index)
for obj in objects:
if isinstance(obj['name'], unicode):
obj['name'] = obj['name'].encode('utf8')
@ -428,7 +432,12 @@ class AccountReaper(Daemon):
of the container node dicts.
"""
container_nodes = list(container_nodes)
ring = self.get_object_ring(policy_index)
try:
ring = self.get_object_ring(policy_index)
except PolicyError:
self.stats_objects_remaining += 1
self.logger.increment('objects_remaining')
return
part, nodes = ring.get_nodes(account, container, obj)
successes = 0
failures = 0

View File

@ -50,6 +50,9 @@ class FakeLogger(object):
def info(self, msg, *args):
self.msg = msg
def error(self, msg, *args):
self.msg = msg
def timing_since(*args, **kwargs):
pass
@ -313,6 +316,13 @@ class TestReaper(unittest.TestCase):
self.assertEqual(r.stats_objects_remaining, 1)
self.assertEqual(r.stats_objects_possibly_remaining, 1)
def test_reap_object_non_exist_policy_index(self):
r = self.init_reaper({}, fakelogger=True)
r.reap_object('a', 'c', 'partition', cont_nodes, 'o', 2)
self.assertEqual(r.stats_objects_deleted, 0)
self.assertEqual(r.stats_objects_remaining, 1)
self.assertEqual(r.stats_objects_possibly_remaining, 0)
@patch('swift.account.reaper.Ring',
lambda *args, **kwargs: unit.FakeRing())
def test_reap_container(self):
@ -404,6 +414,31 @@ class TestReaper(unittest.TestCase):
self.assertEqual(r.logger.inc['return_codes.4'], 3)
self.assertEqual(r.stats_containers_remaining, 1)
@patch('swift.account.reaper.Ring',
lambda *args, **kwargs: unit.FakeRing())
def test_reap_container_non_exist_policy_index(self):
r = self.init_reaper({}, fakelogger=True)
with patch.multiple('swift.account.reaper',
direct_get_container=DEFAULT,
direct_delete_object=DEFAULT,
direct_delete_container=DEFAULT) as mocks:
headers = {'X-Backend-Storage-Policy-Index': 2}
obj_listing = [{'name': 'o'}]
def fake_get_container(*args, **kwargs):
try:
obj = obj_listing.pop(0)
except IndexError:
obj_list = []
else:
obj_list = [obj]
return headers, obj_list
mocks['direct_get_container'].side_effect = fake_get_container
r.reap_container('a', 'partition', acc_nodes, 'c')
self.assertEqual(r.logger.msg,
'ERROR: invalid storage policy index: 2')
def fake_reap_container(self, *args, **kwargs):
self.called_amount += 1
self.r.stats_containers_deleted = 1