ControlScripts: add script to limit bandwidth for OpenVZ containers
authorRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Fri, 30 Jul 2010 09:29:00 +0000 (12:29 +0300)
committerRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Fri, 30 Jul 2010 09:29:00 +0000 (12:29 +0300)
ControlScripts/bw_limit_ct.sh [new file with mode: 0755]

diff --git a/ControlScripts/bw_limit_ct.sh b/ControlScripts/bw_limit_ct.sh
new file mode 100755 (executable)
index 0000000..243c3ba
--- /dev/null
@@ -0,0 +1,165 @@
+#!/bin/bash
+#
+# Copyright: George Milescu 2010 - george.milescu@gmail.com
+#
+# Razvan Deaconescu: add support for running in OpenVZ containers (SSH to HN)
+#
+# references:
+# * http://tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/
+# * http://lartc.org/howto/lartc.adv-filter.html#LARTC.ADV-FILTER.U32
+# * http://www.topwebhosts.org/tools/traffic-control.php
+# * http://atmail.com/kb/2009/throttling-bandwidth/
+# * http://www.docstoc.com/docs/20252486/Manual-tc-Packet-Filtering-and-netem
+#
+# This script is to be run on an OpenVZ container. It connects to the
+# hardware node (HN) and configures traffic shaping.
+#
+# SSH is used to connect tot the hardware node - remote user is p2p. The
+# remote user requires sudoed tc access. Hardware node is identified from
+# hostname.
+#
+#  tc uses the following units when passed as a parameter.
+#  kbps: Kilobytes per second
+#  mbps: Megabytes per second
+#  kbit: Kilobits per second
+#  mbit: Megabits per second
+#  bps: Bytes per second
+#       Amounts of data can be specified in:
+#       kb or k: Kilobytes
+#       mb or m: Megabytes
+#       mbit: Megabits
+#       kbit: Kilobits
+#  To get the byte figure from bits, divide the number by 8 bit
+
+usage() {
+       # Print help messages
+       echo "Usage: $0 set interface down-bw down-burst up-bw up-burst"
+       echo "       $0 del|reset|show interface"
+       echo "* set - set the limitations or show the status of the limitations"
+       echo "  * interface - the network interface that will be limited"
+       echo "  * down-bw - upload bandwidth, in Mbps"
+       echo "  * down-burst - upload burst, in k"
+       echo "  * up-bw - download bandwidth, in Mbps"
+       echo "  * up-burst - download burst, in k"
+       echo "* del|reset|show - delete, reset the limitations or show the status of the limitations"
+       echo "  * interface - the network interface that will be limited"
+}
+
+if [ $# -lt 2 ]; then
+       usage
+       exit 1
+fi
+
+_tmp=$(hostname)
+# hardware node hostname
+HN=${_tmp%-*}
+# container ID
+CTID=${_tmp#$HN-}
+
+# SSH command
+SSH="ssh -l p2p $HN"
+
+IP_ADDRESS=$(/sbin/ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}')
+
+# Name of the traffic control command.
+TC="sudo /sbin/tc"
+
+# The action requested (set, del, reset, show limitations)
+ACTION=$1           # Action
+
+# The network interface we're planning on limiting bandwidth for egress
+EGRESS_IF=$2               # Interface
+INGRESS_IF="veth$CTID.0"
+
+# Download limit (in mega bits)
+#DNLD=8mbit          # DOWNLOAD Limit
+DNLD=${3}mbit          # DOWNLOAD Limit
+
+# Upload limit (in mega bits)
+#UPLD=8mbit          # UPLOAD Limit
+UPLD=${5}mbit          # UPLOAD Limit
+
+# Burst limit (see http://lartc.org/howto/lartc.qdisc.classless.html#AEN691)
+# Should be $DNLD/8*10ms and $UPLD/8*10ms (meaning 10k) http://mailman.ds9a.nl/pipermail/lartc/2001q4/001972.html ?
+#DL_BURST=100k
+#UP_BURST=100k
+DL_BURST=${4}k
+UP_BURST=${6}k
+
+start() {
+       # Add the egress limitation
+       #
+       # We'll use Hierarchical Token Bucket (HTB) to shape bandwidth.
+       # For detailed configuration options, please consult Linux man
+       # page.
+       $SSH "$TC qdisc add dev $EGRESS_IF root handle 1: htb default 90"
+       $SSH "$TC class add dev $EGRESS_IF parent 1: classid 1:1 htb rate $UPLD ceil $UPLD burst $UP_BURST"
+       $SSH "$TC filter add dev $EGRESS_IF protocol ip parent 1:0 prio 1 u32 match ip src $IP_ADDRESS/32 flowid 1:1"
+       
+       # The first line creates the root qdisc, and next one creates a
+       # child qdisc that are to be used to shape download and upload bandwidth.
+       #
+       # The 3rd line creates the filter to match the interface.
+       # The 'dst' IP address is used to limit upload speed, to any host
+       
+       # Add the ingress limitation - use virtual Ethernet interface
+       $SSH "$TC qdisc add dev $INGRESS_IF root handle 1: htb default 90"
+       $SSH "$TC class add dev $INGRESS_IF parent 1: classid 1:1 htb rate $DNLD ceil $DNLD burst $DL_BURST"
+       $SSH "$TC filter add dev $INGRESS_IF protocol ip parent 1:0 prio 1 u32 match ip dst $IP_ADDRESS/32 flowid 1:1"
+       #$SSH "$TC qdisc add dev $INGRESS_IF ingress handle ffff:0"
+       # Attach a filter to the ingress qdisc
+       #$SSH "$TC filter add dev $INGRESS_IF protocol ip parent ffff:0  prio 1 u32 match ip src 0.0.0.0/0 police rate $DNLD burst $DL_BURST action drop flowid 0:1"
+}
+
+stop() {
+       # Stop the bandwidth shaping.
+       $SSH "$TC qdisc del dev $EGRESS_IF root"
+       $SSH "$TC qdisc del dev $INGRESS_IF root"
+       #$SSH "$TC qdisc del dev $INGRESS_IF ingress handle ffff:0"
+}
+
+restart() {
+       # Self-explanatory.
+       stop
+       sleep 1
+       start
+}
+
+show() {
+       # Display status of traffic control status.
+       $SSH "$TC -s qdisc ls dev $EGRESS_IF"
+       $SSH "$TC -s qdisc ls dev $INGRESS_IF"
+}
+
+case "$ACTION" in
+       "set")
+       echo -n "Setting bandwidth limitations: "
+       start
+       echo "done"
+       ;;
+       
+       "del")
+       echo -n "Deleting bandwidth limitations: "
+       stop
+       echo "done"
+       ;;
+       
+       "reset")
+       echo -n "Resetting bandwidth limitations: "
+       restart
+       echo "done"
+       ;;
+       
+       "show")
+       echo "Bandwidth limitations status for $EGRESS_IF and $INGRESS_IF:"
+       show
+       echo ""
+       ;;
+
+       *)
+       usage
+       exit 1
+       ;;
+esac
+
+exit 0