From: Ondrej Lichtner <olichtne(a)redhat.com>
This patch replaces the id to device mapping with id to if_index
mapping. This removes the need to update the mapping if a Device object
is removed and recreated for the same device. This can happen when
working with network namespaces - moving a device to a different
namespace deletes it in the current namespace.
Because of this we also need a new attribute - _tmp_mapping that maps id
to device for software devices that were not initialized yet and don't
have an if_index assigned to them.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Slave/InterfaceManager.py | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/lnst/Slave/InterfaceManager.py b/lnst/Slave/InterfaceManager.py
index d00ee4d..94a5c02 100644
--- a/lnst/Slave/InterfaceManager.py
+++ b/lnst/Slave/InterfaceManager.py
@@ -27,8 +27,9 @@ class IfMgrError(Exception):
class InterfaceManager(object):
def __init__(self, server_handler):
- self._devices = {}
- self._id_mapping = {} #id from the ctl to device
+ self._devices = {} #if_index to device
+ self._id_mapping = {} #id from the ctl to if_index
+ self._tmp_mapping = {} #id from the ctl to newly created device
self._nl_socket = IPRSocket()
self._nl_socket.bind()
@@ -43,7 +44,7 @@ class InterfaceManager(object):
elif if_index not in self._devices:
raise IfMgrError("No interface with index %s found." % if_index)
- self._id_mapping[if_id] = self._devices[if_index]
+ self._id_mapping[if_id] = if_index
return
def clear_if_mapping(self):
@@ -71,20 +72,21 @@ class InterfaceManager(object):
if msg['index'] in self._devices:
update_msg = self._devices[msg['index']].update_netlink(msg)
if update_msg != None:
- for if_id, dev in self._id_mapping.iteritems():
- if dev.get_if_index() == msg['index']:
+ for if_id, if_index in self._id_mapping.iteritems():
+ if if_index == msg['index']:
update_msg["if_id"] = if_id
break
if "if_id" in update_msg:
self._server_handler.send_data_to_ctl(update_msg)
else:
dev = None
- for d in self._id_mapping.values():
+ for if_id, d in self._tmp_mapping.items():
d_cfg = d.get_conf_dict()
- if d.get_if_index() == None and\
- d_cfg["name"] == msg.get_attr("IFLA_IFNAME"):
- dev = d
- break
+ if d_cfg["name"] == msg.get_attr("IFLA_IFNAME"):
+ dev = d
+ self._id_mapping[if_id] = msg['index']
+ del self._tmp_mapping[if_id]
+ break
if dev == None:
dev = Device(self)
dev.init_netlink(msg)
@@ -98,12 +100,20 @@ class InterfaceManager(object):
def get_mapped_device(self, if_id):
if if_id in self._id_mapping:
- return self._id_mapping[if_id]
+ if_index = self._id_mapping[if_id]
+ return self._devices[if_index]
+ elif if_id in self._tmp_mapping:
+ return self._tmp_mapping[if_id]
else:
raise IfMgrError("No device with id %s mapped." % if_id)
def get_mapped_devices(self):
- return self._id_mapping
+ ret = {}
+ for if_id, if_index in self._id_mapping.iteritems():
+ ret[if_id] = self._devices[if_index]
+ for if_id, dev in self._tmp_mapping:
+ ret[if_id] = self._tmp_mapping[if_id]
+ return ret
def get_device(self, if_index):
if if_index in self._devices:
@@ -134,7 +144,7 @@ class InterfaceManager(object):
device.set_configuration(config)
device.configure()
- self._id_mapping[if_id] = device
+ self._tmp_mapping[if_id] = device
return config["name"]
def _is_name_used(self, name):
--
1.9.3