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