From 94e7d9b143ab9ea609ef367cad7d49d45dabef8b Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Fri, 12 Dec 2014 17:36:47 +0100 Subject: [PATCH] Fixing core dump in NS3/DCE caused by getting the DceApplication Pid too early --- src/nepi/resources/linux/ns3/ns3simulation.py | 2 - src/nepi/resources/ns3/ns3application.py | 21 ++-- src/nepi/resources/ns3/ns3dceapplication.py | 104 ++++++++++-------- src/nepi/resources/ns3/ns3node.py | 7 ++ src/nepi/resources/ns3/ns3wrapper.py | 19 +++- 5 files changed, 92 insertions(+), 61 deletions(-) diff --git a/src/nepi/resources/linux/ns3/ns3simulation.py b/src/nepi/resources/linux/ns3/ns3simulation.py index 61eae0ab..04671bbb 100644 --- a/src/nepi/resources/linux/ns3/ns3simulation.py +++ b/src/nepi/resources/linux/ns3/ns3simulation.py @@ -138,8 +138,6 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): self._client = None self._home = "ns3-simu-%s" % self.guid self._socket_name = "ns3-%s.sock" % os.urandom(4).encode('hex') - self._dce_manager_helper_uuid = None - self._dce_application_helper_uuid = None self._enable_dce = None @property diff --git a/src/nepi/resources/ns3/ns3application.py b/src/nepi/resources/ns3/ns3application.py index 1007c5f4..64bacf7f 100644 --- a/src/nepi/resources/ns3/ns3application.py +++ b/src/nepi/resources/ns3/ns3application.py @@ -24,17 +24,24 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseApplication(NS3Base): _rtype = "abstract::ns3::Application" + def __init__(self, ec, guid): + super(NS3BaseApplication, self).__init__(ec, guid) + self._node = None + @property def node(self): - from nepi.resources.ns3.ns3node import NS3BaseNode - nodes = self.get_connected(NS3BaseNode.get_rtype()) + if not self._node: + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) - if not nodes: - msg = "Application not connected to node" - self.error(msg) - raise RuntimeError, msg + if not nodes: + msg = "Application not connected to node" + self.error(msg) + raise RuntimeError, msg - return nodes[0] + self._node = nodes[0] + + return self._node @property def _rms_to_wait(self): diff --git a/src/nepi/resources/ns3/ns3dceapplication.py b/src/nepi/resources/ns3/ns3dceapplication.py index 4b40ef93..886679e4 100644 --- a/src/nepi/resources/ns3/ns3dceapplication.py +++ b/src/nepi/resources/ns3/ns3dceapplication.py @@ -20,6 +20,7 @@ from nepi.execution.attribute import Attribute, Flags, Types from nepi.execution.resource import clsinit_copy, ResourceState from nepi.resources.ns3.ns3application import NS3BaseApplication +from nepi.execution.trace import TraceAttr from nepi.resources.ns3.ns3wrapper import SIMULATOR_UUID @@ -32,9 +33,9 @@ class NS3BaseDceApplication(NS3BaseApplication): _rtype = "abstract::ns3::DceApplication" # Lock used to synchronize usage of DceManagerHelper - dce_manager_lock = threading.Lock() + _dce_manager_lock = threading.Lock() # Lock used to synchronize usage of DceApplicationHelper - dce_application_lock = threading.Lock() + _dce_application_lock = threading.Lock() _dce_manager_helper_uuid = None _dce_application_helper_uuid = None @@ -83,36 +84,43 @@ class NS3BaseDceApplication(NS3BaseApplication): cls._register_attribute(stoptime) cls._register_attribute(starttime) - @property - def node(self): - from nepi.resources.ns3.ns3node import NS3BaseNode - nodes = self.get_connected(NS3BaseNode.get_rtype()) - - if not nodes: - msg = "DceApplication not connected to node" - self.error(msg) - raise RuntimeError, msg + def __init__(self, ec, guid): + super(NS3BaseDceApplication, self).__init__(ec, guid) + self._pid = None - return nodes[0] + @property + def pid(self): + return self._pid @property def dce_manager_helper_uuid(self): - if not self._dce_manager_helper_uuid: - self._dce_manager_helper_uuid = self.simulation.create( - "DceManagerHelper") + if not NS3BaseDceApplication._dce_manager_helper_uuid: + NS3BaseDceApplication._dce_manager_helper_uuid = \ + self.simulation.create("DceManagerHelper") - if self.get("useDlmLoader"): - self.simulation.invoke( - self._dce_manager_helper_uuid, "SetLoader", - "ns3::DlmLoaderFactory") + if self.get("useDlmLoader"): + self.simulation.invoke( + NS3BaseDceApplication._dce_manager_helper_uuid, + "SetLoader", + "ns3::DlmLoaderFactory") - return self._dce_manager_helper_uuid + return NS3BaseDceApplication._dce_manager_helper_uuid @property def dce_application_helper_uuid(self): - if not self._dce_application_helper_uuid: - self._dce_application_helper_uuid = self.simulation.create("DceApplicationHelper") - return self._dce_application_helper_uuid + if not NS3BaseDceApplication._dce_application_helper_uuid: + NS3BaseDceApplication._dce_application_helper_uuid = \ + self.simulation.create("DceApplicationHelper") + + return NS3BaseDceApplication._dce_application_helper_uuid + + @property + def dce_manager_lock(self): + return NS3BaseDceApplication._dce_manager_lock + + @property + def dce_application_lock(self): + return NS3BaseDceApplication._dce_application_lock def _instantiate_object(self): pass @@ -160,6 +168,7 @@ class NS3BaseDceApplication(NS3BaseApplication): self.dce_application_helper_uuid, "InstallInNode", self.node.uuid) + """ container_uuid = self.simulation.create("NodeContainer") self.simulation.invoke(container_uuid, "Add", self.node.uuid) @@ -188,37 +197,36 @@ class NS3BaseDceApplication(NS3BaseApplication): self.debug("---- RESCHEDULING START ----" ) self.ec.schedule(self.reschedule_delay, self.start) else: - self._configure_traces() - super(NS3BaseApplication, self).do_start() - self._start_time = self.simulation.start_time + is_app_running = self.simulation.invoke(self.uuid, "isAppRunning") + is_simu_finished = self.simulation.invoke(SIMULATOR_UUID, "isFinished") - def _configure_traces(self): - # Waiting until dce application is actually started - is_running = False - for i in xrange(200): - is_running = self.simulation.invoke(self.uuid, "isAppRunning") - is_finished = self.simulation.invoke(SIMULATOR_UUID, "isFinished") - - if is_running or is_finished: - break + if is_app_running or is_simu_finished: + super(NS3BaseApplication, self).do_start() + self._start_time = self.simulation.start_time else: - time.sleep(1) - else: - if not is_running: - msg = " Application did not start" - self.error(msg) - raise RuntimeError + # Reschedule until dce application is actually started + self.debug("---- RESCHEDULING START ----" ) + self.ec.schedule(self.reschedule_delay, self.start) + + def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0): + self._configure_traces() + return super(NS3BaseDceApplication, self).trace(name, attr = attr, + block = block, offset = offset) + + def _configure_traces(self): + if self.pid is not None: + return # Using lock to prevent concurrent access to the DceApplicationHelper # from different DceApplication RMs with self.dce_application_lock: - pid = self.simulation.invoke(self.dce_application_helper_uuid, + self._pid = self.simulation.invoke(self.dce_application_helper_uuid, "GetPid", self.uuid) - - node_id = self.simulation.invoke(self.node.uuid, "GetId") - self._trace_filename["stdout"] = "files-%s/var/log/%s/stdout" % (node_id, pid) - self._trace_filename["stderr"] = "files-%s/var/log/%s/stderr" % (node_id, pid) - self._trace_filename["status"] = "files-%s/var/log/%s/status" % (node_id, pid) - self._trace_filename["cmdline"] = "files-%s/var/log/%s/cmdline" % (node_id, pid) + + node_id = self.node.node_id + self._trace_filename["stdout"] = "files-%s/var/log/%s/stdout" % (node_id, self.pid) + self._trace_filename["stderr"] = "files-%s/var/log/%s/stderr" % (node_id, self.pid) + self._trace_filename["status"] = "files-%s/var/log/%s/status" % (node_id, self.pid) + self._trace_filename["cmdline"] = "files-%s/var/log/%s/cmdline" % (node_id, self.pid) diff --git a/src/nepi/resources/ns3/ns3node.py b/src/nepi/resources/ns3/ns3node.py index a85ba0dc..2d14b856 100644 --- a/src/nepi/resources/ns3/ns3node.py +++ b/src/nepi/resources/ns3/ns3node.py @@ -28,6 +28,7 @@ class NS3BaseNode(NS3Base): def __init__(self, ec, guid): super(NS3BaseNode, self).__init__(ec, guid) self._simulation = None + self._node_id = None self._ipv4 = None self._arp = None self._mobility = None @@ -106,6 +107,10 @@ class NS3BaseNode(NS3Base): return self._devices + @property + def node_id(self): + return self._node_id + @property def dceapplications(self): if not self._dceapplications: @@ -153,6 +158,8 @@ class NS3BaseNode(NS3Base): uuid_packet_socket_factory = self.simulation.create("PacketSocketFactory") self.simulation.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory) + self._node_id = self.simulation.invoke(self.uuid, "GetId") + dceapplications = self.dceapplications if dceapplications: self._add_dce(dceapplications) diff --git a/src/nepi/resources/ns3/ns3wrapper.py b/src/nepi/resources/ns3/ns3wrapper.py index eadd71fa..c0f27beb 100644 --- a/src/nepi/resources/ns3/ns3wrapper.py +++ b/src/nepi/resources/ns3/ns3wrapper.py @@ -174,7 +174,16 @@ class NS3Wrapper(object): @property def is_running(self): - return self._started and not self.ns3.Simulator.IsFinished() + return self.is_started and not self.ns3.Simulator.IsFinished() + + @property + def is_started(self): + if not self._started: + now = self.ns3.Simulator.Now() + if not now.IsZero(): + self._started = True + + return self._started @property def is_finished(self): @@ -263,6 +272,9 @@ class NS3Wrapper(object): if operation == "isRunning": result = self.is_running + elif operation == "isStarted": + result = self.is_started + elif operation == "isFinished": result = self.is_finished @@ -406,8 +418,7 @@ class NS3Wrapper(object): args = [self._condition]) self._simulator_thread.setDaemon(True) self._simulator_thread.start() - self._started = True - + ### DEBUG self.logger.debug("START") @@ -570,7 +581,7 @@ class NS3Wrapper(object): return realkwargs - def _is_app_running(self, uuid): + def _is_app_running(self, uuid): now = self.ns3.Simulator.Now() if now.IsZero(): return False -- 2.43.0