Recording whether a node is whitelisted or not.
[nodemanager.git] / bwmon.py
index 646d93a..b8ca5e2 100644 (file)
--- a/bwmon.py
+++ b/bwmon.py
@@ -15,7 +15,7 @@
 # Faiyaz Ahmed <faiyaza@cs.princeton.edu>
 # Copyright (C) 2004-2006 The Trustees of Princeton University
 #
-# $Id: bwmon.py,v 1.12 2007/03/06 20:46:54 faiyaza Exp $
+# $Id: bwmon.py,v 1.18 2007/04/25 22:19:59 faiyaza Exp $
 #
 
 import os
@@ -209,65 +209,61 @@ class Slice:
         return self.name
 
     def updateSliceAttributes(self, rspec):
-        # Incase the limits have changed. 
-        if (self.MaxRate != default_MaxRate) or \
-        (self.Maxi2Rate != default_Maxi2Rate):
-            self.MaxRate = int(bwlimit.get_bwcap() / 1000)
-            self.Maxi2Rate = int(bwlimit.bwmax / 1000)
-
         # Get attributes
-        if rspec.has_key('net_min_rate'):     
-            logger.log("bwmon:  Updating %s. Min Rate = %s" %(self.name, self.MinRate))
-            # To ensure min does not go above 25% of nodecap.
-            if int(rspec['net_min_rate']) > int(.25 * default_MaxRate):
-                self.MinRate = int(.25 * default_MaxRate)
-            else:    
-                self.MinRate = int(rspec['net_min_rate'])
+
+        # Sanity check plus policy decision for MinRate:
+        # Minrate cant be greater than 25% of MaxRate or NodeCap.
+        MinRate = int(rspec.get("net_min_rate", default_MinRate))
+        if MinRate > int(.25 * default_MaxRate):
+            MinRate = int(.25 * default_MaxRate)
+        if MinRate != self.MinRate:
+            self.MinRate = MinRate
+            logger.log("bwmon:  Updating %s: Min Rate = %s" %(self.name, self.MinRate))
 
         MaxRate = int(rspec.get('net_max_rate', bwlimit.get_bwcap() / 1000))
         if MaxRate != self.MaxRate:
             self.MaxRate = MaxRate
-            logger.log("bwmon:  Updating %s. Max Rate = %s" %(self.name, self.MaxRate))
+            logger.log("bwmon:  Updating %s: Max Rate = %s" %(self.name, self.MaxRate))
 
         Mini2Rate = int(rspec.get('net_i2_min_rate', default_Mini2Rate))
         if Mini2Rate != self.Mini2Rate:
             self.Mini2Rate = Mini2Rate 
-            logger.log("bwmon:  Updating %s. Min i2 Rate = %s" %(self.name, self.Mini2Rate))
+            logger.log("bwmon:  Updating %s: Min i2 Rate = %s" %(self.name, self.Mini2Rate))
 
         Maxi2Rate = int(rspec.get('net_i2_max_rate', bwlimit.bwmax / 1000))
         if Maxi2Rate != self.Maxi2Rate:
             self.Maxi2Rate = Maxi2Rate
-            logger.log("bwmon:  Updating %s. Max i2 Rate = %s" %(self.name, self.Maxi2Rate))
+            logger.log("bwmon:  Updating %s: Max i2 Rate = %s" %(self.name, self.Maxi2Rate))
                           
         MaxKByte = int(rspec.get('net_max_kbyte', default_MaxKByte))
         if MaxKByte != self.MaxKByte:
             self.MaxKByte = MaxKByte
-            logger.log("bwmon:  Updating %s. Max KByte lim = %s" %(self.name, self.MaxKByte))
+            logger.log("bwmon:  Updating %s: Max KByte lim = %s" %(self.name, self.MaxKByte))
                           
         Maxi2KByte = int(rspec.get('net_i2_max_kbyte', default_Maxi2KByte))
         if Maxi2KByte != self.Maxi2KByte:
             self.Maxi2KByte = Maxi2KByte
