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