X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Ftestbeds%2Fns3%2Fexecute.py;h=0635f2624cab348c607ca3b96c65f0475b29c653;hb=4bea9f9369373d6f6be4b4b781de6d615bfaf610;hp=4c2bca1b6b5e72c080829eed14e54570a2d1a008;hpb=ca773a2144309bbf20ae3af832924c7d48cd959d;p=nepi.git diff --git a/src/nepi/testbeds/ns3/execute.py b/src/nepi/testbeds/ns3/execute.py index 4c2bca1b..0635f262 100644 --- a/src/nepi/testbeds/ns3/execute.py +++ b/src/nepi/testbeds/ns3/execute.py @@ -3,9 +3,8 @@ from nepi.core import testbed_impl from nepi.core.attributes import Attribute -from constants import TESTBED_ID -from nepi.util.constants import TIME_NOW, \ - TESTBED_STATUS_STARTED +from constants import TESTBED_ID, TESTBED_VERSION +from nepi.util.constants import TIME_NOW, TestbedStatus as TS import os import sys import threading @@ -13,41 +12,44 @@ import random import socket import weakref -def init(): - if 'ns3' in sys.modules: - return +def load_ns3_module(): + import sys + if 'ns3' in sys.modules: + return - import ctypes - import imp + import ctypes + import imp + import re - bindings = os.environ["NEPI_NS3BINDINGS"] \ + bindings = os.environ["NEPI_NS3BINDINGS"] \ if "NEPI_NS3BINDINGS" in os.environ else None - libfile = os.environ["NEPI_NS3LIBRARY"] \ + libdir = os.environ["NEPI_NS3LIBRARY"] \ if "NEPI_NS3LIBRARY" in os.environ else None - if libfile: - ctypes.CDLL(libfile, ctypes.RTLD_GLOBAL) - - path = [ os.path.dirname(__file__) ] + sys.path - if bindings: - path = [ bindings ] + path - - try: - module = imp.find_module ('ns3', path) - mod = imp.load_module ('ns3', *module) - except ImportError: - # In some environments, ns3 per-se does not exist, - # only the low-level _ns3 - module = imp.find_module ('_ns3', path) - mod = imp.load_module ('_ns3', *module) - sys.modules["ns3"] = mod # install it as ns3 too - - # When using _ns3, we have to make sure we destroy - # the simulator when the process finishes - import atexit - atexit.register(mod.Simulator.Destroy) - - + if libdir: + files = os.listdir(libdir) + regex = re.compile("(.*\.so)$") + libs = [m.group(1) for filename in files for m in [regex.search(filename)] if m] + + libscp = list(libs) + while len(libs) > 0: + for lib in libscp: + libfile = os.path.join(libdir, lib) + try: + ctypes.CDLL(libfile, ctypes.RTLD_GLOBAL) + libs.remove(lib) + except: + pass + # if did not load any libraries in the last iteration + if len(libscp) == len(libs): + raise RuntimeError("Imposible to load shared libraries %s" % str(libs)) + libscp = list(libs) + + if bindings: + sys.path.append(bindings) + + import ns3_bindings_import as mod + sys.modules["ns3"] = mod class TestbedController(testbed_impl.TestbedController): from nepi.util.tunchannel_impl import TunChannel @@ -58,8 +60,8 @@ class TestbedController(testbed_impl.TestbedController): LOCAL_TYPES = tuple(LOCAL_FACTORIES.values()) - def __init__(self, testbed_version): - super(TestbedController, self).__init__(TESTBED_ID, testbed_version) + def __init__(self): + super(TestbedController, self).__init__(TESTBED_ID, TESTBED_VERSION) self._ns3 = None self._home_directory = None self._traces = dict() @@ -77,7 +79,7 @@ class TestbedController(testbed_impl.TestbedController): def do_setup(self): self._home_directory = self._attributes.\ get_attribute_value("homeDirectory") - self._ns3 = self._load_ns3_module() + self._ns3 = self._configure_ns3_module() # create home... home = os.path.normpath(self.home_directory) @@ -96,7 +98,6 @@ class TestbedController(testbed_impl.TestbedController): def stop(self, time = TIME_NOW): super(TestbedController, self).stop(time) - #self.ns3.Simulator.Stop() self._stop_simulation(time) def set(self, guid, name, value, time = TIME_NOW): @@ -104,14 +105,10 @@ class TestbedController(testbed_impl.TestbedController): # TODO: take on account schedule time for the task factory_id = self._create[guid] factory = self._factories[factory_id] - if factory.box_attributes.is_attribute_design_only(name): - return element = self._elements[guid] if factory_id in self.LOCAL_FACTORIES: setattr(element, name, value) - elif factory.box_attributes.is_attribute_invisible(name): - return - else: + elif not factory.box_attributes.is_attribute_metadata(name): ns3_value = self._to_ns3_value(guid, name, value) self._set_attribute(name, ns3_value, element) @@ -126,9 +123,9 @@ class TestbedController(testbed_impl.TestbedController): return getattr(element, name) else: return value - if factory.box_attributes.is_attribute_design_only(name) or \ - factory.box_attributes.is_attribute_invisible(name): + if factory.box_attributes.is_attribute_metadata(name): return value + TypeId = self.ns3.TypeId() typeid = TypeId.LookupByName(factory_id) info = TypeId.AttributeInfo() @@ -155,6 +152,9 @@ class TestbedController(testbed_impl.TestbedController): filename = self._traces[guid][trace_id] return os.path.join(self.home_directory, filename) + def trace_filename(self, guid, trace_id): + return self._traces[guid][trace_id] + def follow_trace(self, guid, trace_id, filename): if not guid in self._traces: self._traces[guid] = dict() @@ -164,25 +164,19 @@ class TestbedController(testbed_impl.TestbedController): for element in self._elements.itervalues(): if isinstance(element, self.LOCAL_TYPES): # graceful shutdown of locally-implemented objects - element.Cleanup() + element.cleanup() if self.ns3: - self.ns3.Simulator.Stop() + if not self.ns3.Simulator.IsFinished(): + self.stop() - # Wait for it to stop, with a 30s timeout - for i in xrange(300): - if self.ns3.Simulator.IsFinished(): - break - time.sleep(0.1) - #self._stop_simulation("0s") - - self._elements.clear() - - if self.ns3: # TODO!!!! SHOULD WAIT UNTIL THE THREAD FINISHES - # if self._simulator_thread: - # self._simulator_thread.join() + if self._simulator_thread: + self._simulator_thread.join() + self.ns3.Simulator.Destroy() + self._elements.clear() + self._ns3 = None sys.stdout.flush() sys.stderr.flush() @@ -218,15 +212,17 @@ class TestbedController(testbed_impl.TestbedController): # bool flag, a list is used as wrapper has_event_occurred = [False] condition.acquire() - if not self.ns3.Simulator.IsFinished(): - self.ns3.Simulator.ScheduleWithContext(contextId, delay, execute_event, - condition, has_event_occurred, func, *args) - while not has_event_occurred[0] and not self.ns3.Simulator.IsFinished(): - condition.wait() - condition.release() + try: + if not self.ns3.Simulator.IsFinished(): + self.ns3.Simulator.ScheduleWithContext(contextId, delay, execute_event, + condition, has_event_occurred, func, *args) + while not has_event_occurred[0] and not self.ns3.Simulator.IsFinished(): + condition.wait() + finally: + condition.release() def _set_attribute(self, name, ns3_value, element): - if self.status() == TESTBED_STATUS_STARTED: + if self.status() == TS.STATUS_STARTED: # schedule the event in the Simulator self._schedule_event(self._condition, self._set_ns3_attribute, name, ns3_value, element) @@ -234,7 +230,7 @@ class TestbedController(testbed_impl.TestbedController): self._set_ns3_attribute(name, ns3_value, element) def _get_attribute(self, name, ns3_value, element): - if self.status() == TESTBED_STATUS_STARTED: + if self.status() == TS.STATUS_STARTED: # schedule the event in the Simulator self._schedule_event(self._condition, self._get_ns3_attribute, name, ns3_value, element) @@ -248,7 +244,7 @@ class TestbedController(testbed_impl.TestbedController): element.GetAttribute(name, ns3_value) def _stop_simulation(self, time): - if self.status() == TESTBED_STATUS_STARTED: + if self.status() == TS.STATUS_STARTED: # schedule the event in the Simulator self._schedule_event(self._condition, self._stop_ns3_simulation, time) @@ -279,19 +275,24 @@ class TestbedController(testbed_impl.TestbedController): ns3_value.DeserializeFromString(str_value, checker) return ns3_value - def _load_ns3_module(self): + def _configure_ns3_module(self): simu_impl_type = self._attributes.get_attribute_value( "SimulatorImplementationType") + sched_impl_type = self._attributes.get_attribute_value( + "SchedulerType") checksum = self._attributes.get_attribute_value("ChecksumEnabled") stop_time = self._attributes.get_attribute_value("StopTime") - init() + load_ns3_module() import ns3 as mod if simu_impl_type: value = mod.StringValue(simu_impl_type) mod.GlobalValue.Bind ("SimulatorImplementationType", value) + if sched_impl_type: + value = mod.StringValue(sched_impl_type) + mod.GlobalValue.Bind ("SchedulerType", value) if checksum: value = mod.BooleanValue(checksum) mod.GlobalValue.Bind ("ChecksumEnabled", value)