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