]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-ctl.in
ovs-ctl.in: Don't save kernel datapath config.
[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_flows () {
297 if set X `ovs_vsctl list-br`; then
298 shift
299 if "$datadir/scripts/ovs-save" save-flows "$@" > "$script_flows"; then
300 chmod +x "$script_flows"
301 return 0
302 fi
303 fi
304 script_flows=
305 return 1
306 }
307
308 save_interfaces () {
309 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
310 > "${script_interfaces}"
311 }
312
313 restore_flows () {
314 [ -n "${script_flows}" ] && \
315 action "Restoring saved flows" "${script_flows}"
316 }
317
318 force_reload_kmod () {
319 ifaces=`internal_interfaces`
320 action "Detected internal interfaces: $ifaces" true
321
322 script_interfaces=`mktemp`
323 script_flows=`mktemp`
324 trap 'rm -f "${script_interfaces}" "${script_flows}" ' 0 1 2 13 15
325
326 action "Saving flows" save_flows
327
328 # Restart the database first, since a large database may take a
329 # while to load, and we want to minimize forwarding disruption.
330 stop_ovsdb
331 start_ovsdb
332
333 stop_forwarding
334
335 if action "Saving interface configuration" save_interfaces; then
336 :
337 else
338 log_warning_msg "Failed to save configuration, not replacing kernel module"
339 start_forwarding
340 exit 1
341 fi
342 chmod +x "$script_interfaces"
343
344 for dp in `ovs-dpctl dump-dps`; do
345 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
346 done
347
348 # try both old and new names in case this is post upgrade
349 if test -e /sys/module/brcompat_mod; then
350 action "Removing brcompat module" rmmod brcompat_mod
351 elif test -e /sys/module/brcompat; then
352 action "Removing brcompat module" rmmod brcompat
353 fi
354 if test -e /sys/module/openvswitch_mod; then
355 action "Removing openvswitch module" rmmod openvswitch_mod
356 elif test -e /sys/module/openvswitch; then
357 action "Removing openvswitch module" rmmod openvswitch
358 fi
359
360 start_forwarding
361
362 restore_flows
363
364 action "Restoring interface configuration" "$script_interfaces"
365 rc=$?
366 if test $rc = 0; then
367 level=debug
368 else
369 level=err
370 fi
371 log="logger -p daemon.$level -t ovs-save"
372 $log "force-reload-kmod interface restore script exited with status $rc:"
373 $log -f "$script_interfaces"
374
375 "$datadir/scripts/ovs-check-dead-ifs"
376 }
377
378 ## ------- ##
379 ## restart ##
380 ## ------- ##
381
382 restart () {
383 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
384 script_flows=`mktemp`
385 trap 'rm -f "${script_flows}"' 0 1 2 13 15
386
387 action "Saving flows" save_flows
388 fi
389
390 # Restart the database first, since a large database may take a
391 # while to load, and we want to minimize forwarding disruption.
392 stop_ovsdb
393 start_ovsdb
394
395 stop_forwarding
396 start_forwarding
397
398 # Restore the saved flows. Do not return error if restore fails.
399 restore_flows || true
400 }
401
402 ## --------------- ##
403 ## enable-protocol ##
404 ## --------------- ##
405
406 enable_protocol () {
407 # Translate the protocol name to a number, because "iptables -n -L" prints
408 # some protocols by name (despite the -n) and therefore we need to look for
409 # both forms.
410 #
411 # (iptables -S output is more uniform but old iptables doesn't have it.)
412 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
413 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
414 log_failure_msg "unknown protocol $PROTOCOL"
415 return 1
416 fi
417
418 name=$PROTOCOL
419 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
420 insert="iptables -I INPUT -p $PROTOCOL"
421 if test X"$DPORT" != X; then
422 name="$name to port $DPORT"
423 match="$match && /dpt:$DPORT/"
424 insert="$insert --dport $DPORT"
425 fi
426 if test X"$SPORT" != X; then
427 name="$name from port $SPORT"
428 match="$match && /spt:$SPORT/"
429 insert="$insert --sport $SPORT"
430 fi
431 insert="$insert -j ACCEPT"
432
433 if (iptables -n -L INPUT) >/dev/null 2>&1; then
434 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
435 then
436 # There's already a rule for this protocol. Don't override it.
437 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
438 else
439 action "Enabling $name with iptables" $insert
440 fi
441 elif (iptables --version) >/dev/null 2>&1; then
442 action "cannot list iptables rules, not adding a rule for $name"
443 else
444 action "iptables binary not installed, not adding a rule for $name"
445 fi
446 }
447
448 ## ---- ##
449 ## main ##
450 ## ---- ##
451
452 set_defaults () {
453 SYSTEM_ID=
454
455 DELETE_BRIDGES=no
456 BRCOMPAT=no
457
458 DAEMON_CWD=/
459 FORCE_COREFILES=yes
460 MLOCKALL=yes
461 OVSDB_SERVER_PRIORITY=-10
462 OVS_VSWITCHD_PRIORITY=-10
463 OVS_BRCOMPATD_PRIORITY=-10
464 OVSDB_SERVER_WRAPPER=
465 OVS_VSWITCHD_WRAPPER=
466 OVS_BRCOMPATD_WRAPPER=
467
468 DB_FILE=$dbdir/conf.db
469 DB_SOCK=$rundir/db.sock
470 DB_SCHEMA=$datadir/vswitch.ovsschema
471 EXTRA_DBS=
472
473 PROTOCOL=gre
474 DPORT=
475 SPORT=
476
477 type_file=$etcdir/system-type.conf
478 version_file=$etcdir/system-version.conf
479
480 if test -e "$type_file" ; then
481 SYSTEM_TYPE=`cat $type_file`
482 SYSTEM_VERSION=`cat $version_file`
483 elif (lsb_release --id) >/dev/null 2>&1; then
484 SYSTEM_TYPE=`lsb_release --id -s`
485 system_release=`lsb_release --release -s`
486 system_codename=`lsb_release --codename -s`
487 SYSTEM_VERSION="${system_release}-${system_codename}"
488 else
489 SYSTEM_TYPE=unknown
490 SYSTEM_VERSION=unknown
491 fi
492 }
493
494 usage () {
495 set_defaults
496 cat <<EOF
497 $0: controls Open vSwitch daemons
498 usage: $0 [OPTIONS] COMMAND
499
500 This program is intended to be invoked internally by Open vSwitch startup
501 scripts. System administrators should not normally invoke it directly.
502
503 Commands:
504 start start Open vSwitch daemons
505 stop stop Open vSwitch daemons
506 restart stop and start Open vSwitch daemons
507 status check whether Open vSwitch daemons are running
508 version print versions of Open vSwitch daemons
509 load-kmod insert modules if not already present
510 force-reload-kmod save OVS network device state, stop OVS, unload kernel
511 module, reload kernel module, start OVS, restore state
512 enable-protocol enable protocol specified in options with iptables
513 help display this help message
514
515 One of the following options is required for "start", "restart" and "force-reload-kmod":
516 --system-id=UUID set specific ID to uniquely identify this system
517 --system-id=random use a random but persistent UUID to identify this system
518
519 Other important options for "start", "restart" and "force-reload-kmod":
520 --system-type=TYPE set system type (e.g. "XenServer")
521 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
522 --external-id="key=value"
523 add given key-value pair to Open_vSwitch external-ids
524 --delete-bridges delete all bridges just before starting ovs-vswitchd
525
526 Less important options for "start", "restart" and "force-reload-kmod":
527 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
528 --no-force-corefiles do not force on core dumps for OVS daemons
529 --no-mlockall do not lock all of ovs-vswitchd into memory
530 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
531 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
532 --ovs-brcompatd-priority=NICE set ovs-brcompatd's niceness (default: $OVS_BRCOMPATD_PRIORITY)
533
534 Debugging options for "start", "restart" and "force-reload-kmod":
535 --ovsdb-server-wrapper=WRAPPER
536 --ovs-vswitchd-wrapper=WRAPPER
537 --ovs-vswitchd-wrapper=WRAPPER
538 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
539
540 Options for "start", "restart", "force-reload-kmod", "load-kmod", "status", and "version":
541 --brcompat enable Linux bridge compatibility module and daemon
542
543 File location options:
544 --db-file=FILE database file name (default: $DB_FILE)
545 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
546 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
547
548 Options for "enable-protocol":
549 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
550 --sport=PORT source port to match (for tcp or udp protocol)
551 --dport=PORT ddestination port to match (for tcp or udp protocol)
552
553 Other options:
554 -h, --help display this help message
555 -V, --version display version information
556
557 Default directories with "configure" option and environment variable override:
558 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
559 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
560 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
561 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
562 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
563 user binaries: @bindir@ (--bindir, OVS_BINDIR)
564 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
565
566 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
567 EOF
568
569 exit 0
570 }
571
572 set_option () {
573 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
574 eval set=\${$var+yes}
575 eval old_value=\$$var
576 if test X$set = X || \
577 (test $type = bool && \
578 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
579 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
580 return
581 fi
582 eval $var=\$value
583 }
584
585 daemons () {
586 echo ovsdb-server ovs-vswitchd
587 if test X"$BRCOMPAT" = Xyes; then
588 echo ovs-brcompatd
589 fi
590 }
591
592 set_defaults
593 extra_ids=
594 command=
595 for arg
596 do
597 case $arg in
598 -h | --help)
599 usage
600 ;;
601 -V | --version)
602 echo "$0 (Open vSwitch) $VERSION"
603 exit 0
604 ;;
605 --external-id=*)
606 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
607 case $value in
608 *=*)
609 extra_ids="$extra_ids external-ids:$value"
610 ;;
611 *)
612 echo >&2 "$0: --external-id argument not in the form \"key=value\""
613 exit 1
614 ;;
615 esac
616 ;;
617 --[a-z]*=*)
618 option=`expr X"$arg" : 'X--\([^=]*\)'`
619 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
620 type=string
621 set_option
622 ;;
623 --no-[a-z]*)
624 option=`expr X"$arg" : 'X--no-\(.*\)'`
625 value=no
626 type=bool
627 set_option
628 ;;
629 --[a-z]*)
630 option=`expr X"$arg" : 'X--\(.*\)'`
631 value=yes
632 type=bool
633 set_option
634 ;;
635 -*)
636 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
637 exit 1
638 ;;
639 *)
640 if test X"$command" = X; then
641 command=$arg
642 else
643 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
644 exit 1
645 fi
646 ;;
647 esac
648 done
649 case $command in
650 start)
651 start_ovsdb
652 start_forwarding
653 ;;
654 stop)
655 stop_forwarding
656 stop_ovsdb
657 ;;
658 restart)
659 restart
660 ;;
661 status)
662 rc=0
663 for daemon in `daemons`; do
664 daemon_status $daemon || rc=$?
665 done
666 exit $rc
667 ;;
668 version)
669 for daemon in `daemons`; do
670 $daemon --version
671 done
672 ;;
673 force-reload-kmod)
674 force_reload_kmod
675 ;;
676 load-kmod)
677 insert_mod_if_required
678 ;;
679 enable-protocol)
680 enable_protocol
681 ;;
682 help)
683 usage
684 ;;
685 '')
686 echo >&2 "$0: missing command name (use --help for help)"
687 exit 1
688 ;;
689 *)
690 echo >&2 "$0: unknown command \"$command\" (use --help for help)"
691 exit 1
692 ;;
693 esac