-            logger.log("bwmon:  Updating %s. Max i2 KByte = %s" %(self.name, self.Maxi2KByte))
+            logger.log("bwmon:  Updating %s: Max i2 KByte = %s" %(self.name, self.Maxi2KByte))
                           
         ThreshKByte = int(rspec.get('net_thresh_kbyte', default_ThreshKByte))
         if ThreshKByte != self.ThreshKByte:
             self.ThreshKByte = ThreshKByte
-            logger.log("bwmon:  Updating %s. Thresh KByte = %s" %(self.name, self.ThreshKByte))
+            logger.log("bwmon:  Updating %s: Thresh KByte = %s" %(self.name, self.ThreshKByte))
                           
         Threshi2KByte = int(rspec.get('net_i2_thresh_kbyte', default_Threshi2KByte))
         if Threshi2KByte != self.Threshi2KByte:    
             self.Threshi2KByte = Threshi2KByte
-            logger.log("bwmon:  Updating %s. i2 Thresh KByte = %s" %(self.name, self.Threshi2KByte))
+            logger.log("bwmon:  Updating %s: i2 Thresh KByte = %s" %(self.name, self.Threshi2KByte))
  
         Share = int(rspec.get('net_share', default_Share))
         if Share != self.Share:
             self.Share = Share
-            logger.log("bwmon:  Updating %s. Net Share = %s" %(self.name, self.Share))
+            logger.log("bwmon:  Updating %s: Net Share = %s" %(self.name, self.Share))
 
         Sharei2 = int(rspec.get('net_i2_share', default_Share))
         if Sharei2 != self.Sharei2:
             self.Sharei2 = Sharei2 
-            logger.log("bwmon:  Updating %s. Net i2 Share = %s" %(self.name, self.i2Share))
+            logger.log("bwmon:  Updating %s: Net i2 Share = %s" %(self.name, self.i2Share))
 
 
     def reset(self, runningmaxrate, runningmaxi2rate, usedbytes, usedi2bytes, rspec):
@@ -321,6 +317,9 @@ class Slice:
                   'period': format_period(period)} 
 
         if usedbytes >= (self.bytes + (self.ThreshKByte * 1024)):
+            if verbose:
+                logger.log("bwmon: %s over thresh %s" \
+                  % (self.name, format_bytes(self.ThreshKByte * 1024)))
             sum = self.bytes + (self.ThreshKByte * 1024)
             maxbyte = self.MaxKByte * 1024
             bytesused = usedbytes - self.bytes
@@ -335,11 +334,12 @@ class Slice:
         params['class'] = "low bandwidth"
         params['bytes'] = format_bytes(usedbytes - self.bytes)
         params['limit'] = format_bytes(self.MaxKByte * 1024)
+        params['thresh'] = format_bytes(self.ThreshKByte * 1024)
         params['new_maxrate'] = bwlimit.format_tc_rate(new_maxrate)
 
         if verbose:
             logger.log("bwmon:  %(slice)s %(class)s " \
-                  "%(bytes)s of %(limit)s (%(new_maxrate)s/s maxrate)" % \
+                  "%(bytes)s of %(limit)s max %(thresh)s thresh (%(new_maxrate)s/s maxrate)" % \
                   params)
 
         # Cap low bandwidth burst rate
@@ -417,21 +417,24 @@ def GetSlivers(db):
         (version, slices) = pickle.load(f)
         f.close()
         # Check version of data file
-        if version != "$Id: bwmon.py,v 1.12 2007/03/06 20:46:54 faiyaza Exp $":
+        if version != "$Id: bwmon.py,v 1.18 2007/04/25 22:19:59 faiyaza Exp $":
             logger.log("bwmon:  Not using old version '%s' data file %s" % (version, datafile))
             raise Exception
     except Exception:
