From 7f49f3dd69481a6c6a862497f7558b31d836241b Mon Sep 17 00:00:00 2001 From: rezky_nightky Date: Thu, 8 Jan 2026 22:14:46 +0700 Subject: [PATCH 1/2] chore(repo): add codespell config, fix typos, and harden CI workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add repository-wide spellcheck configuration and clean up spelling/wording issues in user-facing docs and shell scripts. Also tighten GitHub Actions workflow YAML to satisfy common lint rules (yamllint/actionlint/shellcheck) and improve readability/robustness of test setup scripts. Changes included: - Add [.codespellrc](cci:7://file:///home/rezky/Desktop/dkms/.codespellrc:0:0-0:0) - Introduce a `[codespell]` configuration with an explicit `skip` list. - Skip VCS metadata and generated/built artifacts (e.g. [./.git](cci:7://file:///home/rezky/Desktop/dkms/.git:0:0-0:0), `./dist`, generated manpage/binaries/completions, distro install helper outputs, and test log artifacts) to keep spell checks focused on maintained sources. - Fix typos / wording across docs & scripts - [README.md](cci:7://file:///home/rezky/Desktop/dkms/README.md:0:0-0:0): `non-existant` -> `non-existent`. - [dkms.8.in](cci:7://file:///home/rezky/Desktop/dkms/dkms.8.in:0:0-0:0): `non-existant` -> `non-existent` in the manpage. - [dkms.in](cci:7://file:///home/rezky/Desktop/dkms/dkms.in:0:0-0:0): - `non-existant` -> `non-existent`. - `accomodate` -> `accommodate`. - Minor quoting/wording cleanup in an example comment to avoid confusion. - [dkms_common.postinst.in](cci:7://file:///home/rezky/Desktop/dkms/dkms_common.postinst.in:0:0-0:0): replace “buildd” phrasing with “build daemon” for clearer, less jargon-heavy comments. - [run_test.sh](cci:7://file:///home/rezky/Desktop/dkms/run_test.sh:0:0-0:0): `Unsuported` -> `Unsupported`. - CI/workflows maintenance - [.github/workflows/shellcheck.yml](cci:7://file:///home/rezky/Desktop/dkms/.github/workflows/shellcheck.yml:0:0-0:0): add YAML document start (`---`) and quote `'on'` to avoid YAML truthiness/lint issues. - [.github/workflows/tests.yml](cci:7://file:///home/rezky/Desktop/dkms/.github/workflows/tests.yml:0:0-0:0): - Reformat/normalize YAML for lint compatibility and readability. - Improve shell safety in `run:` blocks by consistently quoting variables and command substitutions, and by avoiding brittle word-splitting. - Refactor distro dependency installation steps to reduce duplication and line-length issues (e.g., introduce local `variant` variables and split long package install lines). - Make Gentoo setup more robust by using an `nproc` variable, writing `MAKEOPTS`/`ACCEPT_LICENSE` cleanly, and passing `FEATURES`/`USE` via environment on the same command invocation. - Harden kernel discovery/test execution logic by using `printf` pipelines and quoting loop variables to prevent accidental globbing/splitting. Impact: - Improves repository hygiene by preventing generated artifacts from polluting typo checks. - Reduces CI lint noise and improves workflow maintainability without changing intended project functionality. BREAKING CHANGE: none --- .codespellrc | 2 + .github/workflows/shellcheck.yml | 3 +- .github/workflows/tests.yml | 372 +++++++++++++++++++---------- README.md | 2 +- dkms.8.in | 2 +- dkms.in | 391 ++++++++++++++----------------- dkms_common.postinst.in | 6 +- run_test.sh | 2 +- 8 files changed, 430 insertions(+), 350 deletions(-) create mode 100644 .codespellrc 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..e25c0e7f 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,55 +979,6 @@ 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 - case "$kconf" in - !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && return 1 ;; - *) grep -q "^${kconf}=[ym]" "${kernel_config}" || return 1 ;; - esac - done - fi - - if [[ ${BUILD_EXCLUSIVE_CONFIG[$module_index]} && -e "${kernel_config}" ]]; then - local kconf - for kconf in ${BUILD_EXCLUSIVE_CONFIG[$module_index]} ; do - case "$kconf" in - !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && return 1 ;; - *) grep -q "^${kconf}=[ym]" "${kernel_config}" || return 1 ;; - esac - done - fi - - return 0 - } - # Check if any module should be excluded from build build_exclude="" buildable_modules=0 @@ -963,167 +1072,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."\ @@ -1439,7 +1390,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 +1674,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 +1837,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 @@ -2275,7 +2226,7 @@ remove_module() # Get rid of any remnant directories if necessary # shellcheck disable=SC2012 # TODO: use find instead - if (($(ls "$dkms_tree/$module" | wc -w | awk '{print $1}') == 0)); then + if (($(ls "$dkms_tree/$module" | wc -w | awk {'print $1}') == 0)); then rm -rf "${dkms_tree:?}/$module" 2>/dev/null fi } @@ -2557,7 +2508,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" 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 From f9ff8bac93c80717e586b89481b26eadf47b26a1 Mon Sep 17 00:00:00 2001 From: rezky_nightky Date: Fri, 9 Jan 2026 16:22:43 +0700 Subject: [PATCH 2/2] fix(dkms): restore BUILD_EXCLUSIVE helper in dkms.in Author: rezky_nightky Repository: dkms Branch: main Signing: GPG (4B65AAC2) HashAlgo: BLAKE3 [ Block Metadata ] BlockHash: b3d5667835adf9173292437e875967bed86a3a374726794b8d1fa274e54bb287 PrevHash: e85bd390a9c0d55961d3dd5398fcba4e320e0fc13908af12736cb434c35f5d06 PatchHash: b880aa9058b65d9705ba736b746133a4a31a4b31229b16a06fcba27f11886804 FilesChanged: 1 Lines: +49 / -5 Timestamp: 2026-01-09T09:22:43Z Signature1: 8e280478dc859a501317992636de9b6c0fe128fe5a9a5f25670dc0f7c823073f Signature2: 8e733377cc49b08df09a1892052bd6952528927772a1634ec433321eea7a1aa6 Signed-off-by: rezky_nightky --- dkms.in | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/dkms.in b/dkms.in index e25c0e7f..8e7f4204 100644 --- a/dkms.in +++ b/dkms.in @@ -979,6 +979,50 @@ read_conf() { [[ $has_per_module_max == false ]] && BUILD_EXCLUSIVE_KERNEL_MAX=$obsolete_by fi + check_build_exclusive_for_module() { + local module_index="$1" + local kernel_version="$2" + local arch="$3" + + 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 + + [[ $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 + + [[ ${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 + + if [[ $BUILD_EXCLUSIVE_CONFIG && -e "${kernel_config}" ]]; then + local kconf + for kconf in $BUILD_EXCLUSIVE_CONFIG ; do + case "$kconf" in + !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && return 1 ;; + *) grep -q "^${kconf}=[ym]" "${kernel_config}" || return 1 ;; + esac + done + fi + + if [[ ${BUILD_EXCLUSIVE_CONFIG[$module_index]} && -e "${kernel_config}" ]]; then + local kconf + for kconf in ${BUILD_EXCLUSIVE_CONFIG[$module_index]} ; do + case "$kconf" in + !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && return 1 ;; + *) grep -q "^${kconf}=[ym]" "${kernel_config}" || return 1 ;; + esac + done + fi + + return 0 + } + # Check if any module should be excluded from build build_exclude="" buildable_modules=0 @@ -1368,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." @@ -2226,7 +2270,7 @@ remove_module() # Get rid of any remnant directories if necessary # shellcheck disable=SC2012 # TODO: use find instead - if (($(ls "$dkms_tree/$module" | wc -w | awk {'print $1}') == 0)); then + if (($(ls "$dkms_tree/$module" | wc -w | awk '{print $1}') == 0)); then rm -rf "${dkms_tree:?}/$module" 2>/dev/null fi } @@ -2523,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 @@ -2718,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"