Commit a6d13d0e authored by Grégory Wisniewski's avatar Grégory Wisniewski

Fix implementation of setNodeState in master administration handler, it's now

allowed to set a disconnected node to DOWN state and drop it from the partition
table. A global review of node state alteration by the admin node is required to
ensure all and no less-or-more is allowed here. Add a TODO entry about that.


git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@1240 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 8971228c
...@@ -79,6 +79,9 @@ RC - Review output of pylint (CODE) ...@@ -79,6 +79,9 @@ RC - Review output of pylint (CODE)
- Fix packet types (CODE) - Fix packet types (CODE)
Some packets are of response type but have a name starting with 'notify'. Some packets are of response type but have a name starting with 'notify'.
Decide wether they are notifications or responses, and fix the right one. Decide wether they are notifications or responses, and fix the right one.
- Consider replace setNodeState admin packet by one per action, like
dropNode to reduce packet processing complexity and reduce bad actions
like set a node in TEMPORARILY_DOWN state.
Storage Storage
- Implement incremental storage verification (BANDWITH) - Implement incremental storage verification (BANDWITH)
......
...@@ -311,6 +311,7 @@ class Application(object): ...@@ -311,6 +311,7 @@ class Application(object):
def broadcastPartitionChanges(self, ptid, cell_list): def broadcastPartitionChanges(self, ptid, cell_list):
"""Broadcast a Notify Partition Changes packet.""" """Broadcast a Notify Partition Changes packet."""
# XXX: don't send if cell_list is empty, to have an unique check
logging.debug('broadcastPartitionChanges') logging.debug('broadcastPartitionChanges')
self.pt.log() self.pt.log()
for c in self.em.getConnectionList(): for c in self.em.getConnectionList():
......
...@@ -48,20 +48,12 @@ class AdministrationHandler(MasterHandler): ...@@ -48,20 +48,12 @@ class AdministrationHandler(MasterHandler):
app = self.app app = self.app
node = app.nm.getNodeByUUID(uuid) node = app.nm.getNodeByUUID(uuid)
if node is None: if node is None:
p = protocol.protocolError('invalid uuid') raise protocol.ProtocolError('unknown node')
conn.answer(p, packet.getId())
return
if uuid == app.uuid: if uuid == app.uuid:
node.setState(state)
# get message for self # get message for self
if state == RUNNING_STATE: if state != RUNNING_STATE:
# yes I know
p = protocol.noError('node state changed')
conn.answer(p, packet.getId())
return
else:
# I was asked to shutdown
node.setState(state)
p = protocol.noError('node state changed') p = protocol.noError('node state changed')
conn.answer(p, packet.getId()) conn.answer(p, packet.getId())
app.shutdown() app.shutdown()
...@@ -70,51 +62,36 @@ class AdministrationHandler(MasterHandler): ...@@ -70,51 +62,36 @@ class AdministrationHandler(MasterHandler):
# no change, just notify admin node # no change, just notify admin node
p = protocol.noError('node state changed') p = protocol.noError('node state changed')
conn.answer(p, packet.getId()) conn.answer(p, packet.getId())
else: return
# FIXME: this is wrong, what about a disconnected node to set in
# down state ? we can't get a connection to it but still set the if state == protocol.RUNNING_STATE:
# state.
# first make sure to have a connection to the node # first make sure to have a connection to the node
node_conn = None node_conn = None
conn_found = False
for node_conn in app.em.getConnectionList(): for node_conn in app.em.getConnectionList():
if node_conn.getUUID() == node.getUUID(): if node_conn.getUUID() == node.getUUID():
conn_found = True
break break
if conn_found is False: else:
# no connection to the node # no connection to the node
p = protocol.protocolError('no connection to the node') raise protocol.ProtocolError('no connection to the node')
conn.notify(p)
return
# modify the partition table if required elif state == protocol.DOWN_STATE and node.isStorage():
if modify_partition_table and node.isStorage(): # modify the partition table if required
if state in (DOWN_STATE, TEMPORARILY_DOWN_STATE, HIDDEN_STATE): cell_list = []
if modify_partition_table:
# remove from pt # remove from pt
cell_list = app.pt.dropNode(node) cell_list = app.pt.dropNode(node)
else: else:
# add to pt # outdate node in partition table
cell_list = app.pt.addNode(node) cell_list = app.pt.outdate()
if len(cell_list) != 0:
ptid = app.pt.setNextID()
app.broadcastPartitionChanges(ptid, cell_list)
else:
# outdate node in partition table
cell_list = app.pt.outdate()
if len(cell_list) != 0: if len(cell_list) != 0:
ptid = app.pt.setNextID() ptid = app.pt.setNextID()
app.broadcastPartitionChanges(ptid, cell_list) app.broadcastPartitionChanges(ptid, cell_list)
if node.getState() != state: # /!\ send the node information *after* the partition table change
node.setState(state) node.setState(state)
p = protocol.noError('state changed') p = protocol.noError('state changed')
conn.answer(p, packet.getId()) conn.answer(p, packet.getId())
app.broadcastNodeInformation(node) app.broadcastNodeInformation(node)
# If this is a storage node, ask it to start.
if node.isStorage() and state == RUNNING_STATE \
and self.app.cluster_state == RUNNING:
logging.info("asking sn to start operation")
node_conn.notify(protocol.startOperation())
def handleAddPendingNodes(self, conn, packet, uuid_list): def handleAddPendingNodes(self, conn, packet, uuid_list):
uuids = ', '.join([dump(uuid) for uuid in uuid_list]) uuids = ', '.join([dump(uuid) for uuid in uuid_list])
......
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