ovs-ctl: Fix indentation when deleting bridges.
[cascardo/ovs.git] / utilities / ovs-ctl.in
1 #! /bin/sh
2 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 case $0 in
17     */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
18     *) dir0=./ ;;
19 esac
20 . "$dir0/ovs-lib" || exit 1
21
22 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
23     case :$PATH: in
24         *:$dir:*) ;;
25         *) PATH=$PATH:$dir ;;
26     esac
27 done
28
29 ## ----- ##
30 ## start ##
31 ## ----- ##
32
33 # Keep track of removed vports so we can reload them if needed
34 removed_vports=""
35
36 insert_mods () {
37     # Try loading openvswitch again.
38     action "Inserting openvswitch module" modprobe openvswitch
39
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
43     done
44 }
45
46 insert_mod_if_required () {
47     # If this kernel has no module support, expect we're done.
48     if test ! -e /proc/modules
49     then
50         log_success_msg "Kernel has no loadable module support. Skipping modprobe"
51         return 0
52     fi
53
54     # If openvswitch is already loaded then we're done.
55     test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
56      return 0
57
58     # Load openvswitch.  If that's successful then we're done.
59     insert_mods && return 0
60
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)"
67         return 1
68     fi
69     action "removing bridge module" rmmod bridge || return 1
70
71     # Try loading openvswitch again.
72     insert_mods
73 }
74
75 ovs_vsctl () {
76     ovs-vsctl --no-wait "$@"
77 }
78
79 ovsdb_tool () {
80     ovsdb-tool -vconsole:off "$@"
81 }
82
83 create_db () {
84     action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
85 }
86
87 upgrade_db () {
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`
92         create_db
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
99
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).
109         #
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"
114
115         # Upgrade or downgrade schema.
116         if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
117             :
118         else
119             log_warning_msg "Schema conversion failed, using empty database instead"
120             rm -f "$DB_FILE"
121             create_db
122         fi
123     fi
124 }
125
126 set_system_ids () {
127     set ovs_vsctl set Open_vSwitch .
128
129     OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
130     set "$@" ovs-version="$OVS_VERSION"
131
132     case $SYSTEM_ID in
133         random)
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.
140                 . "$uuid_file"
141                 SYSTEM_ID=$INSTALLATION_UUID
142                 echo "$SYSTEM_ID" > "$id_file"
143             elif SYSTEM_ID=`uuidgen`; then
144                 echo "$SYSTEM_ID" > "$id_file"
145             else
146                 log_failure_msg "missing uuidgen, could not generate system ID"
147             fi
148             ;;
149
150         '')
151             log_failure_msg "system ID not configured, please use --system-id"
152             ;;
153
154         *)
155             ;;
156     esac
157     set "$@" external-ids:system-id="\"$SYSTEM_ID\""
158
159     if test X"$SYSTEM_TYPE" != X; then
160         set "$@" system-type="\"$SYSTEM_TYPE\""
161     else
162         log_failure_msg "no default system type, please use --system-type"
163     fi
164
165     if test X"$SYSTEM_VERSION" != X; then
166         set "$@" system-version="\"$SYSTEM_VERSION\""
167     else
168         log_failure_msg "no default system version, please use --system-version"
169     fi
170
171     action "Configuring Open vSwitch system IDs" "$@" $extra_ids
172 }
173
174 check_force_cores () {
175     if test X"$FORCE_COREFILES" = Xyes; then
176         ulimit -c 67108864
177     fi
178 }
179
180 start_ovsdb () {
181     check_force_cores
182
183     if daemon_is_running ovsdb-server; then
184         log_success_msg "ovsdb-server is already running"
185     else
186         # Create initial database or upgrade database schema.
187         upgrade_db || return 1
188
189         # Start ovsdb-server.
190         set ovsdb-server "$DB_FILE"
191         for db in $EXTRA_DBS; do
192             case $db in
193                 /*) ;;
194                 *) db=$dbdir/$db ;;
195             esac
196
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
200                 set "$@" "$db"
201             else
202                 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
203             fi
204         done
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" "$@" \
211             || return 1
212
213         # Initialize database settings.
214         ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
215             || return 1
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
220             done
221         fi
222     fi
223 }
224
225 add_managers () {
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
232     # exist at startup.)
233     action "Enabling remote OVSDB managers" \
234         ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
235             db:Open_vSwitch,Open_vSwitch,manager_options
236 }
237
238 start_forwarding () {
239     check_force_cores
240
241     insert_mod_if_required || return 1
242
243     if daemon_is_running ovs-vswitchd; then
244         log_success_msg "ovs-vswitchd is already running"
245     else
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.
250         MAXFD=65535
251         if [ $(ulimit -n) -lt $MAXFD ]; then
252             ulimit -n $MAXFD
253         fi
254
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
259                 set "$@" --mlockall
260             fi
261             start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
262     fi
263 }
264
265 ## ---- ##
266 ## stop ##
267 ## ---- ##
268
269 stop_ovsdb () {
270     stop_daemon ovsdb-server
271 }
272
273 stop_forwarding () {
274     stop_daemon ovs-vswitchd
275 }
276
277 ## ----------------- ##
278 ## force-reload-kmod ##
279 ## ----------------- ##
280
281 internal_interfaces () {
282     # Outputs a list of internal interfaces:
283     #
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.
287     #
288     #   - There is an internal interface for each Interface record whose
289     #     'type' is 'internal'.
290     #
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`
295     do
296         if test -e "/sys/class/net/$d"; then
297                 printf "%s " "$d"
298             fi
299     done
300 }
301
302 ovs_save () {
303     bridges=`ovs_vsctl -- --real list-br`
304     if [ -n "${bridges}" ] && \
305         "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
306         chmod +x "$2"
307         return 0
308     fi
309     [ -z "${bridges}" ] && return 0
310 }
311
312 save_ofports_if_required () {
313     # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
314     #
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 \
320                 "${script_ofports}"
321             ;;
322     esac
323 }
324
325 save_flows_if_required () {
326     if test X"$DELETE_BRIDGES" != Xyes; then
327         action "Saving flows" ovs_save save-flows "${script_flows}"
328     fi
329 }
330
331 save_interfaces () {
332     "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
333         > "${script_interfaces}"
334 }
335
336 restore_ofports () {
337     [ -x "${script_ofports}" ] && \
338         action "Restoring ofport values" "${script_ofports}"
339 }
340
341 flow_restore_wait () {
342     ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
343 }
344
345 flow_restore_complete () {
346     ovs_vsctl --if-exists remove open_vswitch . other_config \
347         flow-restore-wait="true"
348 }
349
350 restore_flows () {
351     [ -x "${script_flows}" ] && \
352         action "Restoring saved flows" "${script_flows}"
353 }
354
355 restore_interfaces () {
356     [ ! -x "${script_interfaces}" ] && return 0
357     action "Restoring interface configuration" "${script_interfaces}"
358     rc=$?
359     if test $rc = 0; then
360         level=debug
361     else
362         level=err
363     fi
364     log="logger -p daemon.$level -t ovs-save"
365     $log "interface restore script exited with status $rc:"
366     $log -f "$script_interfaces"
367 }
368
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
374 }
375
376 force_reload_kmod () {
377     ifaces=`internal_interfaces`
378     action "Detected internal interfaces: $ifaces" true
379
380     init_restore_scripts
381     save_flows_if_required
382     save_ofports_if_required
383
384     # Restart the database first, since a large database may take a
385     # while to load, and we want to minimize forwarding disruption.
386     stop_ovsdb
387     start_ovsdb
388
389     # Restore of ofports should happen before vswitchd is restarted.
390     restore_ofports
391
392     stop_forwarding
393
394     if action "Saving interface configuration" save_interfaces; then
395         :
396     else
397         log_warning_msg "Failed to save configuration, not replacing kernel module"
398         start_forwarding
399         add_managers
400         exit 1
401     fi
402     chmod +x "$script_interfaces"
403
404     for dp in `ovs-dpctl dump-dps`; do
405         action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
406     done
407
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"
412         fi
413     done
414
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
420     fi
421
422     # Start vswitchd by asking it to wait till flow restore is finished.
423     flow_restore_wait
424     start_forwarding
425
426     # Restore saved flows and inform vswitchd that we are done.
427     restore_flows
428     flow_restore_complete
429     add_managers
430
431     restore_interfaces
432
433     "$datadir/scripts/ovs-check-dead-ifs"
434 }
435
436 ## ------- ##
437 ## restart ##
438 ## ------- ##
439
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"
448             fi
449             ;;
450     esac
451 }
452
453 restart () {
454     if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
455         init_restore_scripts
456         save_interfaces_if_required
457         save_flows_if_required
458         save_ofports_if_required
459     fi
460
461     # Restart the database first, since a large database may take a
462     # while to load, and we want to minimize forwarding disruption.
463     stop_ovsdb
464     start_ovsdb
465
466     # Restore of ofports, if required, should happen before vswitchd is
467     # restarted.
468     restore_ofports
469
470     stop_forwarding
471
472     # Start vswitchd by asking it to wait till flow restore is finished.
473     flow_restore_wait
474     start_forwarding
475
476     # Restore saved flows and inform vswitchd that we are done.
477     restore_flows
478     flow_restore_complete
479     add_managers
480
481     # Restore the interfaces if required. Return true even if restore fails.
482     restore_interfaces || true
483 }
484
485 ## --------------- ##
486 ## enable-protocol ##
487 ## --------------- ##
488
489 enable_protocol () {
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
492     # both forms.
493     #
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"
498         return 1
499     fi
500
501     name=$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"
508     fi
509     if test X"$SPORT" != X; then
510         name="$name from port $SPORT"
511         match="$match && /spt:$SPORT/"
512         insert="$insert --sport $SPORT"
513     fi
514     insert="$insert -j ACCEPT"
515
516     if (iptables -n -L INPUT) >/dev/null 2>&1; then
517         if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
518         then
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"
521         else
522             action "Enabling $name with iptables" $insert
523         fi
524     elif (iptables --version) >/dev/null 2>&1; then
525         action "cannot list iptables rules, not adding a rule for $name"
526     else
527         action "iptables binary not installed, not adding a rule for $name"
528     fi
529 }
530
531 ## ---- ##
532 ## main ##
533 ## ---- ##
534
535 set_defaults () {
536     SYSTEM_ID=
537
538     DELETE_BRIDGES=no
539
540     DAEMON_CWD=/
541     FORCE_COREFILES=yes
542     MLOCKALL=yes
543     OVSDB_SERVER_PRIORITY=-10
544     OVS_VSWITCHD_PRIORITY=-10
545     OVSDB_SERVER_WRAPPER=
546     OVS_VSWITCHD_WRAPPER=
547
548     DB_FILE=$dbdir/conf.db
549     DB_SOCK=$rundir/db.sock
550     DB_SCHEMA=$datadir/vswitch.ovsschema
551     EXTRA_DBS=
552
553     PROTOCOL=gre
554     DPORT=
555     SPORT=
556
557     type_file=$etcdir/system-type.conf
558     version_file=$etcdir/system-version.conf
559
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}"
568     else
569         SYSTEM_TYPE=unknown
570         SYSTEM_VERSION=unknown
571     fi
572 }
573
574 usage () {
575     set_defaults
576     cat <<EOF
577 $0: controls Open vSwitch daemons
578 usage: $0 [OPTIONS] COMMAND
579
580 This program is intended to be invoked internally by Open vSwitch startup
581 scripts.  System administrators should not normally invoke it directly.
582
583 Commands:
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
594
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
598
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
605
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)
612
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')
618
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)
623
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)
628
629 Other options:
630   -h, --help                  display this help message
631   -V, --version               display version information
632
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)
641
642 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
643 EOF
644
645     exit 0
646 }
647
648 set_option () {
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)"
656         return
657     fi
658     eval $var=\$value
659 }
660
661 daemons () {
662     echo ovsdb-server ovs-vswitchd
663 }
664
665 set_defaults
666 extra_ids=
667 command=
668 for arg
669 do
670     case $arg in
671         -h | --help)
672             usage
673             ;;
674         -V | --version)
675             echo "$0 (Open vSwitch) $VERSION"
676             exit 0
677             ;;
678         --external-id=*)
679             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
680             case $value in
681                 *=*)
682                     extra_ids="$extra_ids external-ids:$value"
683                     ;;
684                 *)
685                     echo >&2 "$0: --external-id argument not in the form \"key=value\""
686                     exit 1
687                     ;;
688             esac
689             ;;
690         --[a-z]*=*)
691             option=`expr X"$arg" : 'X--\([^=]*\)'`
692             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
693             type=string
694             set_option
695             ;;
696         --no-[a-z]*)
697             option=`expr X"$arg" : 'X--no-\(.*\)'`
698             value=no
699             type=bool
700             set_option
701             ;;
702         --[a-z]*)
703             option=`expr X"$arg" : 'X--\(.*\)'`
704             value=yes
705             type=bool
706             set_option
707             ;;
708         -*)
709             echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
710             exit 1
711             ;;
712         *)
713             if test X"$command" = X; then
714                 command=$arg
715             else
716                 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
717                 exit 1
718             fi
719             ;;
720     esac
721 done
722 case $command in
723     start)
724         start_ovsdb || exit 1
725         start_forwarding
726         add_managers
727         ;;
728     stop)
729         stop_forwarding
730         stop_ovsdb
731         ;;
732     restart)
733         restart
734         ;;
735     status)
736         rc=0
737         for daemon in `daemons`; do
738             daemon_status $daemon || rc=$?
739         done
740         exit $rc
741         ;;
742     version)
743         for daemon in `daemons`; do
744             $daemon --version
745         done
746         ;;
747     force-reload-kmod)
748             force_reload_kmod
749         ;;
750     load-kmod)
751         insert_mod_if_required
752         ;;
753     enable-protocol)
754         enable_protocol
755         ;;
756     help)
757         usage
758         ;;
759     '')
760         echo >&2 "$0: missing command name (use --help for help)"
761         exit 1
762         ;;
763     *)
764         echo >&2 "$0: unknown command \"$command\" (use --help for help)"
765         exit 1
766         ;;
767 esac