X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fovs-ctl.in;h=0735160ae33fbb6a04f4d00b263bf0b05b55f520;hb=HEAD;hp=a127149a0e668f930bab5278ec848d1ec9cf9514;hpb=751d0ddbedf919854da3d2c6e5ed76b755c15920;p=sliver-openvswitch.git diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in index a127149a0..0735160ae 100755 --- a/utilities/ovs-ctl.in +++ b/utilities/ovs-ctl.in @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc. +# Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ case $0 in */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;; *) dir0=./ ;; esac -. "$dir0/ovs-lib.sh" || exit 1 +. "$dir0/ovs-lib" || exit 1 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do case :$PATH: in @@ -30,15 +30,16 @@ done ## start ## ## ----- ## -insert_modules_if_required () { - # If openvswitch_mod is already loaded then we're done. - test -e /sys/module/openvswitch_mod && return 0 +insert_mod_if_required () { + # If openvswitch is already loaded then we're done. + test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \ + return 0 - # Load openvswitch_mod. If that's successful then we're done. - action "Inserting openvswitch module" modprobe openvswitch_mod && return 0 + # Load openvswitch. If that's successful then we're done. + action "Inserting openvswitch module" modprobe openvswitch && return 0 # If the bridge module is loaded, then that might be blocking - # openvswitch_mod. Try to unload it, if there are no bridges. + # openvswitch. Try to unload it, if there are no bridges. test -e /sys/module/bridge || return 1 bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'` if test "$bridges" != "*"; then @@ -47,16 +48,20 @@ insert_modules_if_required () { fi action "removing bridge module" rmmod bridge || return 1 - # Try loading openvswitch_mod again. - action "Inserting openvswitch module" modprobe openvswitch_mod + # Try loading openvswitch again. + action "Inserting openvswitch module" modprobe openvswitch } ovs_vsctl () { - ovs-vsctl --no-wait --timeout=5 "$@" + ovs-vsctl --no-wait "$@" } ovsdb_tool () { - ovsdb-tool -vANY:console:emer "$@" + ovsdb-tool -vconsole:off "$@" +} + +create_db () { + action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA" } upgrade_db () { @@ -64,14 +69,13 @@ upgrade_db () { if test ! -e "$DB_FILE"; then log_warning_msg "$DB_FILE does not exist" install -d -m 755 -o root -g root `dirname $DB_FILE` - - action "Creating empty database $DB_FILE" true - ovsdb_tool create "$DB_FILE" "$DB_SCHEMA" + create_db elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then # Back up the old version. version=`ovsdb_tool db-version "$DB_FILE"` cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'` - cp "$DB_FILE" "$DB_FILE.backup$version-$cksum" + backup=$DB_FILE.backup$version-$cksum + action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1 # Compact database. This is important if the old schema did not enable # garbage collection (i.e. if it did not have any tables with "isRoot": @@ -82,10 +86,20 @@ upgrade_db () { # does) would cause the record to be dropped by the first transaction, # then the second transaction would cause a referential integrity # failure (for a strong reference). - ovsdb_tool compact "$DB_FILE" + # + # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't + # understand some feature of the schema used in the OVSDB version that + # we're downgrading from, so we don't give up on error. + action "Compacting database" ovsdb_tool compact "$DB_FILE" # Upgrade or downgrade schema. - ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA" + if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then + : + else + log_warning_msg "Schema conversion failed, using empty database instead" + rm -f "$DB_FILE" + create_db + fi fi } @@ -137,54 +151,91 @@ set_system_ids () { action "Configuring Open vSwitch system IDs" "$@" $extra_ids } -start () { +check_force_cores () { if test X"$FORCE_COREFILES" = Xyes; then - ulimit -Sc 67108864 + ulimit -c 67108864 fi +} - insert_modules_if_required || return 1 +start_ovsdb () { + check_force_cores if daemon_is_running ovsdb-server; then - log_success_msg "ovsdb-server is already running" + log_success_msg "ovsdb-server is already running" else - # Create initial database or upgrade database schema. - upgrade_db || return 1 - - # Start ovsdb-server. - set ovsdb-server "$DB_FILE" - set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO - set "$@" --remote=punix:"$DB_SOCK" - set "$@" --remote=db:Open_vSwitch,manager_options - set "$@" --private-key=db:SSL,private_key - set "$@" --certificate=db:SSL,certificate - set "$@" --bootstrap-ca-cert=db:SSL,ca_cert - start_daemon "$OVSDB_SERVER_PRIORITY" "$@" || return 1 - - # Initialize database settings. - ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \ - || return 1 - set_system_ids || return 1 - if test X"$DELETE_BRIDGES" = Xyes; then + # Create initial database or upgrade database schema. + upgrade_db || return 1 + + # Start ovsdb-server. + set ovsdb-server "$DB_FILE" + for db in $EXTRA_DBS; do + case $db in + /*) ;; + *) db=$dbdir/$db ;; + esac + + if test ! -f "$db"; then + log_warning_msg "$db (from \$EXTRA_DBS) does not exist." + elif ovsdb-tool db-version "$db" >/dev/null; then + set "$@" "$db" + else + log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)" + fi + done + set "$@" -vconsole:emer -vsyslog:err -vfile:info + set "$@" --remote=punix:"$DB_SOCK" + set "$@" --private-key=db:Open_vSwitch,SSL,private_key + set "$@" --certificate=db:Open_vSwitch,SSL,certificate + set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert + start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \ + || return 1 + + # Initialize database settings. + ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \ + || return 1 + set_system_ids || return 1 + if test X"$DELETE_BRIDGES" = Xyes; then for bridge in `ovs_vsctl list-br`; do - ovs_vsctl del-br $bridge + ovs_vsctl del-br $bridge done - fi + fi fi +} + +add_managers () { + # Now that ovs-vswitchd has started and completed its initial + # configuration, tell ovsdb-server to conenct to the remote managers. We + # used to do this at ovsdb-server startup time, but waiting for + # ovs-vswitchd to finish configuring means that remote managers see less + # churn in the database at startup or restart. (For example, managers + # won't briefly see empty datapath-id or ofport columns for records that + # exist at startup.) + action "Enabling remote OVSDB managers" \ + ovs-appctl -t ovsdb-server ovsdb-server/add-remote \ + db:Open_vSwitch,Open_vSwitch,manager_options +} + +start_forwarding () { + check_force_cores + + insert_mod_if_required || return 1 if daemon_is_running ovs-vswitchd; then - log_success_msg "ovs-vswitchd is already running" + log_success_msg "ovs-vswitchd is already running" else - # Increase the limit on the number of open file descriptors since - # ovs-vswitchd needs a few per bridge - ulimit -n 4096 - - # Start ovs-vswitchd. - set ovs-vswitchd unix:"$DB_SOCK" - set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO - if test X"$MLOCKALL" != Xno; then - set "$@" --mlockall - fi - start_daemon "$VSWITCHD_PRIORITY" "$@" + # Increase the limit on the number of open file descriptors. + # On Linux, ovs-vswitchd needs about three file descriptors + # per bridge and one file descriptor per bridge port, so this + # allows a very large number of bridges and ports. + ulimit -n 7500 + + # Start ovs-vswitchd. + set ovs-vswitchd unix:"$DB_SOCK" + set "$@" -vconsole:emer -vsyslog:err -vfile:info + if test X"$MLOCKALL" != Xno; then + set "$@" --mlockall + fi + start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@" fi } @@ -192,11 +243,14 @@ start () { ## stop ## ## ---- ## -stop () { - stop_daemon ovs-vswitchd +stop_ovsdb () { stop_daemon ovsdb-server } +stop_forwarding () { + stop_daemon ovs-vswitchd +} + ## ----------------- ## ## force-reload-kmod ## ## ----------------- ## @@ -214,45 +268,227 @@ internal_interfaces () { # But ignore interfaces that don't really exist. for d in `(ovs_vsctl --bare \ -- --columns=name find Interface type=internal \ - -- list-br) | sort -u` + -- list-br) | sort -u` do if test -e "/sys/class/net/$d"; then - printf "%s " "$d" - fi + printf "%s " "$d" + fi done } +ovs_save () { + bridges=`ovs_vsctl -- --real list-br` + if [ -n "${bridges}" ] && \ + "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then + chmod +x "$2" + return 0 + fi + [ -z "${bridges}" ] && return 0 +} + +save_ofports_if_required () { + # Save ofports if we are upgrading from a pre-1.10 branch. + case `ovs-appctl version | sed 1q` in + "ovs-vswitchd (Open vSwitch) 1."[0-9].*) + action "Saving ofport values" ovs_save save-ofports \ + "${script_ofports}" + ;; + esac +} + save_interfaces () { - "$datadir/scripts/ovs-save" $ifaces > "$script" + "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \ + > "${script_interfaces}" +} + +restore_ofports () { + [ -x "${script_ofports}" ] && \ + action "Restoring ofport values" "${script_ofports}" +} + +flow_restore_wait () { + ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true" +} + +flow_restore_complete () { + ovs_vsctl --if-exists remove open_vswitch . other_config \ + flow-restore-wait="true" +} + +restore_flows () { + [ -x "${script_flows}" ] && \ + action "Restoring saved flows" "${script_flows}" +} + +restore_interfaces () { + [ ! -x "${script_interfaces}" ] && return 0 + action "Restoring interface configuration" "${script_interfaces}" + rc=$? + if test $rc = 0; then + level=debug + else + level=err + fi + log="logger -p daemon.$level -t ovs-save" + $log "interface restore script exited with status $rc:" + $log -f "$script_interfaces" +} + +init_restore_scripts () { + script_interfaces=`mktemp` + script_flows=`mktemp` + script_ofports=`mktemp` + trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0 } force_reload_kmod () { ifaces=`internal_interfaces` action "Detected internal interfaces: $ifaces" true - stop + init_restore_scripts + + action "Saving flows" ovs_save save-flows "${script_flows}" + + save_ofports_if_required - script=`mktemp` - if action "Save interface configuration to $script" save_interfaces; then + # Restart the database first, since a large database may take a + # while to load, and we want to minimize forwarding disruption. + stop_ovsdb + start_ovsdb + + # Restore of ofports should happen before vswitchd is restarted. + restore_ofports + + stop_forwarding + + if action "Saving interface configuration" save_interfaces; then : else log_warning_msg "Failed to save configuration, not replacing kernel module" - start + start_forwarding + add_managers exit 1 fi - chmod +x "$script" + chmod +x "$script_interfaces" for dp in `ovs-dpctl dump-dps`; do - action "Removing datapath: $dp" "$dpctl" del-dp "$dp" + action "Removing datapath: $dp" ovs-dpctl del-dp "$dp" done + # try both old and new names in case this is post upgrade if test -e /sys/module/openvswitch_mod; then action "Removing openvswitch module" rmmod openvswitch_mod + elif test -e /sys/module/openvswitch; then + action "Removing openvswitch module" rmmod openvswitch + fi + + # Start vswitchd by asking it to wait till flow restore is finished. + flow_restore_wait + start_forwarding + + # Restore saved flows and inform vswitchd that we are done. + restore_flows + flow_restore_complete + add_managers + + restore_interfaces + + "$datadir/scripts/ovs-check-dead-ifs" +} + +## ------- ## +## restart ## +## ------- ## + +save_interfaces_if_required () { + # Save interfaces if we are upgrading from a pre-1.10 branch. + case `ovs-appctl version | sed 1q` in + "ovs-vswitchd (Open vSwitch) 1."[0-9].*) + ifaces=`internal_interfaces` + action "Detected internal interfaces: $ifaces" true + if action "Saving interface configuration" save_interfaces; then + chmod +x "$script_interfaces" + fi + ;; + esac +} + +restart () { + if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then + init_restore_scripts + save_interfaces_if_required + action "Saving flows" ovs_save save-flows "${script_flows}" + save_ofports_if_required fi - start + # Restart the database first, since a large database may take a + # while to load, and we want to minimize forwarding disruption. + stop_ovsdb + start_ovsdb + + # Restore of ofports, if required, should happen before vswitchd is + # restarted. + restore_ofports + + stop_forwarding + + # Start vswitchd by asking it to wait till flow restore is finished. + flow_restore_wait + start_forwarding + + # Restore saved flows and inform vswitchd that we are done. + restore_flows + flow_restore_complete + add_managers + + # Restore the interfaces if required. Return true even if restore fails. + restore_interfaces || true +} + +## --------------- ## +## enable-protocol ## +## --------------- ## + +enable_protocol () { + # Translate the protocol name to a number, because "iptables -n -L" prints + # some protocols by name (despite the -n) and therefore we need to look for + # both forms. + # + # (iptables -S output is more uniform but old iptables doesn't have it.) + protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'` + if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else + log_failure_msg "unknown protocol $PROTOCOL" + return 1 + fi - action "Restore interface configuration from $script" "$script" + name=$PROTOCOL + match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)" + insert="iptables -I INPUT -p $PROTOCOL" + if test X"$DPORT" != X; then + name="$name to port $DPORT" + match="$match && /dpt:$DPORT/" + insert="$insert --dport $DPORT" + fi + if test X"$SPORT" != X; then + name="$name from port $SPORT" + match="$match && /spt:$SPORT/" + insert="$insert --sport $SPORT" + fi + insert="$insert -j ACCEPT" + + if (iptables -n -L INPUT) >/dev/null 2>&1; then + if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }" + then + # There's already a rule for this protocol. Don't override it. + log_success_msg "iptables already has a rule for $name, not explicitly enabling" + else + action "Enabling $name with iptables" $insert + fi + elif (iptables --version) >/dev/null 2>&1; then + action "cannot list iptables rules, not adding a rule for $name" + else + action "iptables binary not installed, not adding a rule for $name" + fi } ## ---- ## @@ -269,12 +505,25 @@ set_defaults () { MLOCKALL=yes OVSDB_SERVER_PRIORITY=-10 OVS_VSWITCHD_PRIORITY=-10 + OVSDB_SERVER_WRAPPER= + OVS_VSWITCHD_WRAPPER= - DB_FILE=$etcdir/conf.db + DB_FILE=$dbdir/conf.db DB_SOCK=$rundir/db.sock DB_SCHEMA=$datadir/vswitch.ovsschema + EXTRA_DBS= - if (lsb_release --id) >/dev/null 2>&1; then + PROTOCOL=gre + DPORT= + SPORT= + + type_file=$etcdir/system-type.conf + version_file=$etcdir/system-version.conf + + if test -e "$type_file" ; then + SYSTEM_TYPE=`cat $type_file` + SYSTEM_VERSION=`cat $version_file` + elif (lsb_release --id) >/dev/null 2>&1; then SYSTEM_TYPE=`lsb_release --id -s` system_release=`lsb_release --release -s` system_codename=`lsb_release --codename -s` @@ -297,45 +546,57 @@ scripts. System administrators should not normally invoke it directly. Commands: start start Open vSwitch daemons stop stop Open vSwitch daemons + restart stop and start Open vSwitch daemons status check whether Open vSwitch daemons are running version print versions of Open vSwitch daemons + load-kmod insert modules if not already present force-reload-kmod save OVS network device state, stop OVS, unload kernel module, reload kernel module, start OVS, restore state + enable-protocol enable protocol specified in options with iptables help display this help message -One of the following options should be specified when starting Open vSwitch: +One of the following options is required for "start", "restart" and "force-reload-kmod": --system-id=UUID set specific ID to uniquely identify this system --system-id=random use a random but persistent UUID to identify this system -Other important options for starting Open vSwitch: +Other important options for "start", "restart" and "force-reload-kmod": --system-type=TYPE set system type (e.g. "XenServer") --system-version=VERSION set system version (e.g. "5.6.100-39265p") --external-id="key=value" add given key-value pair to Open_vSwitch external-ids --delete-bridges delete all bridges just before starting ovs-vswitchd -Less important options for starting Open vSwitch: - --daemon-cwd=DIR current working directory for OVS daemons (default: $DAEMON_CWD) - --no-force-corefiles - do not forcibly enable core dumps for OVS daemons - --no-mlockall do not lock all of ovs-vswitchd into memory - --ovsdb-server-priority=NICE - set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY) - --ovs-vswitchd-priority=NICE - set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY) +Less important options for "start", "restart" and "force-reload-kmod": + --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD) + --no-force-corefiles do not force on core dumps for OVS daemons + --no-mlockall do not lock all of ovs-vswitchd into memory + --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY) + --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY) + +Debugging options for "start", "restart" and "force-reload-kmod": + --ovsdb-server-wrapper=WRAPPER + --ovs-vswitchd-wrapper=WRAPPER + --ovs-vswitchd-wrapper=WRAPPER + run specified daemon under WRAPPER (either 'valgrind' or 'strace') File location options: --db-file=FILE database file name (default: $DB_FILE) --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK) --db-schema=FILE database schema file name (default: $DB_SCHEMA) +Options for "enable-protocol": + --protocol=PROTOCOL protocol to enable with iptables (default: gre) + --sport=PORT source port to match (for tcp or udp protocol) + --dport=PORT ddestination port to match (for tcp or udp protocol) + Other options: -h, --help display this help message -V, --version display version information Default directories with "configure" option and environment variable override: - logs: @LOGDIR@ (--log-dir, OVS_LOGDIR) - pidfiles and sockets: @RUNDIR@ (--run-dir, OVS_RUNDIR) + logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR) + pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR) + conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR) system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR) data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR) user binaries: @bindir@ (--bindir, OVS_BINDIR) @@ -360,6 +621,10 @@ set_option () { eval $var=\$value } +daemons () { + echo ovsdb-server ovs-vswitchd +} + set_defaults extra_ids= command= @@ -370,7 +635,7 @@ do usage ;; -V | --version) - echo "$0 (Open vSwitch) $VERSION$BUILDNR" + echo "$0 (Open vSwitch) $VERSION" exit 0 ;; --external-id=*) @@ -419,19 +684,37 @@ do done case $command in start) - start + start_ovsdb + start_forwarding + add_managers ;; stop) - stop + stop_forwarding + stop_ovsdb + ;; + restart) + restart ;; status) - daemon_status ovsdb-server && daemon_status ovs-vswitchd + rc=0 + for daemon in `daemons`; do + daemon_status $daemon || rc=$? + done + exit $rc ;; version) - ovsdb-server --version && ovs-vswitchd --version + for daemon in `daemons`; do + $daemon --version + done ;; force-reload-kmod) - force_reload_kmod + force_reload_kmod + ;; + load-kmod) + insert_mod_if_required + ;; + enable-protocol) + enable_protocol ;; help) usage @@ -445,4 +728,3 @@ case $command in exit 1 ;; esac -