-        version = "$Id: bwmon.py,v 1.12 2007/03/06 20:46:54 faiyaza Exp $"
+        version = "$Id: bwmon.py,v 1.18 2007/04/25 22:19:59 faiyaza Exp $"
         slices = {}
 
     # Get/set special slice IDs
     root_xid = bwlimit.get_xid("root")
     default_xid = bwlimit.get_xid("default")
 
+    # Since root is required for sanity, its not in the API/plc database, so pass {} 
+    # to use defaults.
     if root_xid not in slices.keys():
         slices[root_xid] = Slice(root_xid, "root", {})
         slices[root_xid].reset(0, 0, 0, 0, {})
-
+    
+    # Used by bwlimit.  pass {} since there is no rspec (like above).
     if default_xid not in slices.keys():
         slices[default_xid] = Slice(default_xid, "default", {})
         slices[default_xid].reset(0, 0, 0, 0, {})
@@ -442,16 +445,27 @@ def GetSlivers(db):
         live[bwlimit.get_xid(sliver)] = sliver
 
     # Setup new slices.
-    # live.xids - runing.xids = new.xids
-    newslicesxids = Set(live.keys()) - Set(slices.keys())
+    # live.xids - runing(slices).xids = new.xids
+    newslicesxids = []
+    for plcxid in live.keys():
+        if plcxid not in slices.keys():
+            newslicesxids.append(plcxid)
+
+    #newslicesxids = Set(live.keys()) - Set(slices.keys())
     for newslicexid in newslicesxids:
-        if newslicexid != None or db[live[newslicexid]].has_key('_rspec') != True:
+        # Delegated slices dont have xids (which are uids) since they haven't been
+        # instantiated yet.
+        if newslicexid != None and db[live[newslicexid]].has_key('_rspec') == True:
             logger.log("bwmon: New Slice %s" % live[newslicexid])
+            # _rspec is the computed rspec:  NM retrieved data from PLC, computed loans
+            # and made a dict of computed values.
             rspec = db[live[newslicexid]]['_rspec']
             slices[newslicexid] = Slice(newslicexid, live[newslicexid], rspec)
             slices[newslicexid].reset(0, 0, 0, 0, rspec)
         else:
             logger.log("bwmon  Slice %s doesn't have xid.  Must be delegated.  Skipping." % live[newslicexid])
+
+    # ...mlhuang's abortion....
     # Get actual running values from tc.
     # Update slice totals and bandwidth.
     for params in bwlimit.get():
@@ -477,8 +491,15 @@ def GetSlivers(db):
         #xid is populated from bwlimit (read from /etc/passwd) 
         if slices.has_key(xid):
             slice = slices[xid]
+            # Old slices werent being instanciated correctly because
+            # the HTBs were still pleasent, but the slice in bwmon would
+            # have the byte counts set to 0.  The next time update was run
+            # the real byte count would be sent to update, causing the bw cap.
             if time.time() >= (slice.time + period) or \
-               usedbytes < slice.bytes or usedi2bytes < slice.i2bytes:
+               usedbytes < slice.bytes or \
+               usedi2bytes < slice.i2bytes or \
+               xid in newslicesxids:
                 # Reset to defaults every 24 hours or if it appears
                 # that the byte counters have overflowed (or, more
                 # likely, the node was restarted or the HTB buckets
@@ -498,13 +519,8 @@ def GetSlivers(db):
         else:
             # Just in case.  Probably (hopefully) this will never happen.
             # New slice, initialize state
-            logger.log("bwmon: New Slice %s" % name)
-            slice = slices[xid] = Slice(xid, name, db[slice.name]['_rspec'])
-            slice.reset(maxrate, \
-                maxexemptrate, \
-                usedbytes, \
-                usedi2bytes, \
-                db[slice.name]['_rspec'])
+            logger.log("bwmon: Deleting orphaned slice xid %s" % xid)
+            bwlimit.off(xid)
 
     # Delete dead slices
     dead = Set(slices.keys()) - Set(live.keys())