[or-cvs] r20096: {arm} Provided fix for dealing with multiple tor instances - check (arm/trunk/interface)

atagar at seul.org atagar at seul.org
Tue Jul 21 02:56:43 UTC 2009


Author: atagar
Date: 2009-07-20 22:56:42 -0400 (Mon, 20 Jul 2009)
New Revision: 20096

Modified:
   arm/trunk/interface/connPanel.py
   arm/trunk/interface/controller.py
   arm/trunk/interface/headerPanel.py
Log:
Provided fix for dealing with multiple tor instances - checks pid of process with the open control port.



Modified: arm/trunk/interface/connPanel.py
===================================================================
--- arm/trunk/interface/connPanel.py	2009-07-21 01:01:25 UTC (rev 20095)
+++ arm/trunk/interface/connPanel.py	2009-07-21 02:56:42 UTC (rev 20096)
@@ -79,12 +79,13 @@
   Lists netstat provided network data of tor.
   """
   
-  def __init__(self, lock, conn, logger):
+  def __init__(self, lock, conn, torPid, logger):
     TorCtl.PostEventListener.__init__(self)
     util.Panel.__init__(self, lock, -1)
     self.scroll = 0
     self.conn = conn                # tor connection for querrying country codes
     self.logger = logger            # notified in case of problems
+    self.pid = torPid               # tor process ID to make sure we've got the right instance
     self.listingType = LIST_IP      # information used in listing entries
     self.allowDNS = True            # permits hostname resolutions if true
     self.showLabel = True           # shows top label if true, hides otherwise
@@ -101,15 +102,6 @@
     self.cursorSelection = None
     self.cursorLoc = 0              # fallback cursor location if selection disappears
     
-    # gets process id to make sure we get the correct netstat data
-    psCall = os.popen('ps -C tor -o pid')
-    try: self.pid = psCall.read().strip().split()[1]
-    except Exception:
-      # ps call failed
-      self.logger.monitor_event("ERR", "Unable to resolve tor pid, abandoning connection listing")
-      self.pid = -1
-    psCall.close()
-    
     # uses ports to identify type of connections
     self.orPort = self.conn.get_option("ORPort")[0][1]
     self.dirPort = self.conn.get_option("DirPort")[0][1]
@@ -169,7 +161,7 @@
     Reloads netstat results.
     """
     
-    if self.isPaused or self.pid == -1: return
+    if self.isPaused or not self.pid: return
     self.connections = []
     self.connectionCount = [0, 0, 0]
     

Modified: arm/trunk/interface/controller.py
===================================================================
--- arm/trunk/interface/controller.py	2009-07-21 01:01:25 UTC (rev 20095)
+++ arm/trunk/interface/controller.py	2009-07-21 02:56:42 UTC (rev 20096)
@@ -6,6 +6,7 @@
 Curses (terminal) interface for the arm relay status monitor.
 """
 
+import os
 import time
 import curses
 from threading import RLock
@@ -146,15 +147,31 @@
   try: curses.curs_set(0)
   except curses.error: pass
   
+  # gets pid of tor instance with control port open
+  torPid = None       # None if couldn't be resolved (provides error later)
+  pidCall = os.popen("netstat -npl 2> /dev/null | grep 127.0.0.1:%s" % conn.get_option("ControlPort")[0][1])
+  try:
+    results = pidCall.readlines()
+    
+    if len(results) == 1:
+      results = results[0].split()[6] # process field (ex. "7184/tor")
+      torPid = results[:results.find("/")]
+  except IOError: pass # netstat call failed
+  
+  pidCall.close()
+  
   panels = {
-    "header": headerPanel.HeaderPanel(cursesLock, conn),
+    "header": headerPanel.HeaderPanel(cursesLock, conn, torPid),
     "popup": util.Panel(cursesLock, 9),
     "bandwidth": bandwidthPanel.BandwidthMonitor(cursesLock, conn),
     "log": logPanel.LogMonitor(cursesLock, loggedEvents),
     "torrc": confPanel.ConfPanel(cursesLock, conn.get_info("config-file")["config-file"])}
-  panels["conn"] = connPanel.ConnPanel(cursesLock, conn, panels["log"])
+  panels["conn"] = connPanel.ConnPanel(cursesLock, conn, torPid, panels["log"])
   panels["control"] = ControlPanel(cursesLock, panels["conn"].resolver)
   
+  # provides error if pid coulnd't be determined (hopefully shouldn't happen...)
+  if not torPid: panels["log"].monitor_event("ERR", "Unable to resolve tor pid, abandoning connection listing")
+  
   # listeners that update bandwidth and log panels with Tor status
   conn.add_event_listener(panels["log"])
   conn.add_event_listener(panels["bandwidth"])
@@ -165,7 +182,7 @@
   panels["log"].loggedEvents = loggedEvents # strips any that couldn't be set
   
   oldY, oldX = -1, -1
-  isUnresponsive = False    # true if it's been over five seconds since the last BW event (probably due to Tor closing)
+  isUnresponsive = False    # true if it's been over ten seconds since the last BW event (probably due to Tor closing)
   isPaused = False          # if true updates are frozen
   page = 0
   netstatRefresh = time.time()  # time of last netstat refresh
@@ -194,8 +211,8 @@
             panels[panelKey].recreate(stdscr, tmpStartY)
             tmpStartY += panels[panelKey].height
       
-      # if it's been at least five seconds since the last BW event Tor's probably done
-      if not isUnresponsive and panels["log"].getHeartbeat() >= 5:
+      # if it's been at least ten seconds since the last BW event Tor's probably done
+      if not isUnresponsive and panels["log"].getHeartbeat() >= 10:
         isUnresponsive = True
         panels["log"].monitor_event("NOTICE", "Relay unresponsive (last heartbeat: %s)" % time.ctime(panels["log"].lastHeartbeat))
       elif isUnresponsive and panels["log"].getHeartbeat() < 5:

Modified: arm/trunk/interface/headerPanel.py
===================================================================
--- arm/trunk/interface/headerPanel.py	2009-07-21 01:01:25 UTC (rev 20095)
+++ arm/trunk/interface/headerPanel.py	2009-07-21 02:56:42 UTC (rev 20096)
@@ -30,10 +30,10 @@
   fingerprint: BDAD31F6F318E0413833E8EBDA956F76E4D66788
   """
   
