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
183 if daemon_is_running ovsdb-server; then
184 log_success_msg "ovsdb-server is already running"
186 # Create initial database or upgrade database schema.
187 upgrade_db || return 1
189 # Start ovsdb-server.
190 set ovsdb-server "$DB_FILE"
191 for db in $EXTRA_DBS; do
197 if test ! -f "$db"; then
198 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
199 elif ovsdb-tool db-version "$db" >/dev/null; then
202 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
205 set "$@" -vconsole:emer -vsyslog:err -vfile:info
206 set "$@" --remote=punix:"$DB_SOCK"
207 set "$@" --private-key=db:Open_vSwitch,SSL,private_key
208 set "$@" --certificate=db:Open_vSwitch,SSL,certificate
209 set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
210 start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
213 # Initialize database settings.
214 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
216 set_system_ids || return 1
217 if test X"$DELETE_BRIDGES" = Xyes; then
218 for bridge in `ovs_vsctl list-br`; do
219 ovs_vsctl del-br $bridge
226 # Now that ovs-vswitchd has started and completed its initial
227 # configuration, tell ovsdb-server to conenct to the remote managers. We
228 # used to do this at ovsdb-server startup time, but waiting for
229 # ovs-vswitchd to finish configuring means that remote managers see less
230 # churn in the database at startup or restart. (For example, managers
231 # won't briefly see empty datapath-id or ofport columns for records that
233 action "Enabling remote OVSDB managers" \
234 ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
235 db:Open_vSwitch,Open_vSwitch,manager_options
238 start_forwarding () {
241 insert_mod_if_required || return 1
243 if daemon_is_running ovs-vswitchd; then
244 log_success_msg "ovs-vswitchd is already running"
246 # Increase the limit on the number of open file descriptors.
247 # On Linux, ovs-vswitchd needs about three file descriptors
248 # per bridge and "n-handler-threads" file descriptors per bridge
249 # port, so this allows a very large number of bridges and ports.
251 if [ $(ulimit -n) -lt $MAXFD ]; then
255 # Start ovs-vswitchd.
256 set ovs-vswitchd unix:"$DB_SOCK"
257 set "$@" -vconsole:emer -vsyslog:err -vfile:info
258 if test X"$MLOCKALL" != Xno; then
261 start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
270 stop_daemon ovsdb-server
274 stop_daemon ovs-vswitchd
277 ## ----------------- ##
278 ## force-reload-kmod ##
279 ## ----------------- ##
281 internal_interfaces () {
282 # Outputs a list of internal interfaces:
284 # - There is an internal interface for every bridge, whether it
285 # has an Interface record or not and whether the Interface
286 # record's 'type' is properly set or not.
288 # - There is an internal interface for each Interface record whose
289 # 'type' is 'internal'.
291 # But ignore interfaces that don't really exist.
292 for d in `(ovs_vsctl --bare \
293 -- --columns=name find Interface type=internal \
294 -- list-br) | sort -u`
296 if test -e "/sys/class/net/$d"; then
303 bridges=`ovs_vsctl -- --real list-br`
304 if [ -n "${bridges}" ] && \
305 "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
309 [ -z "${bridges}" ] && return 0
312 save_ofports_if_required () {
313 # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
315 # (Versions 1.10 and later save OpenFlow port numbers without assistance,
316 # so we don't have to do anything for them.
317 case `ovs-appctl version | sed 1q` in
318 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
319 action "Saving ofport values" ovs_save save-ofports \
325 save_flows_if_required () {
326 if test X"$DELETE_BRIDGES" != Xyes; then
327 action "Saving flows" ovs_save save-flows "${script_flows}"
332 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
333 > "${script_interfaces}"
337 [ -x "${script_ofports}" ] && \
338 action "Restoring ofport values" "${script_ofports}"
341 flow_restore_wait () {
342 ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
345 flow_restore_complete () {
346 ovs_vsctl --if-exists remove open_vswitch . other_config \
347 flow-restore-wait="true"
351 [ -x "${script_flows}" ] && \
352 action "Restoring saved flows" "${script_flows}"
355 restore_interfaces () {
356 [ ! -x "${script_interfaces}" ] && return 0
357 action "Restoring interface configuration" "${script_interfaces}"
359 if test $rc = 0; then
364 log="logger -p daemon.$level -t ovs-save"
365 $log "interface restore script exited with status $rc:"
366 $log -f "$script_interfaces"
369 init_restore_scripts () {
370 script_interfaces=`mktemp`
371 script_flows=`mktemp`
372 script_ofports=`mktemp`
373 trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
376 force_reload_kmod () {
377 ifaces=`internal_interfaces`
378 action "Detected internal interfaces: $ifaces" true
381 save_flows_if_required
382 save_ofports_if_required
384 # Restart the database first, since a large database may take a
385 # while to load, and we want to minimize forwarding disruption.
389 # Restore of ofports should happen before vswitchd is restarted.
394 if action "Saving interface configuration" save_interfaces; then
397 log_warning_msg "Failed to save configuration, not replacing kernel module"
402 chmod +x "$script_interfaces"
404 for dp in `ovs-dpctl dump-dps`; do
405 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
408 for vport in `awk '/^vport_/ { print $1 }' /proc/modules`; do
409 action "Removing $vport module" rmmod $vport
410 if ! grep -q $vport /proc/modules; then
411 removed_vports="$removed_vports $vport"
415 # try both old and new names in case this is post upgrade
416 if test -e /sys/module/openvswitch_mod; then
417 action "Removing openvswitch module" rmmod openvswitch_mod
418 elif test -e /sys/module/openvswitch; then
419 action "Removing openvswitch module" rmmod openvswitch
422 # Start vswitchd by asking it to wait till flow restore is finished.
426 # Restore saved flows and inform vswitchd that we are done.
428 flow_restore_complete
433 "$datadir/scripts/ovs-check-dead-ifs"
440 save_interfaces_if_required () {
441 # Save interfaces if we are upgrading from a pre-1.10 branch.
442 case `ovs-appctl version | sed 1q` in
443 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
444 ifaces=`internal_interfaces`
445 action "Detected internal interfaces: $ifaces" true
446 if action "Saving interface configuration" save_interfaces; then
447 chmod +x "$script_interfaces"
454 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
456 save_interfaces_if_required
457 save_flows_if_required
458 save_ofports_if_required
461 # Restart the database first, since a large database may take a
462 # while to load, and we want to minimize forwarding disruption.
466 # Restore of ofports, if required, should happen before vswitchd is
472 # Start vswitchd by asking it to wait till flow restore is finished.
476 # Restore saved flows and inform vswitchd that we are done.
478 flow_restore_complete
481 # Restore the interfaces if required. Return true even if restore fails.
482 restore_interfaces || true
485 ## --------------- ##
486 ## enable-protocol ##
487 ## --------------- ##
490 # Translate the protocol name to a number, because "iptables -n -L" prints
491 # some protocols by name (despite the -n) and therefore we need to look for
494 # (iptables -S output is more uniform but old iptables doesn't have it.)
495 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
496 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
497 log_failure_msg "unknown protocol $PROTOCOL"
502 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
503 insert="iptables -I INPUT -p $PROTOCOL"
504 if test X"$DPORT" != X; then
505 name="$name to port $DPORT"
506 match="$match && /dpt:$DPORT/"
507 insert="$insert --dport $DPORT"
509 if test X"$SPORT" != X; then
510 name="$name from port $SPORT"
511 match="$match && /spt:$SPORT/"
512 insert="$insert --sport $SPORT"
514 insert="$insert -j ACCEPT"
516 if (iptables -n -L INPUT) >/dev/null 2>&1; then
517 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
519 # There's already a rule for this protocol. Don't override it.
520 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
522 action "Enabling $name with iptables" $insert
524 elif (iptables --version) >/dev/null 2>&1; then
525 action "cannot list iptables rules, not adding a rule for $name"
527 action "iptables binary not installed, not adding a rule for $name"
543 OVSDB_SERVER_PRIORITY=-10
544 OVS_VSWITCHD_PRIORITY=-10
545 OVSDB_SERVER_WRAPPER=
546 OVS_VSWITCHD_WRAPPER=
548 DB_FILE=$dbdir/conf.db
549 DB_SOCK=$rundir/db.sock
550 DB_SCHEMA=$datadir/vswitch.ovsschema
557 type_file=$etcdir/system-type.conf
558 version_file=$etcdir/system-version.conf
560 if test -e "$type_file" ; then
561 SYSTEM_TYPE=`cat $type_file`
562 SYSTEM_VERSION=`cat $version_file`
563 elif (lsb_release --id) >/dev/null 2>&1; then
564 SYSTEM_TYPE=`lsb_release --id -s`
565 system_release=`lsb_release --release -s`
566 system_codename=`lsb_release --codename -s`
567 SYSTEM_VERSION="${system_release}-${system_codename}"
570 SYSTEM_VERSION=unknown
577 $0: controls Open vSwitch daemons
578 usage: $0 [OPTIONS] COMMAND
580 This program is intended to be invoked internally by Open vSwitch startup
581 scripts. System administrators should not normally invoke it directly.
584 start start Open vSwitch daemons
585 stop stop Open vSwitch daemons
586 restart stop and start Open vSwitch daemons
587 status check whether Open vSwitch daemons are running
588 version print versions of Open vSwitch daemons
589 load-kmod insert modules if not already present
590 force-reload-kmod save OVS network device state, stop OVS, unload kernel
591 module, reload kernel module, start OVS, restore state
592 enable-protocol enable protocol specified in options with iptables
593 help display this help message
595 One of the following options is required for "start", "restart" and "force-reload-kmod":
596 --system-id=UUID set specific ID to uniquely identify this system
597 --system-id=random use a random but persistent UUID to identify this system
599 Other important options for "start", "restart" and "force-reload-kmod":
600 --system-type=TYPE set system type (e.g. "XenServer")
601 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
602 --external-id="key=value"
603 add given key-value pair to Open_vSwitch external-ids
604 --delete-bridges delete all bridges just before starting ovs-vswitchd
606 Less important options for "start", "restart" and "force-reload-kmod":
607 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
608 --no-force-corefiles do not force on core dumps for OVS daemons
609 --no-mlockall do not lock all of ovs-vswitchd into memory
610 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
611 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
613 Debugging options for "start", "restart" and "force-reload-kmod":
614 --ovsdb-server-wrapper=WRAPPER
615 --ovs-vswitchd-wrapper=WRAPPER
616 --ovs-vswitchd-wrapper=WRAPPER
617 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
619 File location options:
620 --db-file=FILE database file name (default: $DB_FILE)
621 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
622 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
624 Options for "enable-protocol":
625 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
626 --sport=PORT source port to match (for tcp or udp protocol)
627 --dport=PORT ddestination port to match (for tcp or udp protocol)
630 -h, --help display this help message
631 -V, --version display version information
633 Default directories with "configure" option and environment variable override:
634 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
635 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
636 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
637 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
638 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
639 user binaries: @bindir@ (--bindir, OVS_BINDIR)
640 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
642 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
649 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
650 eval set=\${$var+yes}
651 eval old_value=\$$var
652 if test X$set = X || \
653 (test $type = bool && \
654 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
655 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
662 echo ovsdb-server ovs-vswitchd
675 echo "$0 (Open vSwitch) $VERSION"
679 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
682 extra_ids="$extra_ids external-ids:$value"
685 echo >&2 "$0: --external-id argument not in the form \"key=value\""
691 option=`expr X"$arg" : 'X--\([^=]*\)'`
692 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
697 option=`expr X"$arg" : 'X--no-\(.*\)'`
703 option=`expr X"$arg" : 'X--\(.*\)'`
709 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
713 if test X"$command" = X; then
716 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
724 start_ovsdb || exit 1
737 for daemon in `daemons`; do
738 daemon_status $daemon || rc=$?
743 for daemon in `daemons`; do
751 insert_mod_if_required
760 echo >&2 "$0: missing command name (use --help for help)"
764 echo >&2 "$0: unknown command \"$command\" (use --help for help)"