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