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