More convenient output of show.
[util-vserver-pl.git] / python / bwlimit.py
index 073df7a..60b290e 100644 (file)
@@ -66,7 +66,7 @@ verbose = 0
 # bwmin should be small enough that it can be considered negligibly
 # slow compared to the hardware. 8 bits/second appears to be the
 # smallest value supported by tc.
-bwmin = 8
+bwmin = 1000
 
 # bwmax should be large enough that it can be considered at least as
 # fast as the hardware.
@@ -191,6 +191,24 @@ def get_tc_rate(s):
     else:
         return -1
 
+def format_bytes(bytes, si = True):
+    """
+    Formats bytes into a string
+    """
+    if si:
+        kilo = 1000.
+    else:
+        # Officially, a kibibyte
+        kilo = 1024.
+
+    if bytes >= (kilo * kilo * kilo):
+        return "%.1f GB" % (bytes / (kilo * kilo * kilo))
+    elif bytes >= 1000000:
+        return "%.1f MB" % (bytes / (kilo * kilo))
+    elif bytes >= 1000:
+        return "%.1f KB" % (bytes / kilo)
+    else:
+        return "%.0f bytes" % bytes
 
 def format_tc_rate(rate):
     """
@@ -546,9 +564,15 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra
 
 
 def set(xid, share = None, minrate = None, maxrate = None, minexemptrate = None, maxexemptrate = None):
-    on(xid = xid, share = share,
-       minrate = minrate, maxrate = maxrate,
-       minexemptrate = minexemptrate, maxexemptrate = maxexemptrate)
+    # Get defaults from current state if available
+    # get(xid,dev) = ( xid, share, minrate, maxrate, minexemptrate, maxexemptrate, bytes, i2bytes )
+    current = get(xid, dev)
+    if current == None: current = () # must be a new slice if returned nothing.
+    new = ( share, minrate, maxrate, minexemptrate, maxexemptrate )
+    if current[1:6] != new:
+        on(xid = xid, share = share,
+            minrate = minrate, maxrate = maxrate,
+            minexemptrate = minexemptrate, maxexemptrate = maxexemptrate)
 
 
 # Remove class associated with specified slice xid. If further packets
@@ -573,22 +597,21 @@ def exempt_init(group_name, node_ips):
     (burst) cap.
     """
 
-    # Clean up
-    iptables = "/sbin/iptables -t mangle %s POSTROUTING" 
-    run(iptables % "-F")
-    run("/sbin/ipset -X " + group_name)
-
-    # Create a hashed IP set of all of these destinations
-    lines = ["-N %s iphash" % group_name]
-    add_cmd = "-A %s " % group_name
-    lines += [(add_cmd + ip) for ip in node_ips]
-    lines += ["COMMIT"]
-    restore = "\n".join(lines) + "\n"
-    run("/sbin/ipset -R", restore)
-
-    # Add rule to match on destination IP set
-    run((iptables + " -m set --set %s dst -j CLASSIFY --set-class 1:%x") %
-        ("-A", group_name, exempt_minor))
+    # Check of set exists
+    set = run("/sbin/ipset -S " + group_name)
+    if set == None:
+        # Create a hashed IP set of all of these destinations
+        lines = ["-N %s iphash" % group_name]
+        add_cmd = "-A %s " % group_name
+        lines += [(add_cmd + ip) for ip in node_ips]
+        lines += ["COMMIT"]
+        restore = "\n".join(lines) + "\n"
+        run("/sbin/ipset -R", restore)
+    else: # set exists
+        # Check all hosts and add missing.
+        for nodeip in node_ips:
+            if not run("/sbin/ipset -T %s %s" % (group_name, nodeip)):
+               run("/sbin/ipset -A %s %s" % (group_name, nodeip))
 
 
 def usage():
@@ -681,11 +704,11 @@ def main():
                            minexemptrate, maxexemptrate,
                            bytes, exemptbytes)
                 else:
-                    print "%s %d %s %s %s %s %d %d" % \
+                    print "%s %d %s %s %s %s %s %s" % \
                           (slice, share,
                            format_tc_rate(minrate), format_tc_rate(maxrate),
                            format_tc_rate(minexemptrate), format_tc_rate(maxexemptrate),
-                           bytes, exemptbytes)
+                           format_bytes(bytes), format_bytes(exemptbytes))
 
         elif len(argv) >= 2:
             # slice, ...