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