diff --git a/.fmf/version b/.fmf/version deleted file mode 100644 index d00491f..0000000 --- a/.fmf/version +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/.gitignore b/.gitignore index 4e53c68..febc0e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,19 @@ -/kmod-*.tar.xz +/kmod-7.tar.xz +/kmod-8.tar.xz +/kmod-9.tar.xz +/kmod-10.tar.xz +/kmod-11.tar.xz +/kmod-12.tar.xz +/kmod-13.tar.xz +/kmod-14.tar.xz +/kmod-15.tar.xz +/kmod-16.tar.xz +/kmod-17.tar.xz +/kmod-18.tar.xz +/kmod-19.tar.xz +/kmod-20.tar.xz +/kmod-21.tar.xz +/kmod-22.tar.xz +/kmod-23.tar.xz +/kmod-24.tar.xz +/kmod-25.tar.xz diff --git a/depmod.conf.dist b/depmod.conf.dist deleted file mode 100644 index 8513288..0000000 --- a/depmod.conf.dist +++ /dev/null @@ -1,6 +0,0 @@ -# -# depmod.conf -# - -# override default search ordering for kmod packaging -search updates extra built-in weak-updates diff --git a/kmod.spec b/kmod.spec index 8d0b67b..b2e4e6f 100644 --- a/kmod.spec +++ b/kmod.spec @@ -1,105 +1,25 @@ -# Fedora does not support CONFIG_MODVERSIONS. Without kabi support -# weak-modules is useless at best, and can be actively harmful. -# Since RHEL *does* support this and offers kabi support, -# turn it on there by default. -%if 0%{?rhel} -%bcond_without weak_modules -%bcond_without dist_conf -%else -%bcond_with weak_modules -%bcond_with dist_conf -%endif - -%bcond_without zlib -%bcond_without xz -%bcond_without zstd - Name: kmod -Version: 34.2 +Version: 25 Release: 3%{?dist} Summary: Linux kernel module management utilities -# https://docs.fedoraproject.org/en-US/legal/license-field/#_no_effective_license_analysis -# GPL-2.0-or-later: -# build-aux/compile -# build-aux/depcomp -# build-aux/ltmain.sh -# build-aux/ltmain.sh -# build-aux/missing -# build-aux/py-compile -# build-aux/test-driver -# m4/attributes.m4 -# m4/features.m4 -# tools -# GPL-3.0-or-later: -# build-aux/config.guess -# build-aux/config.sub -# build-aux/git-version-gen -# libkmod/docs/gtk-doc.make -# m4/gtk-doc.m4 -# FSFUL: -# configure -# FSFULLRWD: -# aclocal.m4 -# libkmod/docs/Makefile.in -# m4/libtool.m4 -# m4/lt~obsolete.m4 -# m4/ltoptions.m4 -# m4/ltsugar.m4 -# m4/ltversion.m4 -# Makefile.in -# LGPL-2.1-only: -# libkmod/python/kmod/error.py -# libkmod/python/kmod/__init__.py -# libkmod/python/kmod/version.py -# libkmod/python/kmod/version.py.in -# LGPL-2.1-or-later: -# config.h.in (no explicit license, the one in COPYING is assumed) -# libkmod -# man (no explicit license, the one in COPYING is assumed) -# shared -# shell-completion/bash/kmod -# testsuite -# X11: -# build-aux/install-sh -License: GPL-2.0-or-later AND GPL-3.0-or-later AND FSFUL AND FSFULLRWD AND LGPL-2.1-only AND LGPL-2.1-or-later AND X11 -URL: https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git +Group: System Environment/Kernel +License: GPLv2+ +URL: http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=summary Source0: https://www.kernel.org/pub/linux/utils/kernel/kmod/%{name}-%{version}.tar.xz Source1: weak-modules -Source2: depmod.conf.dist Exclusiveos: Linux BuildRequires: gcc BuildRequires: chrpath -%if %{with zlib} BuildRequires: zlib-devel -%endif -%if %{with xz} BuildRequires: xz-devel -%endif -BuildRequires: scdoc gtk-doc -BuildRequires: openssl-devel -BuildRequires: make automake libtool -%if %{with zstd} -BuildRequires: libzstd-devel -%endif +BuildRequires: libxslt Provides: module-init-tools = 4.0-1 Obsoletes: module-init-tools < 4.0-1 Provides: /sbin/modprobe -%if "%{_sbindir}" == "%{_bindir}" -# Compat symlinks for Requires in other packages. -# We rely on filesystem to create the symlinks for us. -Requires: filesystem(unmerged-sbin-symlinks) -Provides: /usr/sbin/modprobe -Provides: /usr/sbin/modinfo -Provides: /usr/sbin/insmod -Provides: /usr/sbin/rmmod -Provides: /usr/sbin/lsmod -Provides: /usr/sbin/depmod -%endif - %description The kmod package provides various programs needed for automatic loading and unloading of modules under 2.6, 3.x, and later kernels, as well @@ -108,6 +28,8 @@ examples of loaded and unloaded modules. %package libs Summary: Libraries to handle kernel module loading and unloading +License: LGPLv2+ +Group: System Environment/Libraries %description libs The kmod-libs package provides runtime libraries for any application that @@ -115,6 +37,7 @@ wishes to load or unload Linux kernel modules from the running system. %package devel Summary: Header files for kmod development +Group: Development/Libraries Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description devel @@ -122,45 +45,40 @@ The kmod-devel package provides header files used for development of applications that wish to load or unload Linux kernel modules. %prep -%autosetup -p1 +%setup -q %build -autoreconf --install +export V=1 %configure \ - --with-openssl \ -%if %{with zlib} --with-zlib \ -%endif -%if %{with xz} - --with-xz \ -%endif -%if %{with zstd} - --with-zstd \ -%endif - --enable-debug - -%{make_build} V=1 + --with-xz +make %{?_smp_mflags} %install -%{make_install} - -pushd $RPM_BUILD_ROOT%{_mandir}/man5 +make install DESTDIR=$RPM_BUILD_ROOT +pushd $RPM_BUILD_ROOT/%{_mandir}/man5 ln -s modprobe.d.5.gz modprobe.conf.5.gz popd -find %{buildroot} -type f -name "*.la" -delete +rm -rf $RPM_BUILD_ROOT%{_libdir}/*.la +mkdir -p $RPM_BUILD_ROOT%{_sbindir} +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/modprobe +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/modinfo +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/insmod +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/rmmod +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/depmod +ln -sf ../bin/kmod $RPM_BUILD_ROOT%{_sbindir}/lsmod mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/depmod.d mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/modprobe.d -%if %{with weak_modules} -install -pm 755 %{SOURCE1} $RPM_BUILD_ROOT%{_sbindir}/weak-modules -%endif +mkdir -p $RPM_BUILD_ROOT/sbin +install -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_sbindir}/weak-modules -%if %{with dist_conf} -install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/depmod.d/dist.conf -%endif +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig %files %dir %{_sysconfdir}/depmod.d @@ -173,23 +91,14 @@ install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/depmod.d/dist.conf %{_sbindir}/rmmod %{_sbindir}/lsmod %{_sbindir}/depmod -%if %{with weak_modules} %{_sbindir}/weak-modules -%endif %{_datadir}/bash-completion/ -%{_datadir}/fish/vendor_functions.d/* -%{_datadir}/zsh/site-functions/* -%if %{with dist_conf} -%{_sysconfdir}/depmod.d/dist.conf -%endif -%{_datadir}/pkgconfig/kmod.pc -%attr(0644,root,root) %{_mandir}/man5/mod*.d*.5* -%attr(0644,root,root) %{_mandir}/man5/depmod.d.5* -%{_mandir}/man5/modprobe.conf.5* +%attr(0644,root,root) %{_mandir}/man5/*.5* %attr(0644,root,root) %{_mandir}/man8/*.8* -%doc NEWS README.md +%doc NEWS README TODO %files libs +%{!?_licensedir:%global license %%doc} %license COPYING %{_libdir}/libkmod.so.* @@ -199,144 +108,6 @@ install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/depmod.d/dist.conf %{_libdir}/libkmod.so %changelog -* Wed Aug 13 2025 Zamir SUN - 34.2-3 -- Rebuild to switch gating to TMT. -- Resolves: rhbz#2382934 - -* Thu Jul 24 2025 Fedora Release Engineering - 34.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Mon Mar 31 2025 Josh Boyer - 34.2-1 -- New upstream v34.2 -- Resolves: rhbz#2355680 - -* Sat Mar 08 2025 Josh Boyer - 34.1-1 -- New upstream v34.1 -- Resolves: rhbz#2350269 - -* Mon Feb 24 2025 Josh Boyer -- New upstream v34 -- Resolves: rhbz#2347049 - -* Fri Jan 17 2025 Fedora Release Engineering - 33-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 33-2 -- Rebuilt for the bin-sbin merge (2nd attempt) - -* Thu Aug 15 2024 Eugene Syromiatnikov - 33-1 -- New upstream v33 -- Resolves: rhbz#2268030 - -* Mon Aug 12 2024 Eugene Syromiatnikov - 31-8 -- weak-modules: use either zcat or xzcat based on symvers file extension - -* Thu Jul 18 2024 Fedora Release Engineering - 31-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Thu Apr 11 2024 Zbigniew Jedrzejewski-Szmek - 31-6 -- Prepare for %%_bindir==%%_sbindir - -* Thu Jan 25 2024 Fedora Release Engineering - 31-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Sun Jan 21 2024 Fedora Release Engineering - 31-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Dec 01 2023 Eugene Syromiatnikov - 31-3 -- migrated to SPDX license - -* Thu Nov 09 2023 Josh Boyer - 31-2 -- Add upstream patches to enable SHA3 support -- New upstream v31 -- Resolves: rhbz#2241394 - -* Thu Jul 20 2023 Fedora Release Engineering - 30-6 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Tue May 09 2023 Eugene Syromiatnikov - 30-5 -- Add symvers.xz support to weak-modules - -* Thu Jan 19 2023 Fedora Release Engineering - 30-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Sat Dec 17 2022 Florian Weimer - 30-3 -- Port configure script to C99 - -* Thu Jul 21 2022 Fedora Release Engineering - 30-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Mon Jul 4 2022 Yauheni Kaliuta - 30-1 -- New upstream v30 -- Resolves: rhbz#2102796 - -* Thu Jan 20 2022 Fedora Release Engineering - 29-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Tue Sep 14 2021 Sahana Prasad - 29-6 -- Rebuilt with OpenSSL 3.0.0 - -* Tue Aug 10 2021 Yauheni Kaliuta - 29-5 -- kmod.spec: enable debug -- weak-modules: compare_initramfs_modules: exit on pushd/popd failures -- weak-modules: split modules into array with read -a -- Add default config file, /etc/depmod.d/dist.conf - -* Thu Jul 22 2021 Fedora Release Engineering - 29-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Tue Jun 08 2021 Neal Gompa - 29-3 -- Fix conditional to only install weak-modules for RHEL - -* Tue May 25 2021 Justin M. Forbes - 29-2 -- Rebuild for weak-modules drop in Fedora - -* Mon May 24 2021 Justin M. Forbes -- Remove weak-modules for Fedora as it causes problems. - -* Fri May 14 2021 Josh Boyer - 29-1 -- New upstream v29 -- Resolves: rhbz#1962980 - -* Tue Jan 26 2021 Fedora Release Engineering - 28-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Thu Jan 07 2021 Josh Boyer - 28-1 -- New upstream v28 -- Enable zstd support -- Resolves: rhbz#1913949 - -* Tue Jul 28 2020 Fedora Release Engineering - 27-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Wed Mar 25 2020 Yauheni Kaliuta - 27-2 -- add 0001-depmod-do-not-output-.bin-to-stdout.patch - Resolves: rhbz#1808430 - -* Thu Feb 20 2020 Peter Robinson - 27-1 -- New upstream v27 - -* Mon Jan 20 2020 Yauheni Kaliuta - 26-5 -- weak-modules: sync with RHEL - -* Thu Jul 25 2019 Fedora Release Engineering - 26-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Mon Feb 25 2019 Yauheni Kaliuta - 26-3 -- weak-modules: sync with RHEL - -* Sun Feb 24 2019 Yauheni Kaliuta - 26-2 -- add PKCS7/openssl support (rhbz 1320921) - -* Sun Feb 24 2019 Yauheni Kaliuta - 26-1 -- Update to version 26 (rhbz 1673749) - -* Fri Feb 01 2019 Fedora Release Engineering - 25-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Mon Oct 29 2018 James Antill - 25-4 -- Remove ldconfig scriptlet, now done via. transfiletrigger in glibc (rhbz 1644063) - * Fri Jul 13 2018 Fedora Release Engineering - 25-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild diff --git a/sources b/sources index 0390a92..994a620 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (kmod-34.2.tar.xz) = 0e095c45ad61a6c61ce1ad61b9aa10cf5040e688b749f9a933b0e7d12de493c58027a5068b459cbbce05576fc564a22b83a3dbef1e6511b2a3e27034c88afd33 +SHA512 (kmod-25.tar.xz) = d579cd0cea24a06362a74927b7a3c777e9e01c990306e1032e4781cd441ffe435c70f2c2c4f6ae39eb1d857e622746411d5824d0c0d8bb79f91dc9fa51956252 diff --git a/tests/libkmod/libkmod.fmf b/tests/libkmod/libkmod.fmf deleted file mode 100644 index 8733518..0000000 --- a/tests/libkmod/libkmod.fmf +++ /dev/null @@ -1,3 +0,0 @@ -test: bash ./runtest.sh -framework: beakerlib -duration: 15m diff --git a/tests/libkmod/metadata b/tests/libkmod/metadata deleted file mode 100644 index 455987a..0000000 --- a/tests/libkmod/metadata +++ /dev/null @@ -1,14 +0,0 @@ -[General] -name=libkmod gating test -owner=Susant Sahani -description=libkmod gating test -license=GPLv2 -confidential=no -destructive=no - -[restraint] -entry_point=./runtest.sh -max_time=15m -use_pty=false -dependencies=gcc,make,libcmocka-devel,kmod-devel - diff --git a/tests/libkmod/runtest.sh b/tests/libkmod/runtest.sh deleted file mode 100755 index d86b2e2..0000000 --- a/tests/libkmod/runtest.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: LGPL-2.1+ -# ~~~ -# runtest.sh of libkmod -# Description: Tests for libkmod. -# -# Author: Susant Sahani -# Copyright (c) 2018 Red Hat, Inc. -# ~~~ - -# Include Beaker environment -. /usr/share/beakerlib/beakerlib.sh || exit 1 - -PACKAGE="kmod-devel" -IPIP="/usr/lib/modules/$(uname -r)/kernel/net/ipv4/ipip.ko.xz" - -rlJournalStart - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlAssertExists "$IPIP" - rlRun "gcc -o test-libkmod test-libkmod.c -lkmod -lcmocka" - rlRun "cp test-libkmod /usr/bin/" - rlPhaseEnd - - rlPhaseStartTest - rlLog "Starting libkmod tests ..." - rlRun "/usr/bin/test-libkmod" - rlPhaseEnd - - rlPhaseStartCleanup - rlRun "rm /usr/bin/test-libkmod" - rlLog "libkmod tests done" - rlPhaseEnd -rlJournalPrintText -rlJournalEnd - -rlGetTestState diff --git a/tests/libkmod/test-libkmod.c b/tests/libkmod/test-libkmod.c deleted file mode 100644 index 507e581..0000000 --- a/tests/libkmod/test-libkmod.c +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ -# ~~~ -# Description: Tests libkmod -# -# Author: Susant Sahani -# Copyright (c) 2018 Red Hat, Inc. -# ~~~ -*/ - -#include -#include -#include -#include -#include -#include -#include - -static int load_module(void **state) { - struct kmod_list *list = NULL; - struct kmod_ctx *ctx = NULL; - struct kmod_list *l; - int r; - - assert_non_null((ctx = kmod_new(NULL, NULL))); - assert_return_code(kmod_module_new_from_lookup(ctx, "ipip", &list), 0); - - kmod_list_foreach(l, list) { - struct kmod_module *mod = NULL; - - mod = kmod_module_get_module(l); - assert_non_null(mod); - - assert_return_code(kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL), 0); - } - - free(ctx); - - return 0; -} - -static int remove_module(void **state) { - struct kmod_list *list = NULL; - struct kmod_ctx *ctx = NULL; - struct kmod_list *l; - int r; - - assert_non_null((ctx = kmod_new(NULL, NULL))); - assert_return_code(kmod_module_new_from_lookup(ctx, "ipip", &list), 0); - - kmod_list_foreach(l, list) { - struct kmod_module *mod = NULL; - - mod = kmod_module_get_module(l); - assert_non_null(mod); - - assert_return_code(kmod_module_remove_module(mod, 0), 0); - } - - free(ctx); - - return 0; -} - -void test_load_module(void **state) { - load_module(NULL); -} - -void test_remove_module(void **state) { - remove_module(NULL); -} - -int main(int argc, char *argv[]) { - const struct CMUnitTest libmod_tests[] = { - cmocka_unit_test_teardown(test_load_module, remove_module), - cmocka_unit_test_setup(test_remove_module, load_module), - }; - - return cmocka_run_group_tests(libmod_tests, NULL, NULL); -} diff --git a/tests/plan.fmf b/tests/plan.fmf deleted file mode 100644 index 160239c..0000000 --- a/tests/plan.fmf +++ /dev/null @@ -1,10 +0,0 @@ -prepare: - how: install - package: - - libcmocka-devel - - make - - gcc -discover: - how: fmf -execute: - how: tmt diff --git a/tests/sanity/Makefile b/tests/sanity/Makefile new file mode 100644 index 0000000..9ea4f00 --- /dev/null +++ b/tests/sanity/Makefile @@ -0,0 +1,81 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of general/kmod/sanity +# Description: kmod test +# +# 2016-07-31 +# Author: Chunyu Hu +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +TENV=_env +ifeq ($(PKG_TOP_DIR),) + export PKG_TOP_DIR := $(shell p=$$PWD; while :; do \ + [ -e $$p/env.mk -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done) + export _TOP_DIR := $(shell p=$$PWD; while :; do \ + [ -d $$p/.git -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done) + -include $(PKG_TOP_DIR)/env.mk +endif +include $(TENV) +ifeq ($(_TOP_DIR),) + _TOP_DIR=/mnt/tests/$(TOPLEVEL_NAMESPACE) +endif + +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(TENV) $(METADATA) _env runtest.sh Makefile PURPOSE lib.sh + +.PHONY: all install download clean + +run: $(FILES) build + ( set +o posix; . /usr/bin/rhts_environment.sh; \ + . /usr/share/beakerlib/beakerlib.sh; \ + . runtest.sh ) + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -fr *~ $(BUILT_FILES) + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Chunyu Hu " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: kmod kernel module check from kernel modules tools">> $(METADATA) + @echo "Type: Regression" >> $(METADATA) + @echo "TestTime: 1h" >> $(METADATA) + @echo "RunFor: kernel" >> $(METADATA) + @echo "Requires: kernel" >> $(METADATA) + @echo "Requires: sysstat perf trace-cmd" >> $(METADATA) + @echo "Requires: $(PACKAGE_NAME) python rpm wget" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "RhtsRequires: kernel-kernel-general-include" >> $(METADATA) + rhts-lint $(METADATA) + diff --git a/tests/sanity/metadata b/tests/sanity/metadata deleted file mode 100644 index 6c68b4b..0000000 --- a/tests/sanity/metadata +++ /dev/null @@ -1,12 +0,0 @@ -[General] -name=kmod gating test -owner=Ziqian SUN -description=kmod gating test -license=GPLv2 -confidential=no -destructive=no - -[restraint] -entry_point=./runtest.sh -max_time=15m -use_pty=false diff --git a/tests/sanity/runtest.sh b/tests/sanity/runtest.sh index 815972f..a0888d4 100755 --- a/tests/sanity/runtest.sh +++ b/tests/sanity/runtest.sh @@ -28,6 +28,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Include Beaker environment +. /usr/bin/rhts-environment.sh || exit 1 . /usr/share/beakerlib/beakerlib.sh || exit 1 . lib.sh @@ -132,3 +133,4 @@ rlJournalStart rlJournalPrintText rlJournalEnd + diff --git a/tests/sanity/sanity.fmf b/tests/sanity/sanity.fmf deleted file mode 100644 index 8733518..0000000 --- a/tests/sanity/sanity.fmf +++ /dev/null @@ -1,3 +0,0 @@ -test: bash ./runtest.sh -framework: beakerlib -duration: 15m diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..d362e9f --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,13 @@ +- hosts: localhost + tags: + - classic + roles: + - role: standard-test-beakerlib + tests: + - sanity + required_packages: + - kernel + - perf + - sysstat + - trace-cmd + diff --git a/weak-modules b/weak-modules index 76523a7..4b621e9 100644 --- a/weak-modules +++ b/weak-modules @@ -3,33 +3,25 @@ # weak-modules - determine which modules are kABI compatible with installed # kernels and set up the symlinks in /lib/*/weak-updates. # +# Changelog: +# +# 2010/01/10 - Further updates for dracut use on Fedora/RHEL (jcm). +# 2009/09/16 - Rebase and add a bunch of updates for dracut (jcm). + unset LANG LC_ALL LC_COLLATE tmpdir=$(mktemp -td ${0##*/}.XXXXXX) trap "rm -rf $tmpdir" EXIT unset ${!changed_modules_*} ${!changed_initramfs_*} -unset BASEDIR -unset CHECK_INITRAMFS -weak_updates_dir_override="" -default_initramfs_prefix="/boot" # will be combined with BASEDIR +initramfs_prefix="/boot" # can customize here dracut="/usr/bin/dracut" -depmod="/sbin/depmod" -depmod_orig="$depmod" -declare -a modules -declare -A module_krels -declare -A weak_modules_before -declare -A groups -declare -A grouped_modules - -# output of validate_weak_links, one iteration -# short_name -> path -declare -A compatible_modules - -# state for update_modules_for_krel (needed for add_kernel case) -# short_name -> path -declare -A installed_modules +if [ ! -x "$dracut" ] +then + echo "weak-modules: this tool requires a dracut-enabled kernel" + exit 1 +fi # doit: # A wrapper used whenever we're going to perform a real operation. @@ -38,82 +30,29 @@ doit() { [ -n "$dry_run" ] || "$@" } -# pr_verbose: -# print verbose -- wrapper used to print extra messages if required -pr_verbose() { - [ -n "$verbose" ] && echo "$@" -} - -# pr_warning: -# print warning -pr_warning() { - echo "WARNING: $*" -} - # rpmsort: The sort in coreutils can't sort the RPM list how we want it so we # instead transform the list into a form it will sort correctly, then sort. rpmsort() { - local IFS=$' ' - REVERSE="" - rpmlist=($(cat)) + local IFS=$' ' + REVERSE="" + rpmlist=($(cat)) - if [ "-r" == "$1" ]; - then - REVERSE="-r" - fi + if [ "-r" == "$1" ]; + then + REVERSE="-r" + fi - echo ${rpmlist[@]} | \ - sed -e 's/-/../g' | \ - sort ${REVERSE} -n -t"." -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -k7,7 \ - -k8,8 -k9,9 -k10,10 | \ - sed -e 's/\.\./-/g' -} - -# krel_of_module: -# Compute the kernel release of a module. -krel_of_module() { - local module="$1" - - if [ x"${module_krels[$module]+set}" = x"set" ]; then - # version cached in the array already - echo "${module_krels[$module]}" - elif [ -f "$module" ]; then - krel_of_module_modinfo "$module" - else - # Try to extract the kernel release from the path - # delete case, the .ko already deleted - set -- "${module#*/lib/modules/}" - echo "${1%%/*}" - fi -} - -# krel_of_module_modinfo: -# Fetches module version from internal module info -krel_of_module_modinfo() { - local module="$1" - /sbin/modinfo -F vermagic "$module" | awk '{print $1}' -} - -# weak_updates_dir: -# gives the root directory for the weak-updates -# We need some flexibility here because of dry-run. -weak_updates_dir() { - local krel="$1" - - if [[ -z "$weak_updates_dir_override" ]]; then - echo "$BASEDIR/lib/modules/$krel/weak-updates" - else - echo "$weak_updates_dir_override" - fi + echo ${rpmlist[@]} | \ + sed -e 's/-/../g' | \ + sort ${REVERSE} -n -t"." -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -k7,7 \ + -k8,8 -k9,9 -k10,10 | \ + sed -e 's/\.\./-/g' } # read_modules_list: # Read in a list of modules from standard input. Convert the filenames into # absolute paths and compute the kernel release for each module (either using # the modinfo section or through the absolute path. -# If used with input redirect, should be used as read_module_list < input, -# not input | read_modules_list, the latter spawns a subshell -# and the arrays are not seen in the caller read_modules_list() { local IFS=$'\n' modules=($(cat)) @@ -122,50 +61,14 @@ read_modules_list() { if [ ${modules[n]:0:1} != '/' ]; then modules[n]="$PWD/${modules[n]}" fi - module_krels["${modules[n]}"]=$(krel_of_module ${modules[n]}) - done -} - -decompress_initramfs() { - local input=$1 - local output=$2 - - # First, check if this is compressed at all - if cpio -i -t < "$input" > /dev/null 2>/dev/null; then - # If this archive contains a file early_cpio, it's a trick. Strip off - # the early cpio archive and try again. - if cpio -i -t < "$input" 2>/dev/null | grep -q '^early_cpio$' ; then - /usr/lib/dracut/skipcpio "$input" > "${tmpdir}/post_early_cpio.img" - decompress_initramfs "${tmpdir}/post_early_cpio.img" "$output" - retval="$?" - rm -f "${tmpdir}/post_early_cpio.img" - return $retval + if [ -f "${modules[n]}" ]; then + module_krels[n]=$(krel_of_module ${modules[n]}) + else + # Try to extract the kernel release from the path + set -- "${modules[n]#/lib/modules/}" + module_krels[n]=${1%%/*} fi - - cp "$input" "$output" - return 0 - fi - - # Try gzip - if gzip -cd < "$input" > "$output" 2>/dev/null ; then - return 0 - fi - - # Next try xz - if xz -cd < "$input" > "$output" 2>/dev/null ; then - return 0 - fi - - echo "Unable to decompress $input: Unknown format" >&2 - return 1 -} - -# List all module files and modprobe configuration that could require a new -# initramfs. The current directory must be the root of the uncompressed -# initramfs. The unsorted list of files is output to stdout. -list_module_files() { - find . -iname \*.ko -o -iname '*.ko.xz' -o -iname '*.ko.gz' 2>/dev/null - find etc/modprobe.d usr/lib/modprobe.d -name \*.conf 2>/dev/null + done } # read_old_initramfs: @@ -178,35 +81,28 @@ compare_initramfs_modules() { mkdir "$tmpdir/old_initramfs" mkdir "$tmpdir/new_initramfs" - decompress_initramfs "$old_initramfs" "$tmpdir/old_initramfs.img" - pushd "$tmpdir/old_initramfs" >/dev/null || exit - cpio -i < "$tmpdir/old_initramfs.img" 2>/dev/null - rm "$tmpdir/old_initramfs.img" - n=0; for i in `list_module_files|sort`; do + pushd "$tmpdir/old_initramfs" >/dev/null + zcat "$old_initramfs" | cpio -i 2>/dev/null + n=0; for i in `find . -iname \*.ko|sort`; do old_initramfs_modules[n]="$i" n=$((n+1)) done - popd >/dev/null || exit + popd >/dev/null - decompress_initramfs "$new_initramfs" "$tmpdir/new_initramfs.img" - pushd "$tmpdir/new_initramfs" >/dev/null || exit - cpio -i < "$tmpdir/new_initramfs.img" 2>/dev/null - rm "$tmpdir/new_initramfs.img" - n=0; for i in `list_module_files|sort`; do + pushd "$tmpdir/new_initramfs" >/dev/null + zcat "$new_initramfs" | cpio -i 2>/dev/null + n=0; for i in `find . -iname \*.ko|sort`; do new_initramfs_modules[n]="$i" n=$((n+1)) done - popd >/dev/null || exit + popd >/dev/null - # Compare the length and contents of the arrays - if [ "${#old_initramfs_modules[@]}" == "${#new_initramfs_modules[@]}" -a \ - "${old_initramfs_modules[*]}" == "${new_initramfs_modules[*]}" ]; + if [ "${#old_initramfs_modules[@]}" == "${#new_initramfs_modules[@]}" ]; then - # If the file lists are the same, compare each file to find any that changed for ((n = 0; n < ${#old_initramfs_modules[@]}; n++)); do - if ! cmp "$tmpdir/old_initramfs/${old_initramfs_modules[n]}" \ - "$tmpdir/new_initramfs/${new_initramfs_modules[n]}" \ - >/dev/null 2>&1 + old_md5=`md5sum $tmpdir/old_initramfs/${old_initramfs_modules[n]}|sed -nre 's:(^\ )* .*:\1:p'` + new_md5=`md5sum $tmpdir/new_initramfs/${new_initramfs_modules[n]}|sed -nre 's:(^\ )* .*:\1:p'` + if [ ! "$old_md5" == "$new_md5" ]; then return 1 fi @@ -232,7 +128,7 @@ check_initramfs() { $dracut -f "$tmp_initramfs" "$kernel" - if ! compare_initramfs_modules "$old_initramfs" "$tmp_initramfs"; + if ! $(compare_initramfs_modules "$old_initramfs" "$tmp_initramfs"); then doit mv "$tmp_initramfs" "$new_initramfs" else @@ -241,6 +137,71 @@ check_initramfs() { fi } +# krel_of_module: +# Compute the kernel release of a module. +krel_of_module() { + declare module=$1 + /sbin/modinfo -F vermagic "$module" | awk '{print $1}' +} + +# module_is_compatible: +# Determine if a module is compatible with a particular kernel release. Also +# include any symbol deps that might be introduced by other external kmods. +module_is_compatible() { + declare module=$1 krel=$2 module_krel=$(krel_of_module "$module") + + if [ ! -e "$tmpdir/all-symvers-$krel-$module_krel" ]; then + # Symbols exported by the "new" kernel + if [ ! -e $tmpdir/symvers-$krel ]; then + if [ -e /boot/symvers-$krel.gz ]; then + zcat /boot/symvers-$krel.gz \ + | sed -r -ne 's:^(0x[0]*[0-9a-f]{8}\t[0-9a-zA-Z_]+)\t.*:\1:p' + fi > $tmpdir/symvers-$krel + fi + + # Symbols that other add-on modules of the "old" kernel export + # (and that this module may require) + if [ ! -e "$tmpdir/extra-symvers-$module_krel" ]; then + if [ -e /lib/modules/$module_krel/extra ] && \ + [ -n "`find /lib/modules/$module_krel/extra -type f`" ]; then + find /lib/modules/$module_krel/extra -name '*.ko' \ + | xargs nm \ + | sed -nre 's:^[0]*([0-9a-f]{8}) A __crc_(.*):0x\1 \2:p' + fi > $tmpdir/extra-symvers-$module_krel + fi + + sort -u $tmpdir/symvers-$krel $tmpdir/extra-symvers-$module_krel \ + > "$tmpdir/all-symvers-$krel-$module_krel" + fi + + # If the module does not have modversions enabled, $tmpdir/modvers + # will be empty. + /sbin/modprobe --dump-modversions "$module" \ + | sed -r -e 's:^(0x[0]*[0-9a-f]{8}\t.*):\1:' \ + | sort -u \ + > $tmpdir/modvers + + # Only include lines of the second file in the output that don't + # match lines in the first file. (The default separator is + # , so we are matching the whole line.) + join -j 1 -v 2 $tmpdir/all-symvers-$krel-$module_krel \ + $tmpdir/modvers > $tmpdir/join + + if [ ! -s $tmpdir/modvers ]; then + echo "Warning: Module ${module##*/} from kernel $module_krel has no" \ + "modversions, so it cannot be reused for kernel $krel" >&2 + elif [ -s $tmpdir/join ]; then + [ -n "$verbose" ] && + echo "Module ${module##*/} from kernel $module_krel is not compatible" \ "with kernel $krel in symbols:" $(sed -e 's:.* ::' $tmpdir/join) + else + [ -n "$verbose" ] && + echo "Module ${module##*/} from kernel $module_krel is compatible" \ + "with kernel $krel" + return 0 + fi + return 1 +} + usage() { echo "Usage: ${0##*/} [options] {--add-modules|--remove-modules}" echo "${0##*/} [options] {--add-kernel|--remove-kernel} {kernel-release}" @@ -253,7 +214,8 @@ usage() { --remove-modules Remove compatibility symlinks from weak-updates/ directories for a list of modules. The list of modules is read from - standard input. Note: it doesn't attempt to locate any + standard input. Optionally specify --delete-modules to + prevent weak-modules from attempting to locate any compatible modules to replace those being removed. --add-kernel @@ -265,7 +227,7 @@ usage() { kernel. --no-initramfs - Do not generate an initramfs. + Do not generate an initramfs. --verbose Print the commands executed. @@ -282,11 +244,8 @@ EOF module_has_changed() { declare module=$1 krel=$2 - declare orig_module=$module module=${module%.ko} - [[ $module == $orig_module ]] && module=${module%.ko.xz} - [[ $module == $orig_module ]] && module=${module%.ko.gz} module=${module##*/} eval "changed_modules_${krel//[^a-zA-Z0-9]/_}=$krel" @@ -294,802 +253,134 @@ module_has_changed() { } -# module_weak_link: -# Generate a weak link path for the module. -# Takes module file name and the target kernel release as arguments -# The way of generation intentionally left from the initial version -module_weak_link() { - local module="$1" - local krel="$2" - local module_krel - local subpath - local module_krel_escaped - - module_krel="$(krel_of_module "$module")" - module_krel_escaped=$(echo "$module_krel" | \ - sed 's/\([.+?^$\/\\|()\[]\|\]\)/\\\0/g') - subpath=$(echo $module | sed -nre "s:$BASEDIR(/usr)?/lib/modules/$module_krel_escaped/([^/]*)/(.*):\3:p") - - if [[ -z $subpath ]]; then - # module is not in /lib/modules/$krel? - # It's possible for example for Oracle ACFS compatibility check - # Install it with its full path as a /lib/modules subpath - subpath="$module" - fi - - echo "$(weak_updates_dir $krel)/${subpath#/}" -} - -# module_short_name: -# 'basename' version purely in bash, cuts off path from the filename -module_short_name() { - echo "${1##*/}" -} - -#### Helper predicates - -# is_weak_for_module_valid: -# Takes real module filename and target kernel as arguments. -# Calculates weak symlink filename for the corresponding module -# for the target kernel, -# returns 'true' if the symlink filename is a symlink -# and the symlink points to a readable file -# EVEN if it points to a different filename -is_weak_for_module_valid() { - local module="$1" - local krel="$2" - local weak_link - - weak_link="$(module_weak_link $module $krel)" - [[ -L "$weak_link" ]] && [[ -r "$weak_link" ]] -} - -# is_weak_link: -# Takes a filename and a kernel release. -# 'true' if the filename is symlink under weak-updates/ for the kernel. -# It doesn't matter, if it's a valid symlink (points to a real file) or not. -is_weak_link() { - local link="$1" - local krel="$2" - - echo $link | grep -q "$(weak_updates_dir $krel)" || return 1 - [[ -L $link ]] -} - -# is_extra_exists: -# Takes a module filename, the module's kernel release and target kernel release. -# The module filename should be a real, not a symlink, filename (i.e. in extra/). -# Returns 'true' if the same module exists for the target kernel. -is_extra_exists() { - local module="$1" - local module_krel="$2" - local krel="$3" - local subpath="${module#*/lib/modules/$module_krel/extra/}" - - [[ -f $BASEDIR/lib/modules/$krel/extra/$subpath ]] -} - -is_kernel_installed() { - local krel="$1" - - find_symvers_file "$krel" > /dev/null && - find_systemmap_file "$krel" > /dev/null -} - -is_empty_file() { - local file="$1" - - [[ "$(wc -l "$file" | cut -f 1 -d ' ')" == 0 ]] -} - -#### Helpers - -# find_modules: -# Takes kernel release and a list of subdirectories. -# Produces list of module files in the subdirectories for the kernel -find_modules() { - local krel="$1" - shift - local dirs="$*" - - for dir in $dirs; do - find $BASEDIR/lib/modules/$krel/$dir \ - -name '*.ko' -o -name '*.ko.xz' -o -name '*.ko.gz' \ - 2>/dev/null - done -} - -# find_modules_dirs: -# Takes a list of directories. -# Produces list of module files in the subdirectories -find_modules_dirs() { - local dirs="$*" - - for dir in $dirs; do - find $dir -name '*.ko' -o -name '*.ko.xz' -o -name '*.ko.gz' \ - 2>/dev/null - done -} - -# find_installed_kernels: -# Produces list of kernels, which modules are still installed -find_installed_kernels() { - ls $BASEDIR/lib/modules/ -} - -# find_kernels_with_extra: -# Produces list of kernels, where exists extra/ directory -find_kernels_with_extra() { - local krel - local extra_dir - - for krel in $(find_installed_kernels); do - extra_dir="$BASEDIR/lib/modules/$krel/extra" - [[ -d "$extra_dir" ]] || continue - echo "$krel" - done -} - -# remove_weak_link_quiet: -# Takes symlink filename and target kernel release. -# Removes the symlink and the directory tree -# if it was the last file in the tree -remove_weak_link_quiet() { - local link="$1" - local krel="$2" - local subpath="${link#*$(weak_updates_dir $krel)}" - - rm -f $link - ( cd "$(weak_updates_dir $krel)" && \ - rmdir --parents --ignore-fail-on-non-empty "$(dirname "${subpath#/}")" 2>/dev/null ) -} - -# prepare_sandbox: -# Takes kernel release, creates temporary weak-modules directory for it -# and depmod config to operate on it. -# Sets the global state accordingly - -prepare_sandbox() { - local krel="$1" - local orig_dir - local dir - local conf="$tmpdir/depmod.conf" - - #directory - orig_dir=$(weak_updates_dir $krel) - dir="$tmpdir/$krel/weak-updates" - - mkdir -p "$dir" - # the orig_dir can be empty - cp -R "$orig_dir"/* "$dir" 2>/dev/null - - weak_updates_dir_override="$dir" - - #config - echo "search external extra built-in weak-updates" >"$conf" - echo "external * $dir" >>"$conf" - - depmod="$depmod_orig -C $conf" -} - -# discard_installed: -# remove installed_modules[] from modules[] -discard_installed() -{ - local short_name - - for m in "${!modules[@]}"; do - short_name="$(module_short_name "${modules[$m]}")" - - [[ -z "${installed_modules[$short_name]}" ]] && continue - - unset "modules[$m]" - done -} - -# update_installed: -# add compatible_modules[] to installed_modules[] -update_installed() -{ - for m in "${!compatible_modules[@]}"; do - installed_modules[$m]="${compatible_modules[$m]}" - done -} - -# finish_sandbox: -# restore global state after sandboxing -# copy configuration to the kernel directory if not dry run -finish_sandbox() { - local krel="$1" - local override="$weak_updates_dir_override" - local wa_dir - - weak_updates_dir_override="" - depmod="$depmod_orig" - - [[ -n "$dry_run" ]] && return - - wa_dir="$(weak_updates_dir $krel)" - - rm -rf "$wa_dir" - mkdir -p "$wa_dir" - - cp -R "${override}"/* "$wa_dir" 2>/dev/null -} - -# Auxiliary functions to find symvers file -make_kernel_file_names() { - local krel="$1" - shift - local file="$1" - shift - - for suffix in "$@"; do - echo "${BASEDIR}/boot/${file}-${krel}${suffix}" - echo "${BASEDIR}/lib/modules/${krel}/${file}${suffix}" - done -} - -find_kernel_file() { - local krel="$1" - shift - local file="$1" - shift - local print="$1" - shift - local i - - if [[ "$print" != "" ]]; then - make_kernel_file_names "$krel" "$file" "$@" - return 0 - fi - - for i in $(make_kernel_file_names "$krel" "$file" "$@"); do - if [[ -r "$i" ]]; then - echo "$i" - return 0 - fi - done - - return 1 -} - -# find_symvers_file: -# Since /boot/ files population process is now controlled by systemd's -# kernel-install bash script and its plug-ins, it might be the case -# that, while present, symvers file is not populated in /boot. -# Let's also check for /lib/modules/$kver/symvers.gz, since that's where -# it is populated from. -# -# $1 - krel -# return - 0 if symvers file is found, 1 otherwise. -# Prints symvers path if found, empty string otherwise. -find_symvers_file() { - local krel="$1" - local print="$2" - - find_kernel_file "$krel" symvers "$print" .xz .gz -} - -# find_systemmap_file: -# Same as above but for System.map -find_systemmap_file() { - local krel="$1" - local print="$2" - local no_suffix="" - - find_kernel_file "$krel" System.map "$print" "$no_suffix" -} - -#### Main logic - -# update_modules_for_krel: -# Takes kernel release and "action" function name. -# Skips kernel without symvers, -# otherwise triggers the main logic of modules installing/removing -# for the given kernel, which is: -# - save current state of weak modules symlinks -# - install/remove the symlinks for the given (via stdin) list of modules -# - validate the state and remove invalid symlinks -# (for the modules, which are not compatible (became incompatible) for -# the given kernel) -# - check the state after validation to produce needed messages -# and trigger initrd regeneration if the list changed. -# -update_modules_for_krel() { - local krel="$1" - local func="$2" - local force_update="$3" - - is_kernel_installed "$krel" || return - - prepare_sandbox $krel - - global_link_state_save $krel - - # remove already installed from modules[] - discard_installed - - # do not run heavy validation procedure if no modules to install - if [[ "${#modules[@]}" -eq 0 ]]; then - finish_sandbox $krel - return - fi - - $func $krel - - if ! validate_weak_links $krel && [[ -z "$force_update" ]]; then - global_link_state_restore $krel - fi - - # add compatible to installed - update_installed - - global_link_state_announce_changes $krel - - finish_sandbox $krel -} - -# update_modules: -# Common entry point for add/remove modules command -# Takes the "action" function, the module list is supplied via stdin. -# Reads the module list and triggers modules update for all installed -# kernels. -# Triggers initrd rebuild for the kernels, which modules are installed. -update_modules() { - local func="$1" - local force_update="$2" - local module_krel - declare -a saved_modules - - read_modules_list || exit 1 - [[ ${#modules[@]} -gt 0 ]] || return - saved_modules=("${modules[@]}") - - for krel in $(find_installed_kernels); do - update_modules_for_krel $krel $func $force_update - modules=("${saved_modules[@]}") - installed_modules=() - done - - for module in "${modules[@]}"; do - # Module was built against this kernel, update initramfs. - module_krel="${module_krels[$module]}" - module_has_changed $module $module_krel - done -} - -# add_weak_links: -# Action function for the "add-modules" command -# Takes the kernel release, where the modules are added -# and the modules[] and module_krels[] global arrays. -# Install symlinks for the kernel with minimal checks -# (just filename checks, no symbol checks) -add_weak_links() { - local krel="$1" - local module_krel - local weak_link - - for module in "${modules[@]}"; do - module_krel="$(krel_of_module $module)" - - case "$module" in - $BASEDIR/lib/modules/$krel/*) - # Module already installed to the current kernel - continue ;; - esac - - if is_extra_exists $module $module_krel $krel; then - pr_verbose "found $(module_short_name $module) for $krel while installing for $module_krel, update case?" - fi - - if is_weak_for_module_valid $module $krel; then - pr_verbose "weak module for $(module_short_name $module) already exists for kernel $krel, update case?" - # we should update initrd in update case, - # the change is not seen by the symlink detector - # (global_link_state_announce_changes()) - module_has_changed $module $krel - fi - - weak_link="$(module_weak_link $module $krel)" - - mkdir -p "$(dirname $weak_link)" - ln -sf $module $weak_link - - done -} - -# remove_weak_links: -# Action function for the "remove-modules" command -# Takes the kernel release, where the modules are removed -# and the modules[] and module_krels[] global arrays. -# Removes symlinks from the given kernel if they are installed -# for the modules in the list. -remove_weak_links() { - local krel="$1" - local weak_link - local target - local module_krel - - for module in "${modules[@]}"; do - module_krel="$(krel_of_module $module)" - - weak_link="$(module_weak_link $module $krel)" - target="$(readlink $weak_link)" - - if [[ "$module" != "$target" ]]; then - pr_verbose "Skipping symlink $weak_link" - continue - fi - # In update case the --remove-modules call is performed - # after --add-modules (from postuninstall). - # So, we shouldn't really remove the symlink in this case. - # But in the remove case the actual target already removed. - if ! is_weak_for_module_valid "$module" "$krel"; then - remove_weak_link_quiet "$weak_link" "$krel" - fi - done -} - -# validate_weak_links: -# Takes kernel release. -# Checks if all the weak symlinks are suitable for the given kernel. -# Uses depmod to perform the actual symbol checks and parses the output. -# Since depmod internally creates the module list in the beginning of its work -# accroding to the priority list in its configuration, but without symbol -# check and doesn't amend the list during the check, the function runs it -# in a loop in which it removes discovered incompatible symlinks -# -# Returns 0 (success) if proposal is fine or -# 1 (false) if some incompatible symlinks were removed -# initializes global hashmap compatible_modules with all the valid ones -validate_weak_links() { - local krel="$1" - local basedir=${BASEDIR:+-b $BASEDIR} - local tmp - declare -A symbols - local is_updates_changed=1 - local module - local module_krel - local target - local modpath - local symbol - local weak_link - # to return to caller that original proposal is not valid - # here 0 is true, 1 is false, since it will be the return code - local is_configuration_valid=0 - local cat_prog - - tmp=$(mktemp -p $tmpdir) - compatible_modules=() - - if ! [[ -e $tmpdir/symvers-$krel ]]; then - local symvers_path=$(find_symvers_file "$krel") - - [[ -n "$symvers_path" ]] || return - cat_prog="cat" - case "$symvers" in - *.gz) cat_prog="zcat" ;; - *.xz) cat_prog="xzcat" ;; - esac - "$cat_prog" "$symvers_path" > $tmpdir/symvers-$krel - fi - - while ((is_updates_changed)); do - is_updates_changed=0 - - # again $tmp because of subshell, see read_modules_list() comment - # create incompatibility report by depmod - # Shorcut if depmod finds a lot of incompatible modules elsewhere, - # we care only about weak-updates - $depmod $basedir -naeE $tmpdir/symvers-$krel $krel 2>&1 1>/dev/null | \ - grep "$(weak_updates_dir $krel)" 2>/dev/null >$tmp - # parse it into symbols[] associative array in form a-la - # symbols["/path/to/the/module"]="list of bad symbols" - while read line; do - set -- $(echo $line | awk '/needs unknown symbol/{print $3 " " $NF}') - modpath=$1 - symbol=$2 - if [[ -n "$modpath" ]]; then - symbols[$modpath]="${symbols[$modpath]} $symbol" - continue - fi - - set -- $(echo $line | awk '/disagrees about version of symbol/{print $3 " " $NF}') - modpath=$1 - symbol=$2 - if [[ -n "$modpath" ]]; then - symbols[$modpath]="${symbols[$modpath]} $symbol" - continue - fi - done < $tmp - - # loop through all the weak links from the list of incompatible - # modules and remove them. Skips non-weak incompatibilities - for modpath in "${!symbols[@]}"; do - is_weak_link $modpath $krel || continue - - target=$(readlink $modpath) - module_krel=$(krel_of_module $target) - - remove_weak_link_quiet "$modpath" "$krel" - - pr_verbose "Module $(module_short_name $modpath) from kernel $module_krel is not compatible with kernel $krel in symbols: ${symbols[$modpath]}" - is_updates_changed=1 - is_configuration_valid=1 # inversed value - done - done - rm -f $tmp - - # this loop is just to produce verbose compatibility messages - # for the compatible modules - for module in "${modules[@]}"; do - is_weak_for_module_valid $module $krel || continue - - weak_link="$(module_weak_link $module $krel)" - target="$(readlink $weak_link)" - module_krel=$(krel_of_module $target) - - if [[ "$module" == "$target" ]]; then - short_name="$(module_short_name "$module")" - compatible_modules+=([$short_name]="$module") - - pr_verbose "Module ${module##*/} from kernel $module_krel is compatible with kernel $krel" - fi - done - return $is_configuration_valid -} - -# global_link_state_save: -# Takes kernel release -# Saves the given kernel's weak symlinks state into the global array -# weak_modules_before[] for later processing -global_link_state_save() { - local krel="$1" - local link - local target - - weak_modules_before=() - for link in $(find_modules_dirs $(weak_updates_dir $krel) | xargs); do - target=$(readlink $link) - weak_modules_before[$link]=$target - done -} - -# global_link_state_restore: -# Takes kernel release -# Restores the previous weak links state -# (for example, if incompatible modules were installed) -global_link_state_restore() { - local krel="$1" - local link - local target - - pr_verbose "Falling back weak-modules state for kernel $krel" - - ( cd "$(weak_updates_dir $krel)" 2>/dev/null && rm -rf * ) - - for link in "${!weak_modules_before[@]}"; do - target=${weak_modules_before[$link]} - - mkdir -p "$(dirname $link)" - ln -sf $target $link - done -} - -# global_link_state_announce_changes: -# Takes kernel release -# Reads the given kernel's weak symlinks state, compares to the saved, -# triggers initrd rebuild if there were changes -# and produces message on symlink removal -global_link_state_announce_changes() { - local krel="$1" - local link - local target - local new_target - declare -A weak_modules_after - - for link in $(find_modules_dirs $(weak_updates_dir $krel) | xargs); do - target=${weak_modules_before[$link]} - new_target=$(readlink $link) - weak_modules_after[$link]=$new_target - - # report change of existing link and appearing of a new link - [[ "$target" == "$new_target" ]] || module_has_changed $new_target $krel - done - - for link in "${!weak_modules_before[@]}"; do - target=${weak_modules_before[$link]} - new_target=${weak_modules_after[$link]} - - # report change of existing link and disappearing of an old link - [[ "$target" == "$new_target" ]] && continue - module_has_changed $target $krel - [[ -n "$new_target" ]] || - pr_verbose "Removing compatible module $(module_short_name $target) from kernel $krel" - done -} - -# remove_modules: -# Read in a list of modules from stdinput and process them for removal. -# Parameter (noreplace) is deprecated, acts always as "noreplace". -# There is no sense in the "replace" functionality since according -# to the current requirements RPM will track existing of only one version -# of extra/ module (no same extra/ modules for different kernels). -remove_modules() { - update_modules remove_weak_links force_update -} - # add_modules: # Read in a list of modules from stdinput and process them for compatibility # with installed kernels under /lib/modules. add_modules() { - no_force_update="" + read_modules_list || exit 1 + if [ ${#modules[@]} -gt 0 ]; then + for krel in $(ls /lib/modules/); do + [ -e "/boot/symvers-$krel.gz" ] || continue + for ((n = 0; n < ${#modules[@]}; n++)); do + module="${modules[n]}" + module_krel="${module_krels[n]}" + case "$module" in + /lib/modules/$krel/*) + # Module was built against this kernel, update initramfs. + module_has_changed $module $krel + continue ;; + esac - update_modules add_weak_links $no_force_update -} + # Module my also serve as a weak-update built against another + # kernel. We need to create symlinks for compatible kernels + # under /lib/modules and rerun depmod/dracut for those. -# do_make_groups: -# Takes tmp file which contains preprocessed modules.dep -# output (or modules.dep) -# -# reads modules.dep format information from stdin -# produces groups associative array -# the group is a maximum subset of modules having at least a link -# -# more fine tuned extra filtering. -do_make_groups() -{ - local tmp="$1" - local group_name - local mod - declare -a mods - - while read i; do - read -a mods <<< "$i" - - echo "${mods[0]}" |grep -q "extra/" || continue - - # if the module already met, then its dependencies already counted - module_group="${grouped_modules[${mods[0]}]}" - [[ -n $module_group ]] && continue - - # new group - group_name="${mods[0]}" - - for mod in "${mods[@]}"; do - echo "$mod" |grep -q "extra/" || continue - - # if there is already such group, - # it is a subset of the one being created - # due to depmod output - unset groups[$mod] - - # extra space doesn't matter, since later (in add_kernel()) - # it is expanded without quotes - groups[$group_name]+=" $mod" - grouped_modules[$mod]=$group_name + subpath=`echo $module | sed -nre "s:/lib/modules/$module_krel/([^/]*)/(.*):\2:p"` + weak_module="/lib/modules/$krel/weak-updates/${subpath#/}" + if [ -r "$weak_module" ]; then + weak_krel=$(krel_of_module "$weak_module") + if [ "$weak_krel" != "$module_krel" ] && + [ "$(printf "%s\n" "$weak_krel" "$module_krel" \ + | rpmsort | (read input; echo "$input"; \ + while read input; do true; done))" = \ + "$module_krel" ]; then + # Keep modules from more recent kernels. + [ -n "$verbose" ] && echo \ +"Keeping module ${module##*/} from kernel $weak_krel for kernel $krel" + continue + fi + fi + if module_is_compatible $module $krel; then + doit mkdir -p $(dirname $weak_module) + doit ln -sf $module $weak_module + # Module was built against another kernel, update initramfs. + module_has_changed $module $krel + fi + done done - done < $tmp # avoid subshell + fi } -# filter_depmod_deps: -# preprocess output for make_groups -# depmod -n produces also aliases, so it cuts them off -# also it removes colon after the first module -cut_depmod_deps() -{ - awk 'BEGIN { pr = 1 } /^#/{ pr = 0 } pr == 1 {sub(":",""); print $0}' -} +# remove_modules: +# Read in a list of modules from stdinput and process them for removal. +# Parameter is noreplace to delete modules, otherwise link compat. +remove_modules() { + delete_modules=${1:-replace} -# filter_extra_absoluted: -# Takes kernel version -# makes full path from the relative module path -# (produced by depmod for in-kernel-dir modules) -# filter only extra/ modules -filter_extra_absoluted() -{ - local kver="$1" - local mod - declare -a mods + read_modules_list || exit 1 + if [ ${#modules[@]} -gt 0 ]; then - while read i; do - # skip non-extra. The check is not perfect, but ok - # to speed up handling in general cases - echo "$i" |grep -q "extra/" || continue + # Hunt for all known users of this module in /lib/modules, remove them + # and create symlinks to other compatible modules (downgrade) if + # possible, update initramfs for each modified kernel too. - read -a mods <<< "$i" - for j in "${!mods[@]}"; do - mod="${mods[$j]}" + krels=($(ls /lib/modules/ | rpmsort -r)) + for krel in "${krels[@]}"; do + [ -e "/boot/symvers-$krel.gz" ] || continue + for ((n = 0; n < ${#modules[@]}; n++)); do + module="${modules[n]}" + module_krel="${module_krels[n]}" - [[ ${mod:0:1} == "/" ]] || mod="$BASEDIR/lib/modules/$kver/$mod" - mods[$j]="$mod" + # Module is going to be removed, update initramfs. + module_has_changed $module $krel + + subpath="${module#/lib/modules/$module_krel/extra}" + weak_module="/lib/modules/$krel/weak-updates/${subpath#/}" + if [ "$module" == "`readlink $weak_module`" ]; then + [ -n "$verbose" ] && echo \ +"Removing compatible module ${module##*/} from kernel $krel" + doit rm -f "$weak_module" + if [ "replace" == "$delete_modules" ]; then + for krel2 in "${krels[@]}"; do + if [ $krel2 != $krel ]; then + module="/lib/modules/$krel2/extra/${subpath#/}" + [ -e "$module" ] || continue + if module_is_compatible "$module" "$krel"; then + [ -n "$verbose" ] && echo \ +"Adding compatible module ${module##*/} from kernel $krel2 instead" + doit ln -s "$module" "$weak_module" + module_has_changed $module $krel + break + fi + fi + done + fi + doit rmdir --parents --ignore-fail-on-non-empty \ + "$(dirname "$weak_module")" + fi + done done - echo "${mods[@]}" - done -} - -# make_groups: -# takes k -- kernel version, we are installing extras from -# prepares and feeds to do_make_groups -# to create the module groups (global) -make_groups() -{ - local k="$1" - local tmp2=$(mktemp -p $tmpdir) - local basedir=${BASEDIR:+-b $BASEDIR} - - groups=() - grouped_modules=() - - $depmod -n $basedir $k 2>/dev/null | - cut_depmod_deps | filter_extra_absoluted $k > $tmp2 - - do_make_groups $tmp2 - - rm -f $tmp2 + fi } add_kernel() { - local krel=${1:-$(uname -r)} - local tmp - local no_force_update="" - local num - - tmp=$(mktemp -p $tmpdir) - - if ! find_symvers_file "$krel" > /dev/null; then - echo "Symvers dump file is not found in" \ - $(find_symvers_file "$krel" print) >&2 + add_krel=${1:-$(uname -r)} + if [ ! -e "/boot/symvers-$add_krel.gz" ]; then + echo "Symvers dump file /boot/symvers-$add_krel.gz" \ + "not found" >&2 exit 1 fi - - for k in $(find_kernels_with_extra | rpmsort -r); do - [[ "$krel" == "$k" ]] && continue - find_modules $k extra > $tmp - - is_empty_file "$tmp" || make_groups $k - - # reuse tmp - - # optimization, check independent modules in one run. - # first try groups with one element in each. - # it means independent modules, so we can safely remove - # incompatible links - # some cut and paste here - - echo > $tmp - for g in "${groups[@]}"; do - num="$(echo "$g" | wc -w)" - [ "$num" -gt 1 ] && continue - - printf '%s\n' $g >> $tmp - done - # to avoid subshell, see the read_modules_list comment - read_modules_list < $tmp - update_modules_for_krel $krel add_weak_links force_update - - for g in "${groups[@]}"; do - num="$(echo "$g" | wc -w)" - [ "$num" -eq 1 ] && continue - - printf '%s\n' $g > $tmp - read_modules_list < $tmp - update_modules_for_krel $krel add_weak_links $no_force_update + for krel in $(ls /lib/modules/ | rpmsort -r); do + [ "$add_krel" = "$krel" ] && continue + [ -d /lib/modules/$krel/extra ] || continue + for module in $(find /lib/modules/$krel/extra -name '*.ko'); do + subpath="${module#/lib/modules/$krel/extra}" + weak_module="/lib/modules/$add_krel/weak-updates/${subpath#/}" + [ -e "$weak_module" ] && continue + if module_is_compatible $module $add_krel; then + module_has_changed $module $add_krel + doit mkdir -p $(dirname $weak_module) + doit ln -sf $module $weak_module + fi done done - - rm -f $tmp - } remove_kernel() { remove_krel=${1:-$(uname -r)} - weak_modules="$(weak_updates_dir $remove_krel)" + weak_modules="/lib/modules/$remove_krel/weak-updates" module_has_changed $weak_modules $remove_krel - - # Remove everything beneath the weak-updates directory - ( cd "$weak_modules" && doit rm -rf * ) + doit rm -rf "$weak_modules" } ################################################################################ @@ -1098,8 +389,7 @@ remove_kernel() { options=`getopt -o h --long help,add-modules,remove-modules \ --long add-kernel,remove-kernel \ - --long dry-run,no-initramfs,verbose,delete-modules \ - --long basedir:,dracut:,check-initramfs-prog: -- "$@"` + --long dry-run,no-initramfs,verbose,delete-modules -- "$@"` [ $? -eq 0 ] || usage 1 @@ -1121,10 +411,6 @@ while :; do ;; --dry-run) dry_run=1 - # --dry-run option is not pure dry run anymore, - # because of depmod used internally. - # For add/remove modules we have to add/remove the symlinks - # and just restore the original configuration afterwards. ;; --no-initramfs) no_initramfs=1 @@ -1133,19 +419,7 @@ while :; do verbose=1 ;; --delete-modules) - pr_warning "--delete-modules is deprecated, no effect" - ;; - --basedir) - BASEDIR="$2" - shift - ;; - --dracut) - dracut="$2" - shift - ;; - --check-initramfs-prog) - CHECK_INITRAMFS="$2" - shift + do_delete_modules=1 ;; -h|--help) usage 0 @@ -1158,31 +432,27 @@ while :; do shift done -if [ ! -x "$dracut" ] -then - echo "weak-modules: could not find dracut at $dracut" - exit 1 -fi - -initramfs_prefix="$BASEDIR/${default_initramfs_prefix#/}" - if [ -n "$do_add_modules" ]; then - add_modules + add_modules elif [ -n "$do_remove_modules" ]; then - remove_modules + if [ -n "$do_delete_modules" ]; then + remove_modules "noreplace" + else + remove_modules + fi elif [ -n "$do_add_kernel" ]; then - kernel=${1:-$(uname -r)} - add_kernel $kernel + kernel=${1:-$(uname -r)} + add_kernel $kernel elif [ -n "$do_remove_kernel" ]; then - kernel=${1:-$(uname -r)} - remove_kernel $kernel + kernel=${1:-$(uname -r)} + remove_kernel $kernel - exit 0 + exit 0 else - usage 1 + usage 1 fi ################################################################################ @@ -1192,19 +462,14 @@ fi # run depmod and dracut as needed for krel in ${!changed_modules_*}; do krel=${!krel} - basedir=${BASEDIR:+-b $BASEDIR} - if is_kernel_installed $krel; then - doit $depmod $basedir -ae -F $(find_systemmap_file $krel) $krel - else - pr_verbose "Skipping depmod for non-installed kernel $krel" - fi + doit /sbin/depmod -ae -F /boot/System.map-$krel $krel done for krel in ${!changed_initramfs_*}; do krel=${!krel} if [ ! -n "$no_initramfs" ]; then - ${CHECK_INITRAMFS:-check_initramfs} $krel + check_initramfs $krel fi done