- MyPLC 0.4 RC2
[mom.git] / bwmon.py
index b1b18e6..60cb543 100755 (executable)
--- a/bwmon.py
+++ b/bwmon.py
 #
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Andy Bavier <acb@cs.princeton.edu>
+# Faiyaz Ahmed <faiyaza@cs.princeton.edu>
 # Copyright (C) 2004-2006 The Trustees of Princeton University
 #
-# $Id: bwmon.py,v 1.4 2006/06/02 04:00:00 mlhuang Exp $
+# $Id: bwmon.py,v 1.8 2006/07/10 20:22:12 faiyaza Exp $
 #
 
 import syslog
@@ -84,14 +85,22 @@ class Slice:
     name - slice name
     time - beginning of recording period in UNIX seconds
     bytes - low bandwidth bytes transmitted at the beginning of the recording period
-    exemptbytes - high bandwidth bytes transmitted at the beginning of the recording period
-    avgrate - average low bandwidth rate to enforce over the recording period
-    avgexemptrate - average high bandwidth rate to enforce over the recording period 
+    exemptbytes - high bandwidth bytes transmitted at the beginning of the recording period (for I2 -F)
+    last_avgrate - last recorded avgrate from NM
+    last_maxrate - last recorded maxrate from NM
+    last_avgexemptrate - last recorded avgexemptrate from NM
+    last_maxexemptrate - last recorded maxexemptrate from NM
     """
 
     def __init__(self, xid, name, maxrate, maxexemptrate, bytes, exemptbytes):
         self.xid = xid
         self.name = name
+       self.time = 0
+       self.exemptbytes = 0
+       self.last_maxrate = default_maxrate
+       self.last_avgrate = default_avgrate
+       self.last_avgexemptrate = default_avgexemptrate 
+       self.last_maxexemptrate = default_maxexemptrate 
         self.reset(maxrate, maxexemptrate, bytes, exemptbytes)
 
     def __repr__(self):
@@ -110,12 +119,24 @@ class Slice:
         self.bytes = bytes
         self.exemptbytes = exemptbytes
 
+       # If NM except"ns below, and new_max* doesn't get set, use last.
+       new_maxrate = self.last_maxrate
+       new_maxexemptrate = self.last_maxexemptrate
+
         # Query Node Manager for max rate overrides
-        (new_maxrate, new_maxexemptrate) = nm.query(self.name, [('nm_net_max_rate', -1), ('nm_net_max_exempt_rate', -1)])
-        if new_maxrate == -1:
-            new_maxrate = default_maxrate
-        if new_maxexemptrate == -1:
-            new_maxexemptrate = default_maxexemptrate
+       try:
+               vals = nm.query(self.name, [('nm_net_max_rate', self.last_maxrate),
+                               ('nm_net_max_exempt_rate', self.last_maxexemptrate),
+                               ('nm_net_avg_rate', self.last_avgrate),
+                               ('nm_net_avg_exempt_rate', self.last_avgexemptrate)])
+               (new_maxrate, new_maxexemptrate, 
+                       self.last_avgrate, self.last_avgexemptrate) = vals 
+               #If NM is alive, and there is a cap, update new
+               self.last_maxrate = new_maxrate
+               self.last_maxexemptrate = new_maxexemptrate
+
+       except Exception, err:
+               print "Warning: Exception received while querying NM:", err
 
         if new_maxrate != maxrate or new_maxexemptrate != maxexemptrate:
             print "%s reset to %s/%s" % \
@@ -134,15 +155,23 @@ class Slice:
         it will get to send slightly more than the average daily byte
         limit.
         """
+       
+       # If NM except'ns below, and avg*rate doesn't get set, use last_*.
+       avgrate = self.last_avgrate
+       avgexemptrate = self.last_avgexemptrate
 
         # Query Node Manager for max average rate overrides
-        (self.avgrate, self.avgexemptrate) = nm.query(self.name, [('nm_net_avg_rate', -1), ('nm_net_avg_exempt_rate', -1)])
-        if self.avgrate == -1:
-            self.avgrate = default_avgrate
-        if self.avgexemptrate == -1:
-            self.avgexemptrate = default_avgexemptrate
-
-        # Prepare message parameters from the template
+       try:
+               (avgrate, avgexemptrate) = nm.query(self.name, 
+                       [('nm_net_avg_rate', self.last_avgrate), 
+                       ('nm_net_avg_exempt_rate', self.last_avgexemptrate)])
+               #If NM is alive, and there is a cap, update new
+               self.last_avgexemptrate = avgexemptrate
+               self.last_avgrate = avgrate
+        except Exception, err:
+                print "Warning: Exception received while querying NM:", err
+       # Prepare message parameters from the template
         message = ""
         params = {'slice': self.name, 'hostname': socket.gethostname(),
                   'since': time.asctime(time.gmtime(self.time)) + " GMT",
@@ -150,10 +179,10 @@ class Slice:
                   'date': time.asctime(time.gmtime()) + " GMT",
                   'period': format_period(period)} 
 
