X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fns3%2Fns3server.py;h=0149f501502d64c33f685388d7741ee1ec9b0cef;hb=9199b66cf4e5c3bdf8926153a63084c352c40721;hp=f761b86e662880a0c11a039167128cb766bd5184;hpb=2efd5eabeba8a6577ace9132d6336d44be0510e8;p=nepi.git diff --git a/src/nepi/resources/ns3/ns3server.py b/src/nepi/resources/ns3/ns3server.py index f761b86e..0149f501 100644 --- a/src/nepi/resources/ns3/ns3server.py +++ b/src/nepi/resources/ns3/ns3server.py @@ -3,9 +3,8 @@ # Copyright (C) 2014 INRIA # # This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation; # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,7 +17,7 @@ # Author: Alina Quereilhac import base64 -import cPickle +import pickle import errno import logging import os @@ -27,7 +26,7 @@ import sys from optparse import OptionParser, SUPPRESS_HELP -from ns3wrapper import NS3Wrapper +from nepi.resources.ns3.ns3wrapper import NS3Wrapper class NS3WrapperMessage: CREATE = "CREATE" @@ -43,70 +42,50 @@ class NS3WrapperMessage: def handle_message(ns3_wrapper, msg_type, args, kwargs): if msg_type == NS3WrapperMessage.SHUTDOWN: ns3_wrapper.shutdown() - - ns3_wrapper.logger.debug("SHUTDOWN") - + return "BYEBYE" if msg_type == NS3WrapperMessage.STOP: time = kwargs.get("time") - ns3_wrapper.logger.debug("STOP time=%s" % str(time)) - ns3_wrapper.stop(time=time) + return "STOPPED" if msg_type == NS3WrapperMessage.START: - ns3_wrapper.logger.debug("START") - ns3_wrapper.start() + return "STARTED" if msg_type == NS3WrapperMessage.CREATE: clazzname = args.pop(0) - ns3_wrapper.logger.debug("CREATE %s %s" % (clazzname, str(args))) - - uuid = ns3_wrapper.create(clazzname, *args) - return uuid - + return ns3_wrapper.create(clazzname, *args) + if msg_type == NS3WrapperMessage.FACTORY: type_name = args.pop(0) - ns3_wrapper.logger.debug("FACTORY %s %s" % (type_name, str(kwargs))) - - uuid = ns3_wrapper.factory(type_name, **kwargs) - return uuid - + return ns3_wrapper.factory(type_name, **kwargs) + if msg_type == NS3WrapperMessage.INVOKE: uuid = args.pop(0) operation = args.pop(0) - - ns3_wrapper.logger.debug("INVOKE %s %s %s %s " % (uuid, operation, - str(args), str(kwargs))) - - uuid = ns3_wrapper.invoke(uuid, operation, *args, **kwargs) - return uuid + + return ns3_wrapper.invoke(uuid, operation, *args, **kwargs) if msg_type == NS3WrapperMessage.GET: uuid = args.pop(0) name = args.pop(0) - ns3_wrapper.logger.debug("GET %s %s" % (uuid, name)) - - value = ns3_wrapper.get(uuid, name) - return value - + return ns3_wrapper.get(uuid, name) + if msg_type == NS3WrapperMessage.SET: uuid = args.pop(0) name = args.pop(0) value = args.pop(0) - ns3_wrapper.logger.debug("SET %s %s %s" % (uuid, name, str(value))) + return ns3_wrapper.set(uuid, name, value) - value = ns3_wrapper.set(uuid, name, value) - return value - if msg_type == NS3WrapperMessage.FLUSH: # Forces flushing output and error streams. # NS-3 output will stay unflushed until the program exits or @@ -118,11 +97,17 @@ def handle_message(ns3_wrapper, msg_type, args, kwargs): return "FLUSHED" -def create_socket(socket_name): +def open_socket(socket_name): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.bind(socket_name) return sock +def close_socket(sock): + try: + sock.close() + except: + pass + def recv_msg(conn): msg = [] chunk = '' @@ -130,7 +115,7 @@ def recv_msg(conn): while '\n' not in chunk: try: chunk = conn.recv(1024) - except (OSError, socket.error), e: + except (OSError, socket.error) as e: if e[0] != errno.EINTR: raise # Ignore eintr errors @@ -151,9 +136,9 @@ def recv_msg(conn): def decode(item): item = base64.b64decode(item).rstrip() - return cPickle.loads(item) + return pickle.loads(item) - decoded = map(decode, msg.split("|")) + decoded = [ decode(x) for x in msg.split("|") ] # decoded message dmsg_type = decoded.pop(0) @@ -163,11 +148,11 @@ def recv_msg(conn): return (dmsg_type, dargs, dkwargs) def send_reply(conn, reply): - encoded = base64.b64encode(cPickle.dumps(reply)) + encoded = base64.b64encode(pickle.dumps(reply)) conn.send("%s\n" % encoded) def get_options(): - usage = ("usage: %prog -S -L -v ") + usage = ("usage: %prog -S -L -D -v ") parser = OptionParser(usage = usage) @@ -179,6 +164,12 @@ def get_options(): help = "NS_LOG environmental variable to be set", default = "", type="str") + parser.add_option("-D", "--enable-dump", dest="enable_dump", + help = "Enable dumping the remote executed ns-3 commands to a script " + "in order to later reproduce and debug the experiment", + action = "store_true", + default = False) + parser.add_option("-v", "--verbose", help="Print debug output", action="store_true", @@ -186,9 +177,11 @@ def get_options(): (options, args) = parser.parse_args() - return (options.socket_name, options.verbose, options.ns_log) + return (options.socket_name, options.verbose, options.ns_log, + options.enable_dump) -def run_server(socket_name, level = logging.INFO, ns_log = None): +def run_server(socket_name, level = logging.INFO, ns_log = None, + enable_dump = False): # Sets NS_LOG environmental variable for NS debugging if ns_log: @@ -196,12 +189,12 @@ def run_server(socket_name, level = logging.INFO, ns_log = None): ###### ns-3 wrapper instantiation - ns3_wrapper = NS3Wrapper(loglevel=level) + ns3_wrapper = NS3Wrapper(loglevel=level, enable_dump = enable_dump) ns3_wrapper.logger.info("STARTING...") # create unix socket to receive instructions - sock = create_socket(socket_name) + sock = open_socket(socket_name) sock.listen(0) # wait for messages to arrive and process them @@ -209,17 +202,19 @@ def run_server(socket_name, level = logging.INFO, ns_log = None): while not stop: conn, addr = sock.accept() - conn.settimeout(5) + conn.settimeout(30) try: (msg_type, args, kwargs) = recv_msg(conn) - except socket.timeout, e: + except socket.timeout as e: # Ingore time-out + close_socket(conn) continue if not msg_type: # Ignore - connection lost - break + close_socket(conn) + continue if msg_type == NS3WrapperMessage.SHUTDOWN: stop = True @@ -230,18 +225,27 @@ def run_server(socket_name, level = logging.INFO, ns_log = None): import traceback err = traceback.format_exc() ns3_wrapper.logger.error(err) + close_socket(conn) raise try: send_reply(conn, reply) except socket.error: - break + import traceback + err = traceback.format_exc() + ns3_wrapper.logger.error(err) + close_socket(conn) + raise + close_socket(conn) + + close_socket(sock) + ns3_wrapper.logger.info("EXITING...") if __name__ == '__main__': - (socket_name, verbose, ns_log) = get_options() + (socket_name, verbose, ns_log, enable_dump) = get_options() ## configure logging FORMAT = "%(asctime)s %(name)s %(levelname)-4s %(message)s" @@ -250,5 +254,5 @@ if __name__ == '__main__': logging.basicConfig(format = FORMAT, level = level) ## Run the server - run_server(socket_name, level, ns_log) + run_server(socket_name, level, ns_log, enable_dump)