From f1153326f0a0eec02c26474351f6db7ef2875bce Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Aguerre?= Date: Wed, 23 Apr 2014 11:26:59 +0200 Subject: [PATCH] fix bug with ORB port management --- bin/addToKillList.py | 11 +- .../TestConcurrentSession.py | 8 +- .../concurrentSession/TestMinimalExample.py | 15 ++- .../concurrentSession/usecase_concurrent.sh | 2 +- bin/killSalomeWithPort.py | 108 +++++++++++++++--- bin/orbmodule.py | 8 +- bin/salomeContext.py | 4 - bin/searchFreePort.py | 2 +- src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx | 6 +- 9 files changed, 123 insertions(+), 41 deletions(-) diff --git a/bin/addToKillList.py b/bin/addToKillList.py index de99c7477..7d688aca2 100755 --- a/bin/addToKillList.py +++ b/bin/addToKillList.py @@ -49,11 +49,7 @@ def addToKillList(command_pid, command, port=None): # retrieve current processes dictionary from killSalomeWithPort import getPiDict if port is None: port=findFileDict() - try: - import PortManager - filedict = getPiDict(port, hidden=True, with2809pid=True) - except: - filedict=getPiDict(port) + filedict = getPiDict(port) try: with open(filedict, 'r') as fpid: @@ -71,6 +67,7 @@ def addToKillList(command_pid, command, port=None): pass if already_in: break pass + # add process to the dictionary if not already_in: import types @@ -98,10 +95,12 @@ def killList(port=None): # retrieve processes dictionary from killSalomeWithPort import getPiDict if port is None: port=findFileDict() + # new-style dot-prefixed pidict file - filedict=getPiDict(port, hidden=True) + filedict=getPiDict(port) # provide compatibility with old-style pidict file (not dot-prefixed) if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False) + try: with open(filedict, 'r') as fpid: process_ids=pickle.load(fpid) diff --git a/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py b/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py index 1384b21e6..9e70667d3 100644 --- a/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py +++ b/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py @@ -25,7 +25,7 @@ import sys import imp from cStringIO import StringIO import multiprocessing - +import logging class TestConcurrentLaunch(unittest.TestCase): def setUp(self): @@ -90,8 +90,10 @@ class TestConcurrentLaunch(unittest.TestCase): if __name__ == "__main__": path_to_launcher = os.getenv("SALOME_LAUNCHER") if not path_to_launcher: - msg = "Error: please set SALOME_LAUNCHER variable to the salome command in your application folder." - raise Exception(msg) + msg = "\n" + msg += "Error: please set SALOME_LAUNCHER variable to the salome command in your application folder.\n" + logging.error(msg) + sys.exit(1) if not os.path.isfile("hello.py"): with open("hello.py", "w") as f: diff --git a/bin/appliskel/tests/concurrentSession/TestMinimalExample.py b/bin/appliskel/tests/concurrentSession/TestMinimalExample.py index 7525e4f1b..049759bed 100644 --- a/bin/appliskel/tests/concurrentSession/TestMinimalExample.py +++ b/bin/appliskel/tests/concurrentSession/TestMinimalExample.py @@ -22,6 +22,7 @@ import os import sys import multiprocessing import unittest +import logging def port_reservation(obtained_ports, prefered=None, test=None, expected=None): from PortManager import getPort @@ -139,14 +140,20 @@ class TestMinimalExample(unittest.TestCase): if __name__ == "__main__": omniorb_user_path = os.getenv("OMNIORB_USER_PATH") if not omniorb_user_path: - msg = "Error: please set OMNIORB_USER_PATH variable." - raise Exception(msg) + msg = "\n" + msg += "Error: please set OMNIORB_USER_PATH variable.\n" + msg += " Usually this points to your application USERS directory.\n" + logging.error(msg) + sys.exit(1) try: import PortManager except ImportError: - msg = "Error: can't import PortManager; please check PYTHONPATH variable." - raise Exception(msg) + msg = "\n" + msg += "Error: can't import PortManager; please check PYTHONPATH variable.\n" + msg += " You need to add /bin/salome path.\n" + logging.error(msg) + sys.exit(1) unittest.main() # diff --git a/bin/appliskel/tests/concurrentSession/usecase_concurrent.sh b/bin/appliskel/tests/concurrentSession/usecase_concurrent.sh index a730f4793..9983e22cf 100755 --- a/bin/appliskel/tests/concurrentSession/usecase_concurrent.sh +++ b/bin/appliskel/tests/concurrentSession/usecase_concurrent.sh @@ -2,7 +2,7 @@ echo "This is a script that can be run concurrently." echo "It takes as single argument the number of concurrent executions:" -echo "Usage: " $0 "" +echo "Usage: " $0 " " echo echo "Here is what executed code contents looks like:" echo " - do some stuff" diff --git a/bin/killSalomeWithPort.py b/bin/killSalomeWithPort.py index d2f5c8443..bce9b70be 100755 --- a/bin/killSalomeWithPort.py +++ b/bin/killSalomeWithPort.py @@ -35,7 +35,7 @@ import os, sys, pickle, signal, commands,glob from salome_utils import verbose import salome_utils -def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with2809pid=False): +def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None): """ Get file with list of SALOME processes. This file is located in the user's home directory @@ -52,6 +52,13 @@ def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with280 - hidden : if True, file name is prefixed with . (dot) symbol; this internal parameter is used to support compatibility with older versions of SALOME """ + # bug fix: ensure port is an integer + # Note: this function is also called with port='#####' !!! + try: + port = int(port) + except: + pass + from salome_utils import generateFileName, getTmpDir dir = "" if not hostname: @@ -71,11 +78,8 @@ def getPiDict(port,appname='salome',full=True,hidden=True,hostname=None, with280 pass pass - suffix = "pidict" - if port == 2809 and with2809pid: - suffix = suffix + "-%s"%(os.getpid()) return generateFileName(dir, - suffix=suffix, + suffix="pidict", hidden=hidden, with_username=True, with_hostname=hostname or True, @@ -89,6 +93,9 @@ def appliCleanOmniOrbConfig(port): - ${OMNIORB_USER_PATH}/.omniORB_${USER}_last.cfg the last is removed only if the link points to the first file. """ + if verbose(): + print "clean OmniOrb config for port %s"%port + from salome_utils import generateFileName, getUserName omniorbUserPath = os.getenv("OMNIORB_USER_PATH") if omniorbUserPath is None: @@ -157,6 +164,8 @@ def shutdownMyPort(port, cleanup=True): - port - port number """ if not port: return + # bug fix: ensure port is an integer + port = int(port) try: from PortManager import releasePort @@ -186,6 +195,7 @@ def shutdownMyPort(port, cleanup=True): try: import time from omniORB import CORBA + from LifeCycleCORBA import LifeCycleCORBA # shutdown all orb = CORBA.ORB_init([''], CORBA.ORB_ID) @@ -204,6 +214,10 @@ def shutdownMyPort(port, cleanup=True): pass def __killMyPort(port, filedict): + # bug fix: ensure port is an integer + if port: + port = int(port) + try: with open(filedict, 'r') as fpid: # @@ -251,6 +265,32 @@ def __killMyPort(port, filedict): for process_id in process_ids: for pid, cmd in process_id.items(): if verbose(): print "stop process %s : %s"% (pid, cmd[0]) + if cmd[0] == "omniNames": + if not sys.platform == 'win32': + import subprocess + import shlex + proc1 = subprocess.Popen(shlex.split('ps -eo pid,command'),stdout=subprocess.PIPE) + proc2 = subprocess.Popen(shlex.split('egrep "[0-9] omniNames -start"'),stdin=proc1.stdout, stdout=subprocess.PIPE,stderr=subprocess.PIPE) + proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits. + out,err=proc2.communicate() + # out looks like: PID omniNames -start PORT + + # extract omninames pid and port number + try: + import re + omniNamesPid, omniNamesPort = re.search('(.+?) omniNames -start (.+?) ', out).group(1, 2) + if verbose(): + print "stop omniNames [pid=%s] on port %s"%(omniNamesPid, omniNamesPort) + appliCleanOmniOrbConfig(omniNamesPort) + from PortManager import releasePort + releasePort(omniNamesPort) + os.kill(int(omniNamesPid),signal.SIGKILL) + except (ImportError, AttributeError, OSError) as e: + pass + except: + import traceback + traceback.print_exc() + try: if sys.platform == "win32": import win32pm @@ -284,15 +324,50 @@ def __killMyPort(port, filedict): # # +def __guessPiDictFilename(port): + from salome_utils import getShortHostName, getHostName + filedicts = [ + # new-style dot-prefixed pidict file + getPiDict(port, hidden=True), + # provide compatibility with old-style pidict file (not dot-prefixed) + getPiDict(port, hidden=False), + # provide compatibility with old-style pidict file (short hostname) + getPiDict(port, hidden=True, hostname=getShortHostName()), + # provide compatibility with old-style pidict file (not dot-prefixed, short hostname + getPiDict(port, hidden=False, hostname=getShortHostName()), + # provide compatibility with old-style pidict file (long hostname) + getPiDict(port, hidden=True, hostname=getHostName()), + # provide compatibility with old-style pidict file (not dot-prefixed, long hostname) + getPiDict(port, hidden=False, hostname=getHostName()) + ] + + log_msg = "" + for filedict in filedicts: + log_msg += "Trying %s..."%filedict + if os.path.exists(filedict): + log_msg += " ... OK\n" + break + else: + log_msg += " ... not found\n" + + if verbose(): + print log_msg + + return filedict +# + def killMyPort(port): """ Kill SALOME session running on the specified port. Parameters: - port - port number """ - from salome_utils import getShortHostName, getHostName print "Terminating SALOME on port %s..."%(port) + # bug fix: ensure port is an integer + if port: + port = int(port) + # try to shutdown session normally import threading, time threading.Thread(target=shutdownMyPort, args=(port,False)).start() @@ -300,26 +375,17 @@ def killMyPort(port): try: import PortManager - filedict = getPiDict(port, hidden=True, with2809pid=False) + filedict = getPiDict(port) + #filedict = __guessPiDictFilename(port) import glob all_files = glob.glob("%s*"%filedict) for f in all_files: __killMyPort(port, f) except ImportError: - # new-style dot-prefixed pidict file - filedict = getPiDict(port, hidden=True) - # provide compatibility with old-style pidict file (not dot-prefixed) - if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False) - # provide compatibility with old-style pidict file (short hostname) - if not os.path.exists(filedict): filedict = getPiDict(port, hidden=True, hostname=getShortHostName()) - # provide compatibility with old-style pidict file (not dot-prefixed, short hostname) - if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False, hostname=getShortHostName()) - # provide compatibility with old-style pidict file (long hostname) - if not os.path.exists(filedict): filedict = getPiDict(port, hidden=True, hostname=getHostName()) - # provide compatibility with old-style pidict file (not dot-prefixed, long hostname) - if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False, hostname=getHostName()) + filedict = __guessPiDictFilename(port) __killMyPort(port, filedict) # + appliCleanOmniOrbConfig(port) pass @@ -329,6 +395,10 @@ def cleanApplication(port): Parameters: - port - port number """ + # bug fix: ensure port is an integer + if port: + port = int(port) + try: filedict=getPiDict(port) os.remove(filedict) diff --git a/bin/orbmodule.py b/bin/orbmodule.py index 32c382804..dc280ce81 100755 --- a/bin/orbmodule.py +++ b/bin/orbmodule.py @@ -50,7 +50,7 @@ class client: def initNS(self,args): # Obtain a reference to the root naming context - obj = self.orb.resolve_initial_references("NameService") + obj = self.orb.resolve_initial_references("NameService") try: self.rootContext = obj._narrow(CosNaming.NamingContext) return @@ -89,6 +89,12 @@ class client: # -------------------------------------------------------------------------- def showNScontext(self,context,dec=''): + if not context: + print "[NS] No context" + return + else: + print context + bl,bi=context.list(0) if bi is not None: ok,b=bi.next_one() diff --git a/bin/salomeContext.py b/bin/salomeContext.py index fc5e31af2..b773833c7 100644 --- a/bin/salomeContext.py +++ b/bin/salomeContext.py @@ -349,10 +349,6 @@ class SalomeContext: p = Process(target = killMyPort, args=(port,)) p.start() p.join() - - p = Process(target = killMyPort, args=(2809,)) - p.start() - p.join() except ImportError: from killSalome import killAllPorts killAllPorts() diff --git a/bin/searchFreePort.py b/bin/searchFreePort.py index 999a952e9..9b14fabdb 100644 --- a/bin/searchFreePort.py +++ b/bin/searchFreePort.py @@ -167,7 +167,6 @@ def searchFreePort(args={}, save_config=1, use_port=None): Search free port for SALOME session. Returns first found free port number. """ - try: import PortManager # mandatory from multiprocessing import Process, Queue @@ -178,6 +177,7 @@ def searchFreePort(args={}, save_config=1, use_port=None): os.environ['OMNIORB_CONFIG'] = info[0] os.environ['NSPORT'] = info[1] + args['port'] = os.environ['NSPORT'] os.environ['NSHOST'] = info[2] __savePortToFile(args) diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx index 1bfdd89cc..41e294e02 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx @@ -624,7 +624,8 @@ void SALOME_LifeCycleCORBA::killOmniNames() { std::string cmd = ("from killSalomeWithPort import cleanApplication; "); cmd += std::string("cleanApplication(") + portNumber + "); "; - cmd = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null"; + //cmd = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null"; + cmd = python_exe + std::string(" -c \"") + cmd +"\""; MESSAGE(cmd); system( cmd.c_str() ); } @@ -635,7 +636,8 @@ void SALOME_LifeCycleCORBA::killOmniNames() { std::string cmd = ("from PortManager import releasePort; "); cmd += std::string("releasePort(") + portNumber + "); "; - cmd = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null"; + //cmd = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null"; + cmd = python_exe + std::string(" -c \"") + cmd +"\""; MESSAGE(cmd); system( cmd.c_str() ); } -- 2.39.2