X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fbwlimit.py;h=ab760b5dd4a74de10c9d194deeaa6d0a13ebc8cb;hb=acec183ad3b8f235afd6a86665dff6b6e761a50a;hp=6591b8398bd854fa63ca31b877cd46de564d000f;hpb=8bdc71ddc20ec5695cc96ab00c62439c10a4aeb0;p=util-vserver-pl.git diff --git a/python/bwlimit.py b/python/bwlimit.py index 6591b83..ab760b5 100644 --- a/python/bwlimit.py +++ b/python/bwlimit.py @@ -50,7 +50,6 @@ # import sys, os, re, getopt -from sets import Set import pwd @@ -66,7 +65,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. @@ -125,6 +124,8 @@ cburst = None # | | # 1:10 (8bit, 5mbit) 1:20 (8bit, 1gbit) # | | +# 1:100 (8bit, 5mbit) | +# | | # 1:1000 (8bit, 5mbit), 1:2000 (8bit, 1gbit), # 1:1001 (8bit, 5mbit), 1:2001 (8bit, 1gbit), # 1:1002 (1mbit, 5mbit), 1:2002 (1mbit, 1gbit), @@ -154,24 +155,24 @@ default_share = 1 # be off by a small fraction. suffixes = { "": 1, - "bit": 1, - "kibit": 1024, - "kbit": 1000, - "mibit": 1024*1024, - "mbit": 1000000, - "gibit": 1024*1024*1024, - "gbit": 1000000000, - "tibit": 1024*1024*1024*1024, - "tbit": 1000000000000, - "bps": 8, - "kibps": 8*1024, - "kbps": 8000, - "mibps": 8*1024*1024, - "mbps": 8000000, - "gibps": 8*1024*1024*1024, - "gbps": 8000000000, - "tibps": 8*1024*1024*1024*1024, - "tbps": 8000000000000 + "bit": 1, + "kibit": 1024, + "kbit": 1000, + "mibit": 1024*1024, + "mbit": 1000000, + "gibit": 1024*1024*1024, + "gbit": 1000000000, + "tibit": 1024*1024*1024*1024, + "tbit": 1000000000000, + "bps": 8, + "kibps": 8*1024, + "kbps": 8000, + "mibps": 8*1024*1024, + "mbps": 8000000, + "gibps": 8*1024*1024*1024, + "gbps": 8000000000, + "tibps": 8*1024*1024*1024*1024, + "tbps": 8000000000000 } @@ -191,6 +192,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): """ @@ -303,6 +322,16 @@ def tc(cmd): return run(TC + " " + cmd) +def stop(dev = dev): + ''' + Turn off all queing. Stops all slice HTBS and reverts to pfifo_fast (the default). + ''' + try: + for i in range(0,2): + tc("qdisc del dev %s root" % dev) + except: pass + + def init(dev = dev, bwcap = bwmax): """ (Re)initialize the bandwidth limits on this node @@ -339,6 +368,12 @@ def init(dev = dev, bwcap = bwmax): tc("class add dev %s parent 1:1 classid 1:10 htb rate %dbit ceil %dbit" % \ (dev, bwmin, bwcap)) + # Set up a subclass for DRL(Distributed Rate Limiting). + # DRL will directly modify that subclass implementing the site limits. + tc("class add dev %s parent 1:10 classid 1:100 htb rate %dbit ceil %dbit" % \ + (dev, bwmin, bwcap)) + + # Set up a subclass that represents "exemption" from the node # bandwidth cap. Once the node bandwidth cap is reached, bandwidth # to exempt destinations can still be fairly shared up to bwmax. @@ -488,7 +523,7 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra maxexemptrate = cap[5] # Figure out what the current node bandwidth cap is - bwcap = get_bwcap() + bwcap = get_bwcap(dev) # Set defaults if share is None: @@ -529,7 +564,7 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra minexemptrate = maxexemptrate # Set up subclasses for the slice - tc("class replace dev %s parent 1:10 classid 1:%x htb rate %dbit ceil %dbit quantum %d" % \ + tc("class replace dev %s parent 1:100 classid 1:%x htb rate %dbit ceil %dbit quantum %d" % \ (dev, default_minor | xid, minrate, maxrate, share * quantum)) tc("class replace dev %s parent 1:20 classid 1:%x htb rate %dbit ceil %dbit quantum %d" % \ @@ -545,8 +580,8 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra (dev, exempt_minor | xid, exempt_minor | xid)) -def set(xid, share = None, minrate = None, maxrate = None, minexemptrate = None, maxexemptrate = None): - on(xid = xid, share = share, +def set(xid, share = None, minrate = None, maxrate = None, minexemptrate = None, maxexemptrate = None, dev = dev ): + on(xid = xid, dev = dev, share = share, minrate = minrate, maxrate = maxrate, minexemptrate = minexemptrate, maxexemptrate = maxexemptrate) @@ -599,7 +634,7 @@ Usage: %s [OPTION]... [COMMAND] [ARGUMENT]... Options: - -d device Network interface (default: %s) + -d device Network interface (default: %s) -r rate Node bandwidth cap (default: %s) -q quantum Share multiplier (default: %d bytes) -n Print rates in numeric bits per second @@ -626,7 +661,7 @@ def main(): # Defaults numeric = False - bwcap = get_bwcap() + bwcap = None (opts, argv) = getopt.getopt(sys.argv[1:], "d:nr:q:vh") for (opt, optval) in opts: @@ -643,6 +678,12 @@ def main(): elif opt == '-h': usage() + if not bwcap: + bwcap = get_bwcap(dev) + + if bwcap == -1: + return 0 + if len(argv): if argv[0] == "init" or (argv[0] == "on" and len(argv) == 1): # (Re)initialize @@ -680,11 +721,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, ...