a127149a0e668f930bab5278ec848d1ec9cf9514
[sliver-openvswitch.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     if action "Save interface configuration to $script" save_interfaces; then
237         :
238     else
239         log_warning_msg "Failed to save configuration, not replacing kernel module"
240         start
241         exit 1
242     fi
243     chmod +x "$script"
244
245     for dp in `ovs-dpctl dump-dps`; do
246         action "Removing datapath: $dp" "$dpctl" del-dp "$dp"
247     done
248
249     if test -e /sys/module/openvswitch_mod; then
250         action "Removing openvswitch module" rmmod openvswitch_mod
251     fi
252
253     start
254
255     action "Restore interface configuration from $script" "$script"
256 }
257
258 ## ---- ##
259 ## main ##
260 ## ---- ##
261
262 set_defaults () {
263     SYSTEM_ID=
264
265     DELETE_BRIDGES=no
266
267     DAEMON_CWD=/
268     FORCE_COREFILES=yes
269     MLOCKALL=yes
270     OVSDB_SERVER_PRIORITY=-10
271     OVS_VSWITCHD_PRIORITY=-10
272
273     DB_FILE=$etcdir/conf.db
274     DB_SOCK=$rundir/db.sock
275     DB_SCHEMA=$datadir/vswitch.ovsschema
276
277     if (lsb_release --id) >/dev/null 2>&1; then
278         SYSTEM_TYPE=`lsb_release --id -s`
279         system_release=`lsb_release --release -s`
280         system_codename=`lsb_release --codename -s`
281         SYSTEM_VERSION="${system_release}-${system_codename}"
282     else
283         SYSTEM_TYPE=unknown
284         SYSTEM_VERSION=unknown
285     fi
286 }
287
288 usage () {
289     set_defaults
290     cat <<EOF
291 $0: controls Open vSwitch daemons
292 usage: $0 [OPTIONS] COMMAND
293
294 This program is intended to be invoked internally by Open vSwitch startup
295 scripts.  System administrators should not normally invoke it directly.
296
297 Commands:
298   start              start Open vSwitch daemons
299   stop               stop Open vSwitch daemons
300   status             check whether Open vSwitch daemons are running
301   version            print versions of Open vSwitch daemons
302   force-reload-kmod  save OVS network device state, stop OVS, unload kernel
303                      module, reload kernel module, start OVS, restore state
304   help               display this help message
305
306 One of the following options should be specified when starting Open vSwitch:
307   --system-id=UUID   set specific ID to uniquely identify this system
308   --system-id=random  use a random but persistent UUID to identify this system
309
310 Other important options for starting Open vSwitch:
311   --system-type=TYPE  set system type (e.g. "XenServer")
312   --system-version=VERSION  set system version (e.g. "5.6.100-39265p")
313   --external-id="key=value"
314                      add given key-value pair to Open_vSwitch external-ids
315   --delete-bridges   delete all bridges just before starting ovs-vswitchd
316
317 Less important options for starting Open vSwitch:
318   --daemon-cwd=DIR   current working directory for OVS daemons (default: $DAEMON_CWD)
319   --no-force-corefiles
320                      do not forcibly enable core dumps for OVS daemons
321   --no-mlockall      do not lock all of ovs-vswitchd into memory
322   --ovsdb-server-priority=NICE
323                      set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
324   --ovs-vswitchd-priority=NICE
325                      set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
326
327 File location options:
328   --db-file=FILE     database file name (default: $DB_FILE)
329   --db-sock=SOCKET   JSON-RPC socket name (default: $DB_SOCK)
330   --db-schema=FILE   database schema file name (default: $DB_SCHEMA)
331
332 Other options:
333   -h, --help                  display this help message
334   -V, --version               display version information
335
336 Default directories with "configure" option and environment variable override:
337   logs: @LOGDIR@ (--log-dir, OVS_LOGDIR)
338   pidfiles and sockets: @RUNDIR@ (--run-dir, OVS_RUNDIR)
339   system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
340   data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
341   user binaries: @bindir@ (--bindir, OVS_BINDIR)
342   system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
343
344 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
345 EOF
346
347     exit 0
348 }
349
350 set_option () {
351     var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
352     eval set=\${$var+yes}
353     eval old_value=\$$var
354     if test X$set = X || \
355         (test $type = bool && \
356         test X"$old_value" != Xno && test X"$old_value" != Xyes); then
357         echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
358         return
359     fi
360     eval $var=\$value
361 }
362
363 set_defaults
364 extra_ids=
365 command=
366 for arg
367 do
368     case $arg in
369         -h | --help)
370             usage
371             ;;
372         -V | --version)
373             echo "$0 (Open vSwitch) $VERSION$BUILDNR"
374             exit 0
375             ;;
376         --external-id=*)
377             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
378             case $value in
379                 *=*)
380                     extra_ids="$extra_ids external-ids:$value"
381                     ;;
382                 *)
383                     echo >&2 "$0: --external-id argument not in the form \"key=value\""
384                     exit 1
385                     ;;
386             esac
387             ;;
388         --[a-z]*=*)
389             option=`expr X"$arg" : 'X--\([^=]*\)'`
390             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
391             type=string
392             set_option
393             ;;
394         --no-[a-z]*)
395             option=`expr X"$arg" : 'X--no-\(.*\)'`
396             value=no
397             type=bool
398             set_option
399             ;;
400         --[a-z]*)
401             option=`expr X"$arg" : 'X--\(.*\)'`
402             value=yes
403             type=bool
404             set_option
405             ;;
406         -*)
407             echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
408             exit 1
409             ;;
410         *)
411             if test X"$command" = X; then
412                 command=$arg
413             else
414                 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
415                 exit 1
416             fi
417             ;;
418     esac
419 done
420 case $command in
421     start)
422         start
423         ;;
424     stop)
425         stop
426         ;;
427     status)
428         daemon_status ovsdb-server && daemon_status ovs-vswitchd
429         ;;
430     version)
431         ovsdb-server --version && ovs-vswitchd --version
432         ;;
433     force-reload-kmod)
434         force_reload_kmod
435         ;;
436     help)
437         usage
438         ;;
439     '')
440         echo >&2 "$0: missing command name (use --help for help)"
441         exit 1
442         ;;
443     *)
444         echo >&2 "$0: unknown command \"$command\" (use --help for help)"
445         exit 1
446         ;;
447 esac
448