2 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
20 . "$dir0/ovs-lib" || exit 1
22 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
33 # Keep track of removed vports so we can reload them if needed
37 # Try loading openvswitch again.
38 action "Inserting openvswitch module" modprobe openvswitch
40 for vport in $removed_vports; do
41 # Don't treat failures to load vports as fatal error
42 action "Inserting $vport module" modprobe $vport || true
46 insert_mod_if_required () {
47 # If this kernel has no module support, expect we're done.
48 if test ! -e /proc/modules
50 log_success_msg "Kernel has no loadable module support. Skipping modprobe"
54 # If openvswitch is already loaded then we're done.
55 test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
58 # Load openvswitch. If that's successful then we're done.
59 insert_mods && return 0
61 # If the bridge module is loaded, then that might be blocking
62 # openvswitch. Try to unload it, if there are no bridges.
63 test -e /sys/module/bridge || return 1
64 bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
65 if test "$bridges" != "*"; then
66 log_warning_msg "not removing bridge module because bridges exist ($bridges)"
69 action "removing bridge module" rmmod bridge || return 1
71 # Try loading openvswitch again.
76 ovs-vsctl --no-wait "$@"
80 ovsdb-tool -vconsole:off "$@"
84 action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
88 schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
89 if test ! -e "$DB_FILE"; then
90 log_warning_msg "$DB_FILE does not exist"
91 install -d -m 755 -o root -g root `dirname $DB_FILE`
93 elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
94 # Back up the old version.
95 version=`ovsdb_tool db-version "$DB_FILE"`
96 cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
97 backup=$DB_FILE.backup$version-$cksum
98 action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
100 # Compact database. This is important if the old schema did not enable
101 # garbage collection (i.e. if it did not have any tables with "isRoot":
102 # true) but the new schema does. In that situation the old database
103 # may contain a transaction that creates a record followed by a
104 # transaction that creates the first use of the record. Replaying that
105 # series of transactions against the new database schema (as "convert"
106 # does) would cause the record to be dropped by the first transaction,
107 # then the second transaction would cause a referential integrity
108 # failure (for a strong reference).
110 # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
111 # understand some feature of the schema used in the OVSDB version that
112 # we're downgrading from, so we don't give up on error.
113 action "Compacting database" ovsdb_tool compact "$DB_FILE"
115 # Upgrade or downgrade schema.
116 if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
119 log_warning_msg "Schema conversion failed, using empty database instead"
127 set ovs_vsctl set Open_vSwitch .
129 OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
130 set "$@" ovs-version="$OVS_VERSION"
134 id_file=$etcdir/system-id.conf
135 uuid_file=$etcdir/install_uuid.conf
136 if test -e "$id_file"; then
137 SYSTEM_ID=`cat "$id_file"`
138 elif test -e "$uuid_file"; then
139 # Migrate from old file name.
141 SYSTEM_ID=$INSTALLATION_UUID
142 echo "$SYSTEM_ID" > "$id_file"
143 elif SYSTEM_ID=`uuidgen`; then
144 echo "$SYSTEM_ID" > "$id_file"
146 log_failure_msg "missing uuidgen, could not generate system ID"
151 log_failure_msg "system ID not configured, please use --system-id"
157 set "$@" external-ids:system-id="\"$SYSTEM_ID\""
159 if test X"$SYSTEM_TYPE" != X; then
160 set "$@" system-type="\"$SYSTEM_TYPE\""
162 log_failure_msg "no default system type, please use --system-type"
165 if test X"$SYSTEM_VERSION" != X; then
166 set "$@" system-version="\"$SYSTEM_VERSION\""
168 log_failure_msg "no default system version, please use --system-version"
171 action "Configuring Open vSwitch system IDs" "$@" $extra_ids
174 check_force_cores () {
175 if test X"$FORCE_COREFILES" = Xyes; then
180 del_transient_ports () {
181 for port in `ovs-vsctl --bare -- --columns=name find port other_config:transient=true`; do
182 ovs_vsctl -- del-port "$port"
189 if daemon_is_running ovsdb-server; then
190 log_success_msg "ovsdb-server is already running"
192 # Create initial database or upgrade database schema.
193 upgrade_db || return 1
195 # Start ovsdb-server.
196 set ovsdb-server "$DB_FILE"
197 for db in $EXTRA_DBS; do
203 if test ! -f "$db"; then
204 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
205 elif ovsdb-tool db-version "$db" >/dev/null; then
208 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
211 set "$@" -vconsole:emer -vsyslog:err -vfile:info
212 set "$@" --remote=punix:"$DB_SOCK"
213 set "$@" --private-key=db:Open_vSwitch,SSL,private_key
214 set "$@" --certificate=db:Open_vSwitch,SSL,certificate
215 set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
216 start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
219 # Initialize database settings.
220 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
222 set_system_ids || return 1
223 if test X"$DELETE_BRIDGES" = Xyes; then
224 for bridge in `ovs_vsctl list-br`; do
225 ovs_vsctl del-br $bridge
228 if test X"$DELETE_TRANSIENT_PORTS" = Xyes; then
235 # Now that ovs-vswitchd has started and completed its initial
236 # configuration, tell ovsdb-server to conenct to the remote managers. We
237 # used to do this at ovsdb-server startup time, but waiting for
238 # ovs-vswitchd to finish configuring means that remote managers see less
239 # churn in the database at startup or restart. (For example, managers
240 # won't briefly see empty datapath-id or ofport columns for records that
242 action "Enabling remote OVSDB managers" \
243 ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
244 db:Open_vSwitch,Open_vSwitch,manager_options
247 start_forwarding () {
250 insert_mod_if_required || return 1
252 if daemon_is_running ovs-vswitchd; then
253 log_success_msg "ovs-vswitchd is already running"
255 # Increase the limit on the number of open file descriptors.
256 # On Linux, ovs-vswitchd needs about three file descriptors
257 # per bridge and "n-handler-threads" file descriptors per bridge
258 # port, so this allows a very large number of bridges and ports.
260 if [ $(ulimit -n) -lt $MAXFD ]; then
264 # Start ovs-vswitchd.
265 set ovs-vswitchd unix:"$DB_SOCK"
266 set "$@" -vconsole:emer -vsyslog:err -vfile:info
267 if test X"$MLOCKALL" != Xno; then
270 start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
279 stop_daemon ovsdb-server
283 stop_daemon ovs-vswitchd
286 ## ----------------- ##
287 ## force-reload-kmod ##
288 ## ----------------- ##
290 internal_interfaces () {
291 # Outputs a list of internal interfaces:
293 # - There is an internal interface for every bridge, whether it
294 # has an Interface record or not and whether the Interface
295 # record's 'type' is properly set or not.
297 # - There is an internal interface for each Interface record whose
298 # 'type' is 'internal'.
300 # But ignore interfaces that don't really exist.
301 for d in `(ovs_vsctl --bare \
302 -- --columns=name find Interface type=internal \
303 -- list-br) | sort -u`
305 if test -e "/sys/class/net/$d"; then
312 bridges=`ovs_vsctl -- --real list-br`
313 if [ -n "${bridges}" ] && \
314 "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
318 [ -z "${bridges}" ] && return 0
321 save_ofports_if_required () {
322 # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
324 # (Versions 1.10 and later save OpenFlow port numbers without assistance,
325 # so we don't have to do anything for them.
326 case `ovs-appctl version | sed 1q` in
327 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
328 action "Saving ofport values" ovs_save save-ofports \
334 save_flows_if_required () {
335 if test X"$DELETE_BRIDGES" != Xyes; then
336 action "Saving flows" ovs_save save-flows "${script_flows}"
341 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
342 > "${script_interfaces}"
346 [ -x "${script_ofports}" ] && \
347 action "Restoring ofport values" "${script_ofports}"
350 flow_restore_wait () {
351 ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
354 flow_restore_complete () {
355 ovs_vsctl --if-exists remove open_vswitch . other_config \
356 flow-restore-wait="true"
360 [ -x "${script_flows}" ] && \
361 action "Restoring saved flows" "${script_flows}"
364 restore_interfaces () {
365 [ ! -x "${script_interfaces}" ] && return 0
366 action "Restoring interface configuration" "${script_interfaces}"
368 if test $rc = 0; then
373 log="logger -p daemon.$level -t ovs-save"
374 $log "interface restore script exited with status $rc:"
375 $log -f "$script_interfaces"
378 init_restore_scripts () {
379 script_interfaces=`mktemp`
380 script_flows=`mktemp`
381 script_ofports=`mktemp`
382 trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
385 force_reload_kmod () {
386 ifaces=`internal_interfaces`
387 action "Detected internal interfaces: $ifaces" true
390 save_flows_if_required
391 save_ofports_if_required
393 # Restart the database first, since a large database may take a
394 # while to load, and we want to minimize forwarding disruption.
398 # Restore of ofports should happen before vswitchd is restarted.
403 if action "Saving interface configuration" save_interfaces; then
406 log_warning_msg "Failed to save configuration, not replacing kernel module"
411 chmod +x "$script_interfaces"
413 for dp in `ovs-dpctl dump-dps`; do
414 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
417 for vport in `awk '/^vport_/ { print $1 }' /proc/modules`; do
418 action "Removing $vport module" rmmod $vport
419 if ! grep -q $vport /proc/modules; then
420 removed_vports="$removed_vports $vport"
424 # try both old and new names in case this is post upgrade
425 if test -e /sys/module/openvswitch_mod; then
426 action "Removing openvswitch module" rmmod openvswitch_mod
427 elif test -e /sys/module/openvswitch; then
428 action "Removing openvswitch module" rmmod openvswitch
431 # Start vswitchd by asking it to wait till flow restore is finished.
435 # Restore saved flows and inform vswitchd that we are done.
437 flow_restore_complete
442 "$datadir/scripts/ovs-check-dead-ifs"
449 save_interfaces_if_required () {
450 # Save interfaces if we are upgrading from a pre-1.10 branch.
451 case `ovs-appctl version | sed 1q` in
452 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
453 ifaces=`internal_interfaces`
454 action "Detected internal interfaces: $ifaces" true
455 if action "Saving interface configuration" save_interfaces; then
456 chmod +x "$script_interfaces"
463 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
465 save_interfaces_if_required
466 save_flows_if_required
467 save_ofports_if_required
470 # Restart the database first, since a large database may take a
471 # while to load, and we want to minimize forwarding disruption.
475 # Restore of ofports, if required, should happen before vswitchd is
481 # Start vswitchd by asking it to wait till flow restore is finished.
485 # Restore saved flows and inform vswitchd that we are done.
487 flow_restore_complete
490 # Restore the interfaces if required. Return true even if restore fails.
491 restore_interfaces || true
494 ## --------------- ##
495 ## enable-protocol ##
496 ## --------------- ##
499 # Translate the protocol name to a number, because "iptables -n -L" prints
500 # some protocols by name (despite the -n) and therefore we need to look for
503 # (iptables -S output is more uniform but old iptables doesn't have it.)
504 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
505 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
506 log_failure_msg "unknown protocol $PROTOCOL"
511 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
512 insert="iptables -I INPUT -p $PROTOCOL"
513 if test X"$DPORT" != X; then
514 name="$name to port $DPORT"
515 match="$match && /dpt:$DPORT/"
516 insert="$insert --dport $DPORT"
518 if test X"$SPORT" != X; then
519 name="$name from port $SPORT"
520 match="$match && /spt:$SPORT/"
521 insert="$insert --sport $SPORT"
523 insert="$insert -j ACCEPT"
525 if (iptables -n -L INPUT) >/dev/null 2>&1; then
526 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
528 # There's already a rule for this protocol. Don't override it.
529 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
531 action "Enabling $name with iptables" $insert
533 elif (iptables --version) >/dev/null 2>&1; then
534 action "cannot list iptables rules, not adding a rule for $name"
536 action "iptables binary not installed, not adding a rule for $name"
548 DELETE_TRANSIENT_PORTS=no
553 OVSDB_SERVER_PRIORITY=-10
554 OVS_VSWITCHD_PRIORITY=-10
555 OVSDB_SERVER_WRAPPER=
556 OVS_VSWITCHD_WRAPPER=
558 DB_FILE=$dbdir/conf.db
559 DB_SOCK=$rundir/db.sock
560 DB_SCHEMA=$datadir/vswitch.ovsschema
567 type_file=$etcdir/system-type.conf
568 version_file=$etcdir/system-version.conf
570 if test -e "$type_file" ; then
571 SYSTEM_TYPE=`cat $type_file`
572 SYSTEM_VERSION=`cat $version_file`
573 elif (lsb_release --id) >/dev/null 2>&1; then
574 SYSTEM_TYPE=`lsb_release --id -s`
575 system_release=`lsb_release --release -s`
576 system_codename=`lsb_release --codename -s`
577 SYSTEM_VERSION="${system_release}-${system_codename}"
580 SYSTEM_VERSION=unknown
587 $0: controls Open vSwitch daemons
588 usage: $0 [OPTIONS] COMMAND
590 This program is intended to be invoked internally by Open vSwitch startup
591 scripts. System administrators should not normally invoke it directly.
594 start start Open vSwitch daemons
595 stop stop Open vSwitch daemons
596 restart stop and start Open vSwitch daemons
597 status check whether Open vSwitch daemons are running
598 version print versions of Open vSwitch daemons
599 load-kmod insert modules if not already present
600 force-reload-kmod save OVS network device state, stop OVS, unload kernel
601 module, reload kernel module, start OVS, restore state
602 enable-protocol enable protocol specified in options with iptables
603 help display this help message
605 One of the following options is required for "start", "restart" and "force-reload-kmod":
606 --system-id=UUID set specific ID to uniquely identify this system
607 --system-id=random use a random but persistent UUID to identify this system
609 Other important options for "start", "restart" and "force-reload-kmod":
610 --system-type=TYPE set system type (e.g. "XenServer")
611 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
612 --external-id="key=value"
613 add given key-value pair to Open_vSwitch external-ids
614 --delete-bridges delete all bridges just before starting ovs-vswitchd
616 Less important options for "start", "restart" and "force-reload-kmod":
617 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
618 --no-force-corefiles do not force on core dumps for OVS daemons
619 --no-mlockall do not lock all of ovs-vswitchd into memory
620 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
621 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
623 Debugging options for "start", "restart" and "force-reload-kmod":
624 --ovsdb-server-wrapper=WRAPPER
625 --ovs-vswitchd-wrapper=WRAPPER
626 --ovs-vswitchd-wrapper=WRAPPER
627 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
629 File location options:
630 --db-file=FILE database file name (default: $DB_FILE)
631 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
632 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
634 Options for "enable-protocol":
635 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
636 --sport=PORT source port to match (for tcp or udp protocol)
637 --dport=PORT ddestination port to match (for tcp or udp protocol)
640 -h, --help display this help message
641 -V, --version display version information
643 Default directories with "configure" option and environment variable override:
644 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
645 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
646 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
647 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
648 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
649 user binaries: @bindir@ (--bindir, OVS_BINDIR)
650 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
652 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
659 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
660 eval set=\${$var+yes}
661 eval old_value=\$$var
662 if test X$set = X || \
663 (test $type = bool && \
664 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
665 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
672 echo ovsdb-server ovs-vswitchd
685 echo "$0 (Open vSwitch) $VERSION"
689 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
692 extra_ids="$extra_ids external-ids:$value"
695 echo >&2 "$0: --external-id argument not in the form \"key=value\""
701 option=`expr X"$arg" : 'X--\([^=]*\)'`
702 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
707 option=`expr X"$arg" : 'X--no-\(.*\)'`
713 option=`expr X"$arg" : 'X--\(.*\)'`
719 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
723 if test X"$command" = X; then
726 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
734 start_ovsdb || exit 1
747 for daemon in `daemons`; do
748 daemon_status $daemon || rc=$?
753 for daemon in `daemons`; do
761 insert_mod_if_required
770 echo >&2 "$0: missing command name (use --help for help)"
774 echo >&2 "$0: unknown command \"$command\" (use --help for help)"