-        bytelimit = self.avgrate * period / bits_per_byte
+        bytelimit = avgrate * period / bits_per_byte
         if bytes >= (self.bytes + bytelimit) and \
-           maxrate > self.avgrate:
-            new_maxrate = self.avgrate
+           maxrate > avgrate:
+            new_maxrate = avgrate
         else:
             new_maxrate = maxrate
 
@@ -162,11 +191,11 @@ class Slice:
         params['bytes'] = format_bytes(bytes - self.bytes)
         params['maxrate'] = bwlimit.format_tc_rate(maxrate)
         params['limit'] = format_bytes(bytelimit)
-        params['avgrate'] = bwlimit.format_tc_rate(self.avgrate)
+        params['avgrate'] = bwlimit.format_tc_rate(avgrate)
 
         if verbose:
             print "%(slice)s %(class)s " \
-                  "%(bytes)s/%(limit)s (%(maxrate)s/%(avgrate)s)" % \
+                  "%(bytes)s, %(limit)s (%(maxrate)s max/%(avgrate)s avg)" % \
                   params
 
         # Cap low bandwidth burst rate
@@ -174,10 +203,10 @@ class Slice:
             message += template % params
             print "%(slice)s %(class)s capped at %(avgrate)s (%(bytes)s/%(limit)s)" % params
 
-        exemptbytelimit = self.avgexemptrate * period / bits_per_byte
+        exemptbytelimit = avgexemptrate * period / bits_per_byte
         if exemptbytes >= (self.exemptbytes + exemptbytelimit) and \
-           maxexemptrate > self.avgexemptrate:
-            new_maxexemptrate = self.avgexemptrate
+           maxexemptrate > avgexemptrate:
+            new_maxexemptrate = avgexemptrate
         else:
             new_maxexemptrate = maxexemptrate
 
@@ -186,11 +215,11 @@ class Slice:
         params['bytes'] = format_bytes(exemptbytes - self.exemptbytes)
         params['maxrate'] = bwlimit.format_tc_rate(maxexemptrate)
         params['limit'] = format_bytes(exemptbytelimit)
-        params['avgrate'] = bwlimit.format_tc_rate(self.avgexemptrate)
+        params['avgrate'] = bwlimit.format_tc_rate(avgexemptrate)
 
         if verbose:
             print "%(slice)s %(class)s " \
-                  "%(bytes)s/%(limit)s (%(maxrate)s/%(avgrate)s)" % \
+                  "%(bytes)s, %(limit)s (%(maxrate)s max /%(avgrate)s avg)" % \
                   params
 
         # Cap high bandwidth burst rate
@@ -269,18 +298,18 @@ def main():
         (version, slices) = pickle.load(f)
         f.close()
         # Check version of data file
-        if version != "$Id: bwmon.py,v 1.4 2006/06/02 04:00:00 mlhuang Exp $":
+        if version != "$Id: bwmon.py,v 1.8 2006/07/10 20:22:12 faiyaza Exp $":
             print "Not using old version '%s' data file %s" % (version, datafile)
             raise Exception
     except Exception:
-        version = "$Id: bwmon.py,v 1.4 2006/06/02 04:00:00 mlhuang Exp $"
+        version = "$Id: bwmon.py,v 1.8 2006/07/10 20:22:12 faiyaza Exp $"
         slices = {}
 
     # Get special slice IDs
     root_xid = bwlimit.get_xid("root")
     default_xid = bwlimit.get_xid("default")
 
-    # Open connection to Node Manager
+    #Open connection to Node Manager
     nm = NM()
 
     live = []
@@ -304,6 +333,8 @@ def main():
         if names and name not in names:
             continue
 
+       #slices is populated from the pickle file
+       #xid is populated from bwlimit (read from /etc/passwd) 
         if slices.has_key(xid):
             slice = slices[xid]
             if time.time() >= (slice.time + period) or \