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