[ovs-dev] [PATCH 1/4] ovs-kmod-ctl: introduce a kernel module load script
Ansis Atteka
ansisatteka at gmail.com
Mon Mar 26 21:23:51 UTC 2018
On 20 March 2018 at 14:05, Aaron Conole <aconole at redhat.com> wrote:
> Currently, Open vSwitch on linux embeds the logic of loading and unloading
> kernel modules into the ovs-ctl and ovs-lib script files. This works, but
> it means that there is no way to leverage extended filesystem attributes
> to grant fine grain permissions relating to module loading.
>
> The split out utility 'ovs-kmod-ctl' will be used in an upcoming commit
> for RHEL-based distributions to have a separate transition domain that
> will allow module loading to be given to a separate selinux domain from
> the openvswitch_t domain.
>
> Signed-off-by: Aaron Conole <aconole at redhat.com>
> ---
> debian/openvswitch-switch.install | 1 +
> debian/openvswitch-switch.manpages | 1 +
> rhel/openvswitch-fedora.spec.in | 2 +
> rhel/openvswitch.spec.in | 2 +
> utilities/.gitignore | 1 +
> utilities/automake.mk | 5 +
> utilities/ovs-ctl.in | 32 +-----
> utilities/ovs-kmod-ctl.8 | 103 +++++++++++++++++
> utilities/ovs-kmod-ctl.in | 228 +++++++++++++++++++++++++++++++++++++
> utilities/ovs-lib.in | 12 +-
> 10 files changed, 350 insertions(+), 37 deletions(-)
> create mode 100644 utilities/ovs-kmod-ctl.8
> create mode 100644 utilities/ovs-kmod-ctl.in
>
> diff --git a/debian/openvswitch-switch.install b/debian/openvswitch-switch.install
> index bfb391fe8..6a6e9a543 100644
> --- a/debian/openvswitch-switch.install
> +++ b/debian/openvswitch-switch.install
> @@ -12,5 +12,6 @@ usr/sbin/ovs-vswitchd
> usr/sbin/ovsdb-server
> usr/share/openvswitch/scripts/ovs-check-dead-ifs
> usr/share/openvswitch/scripts/ovs-ctl
> +usr/share/openvswitch/scripts/ovs-kmod-ctl
> usr/share/openvswitch/scripts/ovs-save
> usr/share/openvswitch/vswitch.ovsschema
> diff --git a/debian/openvswitch-switch.manpages b/debian/openvswitch-switch.manpages
> index a2f661a3e..47a1ba174 100644
> --- a/debian/openvswitch-switch.manpages
> +++ b/debian/openvswitch-switch.manpages
> @@ -2,6 +2,7 @@ ovsdb/ovsdb-server.1
> utilities/ovs-ctl.8
> utilities/ovs-dpctl-top.8
> utilities/ovs-dpctl.8
> +utilities/ovs-kmod-ctl.8
> utilities/ovs-pcap.1
> utilities/ovs-tcpdump.8
> utilities/ovs-tcpundump.1
> diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in
> index 8a804942b..8fbc985ce 100644
> --- a/rhel/openvswitch-fedora.spec.in
> +++ b/rhel/openvswitch-fedora.spec.in
> @@ -542,6 +542,7 @@ fi
> %{_datadir}/openvswitch/scripts/ovs-save
> %{_datadir}/openvswitch/scripts/ovs-vtep
> %{_datadir}/openvswitch/scripts/ovs-ctl
> +%{_datadir}/openvswitch/scripts/ovs-kmod-ctl
> %{_datadir}/openvswitch/scripts/ovs-systemd-reload
> %config %{_datadir}/openvswitch/vswitch.ovsschema
> %config %{_datadir}/openvswitch/vtep.ovsschema
> @@ -574,6 +575,7 @@ fi
> %{_mandir}/man8/ovs-ctl.8*
> %{_mandir}/man8/ovs-dpctl.8*
> %{_mandir}/man8/ovs-dpctl-top.8*
> +%{_mandir}/man8/ovs-kmod-ctl.8*
> %{_mandir}/man8/ovs-ofctl.8*
> %{_mandir}/man8/ovs-pki.8*
> %{_mandir}/man8/ovs-vsctl.8*
> diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in
> index 876990698..71d5afbdb 100644
> --- a/rhel/openvswitch.spec.in
> +++ b/rhel/openvswitch.spec.in
> @@ -236,6 +236,7 @@ exit 0
> /usr/share/man/man8/ovs-ctl.8.gz
> /usr/share/man/man8/ovs-dpctl.8.gz
> /usr/share/man/man8/ovs-dpctl-top.8.gz
> +/usr/share/man/man8/ovs-kmod-ctl.8.gz
> /usr/share/man/man8/ovs-ofctl.8.gz
> /usr/share/man/man8/ovs-parse-backtrace.8.gz
> /usr/share/man/man8/ovs-pki.8.gz
> @@ -249,6 +250,7 @@ exit 0
> /usr/share/openvswitch/scripts/ovs-bugtool-*
> /usr/share/openvswitch/scripts/ovs-check-dead-ifs
> /usr/share/openvswitch/scripts/ovs-ctl
> +/usr/share/openvswitch/scripts/ovs-kmod-ctl
> /usr/share/openvswitch/scripts/ovs-lib
> /usr/share/openvswitch/scripts/ovs-save
> /usr/share/openvswitch/scripts/ovs-vtep
> diff --git a/utilities/.gitignore b/utilities/.gitignore
> index 34c58f20f..eb2a69bf3 100644
> --- a/utilities/.gitignore
> +++ b/utilities/.gitignore
> @@ -13,6 +13,7 @@
> /ovs-dpctl.8
> /ovs-dpctl-top
> /ovs-dpctl-top.8
> +/ovs-kmod-ctl
> /ovs-l3ping
> /ovs-l3ping.8
> /ovs-lib
> diff --git a/utilities/automake.mk b/utilities/automake.mk
> index 60cf1c5ed..d8f2374a3 100644
> --- a/utilities/automake.mk
> +++ b/utilities/automake.mk
> @@ -20,6 +20,7 @@ endif
> scripts_SCRIPTS += \
> utilities/ovs-check-dead-ifs \
> utilities/ovs-ctl \
> + utilities/ovs-kmod-ctl \
> utilities/ovs-save
> scripts_DATA += utilities/ovs-lib
>
> @@ -44,6 +45,7 @@ EXTRA_DIST += \
> utilities/ovs-dev.py \
> utilities/ovs-docker \
> utilities/ovs-dpctl-top.in \
> + utilities/ovs-kmod-ctl.in \
> utilities/ovs-l3ping.in \
> utilities/ovs-lib.in \
> utilities/ovs-parse-backtrace.in \
> @@ -63,6 +65,7 @@ MAN_ROOTS += \
> utilities/ovs-ctl.8 \
> utilities/ovs-dpctl.8.in \
> utilities/ovs-dpctl-top.8.in \
> + utilities/ovs-kmod-ctl.8 \
> utilities/ovs-l3ping.8.in \
> utilities/ovs-ofctl.8.in \
> utilities/ovs-parse-backtrace.8 \
> @@ -81,6 +84,7 @@ CLEANFILES += \
> utilities/ovs-dpctl.8 \
> utilities/ovs-dpctl-top \
> utilities/ovs-dpctl-top.8 \
> + utilities/ovs-kmod-ctl \
> utilities/ovs-l3ping \
> utilities/ovs-l3ping.8 \
> utilities/ovs-lib \
> @@ -107,6 +111,7 @@ man_MANS += \
> utilities/ovs-testcontroller.8 \
> utilities/ovs-dpctl.8 \
> utilities/ovs-dpctl-top.8 \
> + utilities/ovs-kmod-ctl.8 \
> utilities/ovs-l3ping.8 \
> utilities/ovs-ofctl.8 \
> utilities/ovs-parse-backtrace.8 \
> diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in
> index ef06dd967..8fdf8909a 100755
> --- a/utilities/ovs-ctl.in
> +++ b/utilities/ovs-ctl.in
> @@ -30,37 +30,9 @@ done
> ## start ##
> ## ----- ##
>
> -insert_mods () {
> - # Try loading openvswitch again.
> - action "Inserting openvswitch module" modprobe openvswitch
> -}
> -
> insert_mod_if_required () {
> - # If this kernel has no module support, expect we're done.
> - if test ! -e /proc/modules
> - then
> - log_success_msg "Kernel has no loadable module support. Skipping modprobe"
> - return 0
> - fi
> -
> - # If openvswitch is already loaded then we're done.
> - test -e /sys/module/openvswitch && return 0
> -
> - # Load openvswitch. If that's successful then we're done.
> - insert_mods && return 0
> -
> - # If the bridge module is loaded, then that might be blocking
> - # openvswitch. Try to unload it, if there are no bridges.
> - test -e /sys/module/bridge || return 1
> - bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
> - if test "$bridges" != "*"; then
> - log_warning_msg "not removing bridge module because bridges exist ($bridges)"
> - return 1
> - fi
> - action "removing bridge module" rmmod bridge || return 1
> -
> - # Try loading openvswitch again.
> - insert_mods
> + ## This takes care of inserting any required kernel modules
> + ovs_kmod_ctl insert
> }
>
> set_hostname () {
> diff --git a/utilities/ovs-kmod-ctl.8 b/utilities/ovs-kmod-ctl.8
> new file mode 100644
> index 000000000..bc09a8a74
> --- /dev/null
> +++ b/utilities/ovs-kmod-ctl.8
> @@ -0,0 +1,103 @@
> +.\" -*- nroff -*-
> +.de IQ
> +. br
> +. ns
> +. IP "\\$1"
> +..
> +.de ST
> +. PP
> +. RS -0.15in
> +. I "\\$1"
> +. RE
> +..
> +.TH ovs\-ctl 8 "February 2018" "Open vSwitch" "Open vSwitch Manual"
> +.ds PN ovs\-ctl
> +.
> +.SH NAME
> +ovs\-kmod\-ctl \- OVS startup helper script for loading kernel modules
> +.
> +.SH SYNOPSIS
> +\fBovs\-kmod\-ctl\fR \fBinsert
> +.br
> +\fBovs\-kmod\-ctl \fBremove
> +.br
> +\fBovs\-ctl help \fR| \fB\-h \fR| \fB\-\-help
> +.br
> +\fBovs\-ctl \-\-version
Why ovs-ctl in above lines? Copy paste error?
> +.br
> +\fBovs\-kmod\-ctl version
> +.
> +.SH DESCRIPTION
> +.
> +.PP
> +The \fBovs\-kmod\-ctl\fR program is responsible for inserting and
> +remove Open vSwitch kernel modules. It is not meant to be invoked
s/remove/removing ?
> +directly by system administrators but to be called internally by
missing comma before but.
> +system startup scripts.
I would add rationale in the man page that this script is used to
leverage SElinux domain transitions. So that admins would not wonder.
> +.
> +.PP
> +Each of \fBovs\-ctl\fR's commands is described separately below.
> +.
> +.SH "The ``insert'' command"
> +.
> +.PP
> +The \fBinsert\fR command loads the Open vSwitch kernel modules, if
> +needed. If this fails, and the Linux bridge module is loaded but no
> +bridges exist, it tries to unload the bridge module and tries loading
> +the Open vSwitch kernel module again. (This is because the Open
> +vSwitch kernel module cannot coexist with the Linux bridge module
> +before 2.6.37.)
FYI: I believe latest Open vSwitch does not support kernels older than 3.10:
AC_ERROR([Linux kernel in $KBUILD is version $kversion, but
version 3.10 or later is required])
> +.
> +.SH "The ``remove'' command"
> +.
> +.PP
> +The \fBremove\fR command unloads the Open vSwitch kernel module (including
> +the bridge compatibility module, if loaded) and any associated vport
> +modules.
> +.
> +.SH "EXIT STATUS"
> +.
> +\fBovs\-kmod\-ctl\fR exits with status 0 on success and nonzero on
> +failure. The \fBinsert\fR command is considered to succeed if kernel
> +modules are already loaded; the \fBremove\fR command is considered to
> +succeed if none of the kernel modules are loaded.
> +.
> +.SH "ENVIRONMENT"
> +.
> +The following environment variables affect \fBovs\-kmod\-ctl\fR:
> +.
> +.IP "\fBPATH\fR"
> +\fBovs\-kmod\-ctl\fR does not hardcode the location of any of the programs
> +that it runs. \fBovs\-kmod\-ctl\fR will add the \fIsbindir\fR and
> +\fIbindir\fR that were specified at \fBconfigure\fR time to
> +\fBPATH\fR, if they are not already present.
> +.
> +.IP "\fBOVS_LOGDIR\fR"
> +.IQ "\fBOVS_RUNDIR\fR"
> +.IQ "\fBOVS_DBDIR\fR"
> +.IQ "\fBOVS_SYSCONFDIR\fR"
> +.IQ "\fBOVS_PKGDATADIR\fR"
> +.IQ "\fBOVS_BINDIR\fR"
> +.IQ "\fBOVS_SBINDIR\fR"
> +Setting one of these variables in the environment overrides the
> +respective \fBconfigure\fR option, both for \fBovs\-kmod\-ctl\fR itself
> +and for the other Open vSwitch programs that it runs.
> +.
> +.SH "FILES"
> +.
> +\fBovs\-kmod\-ctl\fR uses the following files:
> +.
> +.IP "\fBovs\-lib"
> +Shell function library used internally by \fBovs\-kmod\-ctl\fR. It must
> +be installed in the same directory as \fBovs\-kmod\-ctl\fR.
> +.
> +.SH "EXAMPLE"
> +.
> +.PP
> +The files \fBdebian/openvswitch\-switch.init\fR and
> +\fBxenserver/etc_init.d_openvswitch\fR in the Open vSwitch source
> +distribution are good examples of how to use \fBovs\-ctl\fR.
> +.
> +.SH "SEE ALSO"
> +.
> +\fBREADME.rst\fR, \fBovs\-ctl\fR(8)
> diff --git a/utilities/ovs-kmod-ctl.in b/utilities/ovs-kmod-ctl.in
> new file mode 100644
> index 000000000..b85f6cd04
> --- /dev/null
> +++ b/utilities/ovs-kmod-ctl.in
> @@ -0,0 +1,228 @@
> +#! /bin/sh
> +# Copyright (C) 2018 Red Hat, Inc.
> +#
> +# Licensed under the Apache License, Version 2.0 (the "License");
> +# you may not use this file except in compliance with the License.
> +# You may obtain a copy of the License at:
> +#
> +# http://www.apache.org/licenses/LICENSE-2.0
> +#
> +# Unless required by applicable law or agreed to in writing, software
> +# distributed under the License is distributed on an "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> +# See the License for the specific language governing permissions and
> +# limitations under the License.
> +
> +case $0 in
> + */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
> + *) dir0=./ ;;
> +esac
> +. "$dir0/ovs-lib" || exit 1
> +
> +for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
> + case :$PATH: in
> + *:$dir:*) ;;
> + *) PATH=$PATH:$dir ;;
> + esac
> +done
> +
> +insert_mods () {
> + # Try loading openvswitch again.
> + action "Inserting openvswitch module" modprobe openvswitch
> +}
> +
> +insert_kmod_if_required() {
> + # If this kernel has no module support, expect we're done.
> + if test ! -e /proc/modules
> + then
> + log_success_msg "Kernel has no loadable module support. Skipping modprobe"
> + return 0
> + fi
> +
> + # If openvswitch is already loaded then we're done.
> + test -e /sys/module/openvswitch && return 0
> +
> + # Load openvswitch. If that's successful then we're done.
> + insert_mods && return 0
> +
> + # If the bridge module is loaded, then that might be blocking
> + # openvswitch. Try to unload it, if there are no bridges.
> + test -e /sys/module/bridge || return 1
> + bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
> + if test "$bridges" != "*"; then
> + log_warning_msg "not removing bridge module because bridges exist ($bridges)"
> + return 1
> + fi
> + action "removing bridge module" rmmod bridge || return 1
> +
> + # Try loading openvswitch again.
> + insert_mods
> +}
> +
> +remove_kmods() {
> + for vport in `awk '/^vport_/ { print $1 }' /proc/modules`; do
> + action "Removing $vport module" rmmod $vport
> + done
> +
> + if test -e /sys/module/openvswitch; then
> + action "Removing openvswitch module" rmmod openvswitch
> + fi
> +}
> +
> +set_defaults () {
> + SYSTEM_ID=
> +
> + DELETE_BRIDGES=no
> + DELETE_TRANSIENT_PORTS=no
> +
> + DAEMON_CWD=/
> + FORCE_COREFILES=yes
> + MLOCKALL=yes
> + SELF_CONFINEMENT=yes
> + MONITOR=yes
> + OVS_USER=
> + OVSDB_SERVER=yes
> + OVS_VSWITCHD=yes
> + OVSDB_SERVER_PRIORITY=-10
> + OVS_VSWITCHD_PRIORITY=-10
> + OVSDB_SERVER_WRAPPER=
> + OVS_VSWITCHD_WRAPPER=
> +
> + DB_FILE=$dbdir/conf.db
> + DB_SOCK=$rundir/db.sock
> + DB_SCHEMA=$datadir/vswitch.ovsschema
> + EXTRA_DBS=
> +
> + PROTOCOL=gre
> + DPORT=
> + SPORT=
> +
> + type_file=$etcdir/system-type.conf
> + version_file=$etcdir/system-version.conf
> +
> + if test -e "$type_file" ; then
> + SYSTEM_TYPE=`cat $type_file`
> + SYSTEM_VERSION=`cat $version_file`
> + elif test -e "@sysconfdir@/os-release"; then
> + SYSTEM_TYPE=`. '@sysconfdir@/os-release' && echo "$ID"`
> + SYSTEM_VERSION=`. '@sysconfdir@/os-release' && echo "$VERSION_ID"`
> + elif (lsb_release --id) >/dev/null 2>&1; then
> + SYSTEM_TYPE=`lsb_release --id -s`
> + system_release=`lsb_release --release -s`
> + system_codename=`lsb_release --codename -s`
> + SYSTEM_VERSION="${system_release}-${system_codename}"
> + else
> + SYSTEM_TYPE=unknown
> + SYSTEM_VERSION=unknown
> + fi
> +}
> +
> +usage () {
> + set_defaults
> + cat <<EOF
> +$0: controls Open vSwitch kernel modules
> +usage: $0 [OPTIONS] COMMAND
> +
> +This program is intended to be invoked internally by Open vSwitch startup
> +scripts. System administrators should not normally invoke it directly.
> +
> +Commands:
> + insert insert the Open vSwitch kernel modules
> + remove remove the Open vSwitch kernel modules
> +
> +Options:
> + -h, --help display this help message
> + -V, --version display version information
> +
> +Default directories with "configure" option and environment variable override:
> + logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
> + pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
> + conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
> + system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
> + data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
> + user binaries: @bindir@ (--bindir, OVS_BINDIR)
> + system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
> +
> +Please report bugs to bugs at openvswitch.org (see REPORTING-BUGS for details).
> +EOF
> +
> + exit 0
> +}
> +
> +set_option () {
> + var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
> + eval set=\${$var+yes}
> + eval old_value=\$$var
> + if test X$set = X || \
> + (test $type = bool && \
> + test X"$old_value" != Xno && test X"$old_value" != Xyes); then
> + echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
> + return
> + fi
> + eval $var=\$value
> +}
> +
> +set_defaults
> +extra_ids=
> +command=
> +for arg
> +do
> + case $arg in
> + -h | --help)
> + usage
> + ;;
> + -V | --version)
> + echo "$0 (Open vSwitch) $VERSION"
> + exit 0
> + ;;
> + --[a-z]*=*)
> + option=`expr X"$arg" : 'X--\([^=]*\)'`
> + value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
> + type=string
> + set_option
> + ;;
> + --no-[a-z]*)
> + option=`expr X"$arg" : 'X--no-\(.*\)'`
> + value=no
> + type=bool
> + set_option
> + ;;
> + --[a-z]*)
> + option=`expr X"$arg" : 'X--\(.*\)'`
> + value=yes
> + type=bool
> + set_option
> + ;;
> + -*)
> + echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
> + exit 1
> + ;;
> + *)
> + if test X"$command" = X; then
> + command=$arg
> + else
> + echo >&2 "$0: exactly one non-option argument required (use --help for help)"
> + exit 1
> + fi
> + ;;
> + esac
> +done
> +case $command in
> + remove)
> + remove_kmods
> + ;;
> + insert)
> + insert_kmod_if_required
> + ;;
> + help)
> + usage
> + ;;
> + '')
> + echo >&2 "$0: missing command name (use --help for help)"
> + exit 1
> + ;;
> + *)
> + echo >&2 "$0: unknown command \"$command\" (use --help for help)"
> + exit 1
> + ;;
> +esac
> diff --git a/utilities/ovs-lib.in b/utilities/ovs-lib.in
> index cf6b6d296..106eaddd9 100644
> --- a/utilities/ovs-lib.in
> +++ b/utilities/ovs-lib.in
> @@ -449,6 +449,10 @@ ovs_vsctl () {
> ## force-reload-kmod ##
> ## ----------------- ##
>
> +ovs_kmod_ctl () {
> + "$dir0/ovs-kmod-ctl" "$@"
> +}
> +
> internal_interfaces () {
> # Outputs a list of internal interfaces:
> #
> @@ -563,13 +567,7 @@ force_reload_kmod () {
> action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
> done
>
> - for vport in `awk '/^vport_/ { print $1 }' /proc/modules`; do
> - action "Removing $vport module" rmmod $vport
> - done
> -
> - if test -e /sys/module/openvswitch; then
> - action "Removing openvswitch module" rmmod openvswitch
> - fi
> + ovs_kmod_ctl remove
>
> # Start vswitchd by asking it to wait till flow restore is finished.
> flow_restore_wait
> --
> 2.14.3
>
More information about the dev
mailing list