ovs-vsctl-bashcomp: Documentation and unit tests.
[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 insert_mod_if_required () {
34     # If this kernel has no module support, expect we're done.
35     if test ! -e /proc/modules
36     then
37         log_success_msg "Kernel has no loadable module support. Skipping modprobe"
38         return 0
39     fi
40
41     # If openvswitch is already loaded then we're done.
42     test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
43      return 0
44
45     # Load openvswitch.  If that's successful then we're done.
46     action "Inserting openvswitch module" modprobe openvswitch && return 0
47
48     # If the bridge module is loaded, then that might be blocking
49     # openvswitch.  Try to unload it, if there are no bridges.
50     test -e /sys/module/bridge || return 1
51     bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
52     if test "$bridges" != "*"; then
53         log_warning_msg "not removing bridge module because bridges exist ($bridges)"
54         return 1
55     fi
56     action "removing bridge module" rmmod bridge || return 1
57
58     # Try loading openvswitch again.
59     action "Inserting openvswitch module" modprobe openvswitch
60 }
61
62 ovs_vsctl () {
63     ovs-vsctl --no-wait "$@"
64 }
65
66 ovsdb_tool () {
67     ovsdb-tool -vconsole:off "$@"
68 }
69
70 create_db () {
71     action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
72 }
73
74 upgrade_db () {
75     schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
76     if test ! -e "$DB_FILE"; then
77         log_warning_msg "$DB_FILE does not exist"
78         install -d -m 755 -o root -g root `dirname $DB_FILE`
79         create_db
80     elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
81         # Back up the old version.
82         version=`ovsdb_tool db-version "$DB_FILE"`
83         cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
84         backup=$DB_FILE.backup$version-$cksum
85         action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
86
87         # Compact database.  This is important if the old schema did not enable
88         # garbage collection (i.e. if it did not have any tables with "isRoot":
89         # true) but the new schema does.  In that situation the old database
90         # may contain a transaction that creates a record followed by a
91         # transaction that creates the first use of the record.  Replaying that
92         # series of transactions against the new database schema (as "convert"
93         # does) would cause the record to be dropped by the first transaction,
94         # then the second transaction would cause a referential integrity
95         # failure (for a strong reference).
96         #
97         # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
98         # understand some feature of the schema used in the OVSDB version that
99         # we're downgrading from, so we don't give up on error.
100         action "Compacting database" ovsdb_tool compact "$DB_FILE"
101
102         # Upgrade or downgrade schema.
103         if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
104             :
105         else
106             log_warning_msg "Schema conversion failed, using empty database instead"
107             rm -f "$DB_FILE"
108             create_db
109         fi
110     fi
111 }
112
113 set_system_ids () {
114     set ovs_vsctl set Open_vSwitch .
115
116     OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
117     set "$@" ovs-version="$OVS_VERSION"
118
119     case $SYSTEM_ID in
120         random)
121             id_file=$etcdir/system-id.conf
122             uuid_file=$etcdir/install_uuid.conf
123             if test -e "$id_file"; then
124                 SYSTEM_ID=`cat "$id_file"`
125             elif test -e "$uuid_file"; then
126                 # Migrate from old file name.
127                 . "$uuid_file"
128                 SYSTEM_ID=$INSTALLATION_UUID
129                 echo "$SYSTEM_ID" > "$id_file"
130             elif SYSTEM_ID=`uuidgen`; then
131                 echo "$SYSTEM_ID" > "$id_file"
132             else
133                 log_failure_msg "missing uuidgen, could not generate system ID"
134             fi
135             ;;
136
137         '')
138             log_failure_msg "system ID not configured, please use --system-id"
139             ;;
140
141         *)
142             ;;
143     esac
144     set "$@" external-ids:system-id="\"$SYSTEM_ID\""
145
146     if test X"$SYSTEM_TYPE" != X; then
147         set "$@" system-type="\"$SYSTEM_TYPE\""
148     else
149         log_failure_msg "no default system type, please use --system-type"
150     fi
151
152     if test X"$SYSTEM_VERSION" != X; then
153         set "$@" system-version="\"$SYSTEM_VERSION\""
154     else
155         log_failure_msg "no default system version, please use --system-version"
156     fi
157
158     action "Configuring Open vSwitch system IDs" "$@" $extra_ids
159 }
160
161 check_force_cores () {
162     if test X"$FORCE_COREFILES" = Xyes; then
163         ulimit -c 67108864
164     fi
165 }
166
167 start_ovsdb () {
168     check_force_cores
169
170     if daemon_is_running ovsdb-server; then
171         log_success_msg "ovsdb-server is already running"
172     else
173         # Create initial database or upgrade database schema.
174         upgrade_db || return 1
175
176         # Start ovsdb-server.
177         set ovsdb-server "$DB_FILE"
178         for db in $EXTRA_DBS; do
179             case $db in
180                 /*) ;;
181                 *) db=$dbdir/$db ;;
182             esac
183
184             if test ! -f "$db"; then
185                 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
186             elif ovsdb-tool db-version "$db" >/dev/null; then
187                 set "$@" "$db"
188             else
189                 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
190             fi
191         done
192         set "$@" -vconsole:emer -vsyslog:err -vfile:info
193         set "$@" --remote=punix:"$DB_SOCK"
194         set "$@" --private-key=db:Open_vSwitch,SSL,private_key
195         set "$@" --certificate=db:Open_vSwitch,SSL,certificate
196         set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
197         start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
198             || return 1
199
200         # Initialize database settings.
201         ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
202             || return 1
203         set_system_ids || return 1
204         if test X"$DELETE_BRIDGES" = Xyes; then
205             for bridge in `ovs_vsctl list-br`; do
206         ovs_vsctl del-br $bridge
207             done
208         fi
209     fi
210 }
211
212 add_managers () {
213     # Now that ovs-vswitchd has started and completed its initial
214     # configuration, tell ovsdb-server to conenct to the remote managers.  We
215     # used to do this at ovsdb-server startup time, but waiting for
216     # ovs-vswitchd to finish configuring means that remote managers see less
217     # churn in the database at startup or restart.  (For example, managers
218     # won't briefly see empty datapath-id or ofport columns for records that
219     # exist at startup.)
220     action "Enabling remote OVSDB managers" \
221         ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
222             db:Open_vSwitch,Open_vSwitch,manager_options
223 }
224
225 start_forwarding () {
226     check_force_cores
227
228     insert_mod_if_required || return 1
229
230     if daemon_is_running ovs-vswitchd; then
231         log_success_msg "ovs-vswitchd is already running"
232     else
233         # Increase the limit on the number of open file descriptors.
234         # On Linux, ovs-vswitchd needs about three file descriptors
235         # per bridge and "n-handler-threads" file descriptors per bridge
236         # port, so this allows a very large number of bridges and ports.
237         MAXFD=65535
238         if [ $(ulimit -n) -lt $MAXFD ]; then
239             ulimit -n $MAXFD
240         fi
241
242             # Start ovs-vswitchd.
243             set ovs-vswitchd unix:"$DB_SOCK"
244             set "$@" -vconsole:emer -vsyslog:err -vfile:info
245             if test X"$MLOCKALL" != Xno; then
246                 set "$@" --mlockall
247             fi
248             start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
249     fi
250 }
251
252 ## ---- ##
253 ## stop ##
254 ## ---- ##
255
256 stop_ovsdb () {
257     stop_daemon ovsdb-server
258 }
259
260 stop_forwarding () {
261     stop_daemon ovs-vswitchd
262 }
263
264 ## ----------------- ##
265 ## force-reload-kmod ##
266 ## ----------------- ##
267
268 internal_interfaces () {
269     # Outputs a list of internal interfaces:
270     #
271     #   - There is an internal interface for every bridge, whether it
272     #     has an Interface record or not and whether the Interface
273     #     record's 'type' is properly set or not.
274     #
275     #   - There is an internal interface for each Interface record whose
276     #     'type' is 'internal'.
277     #
278     # But ignore interfaces that don't really exist.
279     for d in `(ovs_vsctl --bare \
280                 -- --columns=name find Interface type=internal \
281                     -- list-br) | sort -u`
282     do
283         if test -e "/sys/class/net/$d"; then
284                 printf "%s " "$d"
285             fi
286     done
287 }
288
289 ovs_save () {
290     bridges=`ovs_vsctl -- --real list-br`
291     if [ -n "${bridges}" ] && \
292         "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
293         chmod +x "$2"
294         return 0
295     fi
296     [ -z "${bridges}" ] && return 0
297 }
298
299 save_ofports_if_required () {
300     # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
301     #
302     # (Versions 1.10 and later save OpenFlow port numbers without assistance,
303     # so we don't have to do anything for them.
304     case `ovs-appctl version | sed 1q` in
305         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
306             action "Saving ofport values" ovs_save save-ofports \
307                 "${script_ofports}"
308             ;;
309     esac
310 }
311
312 save_interfaces () {
313     "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
314         > "${script_interfaces}"
315 }
316
317 restore_ofports () {
318     [ -x "${script_ofports}" ] && \
319         action "Restoring ofport values" "${script_ofports}"
320 }
321
322 flow_restore_wait () {
323     ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
324 }
325
326 flow_restore_complete () {
327     ovs_vsctl --if-exists remove open_vswitch . other_config \
328         flow-restore-wait="true"
329 }
330
331 restore_flows () {
332     [ -x "${script_flows}" ] && \
333         action "Restoring saved flows" "${script_flows}"
334 }
335
336 restore_interfaces () {
337     [ ! -x "${script_interfaces}" ] && return 0
338     action "Restoring interface configuration" "${script_interfaces}"
339     rc=$?
340     if test $rc = 0; then
341         level=debug
342     else
343         level=err
344     fi
345     log="logger -p daemon.$level -t ovs-save"
346     $log "interface restore script exited with status $rc:"
347     $log -f "$script_interfaces"
348 }
349
350 init_restore_scripts () {
351     script_interfaces=`mktemp`
352     script_flows=`mktemp`
353     script_ofports=`mktemp`
354     trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
355 }
356
357 force_reload_kmod () {
358     ifaces=`internal_interfaces`
359     action "Detected internal interfaces: $ifaces" true
360
361     init_restore_scripts
362
363     action "Saving flows" ovs_save save-flows "${script_flows}"
364
365     save_ofports_if_required
366
367     # Restart the database first, since a large database may take a
368     # while to load, and we want to minimize forwarding disruption.
369     stop_ovsdb
370     start_ovsdb
371
372     # Restore of ofports should happen before vswitchd is restarted.
373     restore_ofports
374
375     stop_forwarding
376
377     if action "Saving interface configuration" save_interfaces; then
378         :
379     else
380         log_warning_msg "Failed to save configuration, not replacing kernel module"
381         start_forwarding
382         add_managers
383         exit 1
384     fi
385     chmod +x "$script_interfaces"
386
387     for dp in `ovs-dpctl dump-dps`; do
388         action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
389     done
390
391     # try both old and new names in case this is post upgrade
392     if test -e /sys/module/openvswitch_mod; then
393         action "Removing openvswitch module" rmmod openvswitch_mod
394     elif test -e /sys/module/openvswitch; then
395         action "Removing openvswitch module" rmmod openvswitch
396     fi
397
398     # Start vswitchd by asking it to wait till flow restore is finished.
399     flow_restore_wait
400     start_forwarding
401
402     # Restore saved flows and inform vswitchd that we are done.
403     restore_flows
404     flow_restore_complete
405     add_managers
406
407     restore_interfaces
408
409     "$datadir/scripts/ovs-check-dead-ifs"
410 }
411
412 ## ------- ##
413 ## restart ##
414 ## ------- ##
415
416 save_interfaces_if_required () {
417     # Save interfaces if we are upgrading from a pre-1.10 branch.
418     case `ovs-appctl version | sed 1q` in
419         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
420             ifaces=`internal_interfaces`
421             action "Detected internal interfaces: $ifaces" true
422             if action "Saving interface configuration" save_interfaces; then
423                 chmod +x "$script_interfaces"
424             fi
425             ;;
426     esac
427 }
428
429 restart () {
430     if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
431         init_restore_scripts
432         save_interfaces_if_required
433         action "Saving flows" ovs_save save-flows "${script_flows}"
434         save_ofports_if_required
435     fi
436
437     # Restart the database first, since a large database may take a
438     # while to load, and we want to minimize forwarding disruption.
439     stop_ovsdb
440     start_ovsdb
441
442     # Restore of ofports, if required, should happen before vswitchd is
443     # restarted.
444     restore_ofports
445
446     stop_forwarding
447
448     # Start vswitchd by asking it to wait till flow restore is finished.
449     flow_restore_wait
450     start_forwarding
451
452     # Restore saved flows and inform vswitchd that we are done.
453     restore_flows
454     flow_restore_complete
455     add_managers
456
457     # Restore the interfaces if required. Return true even if restore fails.
458     restore_interfaces || true
459 }
460
461 ## --------------- ##
462 ## enable-protocol ##
463 ## --------------- ##
464
465 enable_protocol () {
466     # Translate the protocol name to a number, because "iptables -n -L" prints
467     # some protocols by name (despite the -n) and therefore we need to look for
468     # both forms.
469     #
470     # (iptables -S output is more uniform but old iptables doesn't have it.)
471     protonum=`grep "^$PROTOCOL[         ]" /etc/protocols | awk '{print $2}'`
472     if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
473         log_failure_msg "unknown protocol $PROTOCOL"
474         return 1
475     fi
476
477     name=$PROTOCOL
478     match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
479     insert="iptables -I INPUT -p $PROTOCOL"
480     if test X"$DPORT" != X; then
481         name="$name to port $DPORT"
482         match="$match && /dpt:$DPORT/"
483         insert="$insert --dport $DPORT"
484     fi
485     if test X"$SPORT" != X; then
486         name="$name from port $SPORT"
487         match="$match && /spt:$SPORT/"
488         insert="$insert --sport $SPORT"
489     fi
490     insert="$insert -j ACCEPT"
491
492     if (iptables -n -L INPUT) >/dev/null 2>&1; then
493         if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
494         then
495             # There's already a rule for this protocol.  Don't override it.
496             log_success_msg "iptables already has a rule for $name, not explicitly enabling"
497         else
498             action "Enabling $name with iptables" $insert
499         fi
500     elif (iptables --version) >/dev/null 2>&1; then
501         action "cannot list iptables rules, not adding a rule for $name"
502     else
503         action "iptables binary not installed, not adding a rule for $name"
504     fi
505 }
506
507 ## ---- ##
508 ## main ##
509 ## ---- ##
510
511 set_defaults () {
512     SYSTEM_ID=
513
514     DELETE_BRIDGES=no
515
516     DAEMON_CWD=/
517     FORCE_COREFILES=yes
518     MLOCKALL=yes
519     OVSDB_SERVER_PRIORITY=-10
520     OVS_VSWITCHD_PRIORITY=-10
521     OVSDB_SERVER_WRAPPER=
522     OVS_VSWITCHD_WRAPPER=
523
524     DB_FILE=$dbdir/conf.db
525     DB_SOCK=$rundir/db.sock
526     DB_SCHEMA=$datadir/vswitch.ovsschema
527     EXTRA_DBS=
528
529     PROTOCOL=gre
530     DPORT=
531     SPORT=
532
533     type_file=$etcdir/system-type.conf
534     version_file=$etcdir/system-version.conf
535
536     if test -e "$type_file" ; then
537         SYSTEM_TYPE=`cat $type_file`
538         SYSTEM_VERSION=`cat $version_file`
539     elif (lsb_release --id) >/dev/null 2>&1; then
540         SYSTEM_TYPE=`lsb_release --id -s`
541         system_release=`lsb_release --release -s`
542         system_codename=`lsb_release --codename -s`
543         SYSTEM_VERSION="${system_release}-${system_codename}"
544     else
545         SYSTEM_TYPE=unknown
546         SYSTEM_VERSION=unknown
547     fi
548 }
549
550 usage () {
551     set_defaults
552     cat <<EOF
553 $0: controls Open vSwitch daemons
554 usage: $0 [OPTIONS] COMMAND
555
556 This program is intended to be invoked internally by Open vSwitch startup
557 scripts.  System administrators should not normally invoke it directly.
558
559 Commands:
560   start              start Open vSwitch daemons
561   stop               stop Open vSwitch daemons
562   restart            stop and start Open vSwitch daemons
563   status             check whether Open vSwitch daemons are running
564   version            print versions of Open vSwitch daemons
565   load-kmod          insert modules if not already present
566   force-reload-kmod  save OVS network device state, stop OVS, unload kernel
567                      module, reload kernel module, start OVS, restore state
568   enable-protocol    enable protocol specified in options with iptables
569   help               display this help message
570
571 One of the following options is required for "start", "restart" and "force-reload-kmod":
572   --system-id=UUID   set specific ID to uniquely identify this system
573   --system-id=random  use a random but persistent UUID to identify this system
574
575 Other important options for "start", "restart" and "force-reload-kmod":
576   --system-type=TYPE  set system type (e.g. "XenServer")
577   --system-version=VERSION  set system version (e.g. "5.6.100-39265p")
578   --external-id="key=value"
579                      add given key-value pair to Open_vSwitch external-ids
580   --delete-bridges   delete all bridges just before starting ovs-vswitchd
581
582 Less important options for "start", "restart" and "force-reload-kmod":
583   --daemon-cwd=DIR               set working dir for OVS daemons (default: $DAEMON_CWD)
584   --no-force-corefiles           do not force on core dumps for OVS daemons
585   --no-mlockall                  do not lock all of ovs-vswitchd into memory
586   --ovsdb-server-priority=NICE   set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
587   --ovs-vswitchd-priority=NICE   set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
588
589 Debugging options for "start", "restart" and "force-reload-kmod":
590   --ovsdb-server-wrapper=WRAPPER
591   --ovs-vswitchd-wrapper=WRAPPER
592   --ovs-vswitchd-wrapper=WRAPPER
593      run specified daemon under WRAPPER (either 'valgrind' or 'strace')
594
595 File location options:
596   --db-file=FILE     database file name (default: $DB_FILE)
597   --db-sock=SOCKET   JSON-RPC socket name (default: $DB_SOCK)
598   --db-schema=FILE   database schema file name (default: $DB_SCHEMA)
599
600 Options for "enable-protocol":
601   --protocol=PROTOCOL  protocol to enable with iptables (default: gre)
602   --sport=PORT       source port to match (for tcp or udp protocol)
603   --dport=PORT       ddestination port to match (for tcp or udp protocol)
604
605 Other options:
606   -h, --help                  display this help message
607   -V, --version               display version information
608
609 Default directories with "configure" option and environment variable override:
610   logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
611   pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
612   conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
613   system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
614   data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
615   user binaries: @bindir@ (--bindir, OVS_BINDIR)
616   system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
617
618 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
619 EOF
620
621     exit 0
622 }
623
624 set_option () {
625     var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
626     eval set=\${$var+yes}
627     eval old_value=\$$var
628     if test X$set = X || \
629         (test $type = bool && \
630         test X"$old_value" != Xno && test X"$old_value" != Xyes); then
631         echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
632         return
633     fi
634     eval $var=\$value
635 }
636
637 daemons () {
638     echo ovsdb-server ovs-vswitchd
639 }
640
641 set_defaults
642 extra_ids=
643 command=
644 for arg
645 do
646     case $arg in
647         -h | --help)
648             usage
649             ;;
650         -V | --version)
651             echo "$0 (Open vSwitch) $VERSION"
652             exit 0
653             ;;
654         --external-id=*)
655             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
656             case $value in
657                 *=*)
658                     extra_ids="$extra_ids external-ids:$value"
659                     ;;
660                 *)
661                     echo >&2 "$0: --external-id argument not in the form \"key=value\""
662                     exit 1
663                     ;;
664             esac
665             ;;
666         --[a-z]*=*)
667             option=`expr X"$arg" : 'X--\([^=]*\)'`
668             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
669             type=string
670             set_option
671             ;;
672         --no-[a-z]*)
673             option=`expr X"$arg" : 'X--no-\(.*\)'`
674             value=no
675             type=bool
676             set_option
677             ;;
678         --[a-z]*)
679             option=`expr X"$arg" : 'X--\(.*\)'`
680             value=yes
681             type=bool
682             set_option
683             ;;
684         -*)
685             echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
686             exit 1
687             ;;
688         *)
689             if test X"$command" = X; then
690                 command=$arg
691             else
692                 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
693                 exit 1
694             fi
695             ;;
696     esac
697 done
698 case $command in
699     start)
700         start_ovsdb
701         start_forwarding
702         add_managers
703         ;;
704     stop)
705         stop_forwarding
706         stop_ovsdb
707         ;;
708     restart)
709         restart
710         ;;
711     status)
712         rc=0
713         for daemon in `daemons`; do
714             daemon_status $daemon || rc=$?
715         done
716         exit $rc
717         ;;
718     version)
719         for daemon in `daemons`; do
720             $daemon --version
721         done
722         ;;
723     force-reload-kmod)
724             force_reload_kmod
725         ;;
726     load-kmod)
727         insert_mod_if_required
728         ;;
729     enable-protocol)
730         enable_protocol
731         ;;
732     help)
733         usage
734         ;;
735     '')
736         echo >&2 "$0: missing command name (use --help for help)"
737         exit 1
738         ;;
739     *)
740         echo >&2 "$0: unknown command \"$command\" (use --help for help)"
741         exit 1
742         ;;
743 esac