Commit 1d2dca89 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Store the PTID out of the manager until the partition is received.

There was an inconsistency between the ptid and the partition table stored
in the manager between the processing of the AnswerLastIDs and the
AnswerPartitionTable packets. A storage could disconnect leaving the
master with a wrong partition table.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@2087 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent ce98da46
...@@ -33,7 +33,7 @@ class RecoveryManager(MasterHandler): ...@@ -33,7 +33,7 @@ class RecoveryManager(MasterHandler):
def __init__(self, app): def __init__(self, app):
super(RecoveryManager, self).__init__(app) super(RecoveryManager, self).__init__(app)
# The target node's uuid to request next. # The target node's uuid to request next.
self.target_uuid = None self.target_ptid = None
def getHandler(self): def getHandler(self):
return self return self
...@@ -116,8 +116,6 @@ class RecoveryManager(MasterHandler): ...@@ -116,8 +116,6 @@ class RecoveryManager(MasterHandler):
def answerLastIDs(self, conn, loid, ltid, lptid): def answerLastIDs(self, conn, loid, ltid, lptid):
app = self.app app = self.app
pt = app.pt
# Get max values. # Get max values.
if loid is not None: if loid is not None:
if app.loid is None: if app.loid is None:
...@@ -126,19 +124,17 @@ class RecoveryManager(MasterHandler): ...@@ -126,19 +124,17 @@ class RecoveryManager(MasterHandler):
app.loid = max(loid, app.loid) app.loid = max(loid, app.loid)
if ltid is not None: if ltid is not None:
self.app.tm.setLastTID(ltid) self.app.tm.setLastTID(ltid)
if lptid > pt.getID(): if lptid > self.target_ptid:
# something newer # something newer
self.target_uuid = conn.getUUID() self.target_ptid = lptid
app.pt.setID(lptid)
conn.ask(Packets.AskPartitionTable([])) conn.ask(Packets.AskPartitionTable([]))
def answerPartitionTable(self, conn, ptid, row_list): def answerPartitionTable(self, conn, ptid, row_list):
uuid = conn.getUUID()
app = self.app app = self.app
if uuid != self.target_uuid: if ptid != self.target_ptid:
# If this is not from a target node, ignore it. # If this is not from a target node, ignore it.
logging.warn('got answer partition table from %s while waiting ' \ logging.warn('Got %s while waiting %s', dump(ptid),
'for %s', dump(uuid), dump(self.target_uuid)) dump(self.target_ptid))
return return
# load unknown storage nodes # load unknown storage nodes
new_nodes = [] new_nodes = []
......
...@@ -112,7 +112,7 @@ class MasterRecoveryTests(NeoTestBase): ...@@ -112,7 +112,7 @@ class MasterRecoveryTests(NeoTestBase):
recovery.answerLastIDs(conn, new_oid, new_tid, new_ptid) recovery.answerLastIDs(conn, new_oid, new_tid, new_ptid)
self.assertEquals(new_oid, self.app.loid) self.assertEquals(new_oid, self.app.loid)
self.assertEquals(new_tid, self.app.tm.getLastTID()) self.assertEquals(new_tid, self.app.tm.getLastTID())
self.assertEquals(new_ptid, self.app.pt.getID()) self.assertEquals(new_ptid, recovery.target_ptid)
def test_10_answerPartitionTable(self): def test_10_answerPartitionTable(self):
...@@ -126,7 +126,8 @@ class MasterRecoveryTests(NeoTestBase): ...@@ -126,7 +126,8 @@ class MasterRecoveryTests(NeoTestBase):
cells = self.app.pt.getRow(offset) cells = self.app.pt.getRow(offset)
for cell, state in cells: for cell, state in cells:
self.assertEquals(state, CellStates.OUT_OF_DATE) self.assertEquals(state, CellStates.OUT_OF_DATE)
recovery.answerPartitionTable(conn, None, cell_list) recovery.target_ptid = 2
recovery.answerPartitionTable(conn, 1, cell_list)
cells = self.app.pt.getRow(offset) cells = self.app.pt.getRow(offset)
for cell, state in cells: for cell, state in cells:
self.assertEquals(state, CellStates.OUT_OF_DATE) self.assertEquals(state, CellStates.OUT_OF_DATE)
...@@ -148,7 +149,7 @@ class MasterRecoveryTests(NeoTestBase): ...@@ -148,7 +149,7 @@ class MasterRecoveryTests(NeoTestBase):
self.assertFalse(self.app.pt.hasOffset(offset)) self.assertFalse(self.app.pt.hasOffset(offset))
cell_list = [(offset, ((uuid, NodeStates.DOWN,),),)] cell_list = [(offset, ((uuid, NodeStates.DOWN,),),)]
self.checkProtocolErrorRaised(recovery.answerPartitionTable, conn, self.checkProtocolErrorRaised(recovery.answerPartitionTable, conn,
None, cell_list) 2, cell_list)
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment