diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 00000000..c2ad3c70 --- /dev/null +++ b/.codespellrc @@ -0,0 +1,2 @@ +[codespell] +skip = ./.git,./dist,./images,./dkms,./dkms.8,./dkms.bash-completion,./dkms.zsh-completion,./dkms_framework.conf,./dkms_autoinstaller,./dkms.service,./dkms_common.postinst,./debian_kernel_install.d,./debian_kernel_postinst.d,./debian_kernel_preinst.d,./debian_kernel_prerm.d,./redhat_kernel_install.d,./test_cmd_expected_output.log,./test_cmd_output.log diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 3ef7afbb..69352655 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,6 +1,7 @@ +--- name: Shellcheck -on: +'on': push: pull_request: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 380cb0c6..fa61c7c7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,7 @@ +--- name: Run tests -on: +'on': # Build at 23:00 every Sunday schedule: - cron: "0 23 * * 1" @@ -14,139 +15,264 @@ jobs: strategy: matrix: distro: - - {name: "almalinux", tag: "10"} - - {name: "almalinux", tag: "9"} - - {name: "almalinux", tag: "8"} - - {name: "alpine", tag: "3.22", variant: "-lts"} - - {name: "alpine", tag: "3.22", variant: "-virt"} - - {name: "alpine", tag: "3.21", variant: "-lts"} - - {name: "alpine", tag: "3.21", variant: "-virt"} - - {name: "alpine", tag: "3.20", variant: "-lts"} - - {name: "alpine", tag: "3.20", variant: "-virt"} - - {name: "archlinux", tag: "latest"} - - {name: "archlinux", tag: "latest", variant: "-lts"} - - {name: "archlinux", tag: "latest", variant: "-zen"} - - {name: "centos", tag: "stream10", url: "quay.io/centos/"} - - {name: "centos", tag: "stream9", url: "quay.io/centos/"} - - {name: "debian", tag: "13"} - - {name: "debian", tag: "12"} - - {name: "fedora", tag: "rawhide", url: "registry.fedoraproject.org/"} - - {name: "fedora", tag: "43", url: "registry.fedoraproject.org/"} - - {name: "fedora", tag: "42", url: "registry.fedoraproject.org/"} - - {name: "gentoo/stage3", tag: "latest"} - - {name: "opensuse/tumbleweed", tag: "latest", variant: "-default", url: "registry.opensuse.org/"} - - {name: "opensuse/leap", tag: "15.6", variant: "-default", url: "registry.opensuse.org/"} - - {name: "opensuse/leap", tag: "16.0", variant: "-default", url: "registry.opensuse.org/"} - - {name: "oraclelinux", tag: "10", uek: "ol10_UEKR8"} - - {name: "oraclelinux", tag: "9", uek: "ol9_UEKR8", gcc: "gcc-toolset-14"} - - {name: "oraclelinux", tag: "8", uek: "ol8_UEKR7", gcc: "gcc-toolset-11"} - - {name: "ubuntu", tag: "25.10"} - - {name: "ubuntu", tag: "25.04"} - - {name: "ubuntu", tag: "24.04"} - - {name: "ubuntu", tag: "22.04"} + - name: almalinux + tag: "10" + image: "almalinux:10" + - name: almalinux + tag: "9" + image: "almalinux:9" + - name: almalinux + tag: "8" + image: "almalinux:8" + - name: alpine + tag: "3.22" + variant: "-lts" + image: "alpine:3.22" + - name: alpine + tag: "3.22" + variant: "-virt" + image: "alpine:3.22" + - name: alpine + tag: "3.21" + variant: "-lts" + image: "alpine:3.21" + - name: alpine + tag: "3.21" + variant: "-virt" + image: "alpine:3.21" + - name: alpine + tag: "3.20" + variant: "-lts" + image: "alpine:3.20" + - name: alpine + tag: "3.20" + variant: "-virt" + image: "alpine:3.20" + - name: archlinux + tag: "latest" + variant: "" + image: "archlinux:latest" + - name: archlinux + tag: "latest" + variant: "-lts" + image: "archlinux:latest" + - name: archlinux + tag: "latest" + variant: "-zen" + image: "archlinux:latest" + - name: centos + tag: "stream10" + image: "quay.io/centos/centos:stream10" + - name: centos + tag: "stream9" + image: "quay.io/centos/centos:stream9" + - name: debian + tag: "13" + image: "debian:13" + - name: debian + tag: "12" + image: "debian:12" + - name: fedora + tag: "rawhide" + image: "registry.fedoraproject.org/fedora:rawhide" + - name: fedora + tag: "43" + image: "registry.fedoraproject.org/fedora:43" + - name: fedora + tag: "42" + image: "registry.fedoraproject.org/fedora:42" + - name: gentoo/stage3 + tag: "latest" + image: "gentoo/stage3:latest" + - name: opensuse/tumbleweed + tag: "latest" + variant: "-default" + image: "registry.opensuse.org/opensuse/tumbleweed:latest" + - name: opensuse/leap + tag: "15.6" + variant: "-default" + image: "registry.opensuse.org/opensuse/leap:15.6" + - name: opensuse/leap + tag: "16.0" + variant: "-default" + image: "registry.opensuse.org/opensuse/leap:16.0" + - name: oraclelinux + tag: "10" + uek: "ol10_UEKR8" + image: "oraclelinux:10" + - name: oraclelinux + tag: "9" + uek: "ol9_UEKR8" + gcc: "gcc-toolset-14" + image: "oraclelinux:9" + - name: oraclelinux + tag: "8" + uek: "ol8_UEKR7" + gcc: "gcc-toolset-11" + image: "oraclelinux:8" + - name: ubuntu + tag: "25.10" + image: "ubuntu:25.10" + - name: ubuntu + tag: "25.04" + image: "ubuntu:25.04" + - name: ubuntu + tag: "24.04" + image: "ubuntu:24.04" + - name: ubuntu + tag: "22.04" + image: "ubuntu:22.04" runs-on: ubuntu-24.04 container: - image: ${{ matrix.distro.url }}${{ matrix.distro.name }}:${{ matrix.distro.tag }} + image: ${{ matrix.distro.image }} steps: - - name: Checkout - if: matrix.distro.name == 'opensuse/leap' && matrix.distro.tag == '15.6' - # openSUSE Leap 15.6 does not have tar in the base image - run: | - zypper --non-interactive install tar gzip - - uses: actions/checkout@v6 - - - name: Install dependencies for Red Hat based distributions - if: matrix.distro.name == 'almalinux' || matrix.distro.name == 'centos' || matrix.distro.name == 'fedora' - # Relax crypto policies to allow RSA signatures - run: | - dnf install -y gawk diffutils elfutils-libelf gcc kernel kernel-devel make openssl patch crypto-policies-scripts - update-crypto-policies --set LEGACY - make install-redhat - - - name: Install dependencies for Oracle Linux - if: matrix.distro.name == 'oraclelinux' - # Relax crypto policies to allow RSA signatures - run: | - dnf config-manager --set-enabled ${{ matrix.distro.uek }} - dnf install -y gawk diffutils elfutils-libelf gcc kernel-uek kernel-uek-devel make openssl patch crypto-policies-scripts - update-crypto-policies --set LEGACY - make install-redhat - if [ -n "${{ matrix.distro.gcc }}" ]; then - echo "build_environment=\"/opt/rh/${{ matrix.distro.gcc }}/enable\"" >> /etc/dkms/framework.conf.d/uek.conf - fi - - - name: Install Alpine dependencies - if: matrix.distro.name == 'alpine' - run: | - apk --no-cache --update add bash gcc linux-headers linux${{ matrix.distro.variant }} linux${{ matrix.distro.variant }}-dev make openssl coreutils patch - make install - - - name: Install Arch Linux dependencies - if: matrix.distro.name == 'archlinux' - run: | - pacman -Syu --noconfirm diffutils gcc make linux${{ matrix.distro.variant }} linux${{ matrix.distro.variant }}-headers openssl patch - make install - - - name: Install Debian dependencies - if: matrix.distro.name == 'debian' - run: | - export DEBIAN_FRONTEND=noninteractive - apt-get update -q - apt-get install -qy make linux-headers-amd64 linux-image-amd64 openssl xz-utils patch - make install-debian - - - name: Install Gentoo Linux dependencies - if: matrix.distro.name == 'gentoo/stage3' - run: | - echo -e "MAKEOPTS=\"-j$(nproc) -l$(nproc)\"\nACCEPT_LICENSE=\"*\"" >> /etc/portage/make.conf - wget --progress=dot:mega -O - https://github.com/gentoo-mirror/gentoo/archive/master.tar.gz | tar -xz && mv gentoo-master /var/db/repos/gentoo - FEATURES="getbinpkg binpkg-ignore-signature parallel-fetch parallel-install pkgdir-index-trusted" USE="-initramfs" emerge --quiet --noreplace -j$(nproc) -l$(nproc) --autounmask-continue --with-bdeps=n '>=sys-kernel/gentoo-kernel-bin-6.6.0' - make install - - - name: Install openSUSE leap dependencies - if: contains(matrix.distro.name, 'opensuse') - run: | - zypper --non-interactive install diffutils elfutils gcc kernel${{ matrix.distro.variant }} kernel${{ matrix.distro.variant }}-devel make openssl patch zstd - make install - - - name: Install Ubuntu dependencies - if: matrix.distro.name == 'ubuntu' - run: | - export DEBIAN_FRONTEND=noninteractive - apt-get update -q - apt-get install -qy gcc make linux-headers-generic linux-image-generic openssl shim-signed patch - make install-debian - - - name: Run tests - run: | - for moddir in /usr/lib/modules/ /lib/modules/; do - if [ -e "$moddir" ]; then - kernels=$(find "$moddir" -maxdepth 1 -type d -exec basename {} \;) - break + - name: Checkout + if: >- + matrix.distro.name == 'opensuse/leap' && + matrix.distro.tag == '15.6' + # openSUSE Leap 15.6 does not have tar in the base image + run: | + zypper --non-interactive install tar gzip + - uses: actions/checkout@v6 + + - name: Install dependencies for Red Hat based distributions + if: >- + matrix.distro.name == 'almalinux' || + matrix.distro.name == 'centos' || + matrix.distro.name == 'fedora' + # Relax crypto policies to allow RSA signatures + run: | + dnf install -y \ + gawk diffutils elfutils-libelf gcc \ + kernel kernel-devel make \ + openssl patch crypto-policies-scripts + update-crypto-policies --set LEGACY + make install-redhat + + - name: Install dependencies for Oracle Linux + if: matrix.distro.name == 'oraclelinux' + # Relax crypto policies to allow RSA signatures + run: | + uek='${{ matrix.distro.uek }}' + dnf config-manager --set-enabled "${uek}" + dnf install -y \ + gawk diffutils elfutils-libelf gcc \ + kernel-uek kernel-uek-devel make \ + openssl patch crypto-policies-scripts + update-crypto-policies --set LEGACY + make install-redhat + if [ -n "${{ matrix.distro.gcc }}" ]; then + build_environment="/opt/rh/${{ matrix.distro.gcc }}/enable" + echo "build_environment=\"${build_environment}\"" \ + >> /etc/dkms/framework.conf.d/uek.conf + fi + + - name: Install Alpine dependencies + if: matrix.distro.name == 'alpine' + run: | + variant='${{ matrix.distro.variant }}' + apk --no-cache --update add \ + bash gcc linux-headers \ + "linux${variant}" "linux${variant}-dev" \ + make openssl coreutils patch + make install + + - name: Install Arch Linux dependencies + if: matrix.distro.name == 'archlinux' + run: | + variant='${{ matrix.distro.variant }}' + pacman -Syu --noconfirm \ + diffutils gcc make \ + "linux${variant}" "linux${variant}-headers" \ + openssl patch + make install + + - name: Install Debian dependencies + if: matrix.distro.name == 'debian' + run: | + export DEBIAN_FRONTEND=noninteractive + apt-get update -q + apt-get install -qy \ + make \ + linux-headers-amd64 linux-image-amd64 \ + openssl xz-utils patch + make install-debian + + - name: Install Gentoo Linux dependencies + if: matrix.distro.name == 'gentoo/stage3' + run: | + nproc_val="$(nproc)" + echo "MAKEOPTS=\"-j${nproc_val} -l${nproc_val}\"" \ + >> /etc/portage/make.conf + echo "ACCEPT_LICENSE=\"*\"" >> /etc/portage/make.conf + + gentoo_repo_url='https://github.com/gentoo-mirror/gentoo/archive/'\ + 'master.tar.gz' + wget --progress=dot:mega -O - "${gentoo_repo_url}" | tar -xz + mv gentoo-master /var/db/repos/gentoo + + FEATURES='getbinpkg binpkg-ignore-signature parallel-fetch' \ + USE='-initramfs' \ + emerge --quiet --noreplace \ + -j"${nproc_val}" -l"${nproc_val}" \ + --autounmask-continue --with-bdeps=n \ + '>=sys-kernel/gentoo-kernel-bin-6.6.0' + make install + + - name: Install openSUSE leap dependencies + if: contains(matrix.distro.name, 'opensuse') + run: | + variant='${{ matrix.distro.variant }}' + zypper --non-interactive install \ + diffutils elfutils gcc \ + "kernel${variant}" "kernel${variant}-devel" \ + make openssl patch zstd + make install + + - name: Install Ubuntu dependencies + if: matrix.distro.name == 'ubuntu' + run: | + export DEBIAN_FRONTEND=noninteractive + apt-get update -q + apt-get install -qy \ + gcc make \ + linux-headers-generic linux-image-generic \ + openssl shim-signed patch + make install-debian + + - name: Run tests + run: | + for moddir in /usr/lib/modules/ /lib/modules/; do + if [ -e "${moddir}" ]; then + kernels="$( + find "${moddir}" -maxdepth 1 -type d \ + -exec basename {} \; + )" + break fi - done + done - # There should be two entries - "modules" and the kernel we installed - if [ $(echo "${kernels}" | wc -l) -ne 2 ]; then + # There should be two entries - "modules" and the kernel we installed + if [ "$(printf '%s\n' "${kernels}" | wc -l)" -ne 2 ]; then echo >&2 "Error: invalid number of kernels installed" - fi + fi - KERNEL_VER=$(echo "${kernels}" | tail -n1) - if [ -z "${KERNEL_VER}" ] ; then + KERNEL_VER="$(printf '%s\n' "${kernels}" | tail -n 1)" + if [ -z "${KERNEL_VER}" ] ; then echo >&2 "Error: no kernel package found" exit 1 - fi + fi - echo "Found kernel ${KERNEL_VER}" - export KERNEL_VER + echo "Found kernel ${KERNEL_VER}" + export KERNEL_VER - echo "Module search paths" - for depmod in /etc/depmod.d/ /usr/lib/depmod.d/ /lib/depmod.d/; do - [ -e "$depmod" ] && grep -r ^search "$depmod" || true - done + echo "Module search paths" + for depmod in /etc/depmod.d/ /usr/lib/depmod.d/ /lib/depmod.d/; do + [ -e "${depmod}" ] && grep -r ^search "${depmod}" || true + done - # Run all tests - ./run_test.sh + # Run all tests + ./run_test.sh - make uninstall + make uninstall diff --git a/README.md b/README.md index 3b8b0a9b..bb333e8b 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ mok_signing_key="/var/lib/shim-signed/mok/MOK.priv" mok_certificate="/var/lib/shim-signed/mok/MOK.der" ``` -NOTE: If any of the files specified by `mok_signing_key` and `mok_certificate` are non-existant, DKMS will re-create both files. +NOTE: If any of the files specified by `mok_signing_key` and `mok_certificate` are non-existent, DKMS will re-create both files. The paths specified in `mok_signing_key`, `mok_certificate` and `sign_file` can use the variable `${kernelver}` to represent the target kernel version. diff --git a/dkms.8.in b/dkms.8.in index 2757c80e..45184fda 100644 --- a/dkms.8.in +++ b/dkms.8.in @@ -937,7 +937,7 @@ NOTE: If any of the files specified by .B mok_signing_key and .B mok_certificate -are non-existant, dkms will re-create both files. +are non-existent, dkms will re-create both files. .B mok_signing_key can also be a "pkcs11:..." string for PKCS#11 engine, as long as the diff --git a/dkms.in b/dkms.in index 79ad3d54..8e7f4204 100644 --- a/dkms.in +++ b/dkms.in @@ -53,7 +53,7 @@ # 5: prepare_build(): Patch ... as specified in dkms.conf cannot be found in ... # 5: install: This module/version combo is already installed for kernel ... # 6: prepare_build(): Application of patch ... failed. -# 6: install: You cannot install a module onto a non-existant kernel. +# 6: install: You cannot install a module onto a non-existent kernel. # 6: install: Installation aborted. # 6: install: Install Failed (depmod problems). Module rolled back to built state. # 6: make_tarball(): Modules must already be in the built state before using mktarball. @@ -73,7 +73,7 @@ # 12: setup_kernels_arches(): Could not determine architecture. # 13: build: Aborting build of module ... for kernel ... due to missing BUILD_DEPENDS: ... # 14: kernel_preinst/prerm: dkms kernel_preinst/prerm for kernel ... failed for module(s) ... -# 15: gloabl: a call to cd failed +# 15: global: a call to cd failed # 16: setup_kernels_arches()/do_build()/do_install(): empty $kernelver or $arch # 21: prepare_kernel(): Your kernel headers for kernel ... cannot be found ... # 77: skipped due to BUILD_EXCLUSIVE @@ -586,9 +586,167 @@ safe_source() { (( ${#MODULES_CONF_OBSOLETE_ONLY[@]} )) && deprecated "MODULES_CONF_OBSOLETE_ONLY ($to_source_file)" } -# Source a dkms.conf file and perform appropriate postprocessing on it. -# Do our best to not repeatedly source the same .conf file -- this can happen -# when chaining module installation functions or autoinstalling. +# Source specified variables from dkms framework configuration files. +read_framework_conf() { + for i in /etc/dkms/framework.conf /etc/dkms/framework.conf.d/*.conf; do + [[ -e "$i" ]] && safe_source "$i" "$@" + done +} + +# Little helper function for parsing the output of modinfo. +get_module_verinfo(){ + local ver + local srcver + local checksum + local vals + vals= + while read -ra vals; do + [[ ${#vals[@]} -eq 0 ]] && continue + case "${vals[0]}" in + version:) + ver="${vals[1]}" + checksum="${vals[2]}" + ;; + srcversion:) + srcver="${vals[1]}" + ;; + esac + done <<< "$(modinfo "$1")" + + echo -E "${ver}" + # Use obsolete checksum info if srcversion is not available + echo -E "${srcver:-$checksum}" +} + +# Compare two modules' version +# Output: +# "==": They are the same version and the same srcversion +# "=": They are the same version, but not the same srcversion +# ">": 1st one is newer than 2nd one +# "<": 1st one is older than 2nd one +# "?": Cannot determine +# Returns 0 if same version, otherwise 1 +compare_module_version() +{ + readarray -t ver1 <<< "$(get_module_verinfo "$1")" + readarray -t ver2 <<< "$(get_module_verinfo "$2")" + if [[ "${ver1[0]}" = "${ver2[0]}" ]]; then + if [[ "${ver1[1]}" = "${ver2[1]}" ]]; then + echo "==" + else + echo "=" + fi + return 0 + elif [[ ${#ver1[@]} -eq 0 ]] || [[ ${#ver2[@]} -eq 0 ]]; then + echo "?" + elif [[ "$(VER "${ver1[0]}")" > "$(VER "${ver2[0]}")" ]]; then + echo ">" + else + echo "<" + fi + return 1 +} + +# Perform some module version sanity checking whenever we are installing +# modules. +check_version_sanity() +{ + # $1 = kernel_version + # $2 = arch + # $3 = obs by kernel version + # $4 = dest_module_name + + local lib_tree + local i + lib_tree="$install_tree/$1" + i=0 + if [[ $3 ]]; then + # Magic split into array syntax saves trivial awk and cut calls. + local -a obs + local -a my + local obsolete + obs=("${3//-/ }") + my=("${1//-/ }") + obsolete=0 + if [[ ${#obs[@]} -gt 0 && ${#my[@]} -gt 0 ]]; then + if [[ $(VER "${obs[0]}") == $(VER "${my[0]}") && ! $force ]]; then + # They get obsoleted possibly in this kernel release + if [[ ! ${obs[1]} ]]; then + # They were obsoleted in this upstream kernel + obsolete=1 + elif [[ $(VER "${my[1]}") > $(VER "${obs[1]}") ]]; then + # They were obsoleted in an earlier ABI bump of the kernel + obsolete=1 + elif [[ $(VER "${my[1]}") = $(VER "${obs[1]}") ]]; then + # They were obsoleted in this ABI bump of the kernel + obsolete=1 + fi + elif [[ $(VER "${my[0]}") > $(VER "${obs[0]}") && ! $force ]]; then + # They were obsoleted in an earlier kernel release + obsolete=1 + fi + fi + + if ((obsolete == 1)); then + echo "" >&2 + echo "Module has been obsoleted due to being included in kernel $3." >&2 + echo "We will avoid installing for future kernels above $3." >&2 + echo "You may override by specifying --force." >&2 + return 1 + fi + fi + set_module_suffix "$1" + read -ra kernels_module <<< "$(find_module "$lib_tree" "${4}")" + [[ ${#kernels_module[@]} -eq 0 ]] && return 0 + + if [[ "$force_version_override" == "true" ]]; then + # Skip the following version checking code. + return 0 + fi + + if [[ ${kernels_module[1]} ]]; then + warn "Cannot do version sanity checking because multiple ${4}$module_suffix modules were found in kernel $1." + return 0 + fi + local dkms_module + dkms_module=$(compressed_or_uncompressed "$dkms_tree/$module/$module_version/$1/$2/module" "${4}") + + local cmp_res + cmp_res="$(compare_module_version "${kernels_module}" "${dkms_module}")" + if [[ "${cmp_res}" = ">" ]]; then + if [[ ! "$force" ]]; then + error "Module version $(get_module_verinfo "${dkms_module}" | head -n 1) for $4${module_suffix}" \ + "is not newer than what is already found in kernel $1 ($(get_module_verinfo "${kernels_module}" | head -n 1))." \ + "You may override by specifying --force." + return 1 + fi + elif [[ "${cmp_res}" = "==" ]]; then + if [[ ! "$force" ]]; then + # if the module has neither version nor srcversion/checksum, check the binary files instead + local verinfo + verinfo="$(get_module_verinfo "${dkms_module}")" + if [[ "$(echo "$verinfo" | tr -d '[:space:]')" ]] || diff "${kernels_module}" "${dkms_module}" &>/dev/null; then + verinfo=$(echo "$verinfo" | head -n 1) + if [[ $verinfo ]]; then + echo "Module ${kernels_module} already installed at version ${verinfo}, override by specifying --force" >&2 + else + echo "Module ${kernels_module} already installed (unversioned module), override by specifying --force" >&2 + fi + return 1 + fi + fi + fi + return 0 +} + +check_module_args() { + [[ $module && $module_version ]] && return + die 1 "Arguments and are not specified." \ + "Usage: $1 / or" \ + " $1 -m / or" \ + " $1 -m -v " +} + read_conf() { # $1 kernel version (required) # $2 arch (required) @@ -821,32 +979,27 @@ read_conf() { [[ $has_per_module_max == false ]] && BUILD_EXCLUSIVE_KERNEL_MAX=$obsolete_by fi - # Function to check BUILD_EXCLUSIVE conditions for a specific module check_build_exclusive_for_module() { local module_index="$1" local kernel_version="$2" local arch="$3" - # Set has_build_exclusive_directives if any BUILD_EXCLUSIVE directives are defined if [[ $BUILD_EXCLUSIVE_KERNEL || $BUILD_EXCLUSIVE_KERNEL_MIN || $BUILD_EXCLUSIVE_KERNEL_MAX || $BUILD_EXCLUSIVE_ARCH || $BUILD_EXCLUSIVE_CONFIG ]]; then has_build_exclusive_directives=true elif [[ ${BUILD_EXCLUSIVE_KERNEL[$module_index]} || ${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]} || ${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]} || ${BUILD_EXCLUSIVE_ARCH[$module_index]} || ${BUILD_EXCLUSIVE_CONFIG[$module_index]} ]]; then has_build_exclusive_directives=true fi - # Check global BUILD_EXCLUSIVE directives (backward compatibility) [[ $BUILD_EXCLUSIVE_KERNEL && ! $kernel_version =~ $BUILD_EXCLUSIVE_KERNEL ]] && return 1 [[ $BUILD_EXCLUSIVE_KERNEL_MIN && "$(VER "$kernel_version")" < "$(VER "$BUILD_EXCLUSIVE_KERNEL_MIN")" ]] && return 1 [[ $BUILD_EXCLUSIVE_KERNEL_MAX && "$(VER "$kernel_version")" > "$(VER "$BUILD_EXCLUSIVE_KERNEL_MAX")" ]] && return 1 [[ $BUILD_EXCLUSIVE_ARCH && ! $arch =~ $BUILD_EXCLUSIVE_ARCH ]] && return 1 - # Check per-module BUILD_EXCLUSIVE directives [[ ${BUILD_EXCLUSIVE_KERNEL[$module_index]} && ! $kernel_version =~ ${BUILD_EXCLUSIVE_KERNEL[$module_index]} ]] && return 1 [[ ${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]} && "$(VER "$kernel_version")" < "$(VER "${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]}")" ]] && return 1 [[ ${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]} && "$(VER "$kernel_version")" > "$(VER "${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]}")" ]] && return 1 [[ ${BUILD_EXCLUSIVE_ARCH[$module_index]} && ! $arch =~ ${BUILD_EXCLUSIVE_ARCH[$module_index]} ]] && return 1 - # Check BUILD_EXCLUSIVE_CONFIG (both global and per-module) if [[ $BUILD_EXCLUSIVE_CONFIG && -e "${kernel_config}" ]]; then local kconf for kconf in $BUILD_EXCLUSIVE_CONFIG ; do @@ -963,167 +1116,9 @@ read_conf_strict() return $return_value } -# Source specified variables from dkms framework configuration files. -read_framework_conf() { - for i in /etc/dkms/framework.conf /etc/dkms/framework.conf.d/*.conf; do - [[ -e "$i" ]] && safe_source "$i" "$@" - done -} - -# Little helper function for parsing the output of modinfo. -get_module_verinfo(){ - local ver - local srcver - local checksum - local vals - vals= - while read -ra vals; do - [[ ${#vals[@]} -eq 0 ]] && continue - case "${vals[0]}" in - version:) - ver="${vals[1]}" - checksum="${vals[2]}" - ;; - srcversion:) - srcver="${vals[1]}" - ;; - esac - done <<< "$(modinfo "$1")" - - echo -E "${ver}" - # Use obsolete checksum info if srcversion is not available - echo -E "${srcver:-$checksum}" -} - -# Compare two modules' version -# Output: -# "==": They are the same version and the same srcversion -# "=": They are the same version, but not the same srcversion -# ">": 1st one is newer than 2nd one -# "<": 1st one is older than 2nd one -# "?": Cannot determine -# Returns 0 if same version, otherwise 1 -compare_module_version() -{ - readarray -t ver1 <<< "$(get_module_verinfo "$1")" - readarray -t ver2 <<< "$(get_module_verinfo "$2")" - if [[ "${ver1[0]}" = "${ver2[0]}" ]]; then - if [[ "${ver1[1]}" = "${ver2[1]}" ]]; then - echo "==" - else - echo "=" - fi - return 0 - elif [[ ${#ver1[@]} -eq 0 ]] || [[ ${#ver2[@]} -eq 0 ]]; then - echo "?" - elif [[ "$(VER "${ver1[0]}")" > "$(VER "${ver2[0]}")" ]]; then - echo ">" - else - echo "<" - fi - return 1 -} - -# Perform some module version sanity checking whenever we are installing -# modules. -check_version_sanity() -{ - # $1 = kernel_version - # $2 = arch - # $3 = obs by kernel version - # $4 = dest_module_name - - local lib_tree - local i - lib_tree="$install_tree/$1" - i=0 - if [[ $3 ]]; then - # Magic split into array syntax saves trivial awk and cut calls. - local -a obs - local -a my - local obsolete - obs=("${3//-/ }") - my=("${1//-/ }") - obsolete=0 - if [[ ${#obs[@]} -gt 0 && ${#my[@]} -gt 0 ]]; then - if [[ $(VER "${obs[0]}") == $(VER "${my[0]}") && ! $force ]]; then - # They get obsoleted possibly in this kernel release - if [[ ! ${obs[1]} ]]; then - # They were obsoleted in this upstream kernel - obsolete=1 - elif [[ $(VER "${my[1]}") > $(VER "${obs[1]}") ]]; then - # They were obsoleted in an earlier ABI bump of the kernel - obsolete=1 - elif [[ $(VER "${my[1]}") = $(VER "${obs[1]}") ]]; then - # They were obsoleted in this ABI bump of the kernel - obsolete=1 - fi - elif [[ $(VER "${my[0]}") > $(VER "${obs[0]}") && ! $force ]]; then - # They were obsoleted in an earlier kernel release - obsolete=1 - fi - fi - - if ((obsolete == 1)); then - echo "" >&2 - echo "Module has been obsoleted due to being included in kernel $3." >&2 - echo "We will avoid installing for future kernels above $3." >&2 - echo "You may override by specifying --force." >&2 - return 1 - fi - fi - set_module_suffix "$1" - read -ra kernels_module <<< "$(find_module "$lib_tree" "${4}")" - [[ ${#kernels_module[@]} -eq 0 ]] && return 0 - - if [[ "$force_version_override" == "true" ]]; then - # Skip the following version checking code. - return 0 - fi - - if [[ ${kernels_module[1]} ]]; then - warn "Cannot do version sanity checking because multiple ${4}$module_suffix modules were found in kernel $1." - return 0 - fi - local dkms_module - dkms_module=$(compressed_or_uncompressed "$dkms_tree/$module/$module_version/$1/$2/module" "${4}") - - local cmp_res - cmp_res="$(compare_module_version "${kernels_module}" "${dkms_module}")" - if [[ "${cmp_res}" = ">" ]]; then - if [[ ! "$force" ]]; then - error "Module version $(get_module_verinfo "${dkms_module}" | head -n 1) for $4${module_suffix}" \ - "is not newer than what is already found in kernel $1 ($(get_module_verinfo "${kernels_module}" | head -n 1))." \ - "You may override by specifying --force." - return 1 - fi - elif [[ "${cmp_res}" = "==" ]]; then - if [[ ! "$force" ]]; then - # if the module has neither version nor srcversion/checksum, check the binary files instead - local verinfo - verinfo="$(get_module_verinfo "${dkms_module}")" - if [[ "$(echo "$verinfo" | tr -d '[:space:]')" ]] || diff "${kernels_module}" "${dkms_module}" &>/dev/null; then - verinfo=$(echo "$verinfo" | head -n 1) - if [[ $verinfo ]]; then - echo "Module ${kernels_module} already installed at version ${verinfo}, override by specifying --force" >&2 - else - echo "Module ${kernels_module} already installed (unversioned module), override by specifying --force" >&2 - fi - return 1 - fi - fi - fi - return 0 -} - -check_module_args() { - [[ $module && $module_version ]] && return - die 1 "Arguments and are not specified." \ - "Usage: $1 / or" \ - " $1 -m / or" \ - " $1 -m -v " -} - +# Source a dkms.conf file and perform appropriate postprocessing on it. +# Do our best to not repeatedly source the same .conf file -- this can happen +# when chaining module installation functions or autoinstalling. read_conf_or_die() { read_conf "$@" && return die 8 "Bad conf file."\ @@ -1417,7 +1412,7 @@ do_build() # Error out if source_tree is basically empty (binary-only dkms tarball w/ --force check) # shellcheck disable=SC1083,SC2012 # TODO: use find instead of ls - (($(ls "$source_dir" | wc -l | awk {'print $1'}) < 2)) && die 8 \ + (($(ls "$source_dir" | wc -l | awk '{print $1}') < 2)) && die 8 \ "The directory $source_dir does not appear to have module source located within it."\ "Build halted." @@ -1439,7 +1434,7 @@ do_build() # $ grep CONFIG_CC_VERSION_TEXT= /lib/modules/5.15.0-141-generic/build/include/config/auto.conf # CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" # $ grep CONFIG_CC_VERSION_TEXT= /lib/modules/6.8.0-60-generic/build/.config - # CONFIG_CC_VERSION_TEXT="x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0" + # CONFIG_CC_VERSION_TEXT=x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0 # $ grep CONFIG_CC_VERSION_TEXT= /lib/modules/6.8.0-60-generic/build/include/config/auto.conf # CONFIG_CC_VERSION_TEXT=x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0 cc=$(sed -n 's|^CONFIG_CC_VERSION_TEXT="*\([^" ]*\) .*|\1|p' "${kernel_config}") @@ -1723,7 +1718,7 @@ do_install() # Make sure that kernel exists to install into [[ -e $install_tree/$kernelver ]] || die 6 \ "The directory $install_tree/$kernelver doesn't exist." \ - "You cannot install a module onto a non-existant kernel." + "You cannot install a module onto a non-existent kernel." # Read the conf file set_module_suffix "$kernelver" @@ -1886,7 +1881,7 @@ list_each_installed_module() local real_dest_module_location local mod for ((count=0; count < num_modules; count++)); do - real_dest_module_location="$(find_actual_dest_module_location "$1" "$count" "$2" "$3")" + real_dest_module_location="$(find_actual_dest_module_location "$1" $count "$2" "$3")" mod=$(compressed_or_uncompressed "$install_tree/$2${real_dest_module_location}" "${dest_module_name[$count]}") echo "$mod" done @@ -2557,7 +2552,7 @@ make_tarball() local -r binary_only_dir="$temp_dir_name/dkms_binaries_only" echo "" - echo "Creating tarball structure to specifically accomodate binaries." + echo "Creating tarball structure to specifically accommodate binaries." mkdir "$binary_only_dir" echo "$module" > "$binary_only_dir/PACKAGE_NAME" @@ -2572,7 +2567,7 @@ make_tarball() fi # shellcheck disable=SC1083 - if (( $(echo "$kernel_version_list" | wc -m | awk {'print $1'}) > 200 )); then + if (( $(echo "$kernel_version_list" | wc -m | awk '{print $1}') > 200 )); then kernel_version_list="manykernels" fi @@ -2767,9 +2762,9 @@ run_match() # Iterate over the kernel_status and match kernel to the template_kernel while read -r template_line; do # shellcheck disable=SC1083 - template_module=$(echo "$template_line" | awk {'print $1'} | sed 's/,$//') + template_module=$(echo "$template_line" | awk '{print $1}' | sed 's/,$//') # shellcheck disable=SC1083 - template_version=$(echo "$template_line" | awk {'print $2'} | sed 's/,$//') + template_version=$(echo "$template_line" | awk '{print $2}' | sed 's/,$//') # Print out a match header echo "Module: $template_module" diff --git a/dkms_common.postinst.in b/dkms_common.postinst.in index 10dd3920..ba968e0f 100644 --- a/dkms_common.postinst.in +++ b/dkms_common.postinst.in @@ -169,15 +169,15 @@ fi # On 1st installation, let us look for a directory # in $MODDIR which matches $(uname -r). If none -# is found it is possible that buildd is being used +# is found it is possible that a build daemon is being used # and that uname -r is giving us the name of the -# kernel used by the buildd machine. +# kernel used by the build daemon machine. # # If this is the case we try to build the kernel # module for each kernel which has a directory in # $MODDIR. Furthermore we will have to tell # DKMS which architecture it should build the module -# for (e.g. if the buildd machine is using a +# for (e.g. if the build daemon machine is using a # 2.6.24-23-xen 64bit kernel). # # NOTE: if the headers are not installed then the diff --git a/run_test.sh b/run_test.sh index a41201a6..85aa9976 100755 --- a/run_test.sh +++ b/run_test.sh @@ -307,7 +307,7 @@ remove_module_source_tree() { /usr/src/*) ;; *) - echo "Unsuported module source tree location '$p'" + echo "Unsupported module source tree location '$p'" exit 1 ;; esac