#! /bin/sh # Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. case $0 in */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;; *) dir0=./ ;; esac . "$dir0/ovs-lib.sh" || exit 1 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do case :$PATH: in *:$dir:*) ;; *) PATH=$PATH:$dir ;; esac done ## ----- ## ## start ## ## ----- ## insert_modules_if_required () { # If openvswitch_mod is already loaded then we're done. test -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 # If the bridge module is loaded, then that might be blocking # openvswitch_mod. 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 log_warning_msg "not removing bridge module because bridges exist ($bridges)" return 1 fi action "removing bridge module" rmmod bridge || return 1 # Try loading openvswitch_mod again. action "Inserting openvswitch module" modprobe openvswitch_mod } ovs_vsctl () { ovs-vsctl --no-wait --timeout=5 "$@" } ovsdb_tool () { ovsdb-tool -vANY:console:emer "$@" } upgrade_db () { schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"` 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" 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" # 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": # true) but the new schema does. In that situation the old database # may contain a transaction that creates a record followed by a # transaction that creates the first use of the record. Replaying that # series of transactions against the new database schema (as "convert" # 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" # Upgrade or downgrade schema. ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA" fi } set_system_ids () { set ovs_vsctl set Open_vSwitch . OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'` set "$@" ovs-version="$OVS_VERSION" case $SYSTEM_ID in random) id_file=$etcdir/system-id.conf uuid_file=$etcdir/install_uuid.conf if test -e "$id_file"; then SYSTEM_ID=`cat "$id_file"` elif test -e "$uuid_file"; then # Migrate from old file name. . "$uuid_file" SYSTEM_ID=$INSTALLATION_UUID echo "$SYSTEM_ID" > "$id_file" elif SYSTEM_ID=`uuidgen`; then echo "$SYSTEM_ID" > "$id_file" else log_failure_msg "missing uuidgen, could not generate system ID" fi ;; '') log_failure_msg "system ID not configured, please use --system-id" ;; *) ;; esac set "$@" external-ids:system-id="\"$SYSTEM_ID\"" if test X"$SYSTEM_TYPE" != X; then set "$@" system-type="\"$SYSTEM_TYPE\"" else log_failure_msg "no default system type, please use --system-type" fi if test X"$SYSTEM_VERSION" != X; then set "$@" system-version="\"$SYSTEM_VERSION\"" else log_failure_msg "no default system version, please use --system-version" fi action "Configuring Open vSwitch system IDs" "$@" $extra_ids } start () { if test X"$FORCE_COREFILES" = Xyes; then ulimit -Sc 67108864 fi insert_modules_if_required || return 1 if daemon_is_running ovsdb-server; then 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 for bridge in `ovs_vsctl list-br`; do ovs_vsctl del-br $bridge done fi fi if daemon_is_running ovs-vswitchd; then 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" "$@" fi } ## ---- ## ## stop ## ## ---- ## stop () { stop_daemon ovs-vswitchd stop_daemon ovsdb-server } ## ----------------- ## ## force-reload-kmod ## ## ----------------- ## internal_interfaces () { # Outputs a list of internal interfaces: # # - There is an internal interface for every bridge, whether it # has an Interface record or not and whether the Interface # record's 'type' is properly set or not. # # - There is an internal interface for each Interface record whose # 'type' is 'internal'. # # But ignore interfaces that don't really exist. for d in `(ovs_vsctl --bare \ -- --columns=name find Interface type=internal \ -- list-br) | sort -u` do if test -e "/sys/class/net/$d"; then printf "%s " "$d" fi done } save_interfaces () { "$datadir/scripts/ovs-save" $ifaces > "$script" } force_reload_kmod () { ifaces=`internal_interfaces` action "Detected internal interfaces: $ifaces" true stop script=`mktemp` if action "Save interface configuration to $script" save_interfaces; then : else log_warning_msg "Failed to save configuration, not replacing kernel module" start exit 1 fi chmod +x "$script" for dp in `ovs-dpctl dump-dps`; do action "Removing datapath: $dp" "$dpctl" del-dp "$dp" done if test -e /sys/module/openvswitch_mod; then action "Removing openvswitch module" rmmod openvswitch_mod fi start action "Restore interface configuration from $script" "$script" } ## ---- ## ## main ## ## ---- ## set_defaults () { SYSTEM_ID= DELETE_BRIDGES=no DAEMON_CWD=/ FORCE_COREFILES=yes MLOCKALL=yes OVSDB_SERVER_PRIORITY=-10 OVS_VSWITCHD_PRIORITY=-10 DB_FILE=$etcdir/conf.db DB_SOCK=$rundir/db.sock DB_SCHEMA=$datadir/vswitch.ovsschema if (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` SYSTEM_VERSION="${system_release}-${system_codename}" else SYSTEM_TYPE=unknown SYSTEM_VERSION=unknown fi } usage () { set_defaults cat <&2 "$0: unknown option \"$arg\" (use --help for help)" return fi eval $var=\$value } set_defaults extra_ids= command= for arg do case $arg in -h | --help) usage ;; -V | --version) echo "$0 (Open vSwitch) $VERSION$BUILDNR" exit 0 ;; --external-id=*) value=`expr X"$arg" : 'X[^=]*=\(.*\)'` case $value in *=*) extra_ids="$extra_ids external-ids:$value" ;; *) echo >&2 "$0: --external-id argument not in the form \"key=value\"" exit 1 ;; esac ;; --[a-z]*=*) option=`expr X"$arg" : 'X--\([^=]*\)'` value=`expr X"$arg" : 'X[^=]*=\(.*\)'` type=string set_option ;; --no-[a-z]*) option=`expr X"$arg" : 'X--no-\(.*\)'` value=no type=bool set_option ;; --[a-z]*) option=`expr X"$arg" : 'X--\(.*\)'` value=yes type=bool set_option ;; -*) echo >&2 "$0: unknown option \"$arg\" (use --help for help)" exit 1 ;; *) if test X"$command" = X; then command=$arg else echo >&2 "$0: exactly one non-option argument required (use --help for help)" exit 1 fi ;; esac done case $command in start) start ;; stop) stop ;; status) daemon_status ovsdb-server && daemon_status ovs-vswitchd ;; version) ovsdb-server --version && ovs-vswitchd --version ;; force-reload-kmod) force_reload_kmod ;; help) usage ;; '') echo >&2 "$0: missing command name (use --help for help)" exit 1 ;; *) echo >&2 "$0: unknown command \"$command\" (use --help for help)" exit 1 ;; esac