Merge "Fix for bug 845952"

This commit is contained in:
Jenkins
2011-10-07 18:17:45 +00:00
committed by Gerrit Code Review
2 changed files with 33 additions and 1 deletions

View File

@@ -440,6 +440,7 @@ class RingBuilder(object):
Returns an array('I') of partitions to be reassigned by gathering them Returns an array('I') of partitions to be reassigned by gathering them
from removed devices and overweight devices. from removed devices and overweight devices.
""" """
removed_dev_parts = set()
reassign_parts = array('I') reassign_parts = array('I')
if self._remove_devs: if self._remove_devs:
dev_ids = [d['id'] for d in self._remove_devs if d['parts']] dev_ids = [d['id'] for d in self._remove_devs if d['parts']]
@@ -450,7 +451,8 @@ class RingBuilder(object):
if part2dev[part] in dev_ids: if part2dev[part] in dev_ids:
part2dev[part] = 0xffff part2dev[part] = 0xffff
self._last_part_moves[part] = 0 self._last_part_moves[part] = 0
reassign_parts.append(part) removed_dev_parts.add(part)
start = self._last_part_gather_start / 4 + randint(0, self.parts / 2) start = self._last_part_gather_start / 4 + randint(0, self.parts / 2)
self._last_part_gather_start = start self._last_part_gather_start = start
for replica in xrange(self.replicas): for replica in xrange(self.replicas):
@@ -459,6 +461,8 @@ class RingBuilder(object):
for part in half: for part in half:
if self._last_part_moves[part] < self.min_part_hours: if self._last_part_moves[part] < self.min_part_hours:
continue continue
if part in removed_dev_parts:
continue
dev = self.devs[part2dev[part]] dev = self.devs[part2dev[part]]
if dev['parts_wanted'] < 0: if dev['parts_wanted'] < 0:
part2dev[part] = 0xffff part2dev[part] = 0xffff
@@ -466,6 +470,8 @@ class RingBuilder(object):
dev['parts_wanted'] += 1 dev['parts_wanted'] += 1
dev['parts'] -= 1 dev['parts'] -= 1
reassign_parts.append(part) reassign_parts.append(part)
reassign_parts.extend(removed_dev_parts)
shuffle(reassign_parts) shuffle(reassign_parts)
return reassign_parts return reassign_parts

View File

@@ -194,6 +194,32 @@ class TestRingBuilder(unittest.TestCase):
counts[dev_id] = counts.get(dev_id, 0) + 1 counts[dev_id] = counts.get(dev_id, 0) + 1
self.assertEquals(counts[3], 256) self.assertEquals(counts[3], 256)
def test_add_rebalance_add_rebalance_delete_rebalance(self):
""" Test for https://bugs.launchpad.net/swift/+bug/845952 """
# min_part of 0 to allow for rapid rebalancing
rb = ring.RingBuilder(8, 3, 0)
rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1',
'port': 10000, 'device': 'sda1'})
rb.add_dev({'id': 1, 'zone': 1, 'weight': 1, 'ip': '127.0.0.1',
'port': 10001, 'device': 'sda1'})
rb.add_dev({'id': 2, 'zone': 2, 'weight': 1, 'ip': '127.0.0.1',
'port': 10002, 'device': 'sda1'})
rb.rebalance()
rb.add_dev({'id': 3, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1',
'port': 10003, 'device': 'sda1'})
rb.add_dev({'id': 4, 'zone': 1, 'weight': 1, 'ip': '127.0.0.1',
'port': 10004, 'device': 'sda1'})
rb.add_dev({'id': 5, 'zone': 2, 'weight': 1, 'ip': '127.0.0.1',
'port': 10005, 'device': 'sda1'})
rb.rebalance()
rb.remove_dev(1)
rb.rebalance()
def test_validate(self): def test_validate(self):
rb = ring.RingBuilder(8, 3, 1) rb = ring.RingBuilder(8, 3, 1)
rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1', rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1',