-  def __init__(self, lock, conn):
+  def __init__(self, lock, conn, torPid):
     util.Panel.__init__(self, lock, 6)
-    self.vals = []            # mapping of information to be presented
-    self.conn = conn          # Tor control port connection
+    self.vals = {"pid": torPid}     # mapping of information to be presented
+    self.conn = conn                # Tor control port connection
     self.isPaused = False
     self._updateParams()
   
@@ -68,7 +68,7 @@
       # Line 3 (system usage info)
       self.addstr(2, 0, "cpu: %s%%" % self.vals["%cpu"])
       self.addstr(2, 13, "mem: %s (%s%%)" % (util.getSizeLabel(int(self.vals["rss"]) * 1024), self.vals["%mem"]))
-      self.addstr(2, 34, "pid: %s" % self.vals["pid"])
+      self.addstr(2, 34, "pid: %s" % (self.vals["pid"] if self.vals["etime"] else ""))
       self.addstr(2, 47, "uptime: %s" % self.vals["etime"])
       
       # Line 4 (fingerprint)
@@ -106,9 +106,9 @@
     already set)
     """
     
-    if not self.vals:
-      # retrieves static params
-      self.vals = self.conn.get_info(["version"])
+    if len(self.vals) <= 1:
+      # only contains 'pid' - retrieves static params
+      self.vals["version"] = self.conn.get_info(["version"])["version"]
       
       # populates with some basic system information
       unameVals = os.uname()
@@ -145,15 +145,18 @@
       except TorCtl.ErrorReply: pass
       except socket.error: pass
     
-    # ps call provides header followed by params for tor
-    psParams = ["%cpu", "rss", "%mem", "pid", "etime"]
-    psCall = os.popen('ps -C %s -o %s' % ("tor", ",".join(psParams)))
+    if self.vals["pid"]:
+      # ps call provides header followed by params for tor
+      psParams = ["%cpu", "rss", "%mem", "etime"]
+      psCall = os.popen('ps -p %s -o %s' % (self.vals["pid"], ",".join(psParams)))
+      
+      try: sampling = psCall.read().strip().split()[len(psParams):]
+      except IOError: sampling = [] # ps call failed
+      psCall.close()
+    else:
+      sampling = [] # no pid known - blank fields
     
-    try: sampling = psCall.read().strip().split()[len(psParams):]
-    except IOError: sampling = [] # ps call failed
-    psCall.close()
-    
-    if len(sampling) < 5:
+    if len(sampling) < 4:
       # either ps failed or returned no tor instance
       sampling = [""] * len(psParams)
       



More information about the tor-commits mailing list