#! /bin/sh
-# Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
## start ##
## ----- ##
-insert_openvswitch_mod_if_required () {
+insert_mods () {
+ # Try loading openvswitch again.
+ action "Inserting openvswitch module" modprobe openvswitch
+}
+
+insert_mod_if_required () {
+ # If this kernel has no module support, expect we're done.
+ if test ! -e /proc/modules
+ then
+ log_success_msg "Kernel has no loadable module support. Skipping modprobe"
+ return 0
+ fi
+
# If openvswitch is already loaded then we're done.
- test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
- return 0
+ test -e /sys/module/openvswitch && return 0
# Load openvswitch. If that's successful then we're done.
- action "Inserting openvswitch module" modprobe openvswitch && return 0
+ insert_mods && return 0
# If the bridge module is loaded, then that might be blocking
# openvswitch. Try to unload it, if there are no bridges.
action "removing bridge module" rmmod bridge || return 1
# Try loading openvswitch again.
- action "Inserting openvswitch module" modprobe openvswitch
-}
-
-insert_mod_if_required () {
- insert_openvswitch_mod_if_required || return 1
-}
-
-ovs_vsctl () {
- ovs-vsctl --no-wait --timeout=5 "$@"
+ insert_mods
}
-ovsdb_tool () {
- ovsdb-tool -vconsole:off "$@"
-}
-
-create_db () {
- action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
-}
-
-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`
- 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}'`
- 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":
- # 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).
- #
- # 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.
- 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
+set_hostname () {
+ # 'hostname -f' needs network connectivity to work. So we should
+ # call this only after ovs-vswitchd is running.
+ ovs_vsctl set Open_vSwitch . external-ids:hostname="$(hostname -f)"
}
set_system_ids () {
set ovs_vsctl set Open_vSwitch .
- OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
+ OVS_VERSION=`ovs-vswitchd --version | awk '/Open vSwitch/{print $NF}'`
set "$@" ovs-version="$OVS_VERSION"
case $SYSTEM_ID in
esac
set "$@" external-ids:system-id="\"$SYSTEM_ID\""
+ set "$@" external-ids:rundir="\"$rundir\""
+
if test X"$SYSTEM_TYPE" != X; then
set "$@" system-type="\"$SYSTEM_TYPE\""
else
check_force_cores () {
if test X"$FORCE_COREFILES" = Xyes; then
- ulimit -Sc 67108864
+ ulimit -c 67108864
fi
}
-start_ovsdb () {
+del_transient_ports () {
+ for port in `ovs-vsctl --bare -- --columns=name find port other_config:transient=true`; do
+ ovs_vsctl -- del-port "$port"
+ done
+}
+
+do_start_ovsdb () {
check_force_cores
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
+ upgrade_db $DB_FILE $DB_SCHEMA || return 1
# Start ovsdb-server.
set ovsdb-server "$DB_FILE"
log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
fi
done
+ if test X"$SELF_CONFINEMENT" = Xno; then
+ set "$@" --no-self-confinement
+ fi
set "$@" -vconsole:emer -vsyslog:err -vfile:info
set "$@" --remote=punix:"$DB_SOCK"
- set "$@" --remote=db:Open_vSwitch,Open_vSwitch,manager_options
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
+ [ "$OVS_USER" != "" ] && set "$@" --user "$OVS_USER"
+
start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
|| 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
+ if test X"$DELETE_TRANSIENT_PORTS" = Xyes; then
+ del_transient_ports
+ fi
fi
}
-start_forwarding () {
+start_ovsdb() {
+ if test X"$OVSDB_SERVER" = Xyes; then
+ do_start_ovsdb || return 1
+ fi
+ return 0
+}
+
+add_managers () {
+ # Now that ovs-vswitchd has started and completed its initial
+ # configuration, tell ovsdb-server to connect 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.)
+ if test X"$OVSDB_SERVER" = Xyes || test X"$OVS_VSWITCHD" = Xyes; then
+ if daemon_is_running ovsdb-server \
+ && daemon_is_running ovs-vswitchd; then
+ action "Enabling remote OVSDB managers" \
+ ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
+ db:Open_vSwitch,Open_vSwitch,manager_options
+ fi
+ fi
+}
+
+do_start_forwarding () {
check_force_cores
insert_mod_if_required || return 1
log_success_msg "ovs-vswitchd is already running"
else
# Increase the limit on the number of open file descriptors.
- # On Linux, ovs-vswitchd needs about one file descriptor per
- # switch port, so this allows a very large number of switch
- # ports.
- ulimit -n 5000
-
- # 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
-}
-
-## ---- ##
-## stop ##
-## ---- ##
-
-stop_ovsdb () {
- stop_daemon ovsdb-server
-}
-
-stop_forwarding () {
- stop_daemon ovs-vswitchd
-}
-
-## ----------------- ##
-## force-reload-kmod ##
-## ----------------- ##
+ # On Linux, ovs-vswitchd needs about three file descriptors
+ # per bridge and "n-handler-threads" file descriptors per bridge
+ # port, so this allows a very large number of bridges and ports.
+ MAXFD=65535
+ if [ $(ulimit -n) -lt $MAXFD ]; then
+ ulimit -n $MAXFD
+ fi
-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
-}
+ # 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
+ if test X"$SELF_CONFINEMENT" = Xno; then
+ set "$@" --no-self-confinement
+ fi
+ [ "$OVS_USER" != "" ] && set "$@" --user "$OVS_USER"
-ovs_save () {
- bridges=`ovs_vsctl -- --real list-br`
- if [ -n "${bridges}" ] && \
- "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
- chmod +x "$2"
- return 0
+ start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@" ||
+ return 1
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" save-interfaces ${ifaces} \
- > "${script_interfaces}"
-}
-
-restore_ofports () {
- [ -x "${script_ofports}" ] && \
- action "Restoring ofport values" "${script_ofports}"
}
-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
+start_forwarding () {
+ if test X"$OVS_VSWITCHD" = Xyes; then
+ do_start_forwarding || return 1
fi
- log="logger -p daemon.$level -t ovs-save"
- $log "interface restore script exited with status $rc:"
- $log -f "$script_interfaces"
+ set_hostname &
+ return 0
}
-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
-
- init_restore_scripts
-
- action "Saving flows" ovs_save save-flows "${script_flows}"
-
- save_ofports_if_required
-
- # 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_forwarding
- exit 1
- fi
- chmod +x "$script_interfaces"
-
- for dp in `ovs-dpctl dump-dps`; do
- action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
- done
+## ---- ##
+## stop ##
+## ---- ##
- # 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
+stop_ovsdb () {
+ if test X"$OVSDB_SERVER" = Xyes; then
+ stop_daemon ovsdb-server
fi
-
- start_forwarding
-
- restore_flows
-
- 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
+stop_forwarding () {
+ if test X"$OVS_VSWITCHD" = Xyes; then
+ stop_daemon ovs-vswitchd
fi
-
- # 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_forwarding
-
- # Restore the saved flows.
- restore_flows
-
- # Restore the interfaces if required. Return true even if restore fails.
- restore_interfaces || true
}
## --------------- ##
SYSTEM_ID=
DELETE_BRIDGES=no
+ DELETE_TRANSIENT_PORTS=no
DAEMON_CWD=/
FORCE_COREFILES=yes
MLOCKALL=yes
+ SELF_CONFINEMENT=yes
+ MONITOR=yes
+ OVS_USER=
+ OVSDB_SERVER=yes
+ OVS_VSWITCHD=yes
OVSDB_SERVER_PRIORITY=-10
OVS_VSWITCHD_PRIORITY=-10
OVSDB_SERVER_WRAPPER=
if test -e "$type_file" ; then
SYSTEM_TYPE=`cat $type_file`
SYSTEM_VERSION=`cat $version_file`
+ elif test -e "@sysconfdir@/os-release"; then
+ SYSTEM_TYPE=`. '@sysconfdir@/os-release' && echo "$ID"`
+ SYSTEM_VERSION=`. '@sysconfdir@/os-release' && echo "$VERSION_ID"`
elif (lsb_release --id) >/dev/null 2>&1; then
SYSTEM_TYPE=`lsb_release --id -s`
system_release=`lsb_release --release -s`
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
+ 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
+ delete-transient-ports delete transient (other_config:transient=true) ports
+ help display this help message
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
--external-id="key=value"
add given key-value pair to Open_vSwitch external-ids
--delete-bridges delete all bridges just before starting ovs-vswitchd
+ --ovs-user="user[:group]" pass the --user flag to ovs daemons
Less important options for "start", "restart" and "force-reload-kmod":
--daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
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')
done
case $command in
start)
- start_ovsdb
- start_forwarding
+ start_ovsdb || exit 1
+ start_forwarding || exit 1
+ add_managers
;;
stop)
stop_forwarding
enable-protocol)
enable_protocol
;;
+ delete-transient-ports)
+ del_transient_ports
+ ;;
help)
usage
;;