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