2 # Copyright (C) 2009, 2010, 2011, 2012, 2013 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 insert_mod_if_required () {
34 # If openvswitch is already loaded then we're done.
35 test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
38 # Load openvswitch. If that's successful then we're done.
39 action "Inserting openvswitch module" modprobe openvswitch && return 0
41 # If the bridge module is loaded, then that might be blocking
42 # openvswitch. Try to unload it, if there are no bridges.
43 test -e /sys/module/bridge || return 1
44 bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
45 if test "$bridges" != "*"; then
46 log_warning_msg "not removing bridge module because bridges exist ($bridges)"
49 action "removing bridge module" rmmod bridge || return 1
51 # Try loading openvswitch again.
52 action "Inserting openvswitch module" modprobe openvswitch
56 ovs-vsctl --no-wait "$@"
60 ovsdb-tool -vconsole:off "$@"
64 action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
68 schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
69 if test ! -e "$DB_FILE"; then
70 log_warning_msg "$DB_FILE does not exist"
71 install -d -m 755 -o root -g root `dirname $DB_FILE`
73 elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
74 # Back up the old version.
75 version=`ovsdb_tool db-version "$DB_FILE"`
76 cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
77 backup=$DB_FILE.backup$version-$cksum
78 action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
80 # Compact database. This is important if the old schema did not enable
81 # garbage collection (i.e. if it did not have any tables with "isRoot":
82 # true) but the new schema does. In that situation the old database
83 # may contain a transaction that creates a record followed by a
84 # transaction that creates the first use of the record. Replaying that
85 # series of transactions against the new database schema (as "convert"
86 # does) would cause the record to be dropped by the first transaction,
87 # then the second transaction would cause a referential integrity
88 # failure (for a strong reference).
90 # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
91 # understand some feature of the schema used in the OVSDB version that
92 # we're downgrading from, so we don't give up on error.
93 action "Compacting database" ovsdb_tool compact "$DB_FILE"
95 # Upgrade or downgrade schema.
96 if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
99 log_warning_msg "Schema conversion failed, using empty database instead"
107 set ovs_vsctl set Open_vSwitch .
109 OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
110 set "$@" ovs-version="$OVS_VERSION"
114 id_file=$etcdir/system-id.conf
115 uuid_file=$etcdir/install_uuid.conf
116 if test -e "$id_file"; then
117 SYSTEM_ID=`cat "$id_file"`
118 elif test -e "$uuid_file"; then
119 # Migrate from old file name.
121 SYSTEM_ID=$INSTALLATION_UUID
122 echo "$SYSTEM_ID" > "$id_file"
123 elif SYSTEM_ID=`uuidgen`; then
124 echo "$SYSTEM_ID" > "$id_file"
126 log_failure_msg "missing uuidgen, could not generate system ID"
131 log_failure_msg "system ID not configured, please use --system-id"
137 set "$@" external-ids:system-id="\"$SYSTEM_ID\""
139 if test X"$SYSTEM_TYPE" != X; then
140 set "$@" system-type="\"$SYSTEM_TYPE\""
142 log_failure_msg "no default system type, please use --system-type"
145 if test X"$SYSTEM_VERSION" != X; then
146 set "$@" system-version="\"$SYSTEM_VERSION\""
148 log_failure_msg "no default system version, please use --system-version"
151 action "Configuring Open vSwitch system IDs" "$@" $extra_ids
154 check_force_cores () {
155 if test X"$FORCE_COREFILES" = Xyes; then
163 if daemon_is_running ovsdb-server; then
164 log_success_msg "ovsdb-server is already running"
166 # Create initial database or upgrade database schema.
167 upgrade_db || return 1
169 # Start ovsdb-server.
170 set ovsdb-server "$DB_FILE"
171 for db in $EXTRA_DBS; do
177 if test ! -f "$db"; then
178 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
179 elif ovsdb-tool db-version "$db" >/dev/null; then
182 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
185 set "$@" -vconsole:emer -vsyslog:err -vfile:info
186 set "$@" --remote=punix:"$DB_SOCK"
187 set "$@" --private-key=db:Open_vSwitch,SSL,private_key
188 set "$@" --certificate=db:Open_vSwitch,SSL,certificate
189 set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
190 start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
193 # Initialize database settings.
194 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
196 set_system_ids || return 1
197 if test X"$DELETE_BRIDGES" = Xyes; then
198 for bridge in `ovs_vsctl list-br`; do
199 ovs_vsctl del-br $bridge
206 # Now that ovs-vswitchd has started and completed its initial
207 # configuration, tell ovsdb-server to conenct to the remote managers. We
208 # used to do this at ovsdb-server startup time, but waiting for
209 # ovs-vswitchd to finish configuring means that remote managers see less
210 # churn in the database at startup or restart. (For example, managers
211 # won't briefly see empty datapath-id or ofport columns for records that
213 action "Enabling remote OVSDB managers" \
214 ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
215 db:Open_vSwitch,Open_vSwitch,manager_options
218 start_forwarding () {
221 insert_mod_if_required || return 1
223 if daemon_is_running ovs-vswitchd; then
224 log_success_msg "ovs-vswitchd is already running"
226 # Increase the limit on the number of open file descriptors.
227 # On Linux, ovs-vswitchd needs about three file descriptors
228 # per bridge and one file descriptor per bridge port, so this
229 # allows a very large number of bridges and ports.
231 if [ $(ulimit -n) -lt $MAXFD ]; then
235 # Start ovs-vswitchd.
236 set ovs-vswitchd unix:"$DB_SOCK"
237 set "$@" -vconsole:emer -vsyslog:err -vfile:info
238 if test X"$MLOCKALL" != Xno; then
241 start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
250 stop_daemon ovsdb-server
254 stop_daemon ovs-vswitchd
257 ## ----------------- ##
258 ## force-reload-kmod ##
259 ## ----------------- ##
261 internal_interfaces () {
262 # Outputs a list of internal interfaces:
264 # - There is an internal interface for every bridge, whether it
265 # has an Interface record or not and whether the Interface
266 # record's 'type' is properly set or not.
268 # - There is an internal interface for each Interface record whose
269 # 'type' is 'internal'.
271 # But ignore interfaces that don't really exist.
272 for d in `(ovs_vsctl --bare \
273 -- --columns=name find Interface type=internal \
274 -- list-br) | sort -u`
276 if test -e "/sys/class/net/$d"; then
283 bridges=`ovs_vsctl -- --real list-br`
284 if [ -n "${bridges}" ] && \
285 "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
289 [ -z "${bridges}" ] && return 0
292 save_ofports_if_required () {
293 # Save ofports if we are upgrading from a pre-1.10 branch.
294 case `ovs-appctl version | sed 1q` in
295 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
296 action "Saving ofport values" ovs_save save-ofports \
303 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
304 > "${script_interfaces}"
308 [ -x "${script_ofports}" ] && \
309 action "Restoring ofport values" "${script_ofports}"
312 flow_restore_wait () {
313 ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
316 flow_restore_complete () {
317 ovs_vsctl --if-exists remove open_vswitch . other_config \
318 flow-restore-wait="true"
322 [ -x "${script_flows}" ] && \
323 action "Restoring saved flows" "${script_flows}"
326 restore_interfaces () {
327 [ ! -x "${script_interfaces}" ] && return 0
328 action "Restoring interface configuration" "${script_interfaces}"
330 if test $rc = 0; then
335 log="logger -p daemon.$level -t ovs-save"
336 $log "interface restore script exited with status $rc:"
337 $log -f "$script_interfaces"
340 init_restore_scripts () {
341 script_interfaces=`mktemp`
342 script_flows=`mktemp`
343 script_ofports=`mktemp`
344 trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
347 force_reload_kmod () {
348 ifaces=`internal_interfaces`
349 action "Detected internal interfaces: $ifaces" true
353 action "Saving flows" ovs_save save-flows "${script_flows}"
355 save_ofports_if_required
357 # Restart the database first, since a large database may take a
358 # while to load, and we want to minimize forwarding disruption.
362 # Restore of ofports should happen before vswitchd is restarted.
367 if action "Saving interface configuration" save_interfaces; then
370 log_warning_msg "Failed to save configuration, not replacing kernel module"
375 chmod +x "$script_interfaces"
377 for dp in `ovs-dpctl dump-dps`; do
378 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
381 # try both old and new names in case this is post upgrade
382 if test -e /sys/module/openvswitch_mod; then
383 action "Removing openvswitch module" rmmod openvswitch_mod
384 elif test -e /sys/module/openvswitch; then
385 action "Removing openvswitch module" rmmod openvswitch
388 # Start vswitchd by asking it to wait till flow restore is finished.
392 # Restore saved flows and inform vswitchd that we are done.
394 flow_restore_complete
399 "$datadir/scripts/ovs-check-dead-ifs"
406 save_interfaces_if_required () {
407 # Save interfaces if we are upgrading from a pre-1.10 branch.
408 case `ovs-appctl version | sed 1q` in
409 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
410 ifaces=`internal_interfaces`
411 action "Detected internal interfaces: $ifaces" true
412 if action "Saving interface configuration" save_interfaces; then
413 chmod +x "$script_interfaces"
420 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
422 save_interfaces_if_required
423 action "Saving flows" ovs_save save-flows "${script_flows}"
424 save_ofports_if_required
427 # Restart the database first, since a large database may take a
428 # while to load, and we want to minimize forwarding disruption.
432 # Restore of ofports, if required, should happen before vswitchd is
438 # Start vswitchd by asking it to wait till flow restore is finished.
442 # Restore saved flows and inform vswitchd that we are done.
444 flow_restore_complete
447 # Restore the interfaces if required. Return true even if restore fails.
448 restore_interfaces || true
451 ## --------------- ##
452 ## enable-protocol ##
453 ## --------------- ##
456 # Translate the protocol name to a number, because "iptables -n -L" prints
457 # some protocols by name (despite the -n) and therefore we need to look for
460 # (iptables -S output is more uniform but old iptables doesn't have it.)
461 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
462 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
463 log_failure_msg "unknown protocol $PROTOCOL"
468 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
469 insert="iptables -I INPUT -p $PROTOCOL"
470 if test X"$DPORT" != X; then
471 name="$name to port $DPORT"
472 match="$match && /dpt:$DPORT/"
473 insert="$insert --dport $DPORT"
475 if test X"$SPORT" != X; then
476 name="$name from port $SPORT"
477 match="$match && /spt:$SPORT/"
478 insert="$insert --sport $SPORT"
480 insert="$insert -j ACCEPT"
482 if (iptables -n -L INPUT) >/dev/null 2>&1; then
483 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
485 # There's already a rule for this protocol. Don't override it.
486 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
488 action "Enabling $name with iptables" $insert
490 elif (iptables --version) >/dev/null 2>&1; then
491 action "cannot list iptables rules, not adding a rule for $name"
493 action "iptables binary not installed, not adding a rule for $name"
509 OVSDB_SERVER_PRIORITY=-10
510 OVS_VSWITCHD_PRIORITY=-10
511 OVSDB_SERVER_WRAPPER=
512 OVS_VSWITCHD_WRAPPER=
514 DB_FILE=$dbdir/conf.db
515 DB_SOCK=$rundir/db.sock
516 DB_SCHEMA=$datadir/vswitch.ovsschema
523 type_file=$etcdir/system-type.conf
524 version_file=$etcdir/system-version.conf
526 if test -e "$type_file" ; then
527 SYSTEM_TYPE=`cat $type_file`
528 SYSTEM_VERSION=`cat $version_file`
529 elif (lsb_release --id) >/dev/null 2>&1; then
530 SYSTEM_TYPE=`lsb_release --id -s`
531 system_release=`lsb_release --release -s`
532 system_codename=`lsb_release --codename -s`
533 SYSTEM_VERSION="${system_release}-${system_codename}"
536 SYSTEM_VERSION=unknown
543 $0: controls Open vSwitch daemons
544 usage: $0 [OPTIONS] COMMAND
546 This program is intended to be invoked internally by Open vSwitch startup
547 scripts. System administrators should not normally invoke it directly.
550 start start Open vSwitch daemons
551 stop stop Open vSwitch daemons
552 restart stop and start Open vSwitch daemons
553 status check whether Open vSwitch daemons are running
554 version print versions of Open vSwitch daemons
555 load-kmod insert modules if not already present
556 force-reload-kmod save OVS network device state, stop OVS, unload kernel
557 module, reload kernel module, start OVS, restore state
558 enable-protocol enable protocol specified in options with iptables
559 help display this help message
561 One of the following options is required for "start", "restart" and "force-reload-kmod":
562 --system-id=UUID set specific ID to uniquely identify this system
563 --system-id=random use a random but persistent UUID to identify this system
565 Other important options for "start", "restart" and "force-reload-kmod":
566 --system-type=TYPE set system type (e.g. "XenServer")
567 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
568 --external-id="key=value"
569 add given key-value pair to Open_vSwitch external-ids
570 --delete-bridges delete all bridges just before starting ovs-vswitchd
572 Less important options for "start", "restart" and "force-reload-kmod":
573 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
574 --no-force-corefiles do not force on core dumps for OVS daemons
575 --no-mlockall do not lock all of ovs-vswitchd into memory
576 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
577 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
579 Debugging options for "start", "restart" and "force-reload-kmod":
580 --ovsdb-server-wrapper=WRAPPER
581 --ovs-vswitchd-wrapper=WRAPPER
582 --ovs-vswitchd-wrapper=WRAPPER
583 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
585 File location options:
586 --db-file=FILE database file name (default: $DB_FILE)
587 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
588 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
590 Options for "enable-protocol":
591 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
592 --sport=PORT source port to match (for tcp or udp protocol)
593 --dport=PORT ddestination port to match (for tcp or udp protocol)
596 -h, --help display this help message
597 -V, --version display version information
599 Default directories with "configure" option and environment variable override:
600 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
601 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
602 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
603 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
604 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
605 user binaries: @bindir@ (--bindir, OVS_BINDIR)
606 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
608 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
615 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
616 eval set=\${$var+yes}
617 eval old_value=\$$var
618 if test X$set = X || \
619 (test $type = bool && \
620 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
621 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
628 echo ovsdb-server ovs-vswitchd
641 echo "$0 (Open vSwitch) $VERSION"
645 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
648 extra_ids="$extra_ids external-ids:$value"
651 echo >&2 "$0: --external-id argument not in the form \"key=value\""
657 option=`expr X"$arg" : 'X--\([^=]*\)'`
658 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
663 option=`expr X"$arg" : 'X--no-\(.*\)'`
669 option=`expr X"$arg" : 'X--\(.*\)'`
675 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
679 if test X"$command" = X; then
682 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
703 for daemon in `daemons`; do
704 daemon_status $daemon || rc=$?
709 for daemon in `daemons`; do
717 insert_mod_if_required
726 echo >&2 "$0: missing command name (use --help for help)"
730 echo >&2 "$0: unknown command \"$command\" (use --help for help)"