[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