X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=planetlab%2Fscripts%2Fsliver-ovs.in;h=50ecab855c97369fa0389fbf9552fc6a9be0ab6a;hb=b347f2d4d4d41b2fef36eb7b9f07cd6678eca1af;hp=162e7f488f8259e459d21efa96b072aa52aa0bab;hpb=0b11a59b24569f1f75024def4e167073c632a817;p=sliver-openvswitch.git diff --git a/planetlab/scripts/sliver-ovs.in b/planetlab/scripts/sliver-ovs.in index 162e7f488..50ecab855 100755 --- a/planetlab/scripts/sliver-ovs.in +++ b/planetlab/scripts/sliver-ovs.in @@ -9,15 +9,11 @@ COMMAND=$0 RUN_DIR=@RUNDIR@ DB_CONF_FILE=@DBDIR@/conf.db DB_SCHEMA=@pkgdatadir@/vswitch.ovsschema -DB_PID_FILE=$RUN_DIR/db.pid DB_LOG=@LOGDIR@/ovs-db.log -DB_CTL_PATTERN='ovsdb-server.*.ctl' ## DB_SOCKET=$RUN_DIR/db.sock ## -SWITCH_PID_FILE=$RUN_DIR/switch.pid SWITCH_LOG=@LOGDIR@/ovs-switch.log -SWITCH_SOCKET=@RUNDIR@/switch.sock #################### helper functions @@ -33,7 +29,7 @@ function error { function get_params { params=$1; shift err_msg="$COMMAND $SUBCOMMAND $(echo $params | perl -pe 's/\S+/<$&>/g')" - for p in $(echo $params); do + for p in $params; do [[ -z "$@" ]] && error "$err_msg" pname=$(echo -n $p|perl -pe 's/\W/_/g') eval $pname="$1"; shift @@ -42,11 +38,11 @@ function get_params { } function is_switch_running { - ovs-appctl --target=$SWITCH_SOCKET version >& /dev/null + ovs-appctl --target=ovs-vswitchd version >& /dev/null } function is_db_running { - ovs-appctl --target=$DB_CTRL_SOCKET version >& /dev/null + ovs-appctl --target=ovsdb-server version >& /dev/null } function tapname () { @@ -101,22 +97,20 @@ function start_db () { [ -d $RUN_DIR ] || { echo "Could not initialize $RUN_DIR - exiting" ; exit 1 ; } ## run the stuff - if [ ! -f "$DB_PID_FILE" ]; then + if [ ! -f "$RUN_DIR/ovsdb-server.pid" ]; then ovsdb-server $DB_CONF_FILE \ --remote=punix:$DB_SOCKET \ --remote=db:Open_vSwitch,manager_options \ --private-key=db:SSL,private_key \ --certificate=db:SSL,certificate \ --bootstrap-ca-cert=db:SSL,ca_cert \ - --pidfile=$DB_PID_FILE \ + --pidfile \ --log-file=$DB_LOG \ - --unixctl=$DB_CTRL_SOCKET \ --detach >& /dev/null else echo 'ovsdb-server appears to be running already, *not* starting' fi - wait_server $DB_PID_FILE ovsdb-server 30 - echo $DB_PID_FILE + wait_server $RUN_DIR/ovsdb-server.pid ovsdb-server 30 } function start_switch () { @@ -125,29 +119,24 @@ function start_switch () { # ensure ovsdb-server is running is_db_running || { echo "ovsdb-server not running" >&2 ; exit 1 ; } - if [ ! -f "$SWITCH_PID_FILE" ] ; then + if [ ! -f "$RUN_DIR/ovs-vswitchd.pid" ] ; then ovs-vswitchd \ - --pidfile=$SWITCH_PID_FILE \ + --pidfile \ --log-file=$SWITCH_LOG \ - --unixctl=$SWITCH_SOCKET \ --detach \ unix:$DB_SOCKET >& /dev/null else echo 'ovs-vswitchd appears to be running already, *not* starting' fi - wait_server $SWITCH_PID_FILE ovs-vswitchd 30 + wait_server $RUN_DIR/ovs-vswitchd.pid ovs-vswitchd 30 } -# first dumb stab just read "pkill ovsdb-server" and "pkill ovs-vswitchd" -# quick and dirty : we locate the control file through a search in /var/run -# caller should be requested to remember and provide this pid instead function stop_db () { - controlfile=$(ls $RUN_DIR/$DB_CTL_PATTERN) - [ -f $controlfile ] && ovs-appctl --target=$controlfile exit + ovs-appctl --target=ovsdb-server exit || : } function stop_switch () { - ovs-appctl --target=$SWITCH_SOCKET exit || : + ovs-appctl --target=ovs-vswitchd exit || : } function status () { @@ -168,68 +157,93 @@ function stop () { #################### create functions function create_bridge () { - get_params "IP/PREFIX" "$@" + get_params "bridge IP/PREFIX" "$1" "$2" + shift; shift; IP=${IP_PREFIX%/*} PREFIX=${IP_PREFIX#*/} - set -e - # ensure ovs-vswitchd is running - is_switch_running || { echo "ovs-vswitchd not running" >&2 ; exit 1 ; } - - # check whether the address is already assigned - TAPNAME=$(tapname $IP) - if [ ! -z "$TAPNAME" ]; then - if ovs-vsctl --db=unix:$DB_SOCKET br-exists "$TAPNAME"; then - echo $TAPNAME - exit 0 - fi - kill_pltap_ovs - error "$IP already assigned to $TAPNAME" + W= + if ! is_switch_running; then + # we can create the bridge even if ovs-vswitchd is not running, + # but we need a running ovsdb-server + is_db_running || { echo "ovsdb-server not running" >&2; exit 1; } + W="--no-wait" fi - # we're clear - TAPNAME=$(pltap-ovs) - trap kill_pltap_ovs EXIT - # xxx wouldn't that be safer if left-aligned ? - vsysc vif_up << EOF - $TAPNAME - $IP - $PREFIX -EOF - wait_device $TAPNAME 60 && \ - ovs-vsctl --db=unix:$DB_SOCKET add-br $TAPNAME -- set bridge $TAPNAME datapath_type=planetlab - echo $TAPNAME - return 0 + + set -e + ovs-vsctl --db=unix:$DB_SOCKET $W -- --may-exist add-br "$bridge" \ + -- set bridge "$bridge" datapath_type=planetlab \ + -- set interface "$bridge" options:local_ip="$IP" option:local_netmask="$PREFIX" \ + -- "$@" } function create_port () { get_params "bridge port" "$@" + + W= + if ! is_switch_running; then + # we can create the port even if ovs-vswitchd is not running, + # but we need a running ovsdb-server + is_db_running || { echo "ovsdb-server not running" >&2; exit 1; } + W="--no-wait" + fi - # ensure ovs-vswitchd is running - is_switch_running || { echo "ovs-vswitchd not running" >&2 ; exit 1 ; } + set -e + ovs-vsctl --db=unix:$DB_SOCKET $W -- --may-exist add-port "$bridge" "$port" \ + -- set interface "$port" type=tunnel +} + +function get_local_endpoint () { + + get_params "local_port" "$@" + + is_switch_running || { echo "ovs-vswitchd not running" >&2; exit 1; } set -e - if ! ovs-vsctl --db=unix:$DB_SOCKET list-ports "$bridge" | grep -q "^$port\$"; then - ovs-vsctl --db=unix:$DB_SOCKET add-port "$bridge" "$port" -- set interface "$port" type=tunnel - fi - ovs-appctl --target=$SWITCH_SOCKET netdev-tunnel/get-port "$port" - return 0 + ovs-appctl --target=ovs-vswitchd netdev-tunnel/get-port "$local_port" } function set_remote_endpoint () { get_params "local_port remote_ip remote_UDP_port" "$@" - # ensure ovs-vswitchd is running - is_switch_running || { echo "ovs-vswitchd not running" >&2 ; exit 1 ; } + W= + if ! is_switch_running; then + # we can store the info even if ovs-vswitchd is not running, + # but we need a running ovsdb-server + is_db_running || { echo "ovsdb-server not running" >&2; exit 1; } + W="--no-wait" + fi set -e - ovs-vsctl --db=unix:$DB_SOCKET set interface $local_port \ + ovs-vsctl --db=unix:$DB_SOCKET $W set interface $local_port \ options:remote_ip=$remote_ip \ options:remote_port=$remote_UDP_port - return 0 +} + +function set_controller () { + + get_params "bridge_name controller" "$@" + + # ensure ovs-vswitchd is running + is_switch_running || { echo "ovs-vswitchd not running" >&2 ; exit 1 ; } + + set -e + ovs-vsctl --db=unix:$DB_SOCKET set-controller "$bridge_name" "$controller" +} + +function del_controller () { + + get_params "bridge_name" "$@" + + # ensure ovs-vswitchd is running + is_switch_running || { echo "ovs-vswitchd not running" >&2 ; exit 1 ; } + + set -e + ovs-vsctl --db=unix:$DB_SOCKET del-controller "$bridge_name" } #################### del functions @@ -245,10 +259,7 @@ function del_bridge () { W="--no-wait" fi - if ovs-vsctl --db=unix:$DB_SOCKET br-exists "$bridge_name"; then - ovs-vsctl --db=unix:$DB_SOCKET $W del-br $bridge_name - fi - return 0 + ovs-vsctl --db=unix:$DB_SOCKET $W -- --if-exists del-br $bridge_name } function del_port () { @@ -263,11 +274,7 @@ function del_port () { W="--no-wait" fi - set -e - if ovs-vsctl --db=unix:$DB_SOCKET port-to-br "$port" >/dev/null 2>&1; then - ovs-vsctl --db=unix:$DB_SOCKET $W del-port "$port" - fi - return 0 + ovs-vsctl --db=unix:$DB_SOCKET $W -- --if-exists del-port "$port" } function show () { @@ -279,11 +286,80 @@ function show () { ovs-vsctl --db=unix:$DB_SOCKET show } +function get_local_ip () { + + get_params "bridge" "$@" + + set -e + ovs-vsctl --db=unix:$DB_SOCKET br-exists "$bridge" || return + local ip=$(ovs-vsctl get interface "$bridge" options:local_ip) + local netmask=$(ovs-vsctl get interface "$bridge" options:local_netmask) + eval echo $ip/$netmask +} + +function get_local_links () { + + get_params "bridge" "$@" + + set -e + ovs-vsctl --db=unix:$DB_SOCKET br-exists "$bridge" || return + ovs-vsctl --db=unix:$DB_SOCKET list-ifaces "$bridge" +} + +### for demos - connect to an ndnmap deployment to visualize links bandwidth +# this expects 3 arguments +# an interface name, L- based on your ids in conf.mk +# the hostname for a ndnmap deployment +# a linkid, this is the id that this link has in your ndnmap scenario (hard-coded in some json file) +# this one-shot function writes the current statistics onto the ndnmap site +# it needs to be called regularly so that ndnmap can do the bw computations +# would make sense for the caller to redirect stderr onto some relevant location +function gmap_probe_once () { + iface=$1; shift + hostname=$1; shift + linkid=$1; shift + rx_bytes=$(ovs-appctl netdev-tunnel/get-rx-bytes $iface) + tx_bytes=$(ovs-appctl netdev-tunnel/get-tx-bytes $iface) + rx_bits=$(($rx_bytes*8)) + tx_bits=$(($tx_bytes*8)) + now=$(date +%s).$(date +%N) + trigger=http://${hostname}/bw/${linkid}/${now}/${rx_bits}/${tx_bits} +# curl -s -L $trigger | grep -q "Got it" || echo Missed event with $trigger +# echo $trigger + curl -s -L $trigger >& /dev/null +} + +### the front end, manages pid and so on +function gmap_probe () { + iface=$1; shift + hostname=$1; shift + linkid=$1; shift + looptime=$1; shift + [ -z "$looptime" ] && looptime=1 + pid_file=/var/run/openvswitch/gmap-$iface.pid + if [ -f $pid_file ] ; then + pid=$(cat $pid_file) + [ -n "$pid" ] && kill $pid >& /dev/null + rm $pid_file + fi + # close std fds so that ssh invokations can return + exec <&- + exec >&- + while true; do + gmap_probe_once $iface $hostname $linkid + sleep $looptime + done & + # this is the pid for the background process + echo $! > $pid_file +} + #################### SUPPORTED_SUBCOMMANDS="start stop status start_db stop_db start_switch stop_switch create_bridge create_port del_bridge del_port -show set_remote_endpoint" +show get_local_endpoint set_remote_endpoint +set_controller del_controller gmap_probe +get_local_ip get_local_links" function main () { message="Usage: $COMMAND ...