]> git.proxmox.com Git - ovs.git/blob - utilities/ovs-ctl.in
01741e755b7141ed33cea8e42baf97cbb9eb04bb
[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.sh" || 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 ovs_vsctl () {
60 ovs-vsctl --no-wait --timeout=5 "$@"
61 }
62
63 ovsdb_tool () {
64 ovsdb-tool -vANY:console:emer "$@"
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 start () {
159 if test X"$FORCE_COREFILES" = Xyes; then
160 ulimit -Sc 67108864
161 fi
162
163 insert_openvswitch_mod_if_required || return 1
164 if test X"$BRCOMPAT" = Xyes; then
165 insert_brcompat_mod_if_required || return 1
166 fi
167
168 if daemon_is_running ovsdb-server; then
169 log_success_msg "ovsdb-server is already running"
170 else
171 # Create initial database or upgrade database schema.
172 upgrade_db || return 1
173
174 # Start ovsdb-server.
175 set ovsdb-server "$DB_FILE"
176 set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
177 set "$@" --remote=punix:"$DB_SOCK"
178 set "$@" --remote=db:Open_vSwitch,manager_options
179 set "$@" --private-key=db:SSL,private_key
180 set "$@" --certificate=db:SSL,certificate
181 set "$@" --bootstrap-ca-cert=db:SSL,ca_cert
182 start_daemon "$OVSDB_SERVER_PRIORITY" "$@" || return 1
183
184 # Initialize database settings.
185 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
186 || return 1
187 set_system_ids || return 1
188 if test X"$DELETE_BRIDGES" = Xyes; then
189 for bridge in `ovs_vsctl list-br`; do
190 ovs_vsctl del-br $bridge
191 done
192 fi
193 fi
194
195 if daemon_is_running ovs-vswitchd; then
196 log_success_msg "ovs-vswitchd is already running"
197 else
198 # Increase the limit on the number of open file descriptors since
199 # ovs-vswitchd needs a few per bridge
200 ulimit -n 4096
201
202 # Start ovs-vswitchd.
203 set ovs-vswitchd unix:"$DB_SOCK"
204 set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
205 if test X"$MLOCKALL" != Xno; then
206 set "$@" --mlockall
207 fi
208 start_daemon "$OVS_VSWITCHD_PRIORITY" "$@"
209 fi
210
211 if daemon_is_running ovs-brcompatd; then
212 log_success_msg "ovs-brcompatd is already running"
213 elif test X"$BRCOMPAT" = Xyes; then
214 set ovs-brcompatd
215 set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
216 start_daemon "$OVS_BRCOMPATD_PRIORITY" "$@"
217 fi
218 }
219
220 ## ---- ##
221 ## stop ##
222 ## ---- ##
223
224 stop () {
225 stop_daemon ovs-brcompatd
226 stop_daemon ovs-vswitchd
227 stop_daemon ovsdb-server
228 }
229
230 ## ----------------- ##
231 ## force-reload-kmod ##
232 ## ----------------- ##
233
234 internal_interfaces () {
235 # Outputs a list of internal interfaces:
236 #
237 # - There is an internal interface for every bridge, whether it
238 # has an Interface record or not and whether the Interface
239 # record's 'type' is properly set or not.
240 #
241 # - There is an internal interface for each Interface record whose
242 # 'type' is 'internal'.
243 #
244 # But ignore interfaces that don't really exist.
245 for d in `(ovs_vsctl --bare \
246 -- --columns=name find Interface type=internal \
247 -- list-br) | sort -u`
248 do
249 if test -e "/sys/class/net/$d"; then
250 printf "%s " "$d"
251 fi
252 done
253 }
254
255 save_interfaces () {
256 "$datadir/scripts/ovs-save" $ifaces > "$script"
257 }
258
259 force_reload_kmod () {
260 ifaces=`internal_interfaces`
261 action "Detected internal interfaces: $ifaces" true
262
263 stop
264
265 script=`mktemp`
266 trap 'rm -f "$script"' 0 1 2 13 15
267 if action "Saving interface configuration" save_interfaces; then
268 :
269 else
270 log_warning_msg "Failed to save configuration, not replacing kernel module"
271 start
272 exit 1
273 fi
274 chmod +x "$script"
275
276 for dp in `ovs-dpctl dump-dps`; do
277 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
278 done
279
280 if test -e /sys/module/brcompat_mod; then
281 action "Removing brcompat module" rmmod brcompat_mod
282 fi
283 if test -e /sys/module/openvswitch_mod; then
284 action "Removing openvswitch module" rmmod openvswitch_mod
285 fi
286
287 start
288
289 action "Restoring interface configuration" "$script"
290 rc=$?
291 if test $rc = 0; then
292 level=debug
293 else
294 level=err
295 fi
296 log="logger -p daemon.$level -t ovs-save"
297 $log "force-reload-kmod interface restore script exited with status $rc:"
298 $log -f "$script"
299 }
300
301 ## --------------- ##
302 ## enable-protocol ##
303 ## --------------- ##
304
305 enable_protocol () {
306 # Translate the protocol name to a number, because "iptables -n -L" prints
307 # some protocols by name (despite the -n) and therefore we need to look for
308 # both forms.
309 #
310 # (iptables -S output is more uniform but old iptables doesn't have it.)
311 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
312 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
313 log_failure_msg "unknown protocol $PROTOCOL"
314 return 1
315 fi
316
317 name=$PROTOCOL
318 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
319 insert="iptables -I INPUT -p $PROTOCOL"
320 if test X"$DPORT" != X; then
321 name="$name to port $DPORT"
322 match="$match && /dpt:$DPORT/"
323 insert="$insert --dport $DPORT"
324 fi
325 if test X"$SPORT" != X; then
326 name="$name from port $SPORT"
327 match="$match && /spt:$SPORT/"
328 insert="$insert --sport $SPORT"
329 fi
330 insert="$insert -j ACCEPT"
331
332 if (iptables -n -L INPUT) >/dev/null 2>&1; then
333 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
334 then
335 # There's already a rule for this protocol. Don't override it.
336 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
337 else
338 action "Enabling $name with iptables" $insert
339 fi
340 elif (iptables --version) >/dev/null 2>&1; then
341 action "cannot list iptables rules, not adding a rule for $name"
342 else
343 action "iptables binary not installed, not adding a rule for $name"
344 fi
345 }
346
347 ## ---- ##
348 ## main ##
349 ## ---- ##
350
351 set_defaults () {
352 SYSTEM_ID=
353
354 DELETE_BRIDGES=no
355 BRCOMPAT=no
356
357 DAEMON_CWD=/
358 FORCE_COREFILES=yes
359 MLOCKALL=yes
360 OVSDB_SERVER_PRIORITY=-10
361 OVS_VSWITCHD_PRIORITY=-10
362 OVS_BRCOMPATD_PRIORITY=-10
363
364 DB_FILE=$etcdir/conf.db
365 DB_SOCK=$rundir/db.sock
366 DB_SCHEMA=$datadir/vswitch.ovsschema
367
368 PROTOCOL=gre
369 DPORT=
370 SPORT=
371
372 if (lsb_release --id) >/dev/null 2>&1; then
373 SYSTEM_TYPE=`lsb_release --id -s`
374 system_release=`lsb_release --release -s`
375 system_codename=`lsb_release --codename -s`
376 SYSTEM_VERSION="${system_release}-${system_codename}"
377 else
378 SYSTEM_TYPE=unknown
379 SYSTEM_VERSION=unknown
380 fi
381 }
382
383 usage () {
384 set_defaults
385 cat <<EOF
386 $0: controls Open vSwitch daemons
387 usage: $0 [OPTIONS] COMMAND
388
389 This program is intended to be invoked internally by Open vSwitch startup
390 scripts. System administrators should not normally invoke it directly.
391
392 Commands:
393 start start Open vSwitch daemons
394 stop stop Open vSwitch daemons
395 status check whether Open vSwitch daemons are running
396 version print versions of Open vSwitch daemons
397 force-reload-kmod save OVS network device state, stop OVS, unload kernel
398 module, reload kernel module, start OVS, restore state
399 enable-protocol enable protocol specified in options with iptables
400 help display this help message
401
402 One of the following options is required for "start" and "force-reload-kmod":
403 --system-id=UUID set specific ID to uniquely identify this system
404 --system-id=random use a random but persistent UUID to identify this system
405
406 Other important options for "start" and "force-reload-kmod":
407 --system-type=TYPE set system type (e.g. "XenServer")
408 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
409 --external-id="key=value"
410 add given key-value pair to Open_vSwitch external-ids
411 --delete-bridges delete all bridges just before starting ovs-vswitchd
412
413 Less important options for "start" and "force-reload-kmod":
414 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
415 --no-force-corefiles do not force on core dumps for OVS daemons
416 --no-mlockall do not lock all of ovs-vswitchd into memory
417 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
418 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
419 --ovs-brcompatd-priority=NICE set ovs-brcompatd's niceness (default: $OVS_BRCOMPATD_PRIORITY)
420
421 Options for "start", "force-reload-kmod", "status", and "version":
422 --brcompat enable Linux bridge compatibility module and daemon
423
424 File location options:
425 --db-file=FILE database file name (default: $DB_FILE)
426 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
427 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
428
429 Options for "enable-protocol":
430 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
431 --sport=PORT source port to match (for tcp or udp protocol)
432 --dport=PORT ddestination port to match (for tcp or udp protocol)
433
434 Other options:
435 -h, --help display this help message
436 -V, --version display version information
437
438 Default directories with "configure" option and environment variable override:
439 logs: @LOGDIR@ (--log-dir, OVS_LOGDIR)
440 pidfiles and sockets: @RUNDIR@ (--run-dir, OVS_RUNDIR)
441 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
442 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
443 user binaries: @bindir@ (--bindir, OVS_BINDIR)
444 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
445
446 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
447 EOF
448
449 exit 0
450 }
451
452 set_option () {
453 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
454 eval set=\${$var+yes}
455 eval old_value=\$$var
456 if test X$set = X || \
457 (test $type = bool && \
458 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
459 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
460 return
461 fi
462 eval $var=\$value
463 }
464
465 daemons () {
466 echo ovsdb-server ovs-vswitchd
467 if test X"$BRCOMPAT" = Xyes; then
468 echo ovs-brcompatd
469 fi
470 }
471
472 set_defaults
473 extra_ids=
474 command=
475 for arg
476 do
477 case $arg in
478 -h | --help)
479 usage
480 ;;
481 -V | --version)
482 echo "$0 (Open vSwitch) $VERSION$BUILDNR"
483 exit 0
484 ;;
485 --external-id=*)
486 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
487 case $value in
488 *=*)
489 extra_ids="$extra_ids external-ids:$value"
490 ;;
491 *)
492 echo >&2 "$0: --external-id argument not in the form \"key=value\""
493 exit 1
494 ;;
495 esac
496 ;;
497 --[a-z]*=*)
498 option=`expr X"$arg" : 'X--\([^=]*\)'`
499 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
500 type=string
501 set_option
502 ;;
503 --no-[a-z]*)
504 option=`expr X"$arg" : 'X--no-\(.*\)'`
505 value=no
506 type=bool
507 set_option
508 ;;
509 --[a-z]*)
510 option=`expr X"$arg" : 'X--\(.*\)'`
511 value=yes
512 type=bool
513 set_option
514 ;;
515 -*)
516 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
517 exit 1
518 ;;
519 *)
520 if test X"$command" = X; then
521 command=$arg
522 else
523 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
524 exit 1
525 fi
526 ;;
527 esac
528 done
529 case $command in
530 start)
531 start
532 ;;
533 stop)
534 stop
535 ;;
536 status)
537 rc=0
538 for daemon in `daemons`; do
539 daemon_status $daemon || rc=$?
540 done
541 exit $rc
542 ;;
543 version)
544 for daemon in `daemons`; do
545 $daemon --version
546 done
547 ;;
548 force-reload-kmod)
549 force_reload_kmod
550 ;;
551 enable-protocol)
552 enable_protocol
553 ;;
554 help)
555 usage
556 ;;
557 '')
558 echo >&2 "$0: missing command name (use --help for help)"
559 exit 1
560 ;;
561 *)
562 echo >&2 "$0: unknown command \"$command\" (use --help for help)"
563 exit 1
564 ;;
565 esac
566