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