From 0ae1970297df963c53598335cfc3e0c420c49966 Mon Sep 17 00:00:00 2001 From: Razvan Deaconescu Date: Fri, 30 Jul 2010 12:29:00 +0300 Subject: [PATCH] ControlScripts: add script to limit bandwidth for OpenVZ containers --- ControlScripts/bw_limit_ct.sh | 165 ++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100755 ControlScripts/bw_limit_ct.sh diff --git a/ControlScripts/bw_limit_ct.sh b/ControlScripts/bw_limit_ct.sh new file mode 100755 index 0000000..243c3ba --- /dev/null +++ b/ControlScripts/bw_limit_ct.sh @@ -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 -- 2.20.1