]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
Install kmod.pc in ${datadir}/pkgconfig master
authorMike Gilbert <floppym@gentoo.org>
Fri, 8 Mar 2024 19:06:19 +0000 (14:06 -0500)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Tue, 12 Mar 2024 15:30:13 +0000 (10:30 -0500)
The data in this file isn't related to installed libraries, so put it in
an abi-neutral location.

pkg.m4 provides macros that also allow the user to override the location
with configure switches.

Bug: https://bugs.gentoo.org/926431
Signed-off-by: Mike Gilbert <floppym@gentoo.org>
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
140 files changed:
.gitignore
.semaphore/semaphore.yml [deleted file]
.travis.yml [deleted file]
Makefile.am
NEWS
README [deleted file]
README.md
autogen.sh
configure.ac
libkmod/docs/libkmod-sections.txt
libkmod/libkmod-builtin.c
libkmod/libkmod-config.c
libkmod/libkmod-elf.c
libkmod/libkmod-file.c
libkmod/libkmod-internal.h
libkmod/libkmod-module.c
libkmod/libkmod-signature.c
libkmod/libkmod.c
libkmod/libkmod.h
libkmod/libkmod.pc.in
libkmod/libkmod.sym
libkmod/python/.gitignore [deleted file]
libkmod/python/README [deleted file]
libkmod/python/kmod/__init__.py [deleted file]
libkmod/python/kmod/_libkmod_h.pxd [deleted file]
libkmod/python/kmod/_util.pxd [deleted file]
libkmod/python/kmod/_util.pyx [deleted file]
libkmod/python/kmod/error.py [deleted file]
libkmod/python/kmod/kmod.pxd [deleted file]
libkmod/python/kmod/kmod.pyx [deleted file]
libkmod/python/kmod/list.pxd [deleted file]
libkmod/python/kmod/list.pyx [deleted file]
libkmod/python/kmod/module.pxd [deleted file]
libkmod/python/kmod/module.pyx [deleted file]
libkmod/python/kmod/version.py.in [deleted file]
man/Makefile.am
man/depmod.8.xml [moved from man/depmod.xml with 91% similarity]
man/depmod.d.5.xml [moved from man/depmod.d.xml with 86% similarity]
man/insmod.8.xml [moved from man/insmod.xml with 100% similarity]
man/kmod.8.xml [moved from man/kmod.xml with 100% similarity]
man/lsmod.8.xml [moved from man/lsmod.xml with 100% similarity]
man/modinfo.8.xml [moved from man/modinfo.xml with 98% similarity]
man/modprobe.8.xml [moved from man/modprobe.xml with 94% similarity]
man/modprobe.d.5.xml [moved from man/modprobe.d.xml with 98% similarity]
man/modules.dep.5.xml [moved from man/modules.dep.xml with 89% similarity]
man/rmmod.8.xml [moved from man/rmmod.xml with 98% similarity]
shared/hash.c
shared/macro.h
shared/missing.h
shared/util.c
shared/util.h
testsuite/.gitignore
testsuite/mkosi/.gitignore [deleted file]
testsuite/mkosi/mkosi.arch [deleted file]
testsuite/mkosi/mkosi.build [deleted file]
testsuite/mkosi/mkosi.clear [deleted file]
testsuite/mkosi/mkosi.fedora [deleted file]
testsuite/module-playground/.gitignore
testsuite/module-playground/Makefile
testsuite/module-playground/mod-simple.c
testsuite/path.c
testsuite/populate-modules.sh [deleted file]
testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.alias [new file with mode: 0644]
testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.dep [new file with mode: 0644]
testsuite/rootfs-pristine/test-depmod/modules-outdir/lib/modules/4.4.4/modules.builtin [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.builtin with 100% similarity]
testsuite/rootfs-pristine/test-depmod/modules-outdir/lib/modules/4.4.4/modules.order [new file with mode: 0644]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.alias [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.alias with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.alias.bin [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.alias.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin [new file with mode: 0644]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin.alias.bin [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.builtin.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.dep [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.order with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.dep.bin [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.symbols.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.devname [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.devname with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.softdep [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.softdep with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.symbols [moved from testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.symbols with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.symbols.bin [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.symbols.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.alias [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.alias with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.alias.bin [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.alias.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin [new file with mode: 0644]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.dep [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.builtin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.dep.bin [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.builtin.bin with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.devname [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.devname with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.softdep [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.softdep with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.symbols [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.symbols with 100% similarity]
testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.symbols.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.builtin.bin [moved from testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.order with 100% similarity]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.devname [moved from testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/holders/.gitignore with 100% similarity]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.softdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-abspath/proc/modules [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.builtin.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.devname [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.softdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-from-relpath/proc/modules [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/correct.txt [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/correct.txt [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/proc/cmdline [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/proc/cmdline [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/correct.txt [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/correct.txt [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/proc/cmdline [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/proc/cmdline [new file with mode: 0644]
testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep [deleted file]
testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep.bin [deleted file]
testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep [deleted file]
testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep.bin [deleted file]
testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/initstate [deleted file]
testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/refcnt [deleted file]
testsuite/setup-rootfs.sh [new file with mode: 0755]
testsuite/test-depmod.c
testsuite/test-init.c
testsuite/test-initstate.c
testsuite/test-modprobe.c
testsuite/test-new-module.c
testsuite/test-testsuite.c
testsuite/test-tools.c [deleted file]
testsuite/test-util.c
testsuite/testsuite.c
testsuite/testsuite.h
tools/depmod.c
tools/insert.c [deleted file]
tools/kmod.c
tools/kmod.pc.in [new file with mode: 0644]
tools/modinfo.c
tools/modprobe.c
tools/remove.c [deleted file]
tools/static-nodes.c

index 2347858593d7552b3bc173ff93e8a5435577730d..29b31028446c6f07dcc2b95b49fe15d47ed1d71d 100644 (file)
@@ -1,8 +1,11 @@
 *.o
 *.gcda
 *.gcno
+*.pc
 /*.tar.xz
 /*.md5sum
+/*.mbx
+/*.cover
 .deps/
 .libs/
 /Makefile
@@ -18,6 +21,7 @@
 /configure
 /cov-int
 /coverage
+/gtk-doc.make
 /kmod-*.tar.*
 /libtool
 /stamp-h1
diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml
deleted file mode 100644 (file)
index db47ca1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-version: v1.0
-name: Build and Check
-agent:
-  machine:
-    type: e1-standard-2
-    os_image: ubuntu1804
-
-blocks:
-  - name: "Build"
-    task:
-      jobs:
-        - name: Build gcc-8
-          commands:
-            - sem-version c 8
-        - name: Build gcc-7
-          commands:
-            - sem-version c 7
-        - name: Build gcc-6
-          commands:
-            - sem-version c 6
-
-      prologue:
-        commands:
-          - sudo apt update
-          - sudo apt --yes install docbook-xsl liblzma-dev zlib1g-dev cython linux-headers-generic libssl-dev
-          - checkout
-
-      epilogue:
-        commands:
-          - ./autogen.sh c
-          - make
-
-  - name: "Unit tests"
-    task:
-      jobs:
-        - name: check
-          commands:
-            - sem-version c 8
-            - ./autogen.sh c
-            - make check
-
-      prologue:
-        commands:
-          - sudo apt update
-          - sudo apt --yes install docbook-xsl liblzma-dev zlib1g-dev cython linux-headers-generic libssl-dev
-          - checkout
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644 (file)
index 02c753e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-language: c
-
-matrix:
-  include:
-    - compiler: gcc
-      env: MYCC=gcc
-    - compiler: gcc
-      env: MYCC=gcc-4.8
-    - compiler: gcc
-      env: MYCC=gcc-4.9
-    - compiler: clang
-      env: MYCC=clang
-
-before_install:
-  - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
-  - sudo apt-get update -qq
-  - sudo apt-get install -qq liblzma-dev
-  - sudo apt-get install -qq zlib1g-dev
-  - sudo apt-get install -qq xsltproc docbook-xsl
-  - sudo apt-get install -qq cython
-  - sudo apt-get install -qq linux-headers-generic
-  - if [ "$MYCC" = "gcc-4.8" ]; then sudo apt-get install -qq gcc-4.8; sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90; gcc --version; fi
-  - if [ "$MYCC" = "gcc-4.9" ]; then sudo apt-get install -qq gcc-4.9; sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 90; gcc --version; fi
-
-before_script:
-  - unset PYTHON_CFLAGS # hack to broken travis setup
-  - export KDIR="$(find  /lib/modules/* -maxdepth  1 -name build | sort -n --reverse | head -1)"
-
-script:
-  - ./autogen.sh c --without-openssl && make -j
-  - if [ "$MYCC" != "gcc-4.8" ]; then make -j check; fi
-
-notifications:
-  irc:
-    channels:
-      - "irc.freenode.org#kmod"
-    template:
-      - "%{commit}: %{author} - %{message}"
index 8eadb99787c0bc44e2d1d139cf1c16c6cfe5804d..e2e2411188cf261d7cfb796b5b58aa3909e8ec7a 100644 (file)
@@ -19,32 +19,29 @@ AM_CPPFLAGS = \
        -include $(top_builddir)/config.h \
        -I$(top_srcdir) \
        -DSYSCONFDIR=\""$(sysconfdir)"\" \
+       -DDISTCONFDIR=\""$(distconfdir)"\" \
+       -DMODULE_DIRECTORY=\""$(module_directory)"\" \
        ${zlib_CFLAGS}
 
 AM_CFLAGS = $(OUR_CFLAGS)
 AM_LDFLAGS = $(OUR_LDFLAGS)
 
-SED_PROCESS = \
-       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(SED) \
-       -e 's,@VERSION\@,$(VERSION),g' \
-       -e 's,@prefix\@,$(prefix),g' \
-       -e 's,@exec_prefix\@,$(exec_prefix),g' \
-       -e 's,@libdir\@,$(libdir),g' \
-       -e 's,@includedir\@,$(includedir),g' \
-       -e 's,@liblzma_CFLAGS\@,${liblzma_CFLAGS},g' \
-       -e 's,@liblzma_LIBS\@,${liblzma_LIBS},g' \
-       -e 's,@zlib_CFLAGS\@,${zlib_CFLAGS},g' \
-       -e 's,@zlib_LIBS\@,${zlib_LIBS},g' \
-       -e 's,@libcrypto_CFLAGS\@,${libcrypto_CFLAGS},g' \
-       -e 's,@libcrypto_LIBS\@,${libcrypto_LIBS},g' \
-       < $< > $@ || rm $@
-
-%.pc: %.pc.in Makefile
-       $(SED_PROCESS)
-
-LIBKMOD_CURRENT=5
-LIBKMOD_REVISION=5
-LIBKMOD_AGE=3
+# Rules for libtool versioning (from https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html)
+# 1. Start with version information of â€˜0:0:0’ for each libtool library.
+# 2. Update the version information only immediately before a public release of
+#    your software. More frequent updates are unnecessary, and only guarantee that
+#    the current interface number gets larger faster.
+# 3. If the library source code has changed at all since the last update, then
+#    increment revision (‘c:r:a’ becomes â€˜c:r+1:a’).
+# 4. If any interfaces have been added, removed, or changed since the last
+#    update, increment current, and set revision to 0.
+# 5. If any interfaces have been added since the last public release, then
+#    increment age.
+# 6. If any interfaces have been removed or changed since the last public
+#    release, then set age to 0.
+LIBKMOD_CURRENT=6
+LIBKMOD_REVISION=2
+LIBKMOD_AGE=4
 
 noinst_LTLIBRARIES = shared/libshared.la
 shared_libshared_la_SOURCES = \
@@ -90,7 +87,7 @@ libkmod_libkmod_la_DEPENDENCIES = \
        ${top_srcdir}/libkmod/libkmod.sym
 libkmod_libkmod_la_LIBADD = \
        shared/libshared.la \
-       ${liblzma_LIBS} ${zlib_LIBS} ${libcrypto_LIBS}
+       ${libzstd_LIBS} ${liblzma_LIBS} ${zlib_LIBS} ${libcrypto_LIBS}
 
 noinst_LTLIBRARIES += libkmod/libkmod-internal.la
 libkmod_libkmod_internal_la_SOURCES = $(libkmod_libkmod_la_SOURCES)
@@ -99,10 +96,8 @@ libkmod_libkmod_internal_la_LDFLAGS = $(AM_LDFLAGS) \
 libkmod_libkmod_internal_la_DEPENDENCIES  = $(libkmod_libkmod_la_DEPENDENCIES)
 libkmod_libkmod_internal_la_LIBADD = $(libkmod_libkmod_la_LIBADD)
 
-pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libkmod/libkmod.pc
-EXTRA_DIST += libkmod/libkmod.pc.in
-CLEANFILES += libkmod/libkmod.pc
+noarch_pkgconfig_DATA = tools/kmod.pc
 
 bashcompletiondir=@bashcompletiondir@
 dist_bashcompletion_DATA = \
@@ -116,9 +111,19 @@ install-exec-hook:
                ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libkmod.so && \
                mv $(DESTDIR)$(libdir)/libkmod.so.* $(DESTDIR)$(rootlibdir); \
        fi
+if BUILD_TOOLS
+       for tool in insmod lsmod rmmod depmod modprobe modinfo; do \
+               $(LN_S) -f kmod $(DESTDIR)$(bindir)/$$tool; \
+       done
+endif
 
 uninstall-hook:
        rm -f $(DESTDIR)$(rootlibdir)/libkmod.so*
+if BUILD_TOOLS
+       for tool in insmod lsmod rmmod depmod modprobe modinfo; do \
+               rm -f $(DESTDIR)$(bindir)/$$tool; \
+       done
+endif
 
 if BUILD_TOOLS
 bin_PROGRAMS = tools/kmod
@@ -134,12 +139,6 @@ tools_kmod_SOURCES = \
        tools/depmod.c tools/log.h tools/log.c \
        tools/static-nodes.c
 
-if BUILD_EXPERIMENTAL
-tools_kmod_SOURCES += \
-       tools/insert.c \
-       tools/remove.c
-endif
-
 tools_kmod_LDADD = \
        shared/libshared.la \
        libkmod/libkmod-internal.la
@@ -149,97 +148,21 @@ ${noinst_SCRIPTS}: tools/kmod
                $(LN_S) $(notdir $<) $@)
 endif
 
-# ------------------------------------------------------------------------------
-# PYTHON BINDINGS
-# ------------------------------------------------------------------------------
-
-CYTHON_FLAGS_VERBOSE_ =
-CYTHON_FLAGS_VERBOSE_0 =
-CYTHON_FLAGS_VERBOSE_1 = -v
-CYTHON_FLAGS = $(CYTHON_FLAGS_VERBOSE_$(V))
-AM_V_CYTHON = $(am__v_CYTHON_$(V))
-am__v_CYTHON_ = $(am__v_CYTHON_$(AM_DEFAULT_VERBOSITY))
-am__v_CYTHON_0 = @echo "  CYTHON " $@;
-
-.pyx.c:
-       $(AM_V_CYTHON)$(CYTHON) -o $@ $<
-
-%.py: %.py.in Makefile
-       $(SED_PROCESS)
-
-# Remove some warnings for generated code
-PYTHON_NOWARN = -Wno-redundant-decls -Wno-shadow -Wno-strict-aliasing
-
-CPYTHON_MODULE_CFLAGS = \
-       $(AM_CFLAGS) -DCPYTHON_COMPILING_IN_PYPY=0 \
-       $(PYTHON_NOWARN) $(PYTHON_CFLAGS) \
-       -fvisibility=default
-# Filter -Wl,--no-undefined to fix build with python 3.8
-comma = ,
-CPYTHON_MODULE_LDFLAGS = $(subst -Wl$(comma)--no-undefined,,$(AM_LDFLAGS))
-CPYTHON_MODULE_LDFLAGS += -module -avoid-version -shared
-
-if BUILD_PYTHON
-pkgpyexec_LTLIBRARIES = \
-       libkmod/python/kmod/kmod.la \
-       libkmod/python/kmod/list.la \
-       libkmod/python/kmod/module.la \
-       libkmod/python/kmod/_util.la
-
-libkmod_python_kmod_kmod_la_SOURCES = libkmod/python/kmod/kmod.c
-libkmod_python_kmod_kmod_la_CFLAGS = $(CPYTHON_MODULE_CFLAGS)
-libkmod_python_kmod_kmod_la_LDFLAGS = $(CPYTHON_MODULE_LDFLAGS)
-libkmod_python_kmod_kmod_la_LIBADD = $(PYTHON_LIBS) libkmod/libkmod.la
-
-libkmod_python_kmod_list_la_SOURCES = libkmod/python/kmod/list.c
-libkmod_python_kmod_list_la_CFLAGS = $(CPYTHON_MODULE_CFLAGS)
-libkmod_python_kmod_list_la_LDFLAGS = $(CPYTHON_MODULE_LDFLAGS)
-libkmod_python_kmod_list_la_LIBADD = $(PYTHON_LIBS) libkmod/libkmod.la
-
-libkmod_python_kmod_module_la_SOURCES = libkmod/python/kmod/module.c
-libkmod_python_kmod_module_la_CFLAGS = $(CPYTHON_MODULE_CFLAGS)
-libkmod_python_kmod_module_la_LDFLAGS = $(CPYTHON_MODULE_LDFLAGS)
-libkmod_python_kmod_module_la_LIBADD = $(PYTHON_LIBS) libkmod/libkmod.la
-
-libkmod_python_kmod__util_la_SOURCES = libkmod/python/kmod/_util.c
-libkmod_python_kmod__util_la_CFLAGS = $(CPYTHON_MODULE_CFLAGS)
-libkmod_python_kmod__util_la_LDFLAGS = $(CPYTHON_MODULE_LDFLAGS)
-libkmod_python_kmod__util_la_LIBADD = $(PYTHON_LIBS) libkmod/libkmod.la
-
-BUILT_FILES += \
-       $(libkmod_python_kmod_kmod_la_SOURCES) \
-       $(libkmod_python_kmod_list_la_SOURCES) \
-       $(libkmod_python_kmod_module_la_SOURCES) \
-       $(libkmod_python_kmod__util_la_SOURCES)
-
-dist_pkgpyexec_PYTHON = \
-       libkmod/python/kmod/error.py \
-       libkmod/python/kmod/__init__.py \
-       libkmod/python/kmod/version.py
-
-BUILT_FILES += libkmod/python/kmod/version.py
-
-endif
 # ------------------------------------------------------------------------------
 # TESTSUITE
 # ------------------------------------------------------------------------------
 
-EXTRA_DIST += testsuite/populate-modules.sh
+EXTRA_DIST += testsuite/setup-rootfs.sh
 
 MODULE_PLAYGROUND = testsuite/module-playground
 ROOTFS = testsuite/rootfs
 ROOTFS_PRISTINE = $(top_srcdir)/testsuite/rootfs-pristine
-CREATE_ROOTFS = $(AM_V_GEN) ( $(RM) -rf $(ROOTFS) && mkdir -p $(dir $(ROOTFS)) && \
-                               cp -r $(ROOTFS_PRISTINE) $(ROOTFS) && \
-                               find $(ROOTFS) -type d -exec chmod +w {} \; && \
-                               find $(ROOTFS) -type f -name .gitignore -exec rm -f {} \; && \
-                               $(top_srcdir)/testsuite/populate-modules.sh \
-                                       $(MODULE_PLAYGROUND) $(ROOTFS) ) && \
-                               touch testsuite/stamp-rootfs
+CREATE_ROOTFS = $(AM_V_GEN) MODULE_DIRECTORY=$(module_directory) $(top_srcdir)/testsuite/setup-rootfs.sh $(ROOTFS_PRISTINE) $(ROOTFS) $(MODULE_PLAYGROUND) $(top_builddir)/config.h $(sysconfdir)
 
 build-module-playground:
        $(AM_V_GEN)if test "$(top_srcdir)" != "$(top_builddir)"; then \
                $(RM) -rf testsuite/module-playground && \
+               mkdir -p testsuite/ && \
                cp -r $(top_srcdir)/$(MODULE_PLAYGROUND) $(top_builddir)/$(MODULE_PLAYGROUND) && \
                find $(top_builddir)/$(MODULE_PLAYGROUND) -type d -exec chmod +w {} \; ; \
                fi
@@ -265,13 +188,7 @@ TESTSUITE_OVERRIDE_LIBS = \
 TESTSUITE_OVERRIDE_LIBS_LDFLAGS = \
        avoid-version -module -shared -export-dynamic -rpath /nowhere -ldl
 
-check-sysconfdir:
-       $(AM_V_at)if test "$(sysconfdir)" != "/etc" -a "$(sysconfdir)" != "/etc/"; then \
-               echo "warning: Some tests will fail without --sysconfdir=/etc" >&2; \
-       fi
-.PHONY: check-sysconfdir
-
-check-am: rootfs check-sysconfdir
+check-am: rootfs
 
 
 EXTRA_DIST += \
@@ -347,11 +264,6 @@ TESTSUITE = \
        testsuite/test-dependencies testsuite/test-depmod \
        testsuite/test-list
 
-if BUILD_EXPERIMENTAL
-TESTSUITE += \
-       testsuite/test-tools
-endif
-
 check_PROGRAMS = $(TESTSUITE)
 TESTS = $(TESTSUITE)
 
@@ -394,11 +306,6 @@ testsuite_test_depmod_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
 testsuite_test_list_LDADD = $(TESTSUITE_LDADD)
 testsuite_test_list_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
 
-if BUILD_EXPERIMENTAL
-testsuite_test_tools_LDADD = $(TESTSUITE_LDADD)
-testsuite_test_tools_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
-endif
-
 testsuite-distclean:
        $(RM) -r $(ROOTFS)
        $(RM) testsuite/stamp-rootfs
@@ -410,8 +317,8 @@ testsuite-distclean:
 DISTCLEAN_LOCAL_HOOKS += testsuite-distclean
 EXTRA_DIST += testsuite/rootfs-pristine
 
-DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc --enable-python --sysconfdir=/etc \
-       --with-zlib --with-openssl \
+DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc --sysconfdir=/etc \
+       --with-zlib --with-zstd --with-openssl \
        --with-bashcompletiondir=$$dc_install_base/$(bashcompletiondir)
 
 distclean-local: $(DISTCLEAN_LOCAL_HOOKS)
@@ -464,7 +371,7 @@ endif
 
 kmod-coverity-%.tar.xz:
        rm -rf $< cov-int
-       ./autogen.sh c --disable-python --disable-manpages
+       ./autogen.sh c --disable-manpages
        make clean
        cov-build --dir cov-int make -j 4
        tar caf $@ cov-int
@@ -503,13 +410,3 @@ tar: kmod-$(VERSION).tar.xz kmod-$(VERSION).tar.sign
 
 tar-sync: kmod-$(VERSION).tar.xz kmod-$(VERSION).tar.sign
        kup put kmod-$(VERSION).tar.xz  kmod-$(VERSION).tar.sign /pub/linux/utils/kernel/kmod/
-
-# ------------------------------------------------------------------------------
-# mkosi
-# ------------------------------------------------------------------------------
-
-DISTRO ?= "arch"
-
-mkosi:
-       -$(MKDIR_P) $(top_srcdir)/testsuite/mkosi/mkosi.cache
-       $(MKOSI) -C $(top_srcdir)/testsuite/mkosi --build-sources ../../ --default mkosi.${DISTRO} -fi
diff --git a/NEWS b/NEWS
index 1c80582885cfe6aaea8cda3cb91323996a6fb261..6b628f9382e993bd557d1b13e4500058ab6e60f9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,244 @@
+kmod 32
+=======
+
+- Improvements
+
+       - Use any hash algo known by kernel/openssl instead of keep needing
+         to update the mapping
+
+       - Teach kmod to load modprobe.d/depmod.d configuration from ${prefix}/lib
+         and allow it to be overriden during build with --with-distconfdir=DIR
+
+       - Make kernel modules directory configurable. This allows distro to
+         make kmod use only files from /usr regardless of having a compat
+         symlink in place.
+
+       - Install kmod.pc containing the features selected at build time.
+
+       - Install all tools and symlinks by default. Previously kmod relied on
+         distro packaging to set up the symlinks in place like modprobe,
+         depmod, lsmod, etc. Now those symlinks are created by kmod itself
+         and they are always placed in $bindir.
+
+- Bug Fixes
+
+       - Fix warnings due to -Walloc-size
+
+- Others
+
+       - Drop python bindings. Those were not update in ages and not compatible
+         with latest python releases.
+
+       - Cleanup test infra, dropping what was not used anymore
+
+       - Drop experimental tools `kmod insert` / `kmod remove`. Building those
+         was protected by a configure option never set by distros. They also
+         didn't gain enough traction to replace the older interfaces via
+         modprobe/insmod/rmmod.
+
+kmod 31
+=======
+
+- Improvements
+
+       - Allow passing a path to modprobe so the module is loaded from
+         anywhere from the filesystem, but still handling the module
+         dependencies recorded in the indexes. This is mostly intended for kernel
+         developers to speedup testing their kernel modules without having to load the
+         dependencies manually or override the module in /usr/lib/modules/.
+         Now it's possible to do:
+
+               # modprobe ./drivers/gpu/drm/i915/i915.ko
+
+         As long as the dependencies didn't change, this should do the right thing
+
+       - Use in-kernel decompression if available. This will check the runtime support
+         in the kernel for decompressing modules and use it through finit_module().
+         Previously kmod would fallback to the older init_module() when using
+         compressed modules since there wasn't a way to instruct the kernel to
+         uncompress it on load or check if the kernel supported it or not.
+         This requires a recent kernel (>= 6.4) to have that support and
+         in-kernel decompression properly working in the kernel.
+
+       - Make modprobe fallback to syslog when stderr is not available, as was
+         documented in the man page, but not implemented
+
+       - Better explaing `modprobe -r` and how it differentiates from rmmod
+
+       - depmod learned a `-o <dir>` option to allow using a separate output
+         directory. With this, it's possible to split the output files from
+         the ones used as input from the kernel build system
+
+       - Add compat with glibc >= 2.32.9000 that dropped __xstat
+
+       - Improve testsuite to stop skipping tests when sysconfdir is something
+         other than /etc
+
+       - Build system improvements and updates
+
+       - Change a few return codes from -ENOENT to -ENODATA to avoid confusing output
+         in depmod when the module itself lacks a particular ELF section due to e.g.
+         CONFIG_MODVERSIONS=n in the kernel.
+
+
+- Bug Fixes
+
+       - Fix testsuite using uninitialized memory when testing module removal
+         with --wait
+
+       - Fix testsuite not correctly overriding the stat syscall on 32-bit
+         platforms. For most architectures this was harmless, but for MIPS it
+         was causing some tests to fail.
+
+       - Fix handling unknown signature algorithm
+
+       - Fix linking with a static liblzma, libzstd or zlib
+
+       - Fix memory leak when removing module holders
+
+       - Fix out-of-bounds access when using very long paths as argument to rmmod
+
+       - Fix warnings reported by UBSan
+
+kmod 30
+=======
+
+- Improvements
+       - Stop adding duplicate information on modules.builtin.alias.bin, just use
+         the modules.builtin.bin index
+
+       - Speedup depmod, particularly under qemu with emulated arch, by
+         avoiding a lot of open/read/close of modules.alias.bin. On an
+         emulated ARM rootfs, depmod with only 2 modules was taking ~32s
+         vs ~0.07s now.
+
+       - Add kmod_module_new_from_name_lookup() which allows doing a lookup by
+         module name, without considering the aliases. Other than that search
+         order is similar to kmod_module_new_from_lookup().
+
+       - modinfo learned the --modname option to explicitely show information
+         about the module, even if there is an alias with the same name. This
+         allows showing information about e.g. kernel/lib/crc32.ko, even if
+         kernel also exports a crc32 alias in modules.alias:
+
+               alias crc32 crc32_pclmul
+               alias crc32 crc32_generic
+
+         Same behavior will be used to other modules and to aliases provided
+         by user/distro.
+
+       - depmod.conf learned a new "excludedir" directive so distro/user can
+         configure more directories to be excluded from its search, besides
+         the hardcoded values "build" and "source".
+
+       - Better group modprobe options on help output under "Management, Query and General".
+
+       - modprobe learned a --wait <MSEC> option to be used together with -r
+         when removing a module. This allows modprobe to keep trying the
+         removal if it fails because the module is still in use. An exponential backoff
+         time is used for further retries.
+
+         The wait behavior provided by the kernel when not passing O_NONBLOCK
+         to delete_module() was removed in v3.13 due to not be used and the
+         consequences of having to support it in the kernel. However there may
+         be some users, particularly on testsuites for individual susbsystems, that
+         would want that. So provide a userspace implementation inside modprobe for
+         such users. "rmmod" doesn't have a --wait as it remains a bare minimal over
+         the API provided by the kernel. In future the --wait behavior can be added
+         to libkmod for testsuites not exec'ing modprobe for module removal.
+
+       - kmod_module_remove_module() learned a new flag to silence output when
+         caller wants to handle them - this is particularly important for the
+         --wait flag to modprobe, as it's not desired to keep seeing error messages
+         while waiting for the module to be unused.
+
+       - Add SM3 hash algo support to modinfo output, as already available in the kernel.
+
+- Bug Fixes
+       - Fix modinfo output when showing information for a .ko module when running
+         on a kernel that has that module as builtin.
+
+       - Fix kmod_module_new_from_lookup() returning > 0 rather than 0
+         when it matches an alias.
+
+       - Fix modinfo segfault when module doesn't exist.
+
+       - Add missing function in the html documentation: kmod_get_dirname().
+
+       - Fix modprobe incorrectly handling number of arguments when prepending values from
+         MODPROBE_OPTIONS environment variable.
+
+       - Fix modprobe -r --remove-dependencies and since "dependencies" was a
+         misnomer, add the preferred argument option: "--remove-holders". This
+         is the same name used by the kernel. It allows users to also remove
+         other modules holding the one that is being removed.
+
+       - Fix off-by-one in max module name length in depmod.
+
+- Infra/internal
+       - Start some changes in the out-of-tree test modules in kmod so they are useful
+         for being really inserted in the kernel rather than relying on kmod's mock
+         interface. This helps manual testing and may be used to exercise to test
+         changes in the kernel.
+
+kmod 29
+=======
+
+- Improvements
+       - Add support to use /usr/local as a place for configuration files. This makes it easier
+         to install locally without overriding distro files.
+
+- Bug fixes
+       - Fix `modinfo -F` when module is builtin: when we asked by a specific field from modinfo,
+         it was not working correctly if the module was builtin
+
+       - Documentation fixes on precedence order of /etc and /run: the correct order is
+         /etc/modprobe.d, /run/modprobe.d, /lib/modprobe.d
+
+       - Fix the priority order that we use for searching configuration files. The
+         correct one is /etc, /run, /usr/local/lib, /lib, for both modprobe.d
+         and depmo.d
+
+       - Fix kernel command line parsing when there are quotes present. Grub
+         mangles the command line and changes it from 'module.option="val with
+         spaces"' to '"module.option=val with spaces"'. Although this is weird
+         behavior and grub could have been fixed, the kernel understands it
+         correctly for builtin modules. So change libkmod to also parse it
+         correctly. This also brings another hidden behavior from the kernel:
+         newline in the kernel command line is also allowed and can be used to
+         separate options.
+
+       - Fix a memory leak, overflow and double free on error path
+
+       - Fix documentation for return value from kmod_module_get_info(): we
+         return the number of entries we added to the list
+
+       - Fix output of modules.builtin.alias.bin index: we were writing an empty file due to
+         the misuse of kmod_module_get_info()
+
+- Infra/internal
+       - Retire integration with semaphoreci
+
+       - Declare the github mirror also as an official upstream source: now besides accepting
+         patches via mailing list, PRs on github are also acceptable
+
+       - Misc improvements to testsuite, so we can use it reliably regardless
+         of the configuration used: now tests will skip if we don't have the
+         build dependencies)
+
+kmod 28
+=======
+
+- Improvements
+       - Add Zstandard to the supported compression formats using libzstd
+         (pass --with-zstd to configure)
+
+- Bug fixes
+       - Ignore ill-formed kernel command line, e.g. with "ivrs_acpihid[00:14.5]=AMD0020:0"
+         option in it
+       - Fix some memory leaks
+       - Fix 0-length builtin.alias.bin: it needs at least the index header
+
 kmod 27
 =======
 
@@ -415,7 +656,7 @@ kmod 11
 - New features:
        - libkmod now keeps a file opened after the first call to
          kmod_module_get_{info,versions,symbols,dependency_symbols}. This
-         reduces signficantly the amount of time depmod tool takes to
+         reduces significantly the amount of time depmod tool takes to
          execute. Particularly if compressed modules are used.
        - Remove --with-rootprefix from build system. It was not a great idea
          after all and should not be use since it causes more harm then
diff --git a/README b/README
deleted file mode 100644 (file)
index a0226e3..0000000
--- a/README
+++ /dev/null
@@ -1,131 +0,0 @@
-kmod - Linux kernel module handling
-
-Information
-===========
-
-Build Status:
-       https://lucasdemarchi.semaphoreci.com/projects/kmod
-
-Mailing list:
-       linux-modules@vger.kernel.org (no subscription needed)
-       https://lore.kernel.org/linux-modules/
-
-Patchwork:
-       https://patchwork.kernel.org/project/linux-modules/
-
-Signed packages:
-       http://www.kernel.org/pub/linux/utils/kernel/kmod/
-
-Git:
-       git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
-       http://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
-       https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
-
-Gitweb:
-       http://git.kernel.org/?p=utils/kernel/kmod/kmod.git
-
-Irc:
-       #kmod on irc.freenode.org
-
-License:
-       LGPLv2.1+ for libkmod, testsuite and helper libraries
-       GPLv2+ for tools/*
-
-
-OVERVIEW
-========
-
-kmod is a set of tools to handle common tasks with Linux kernel modules like
-insert, remove, list, check properties, resolve dependencies and aliases.
-
-These tools are designed on top of libkmod, a library that is shipped with
-kmod. See libkmod/README for more details on this library and how to use it.
-The aim is to be compatible with tools, configurations and indexes from
-module-init-tools project.
-
-Compilation and installation
-============================
-
-In order to compiler the source code you need following software packages:
-       - GCC compiler
-       - GNU C library
-
-Optional dependencies:
-       - ZLIB library
-       - LZMA library
-
-Typical configuration:
-       ./configure CFLAGS="-g -O2" --prefix=/usr \
-                       --sysconfdir=/etc --libdir=/usr/lib
-
-Configure automatically searches for all required components and packages.
-
-To compile and install run:
-       make && make install
-
-Hacking
-=======
-
-Run 'autogen.sh' script before configure. If you want to accept the recommended
-flags, you just need to run 'autogen.sh c'. Note that the recommended
-flags require cython be installed to compile successfully.
-
-Make sure to read the CODING-STYLE file and the other READMEs: libkmod/README
-and testsuite/README.
-
-Compatibility with module-init-tools
-====================================
-
-kmod replaces module-init-tools, which is end-of-life. Most of its tools are
-rewritten on top of libkmod so it can be used as a drop in replacements.
-Somethings however were changed. Reasons vary from "the feature was already
-long deprecated on module-init-tools" to "it would be too much trouble to
-support it".
-
-There are several features that are being added in kmod, but we don't
-keep track of them here.
-
-modprobe
---------
-
-* 'modprobe -l' was marked as deprecated and does not exist anymore
-
-* 'modprobe -t' is gone, together with 'modprobe -l'
-
-* modprobe doesn't parse configuration files with names not ending in
-  '.alias' or '.conf'. modprobe used to warn about these files.
-
-* modprobe doesn't parse 'config' and 'include' commands in configuration
-  files.
-
-* modprobe from m-i-t does not honour softdeps for install commands. E.g.:
-  config:
-
-        install bli "echo bli"
-       install bla "echo bla"
-       softdep bla pre: bli
-
-  With m-i-t, the output of 'modprobe --show-depends bla' will be:
-        install "echo bla"
-
-  While with kmod:
-        install "echo bli"
-        install "echo bla"
-
-* kmod doesn't dump the configuration as is in the config files. Instead it
-  dumps the configuration as it was parsed. Therefore, comments and file names
-  are not dumped, but on the good side we know what the exact configuration
-  kmod is using. We did this because if we only want to know the entire content
-  of configuration files, it's enough to use find(1) in modprobe.d directories
-
-depmod
-------
-
-* there's no 'depmod -m' option: legacy modules.*map files are gone
-
-lsmod
------
-
-* module-init-tools used /proc/modules to parse module info. kmod uses
-  /sys/module/*, but there's a fallback to /proc/modules if the latter isn't
-  available
index d3b84bd617f6a0de36e573e7e1650abab314e1b6..9b22bd71153a6699ec2faaeff7947d7c00acc03f 100644 (file)
--- a/README.md
+++ b/README.md
@@ -2,4 +2,129 @@
 
 [![Coverity Scan Status](https://scan.coverity.com/projects/2096/badge.svg)](https://scan.coverity.com/projects/2096)
 
-This is a ***mirror only***. Please see [README](../master/README) file for more information.
+
+Information
+===========
+
+Mailing list:
+       linux-modules@vger.kernel.org (no subscription needed)
+       https://lore.kernel.org/linux-modules/
+
+Signed packages:
+       http://www.kernel.org/pub/linux/utils/kernel/kmod/
+
+Git:
+       git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
+       http://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
+       https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
+
+Gitweb:
+       http://git.kernel.org/?p=utils/kernel/kmod/kmod.git
+       https://github.com/kmod-project/kmod
+
+Irc:
+       #kmod on irc.freenode.org
+
+License:
+       LGPLv2.1+ for libkmod, testsuite and helper libraries
+       GPLv2+ for tools/*
+
+
+OVERVIEW
+========
+
+kmod is a set of tools to handle common tasks with Linux kernel modules like
+insert, remove, list, check properties, resolve dependencies and aliases.
+
+These tools are designed on top of libkmod, a library that is shipped with
+kmod. See libkmod/README for more details on this library and how to use it.
+The aim is to be compatible with tools, configurations and indexes from
+module-init-tools project.
+
+Compilation and installation
+============================
+
+In order to compiler the source code you need following software packages:
+       - GCC compiler
+       - GNU C library
+
+Optional dependencies:
+       - ZLIB library
+       - LZMA library
+       - ZSTD library
+       - OPENSSL library (signature handling in modinfo)
+
+Typical configuration:
+       ./configure CFLAGS="-g -O2" --prefix=/usr \
+                       --sysconfdir=/etc --libdir=/usr/lib
+
+Configure automatically searches for all required components and packages.
+
+To compile and install run:
+       make && make install
+
+Hacking
+=======
+
+Run 'autogen.sh' script before configure. If you want to accept the recommended
+flags, you just need to run 'autogen.sh c'.
+
+Make sure to read the CODING-STYLE file and the other READMEs: libkmod/README
+and testsuite/README.
+
+Compatibility with module-init-tools
+====================================
+
+kmod replaces module-init-tools, which is end-of-life. Most of its tools are
+rewritten on top of libkmod so it can be used as a drop in replacements.
+Somethings however were changed. Reasons vary from "the feature was already
+long deprecated on module-init-tools" to "it would be too much trouble to
+support it".
+
+There are several features that are being added in kmod, but we don't
+keep track of them here.
+
+modprobe
+--------
+
+* 'modprobe -l' was marked as deprecated and does not exist anymore
+
+* 'modprobe -t' is gone, together with 'modprobe -l'
+
+* modprobe doesn't parse configuration files with names not ending in
+  '.alias' or '.conf'. modprobe used to warn about these files.
+
+* modprobe doesn't parse 'config' and 'include' commands in configuration
+  files.
+
+* modprobe from m-i-t does not honour softdeps for install commands. E.g.:
+  config:
+
+        install bli "echo bli"
+       install bla "echo bla"
+       softdep bla pre: bli
+
+  With m-i-t, the output of 'modprobe --show-depends bla' will be:
+        install "echo bla"
+
+  While with kmod:
+        install "echo bli"
+        install "echo bla"
+
+* kmod doesn't dump the configuration as is in the config files. Instead it
+  dumps the configuration as it was parsed. Therefore, comments and file names
+  are not dumped, but on the good side we know what the exact configuration
+  kmod is using. We did this because if we only want to know the entire content
+  of configuration files, it's enough to use find(1) in modprobe.d directories
+
+depmod
+------
+
+* there's no 'depmod -m' option: legacy modules.*map files are gone
+
+lsmod
+-----
+
+* module-init-tools used /proc/modules to parse module info. kmod uses
+  /sys/module/*, but there's a fallback to /proc/modules if the latter isn't
+  available
index 67b119f6fc6e092c5d21f87088109ffaca9cdbf9..a7a6022d250c38a2b8f9fee95813ca884e6107c9 100755 (executable)
@@ -25,14 +25,19 @@ fi
 
 if [ ! -L /bin ]; then
     args="$args \
-        --with-rootprefix= \
         --with-rootlibdir=$(libdir /lib) \
         "
 fi
 
 cd $oldpwd
 
-hackargs="--enable-debug --enable-python --with-xz --with-zlib --with-openssl"
+hackargs="\
+--enable-debug \
+--with-zstd \
+--with-xz \
+--with-zlib \
+--with-openssl \
+"
 
 if [ "x$1" = "xc" ]; then
         shift
index 4a65d6ba7a3790eae54b9b82656af77492b4820f..a80780e370f9a67f418adaa8496d9c7fd563461d 100644 (file)
@@ -1,6 +1,6 @@
 AC_PREREQ(2.64)
 AC_INIT([kmod],
-       [27],
+       [32],
        [linux-modules@vger.kernel.org],
        [kmod],
        [http://git.kernel.org/?p=utils/kernel/kmod/kmod.git])
@@ -21,6 +21,9 @@ LT_INIT([disable-static pic-only])
 AS_IF([test "x$enable_static" = "xyes"], [AC_MSG_ERROR([--enable-static is not supported by kmod])])
 AS_IF([test "x$enable_largefile" = "xno"], [AC_MSG_ERROR([--disable-largefile is not supported by kmod])])
 
+module_compressions=""
+module_signatures="legacy"
+
 #####################################################################
 # Program checks and configurations
 #####################################################################
@@ -30,7 +33,6 @@ AC_PROG_MKDIR_P
 AC_PROG_LN_S
 PKG_PROG_PKG_CONFIG
 AC_PATH_PROG([XSLTPROC], [xsltproc])
-AC_PATH_PROG([MKOSI], [mkosi])
 
 AC_PROG_CC_C99
 
@@ -68,7 +70,8 @@ AC_COMPILE_IFELSE(
 
 AC_MSG_CHECKING([whether _Noreturn is supported])
 AC_COMPILE_IFELSE(
-       [AC_LANG_SOURCE([[_Noreturn int foo(void) { exit(0); }]])],
+       [AC_LANG_SOURCE([[#include <stdlib.h>
+       _Noreturn int foo(void) { exit(0); }]])],
         [AC_DEFINE([HAVE_NORETURN], [1], [Define if _Noreturn is available])
         AC_MSG_RESULT([yes])],
        [AC_MSG_RESULT([no])])
@@ -78,17 +81,57 @@ AC_COMPILE_IFELSE(
 # --with-
 #####################################################################
 
+AC_ARG_WITH([distconfdir], AS_HELP_STRING([--with-distconfdir=DIR], [directory to search for distribution configuration files]),
+        [], [with_distconfdir='${prefix}/lib'])
+AC_SUBST([distconfdir], [$with_distconfdir])
+
 AC_ARG_WITH([rootlibdir],
         AS_HELP_STRING([--with-rootlibdir=DIR], [rootfs directory to install shared libraries]),
         [], [with_rootlibdir=$libdir])
 AC_SUBST([rootlibdir], [$with_rootlibdir])
 
+# Ideally this would be $prefix/lib/modules but default to /lib/modules for compatibility with earlier versions
+AC_ARG_WITH([module_directory],
+        AS_HELP_STRING([--with-module-directory=DIR], [directory in which to look for kernel modules @<:@default=/lib/modules@:>@]),
+        [], [with_module_directory=/lib/modules])
+AC_SUBST([module_directory], [$with_module_directory])
+
+# Check all directory arguments for consistency.
+for ac_var in  distconfdir rootlibdir module_directory
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*@<:@^/@:>@\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    @<:@\\/$@:>@* | ?:@<:@\\/@:>@* )  continue;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+AC_ARG_WITH([zstd],
+       AS_HELP_STRING([--with-zstd], [handle Zstandard-compressed modules @<:@default=disabled@:>@]),
+       [], [with_zstd=no])
+AS_IF([test "x$with_zstd" != "xno"], [
+       PKG_CHECK_MODULES([libzstd], [libzstd >= 1.4.4], [LIBS="$LIBS $libzstd_LIBS"])
+       AC_DEFINE([ENABLE_ZSTD], [1], [Enable Zstandard for modules.])
+       module_compressions="zstd $module_compressions"
+], [
+       AC_MSG_NOTICE([Zstandard support not requested])
+])
+CC_FEATURE_APPEND([with_features], [with_zstd], [ZSTD])
+
 AC_ARG_WITH([xz],
        AS_HELP_STRING([--with-xz], [handle Xz-compressed modules @<:@default=disabled@:>@]),
        [], [with_xz=no])
 AS_IF([test "x$with_xz" != "xno"], [
-       PKG_CHECK_MODULES([liblzma], [liblzma >= 4.99])
+       PKG_CHECK_MODULES([liblzma], [liblzma >= 4.99], [LIBS="$LIBS $liblzma_LIBS"])
        AC_DEFINE([ENABLE_XZ], [1], [Enable Xz for modules.])
+       module_compressions="xz $module_compressions"
 ], [
        AC_MSG_NOTICE([Xz support not requested])
 ])
@@ -98,8 +141,9 @@ AC_ARG_WITH([zlib],
        AS_HELP_STRING([--with-zlib], [handle gzipped modules @<:@default=disabled@:>@]),
        [], [with_zlib=no])
 AS_IF([test "x$with_zlib" != "xno"], [
-       PKG_CHECK_MODULES([zlib], [zlib])
+       PKG_CHECK_MODULES([zlib], [zlib], [LIBS="$LIBS $zlib_LIBS"])
        AC_DEFINE([ENABLE_ZLIB], [1], [Enable zlib for modules.])
+       module_compressions="gzip $module_compressions"
 ], [
        AC_MSG_NOTICE([zlib support not requested])
 ])
@@ -109,8 +153,9 @@ AC_ARG_WITH([openssl],
        AS_HELP_STRING([--with-openssl], [handle PKCS7 signatures @<:@default=disabled@:>@]),
        [], [with_openssl=no])
 AS_IF([test "x$with_openssl" != "xno"], [
-       PKG_CHECK_MODULES([libcrypto], [libcrypto >= 1.1.0])
+       PKG_CHECK_MODULES([libcrypto], [libcrypto >= 1.1.0], [LIBS="$LIBS $libcrypto_LIBS"])
        AC_DEFINE([ENABLE_OPENSSL], [1], [Enable openssl for modinfo.])
+       module_signatures="PKCS7 $module_signatures"
 ], [
        AC_MSG_NOTICE([openssl support not requested])
 ])
@@ -130,15 +175,6 @@ AC_SUBST([bashcompletiondir], [$with_bashcompletiondir])
 # --enable-
 #####################################################################
 
-AC_ARG_ENABLE([experimental],
-        AS_HELP_STRING([--enable-experimental], [enable experimental tools and features. Do not enable it unless you know what you are doing. @<:@default=disabled@:>@]),
-        [], enable_experimental=no)
-AM_CONDITIONAL([BUILD_EXPERIMENTAL], [test "x$enable_experimental" = "xyes"])
-AS_IF([test "x$enable_experimental" = "xyes"], [
-       AC_DEFINE(ENABLE_EXPERIMENTAL, [1], [Experimental features.])
-])
-CC_FEATURE_APPEND([with_features], [enable_experimental], [EXPERIMENTAL])
-
 AC_ARG_ENABLE([tools],
         AS_HELP_STRING([--disable-tools], [disable building tools that provide same functionality as module-init-tools @<:@default=enabled@:>@]),
        [], enable_tools=yes)
@@ -168,24 +204,6 @@ AS_IF([test "x$enable_debug" = "xyes"], [
        AC_DEFINE(ENABLE_DEBUG, [1], [Debug messages.])
 ])
 
-AC_ARG_ENABLE([python],
-       AS_HELP_STRING([--enable-python], [enable Python libkmod bindings @<:@default=disabled@:>@]),
-       [], [enable_python=no])
-AS_IF([test "x$enable_python" = "xyes"], [
-       AM_PATH_PYTHON(,,[:])
-       AC_PATH_PROG([CYTHON], [cython], [:])
-
-       PKG_CHECK_MODULES([PYTHON], [python-${PYTHON_VERSION}],
-                         [have_python=yes],
-                         [PKG_CHECK_MODULES([PYTHON], [python],
-                                            [have_python=yes],
-                                            [have_python=no])])
-
-       AS_IF([test "x$have_python" = xno],
-             [AC_MSG_ERROR([*** python support requested but libraries not found])])
-])
-AM_CONDITIONAL([BUILD_PYTHON], [test "x$enable_python" = "xyes"])
-
 AC_ARG_ENABLE([coverage],
        AS_HELP_STRING([--enable-coverage], [enable test coverage @<:@default=disabled@:>@]),
        [], [enable_coverage=no])
@@ -213,6 +231,8 @@ GTK_DOC_CHECK([1.14],[--flavour no-tmpl-flat])
 ], [
 AM_CONDITIONAL([ENABLE_GTK_DOC], false)])
 
+PKG_INSTALLDIR
+PKG_NOARCH_INSTALLDIR
 
 #####################################################################
 # Default CFLAGS and LDFLAGS
@@ -276,11 +296,16 @@ AC_DEFINE_UNQUOTED(KMOD_FEATURES, ["$with_features"], [Features in this build])
 # Generate files from *.in
 #####################################################################
 
+AC_SUBST([module_compressions], $module_compressions)
+AC_SUBST([module_signatures], $module_signatures)
+
 AC_CONFIG_FILES([
        Makefile
        man/Makefile
        libkmod/docs/Makefile
        libkmod/docs/version.xml
+       libkmod/libkmod.pc
+       tools/kmod.pc
 ])
 
 
@@ -291,8 +316,10 @@ AC_MSG_RESULT([
        $PACKAGE $VERSION
        =======
 
+       module_directory:       ${module_directory}
        prefix:                 ${prefix}
        sysconfdir:             ${sysconfdir}
+       distconfdir:            ${distconfdir}
        libdir:                 ${libdir}
        rootlibdir:             ${rootlibdir}
        includedir:             ${includedir}
@@ -303,11 +330,9 @@ AC_MSG_RESULT([
        cflags:                 ${with_cflags} ${CFLAGS}
        ldflags:                ${with_ldflags} ${LDFLAGS}
 
-       experimental features:  ${enable_experimental}
        tools:                  ${enable_tools}
-       python bindings:        ${enable_python}
        logging:                ${enable_logging}
-       compression:            xz=${with_xz}  zlib=${with_zlib}
+       compression:            zstd=${with_zstd}  xz=${with_xz}  zlib=${with_zlib}
        debug:                  ${enable_debug}
        coverage:               ${enable_coverage}
        doc:                    ${enable_gtk_doc}
index e59ab7a4c5a280bb9ef9deb516295fa326c8716f..33d9eec53fd5172a7645ae41782c3954ef654a86 100644 (file)
@@ -15,6 +15,7 @@ kmod_get_log_priority
 kmod_set_log_fn
 kmod_get_userdata
 kmod_set_userdata
+kmod_get_dirname
 </SECTION>
 
 <SECTION>
@@ -46,6 +47,7 @@ kmod_config_iter_free_iter
 <FILE>libkmod-module</FILE>
 kmod_module
 kmod_module_new_from_lookup
+kmod_module_new_from_name_lookup
 kmod_module_new_from_name
 kmod_module_new_from_path
 
index aaec5ddb0609bd2514ba2d3989247fe8e21b5213..65334a8a4e0eed4c608d69178f6ea92ed10016a2 100644 (file)
@@ -54,7 +54,7 @@ struct kmod_builtin_iter {
        char *buf;
 };
 
-struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx)
+static struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx)
 {
        char path[PATH_MAX];
        int file, sv_errno;
@@ -108,7 +108,7 @@ fail:
        return iter;
 }
 
-void kmod_builtin_iter_free(struct kmod_builtin_iter *iter)
+static void kmod_builtin_iter_free(struct kmod_builtin_iter *iter)
 {
        close(iter->file);
        free(iter->buf);
@@ -165,7 +165,7 @@ fail:
        return -1;
 }
 
-bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter)
+static bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter)
 {
        char *line,  *modname;
        size_t linesz;
@@ -216,7 +216,7 @@ bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter)
        return (iter->pos < iter->size);
 }
 
-bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter,
+static bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter,
                                char modname[static PATH_MAX])
 {
        int sv_errno;
@@ -246,7 +246,7 @@ bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter,
 
        len = dot - line;
 
-       if (len > PATH_MAX) {
+       if (len >= PATH_MAX) {
                sv_errno = ENAMETOOLONG;
                goto fail;
        }
@@ -313,7 +313,8 @@ ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname,
        while (offset < iter->next) {
                offset = get_string(iter, pos, &line, &linesz);
                if (offset <= 0) {
-                       count = (offset) ? -errno : -EOF;
+                       count = (offset) ? -errno : -EINVAL;
+                       free(*modinfo);
                        goto fail;
                }
 
index 971f20b8a352406f3bbdeba12cd684266e0dc171..e83621b3415796586e3bbc6a68752b11d27fab88 100644 (file)
@@ -498,8 +498,15 @@ static int kmod_config_parse_kcmdline(struct kmod_config *config)
 {
        char buf[KCMD_LINE_SIZE];
        int fd, err;
-       char *p, *modname,  *param = NULL, *value = NULL;
-       bool is_quoted = false, is_module = true;
+       char *p, *p_quote_start, *modname,  *param = NULL, *value = NULL;
+       bool is_quoted = false, iter = true;
+       enum state {
+               STATE_IGNORE,
+               STATE_MODNAME,
+               STATE_PARAM,
+               STATE_VALUE,
+               STATE_COMPLETE,
+       } state;
 
        fd = open("/proc/cmdline", O_RDONLY|O_CLOEXEC);
        if (fd < 0) {
@@ -516,54 +523,102 @@ static int kmod_config_parse_kcmdline(struct kmod_config *config)
                return err;
        }
 
-       for (p = buf, modname = buf; *p != '\0' && *p != '\n'; p++) {
-               if (*p == '"') {
+       state = STATE_MODNAME;
+       p_quote_start = NULL;
+       for (p = buf, modname = buf; iter; p++) {
+               switch (*p) {
+               case '"':
                        is_quoted = !is_quoted;
 
-                       if (is_quoted) {
-                               /* don't consider a module until closing quotes */
-                               is_module = false;
-                       } else if (param != NULL && value != NULL) {
-                               /*
-                                * If we are indeed expecting a value and
-                                * closing quotes, then this can be considered
-                                * a valid option for a module
-                                */
-                               is_module = true;
+                       /*
+                        * only allow starting quote as first char when looking
+                        * for a modname: anything else is considered ill-formed
+                        */
+                       if (is_quoted && state == STATE_MODNAME && p == modname) {
+                               p_quote_start = p;
+                               modname = p + 1;
+                       } else if (state != STATE_VALUE) {
+                               state = STATE_IGNORE;
                        }
 
-                       continue;
-               }
-               if (is_quoted)
-                       continue;
-
-               switch (*p) {
+                       break;
+               case '\0':
+                       iter = false;
+                       /* fall-through */
                case ' ':
-                       *p = '\0';
-                       if (is_module)
-                               kcmdline_parse_result(config, modname, param, value);
-                       param = value = NULL;
-                       modname = p + 1;
-                       is_module = true;
+               case '\n':
+               case '\t':
+               case '\v':
+               case '\f':
+               case '\r':
+                       if (is_quoted && state == STATE_VALUE) {
+                               /* no state change*/;
+                       } else if (is_quoted) {
+                               /* spaces are only allowed in the value part */
+                               state = STATE_IGNORE;
+                       } else if (state == STATE_VALUE || state == STATE_PARAM) {
+                               *p = '\0';
+                               state = STATE_COMPLETE;
+                       } else {
+                               /*
+                                * go to next option, ignoring any possible
+                                * partial match we have
+                                */
+                               modname = p + 1;
+                               state = STATE_MODNAME;
+                               p_quote_start = NULL;
+                       }
                        break;
                case '.':
-                       if (param == NULL) {
+                       if (state == STATE_MODNAME) {
                                *p = '\0';
                                param = p + 1;
+                               state = STATE_PARAM;
+                       } else if (state == STATE_PARAM) {
+                               state = STATE_IGNORE;
                        }
                        break;
                case '=':
-                       if (param != NULL)
+                       if (state == STATE_PARAM) {
+                               /*
+                                * Don't set *p to '\0': the value var shadows
+                                * param
+                                */
                                value = p + 1;
-                       else
-                               is_module = false;
+                               state = STATE_VALUE;
+                       } else if (state == STATE_MODNAME) {
+                               state = STATE_IGNORE;
+                       }
                        break;
                }
-       }
 
-       *p = '\0';
-       if (is_module)
-               kcmdline_parse_result(config, modname, param, value);
+               if (state == STATE_COMPLETE) {
+                       /*
+                        * We may need to re-quote to unmangle what the
+                        * bootloader passed. Example: grub passes the option as
+                        * "parport.dyndbg=file drivers/parport/ieee1284_ops.c +mpf"
+                        * instead of
+                        * parport.dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
+                        */
+                       if (p_quote_start && p_quote_start < modname) {
+                               /*
+                                * p_quote_start
+                                * |
+                                * |modname  param  value
+                                * ||        |      |
+                                * vv        v      v
+                                * "parport\0dyndbg=file drivers/parport/ieee1284_ops.c +mpf" */
+                               memmove(p_quote_start, modname, value - modname);
+                               value--; modname--; param--;
+                               *value = '"';
+                       }
+                       kcmdline_parse_result(config, modname, param, value);
+                       /* start over on next iteration */
+                       modname = p + 1;
+                       state = STATE_MODNAME;
+                       p_quote_start = NULL;
+               }
+       }
 
        return 0;
 }
@@ -854,8 +909,10 @@ int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config,
                memcpy(cf->path, path, pathlen);
 
                tmp = kmod_list_append(path_list, cf);
-               if (tmp == NULL)
+               if (tmp == NULL) {
+                       free(cf);
                        goto oom;
+               }
                path_list = tmp;
        }
 
index ef4a8a3142a1f48dbbe913b9c8a16ac41d205bf8..933825be2d04c2790bf463797fdef65be99921f0 100644 (file)
@@ -281,6 +281,11 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size)
        assert_cc(sizeof(uint32_t) == sizeof(Elf32_Word));
        assert_cc(sizeof(uint32_t) == sizeof(Elf64_Word));
 
+       if (!memory) {
+               errno = -EINVAL;
+               return NULL;
+       }
+
        class = elf_identify(memory, size);
        if (class < 0) {
                errno = -class;
@@ -392,7 +397,7 @@ static int elf_find_section(const struct kmod_elf *elf, const char *section)
                return i;
        }
 
-       return -ENOENT;
+       return -ENODATA;
 }
 
 int kmod_elf_get_section(const struct kmod_elf *elf, const char *section, const void **buf, uint64_t *buf_size)
@@ -422,7 +427,7 @@ int kmod_elf_get_section(const struct kmod_elf *elf, const char *section, const
                return 0;
        }
 
-       return -ENOENT;
+       return -ENODATA;
 }
 
 /* array will be allocated with strings in a single malloc, just free *array */
@@ -653,7 +658,7 @@ int kmod_elf_strip_vermagic(struct kmod_elf *elf)
        }
 
        ELFDBG(elf, "no vermagic found in .modinfo\n");
-       return -ENOENT;
+       return -ENODATA;
 }
 
 
index 5eeba6a912a2ff987ec3e471da83b92d158182d3..b138e7ee6c37582a0aafcd765430f5a4bdedc777 100644 (file)
@@ -26,6 +26,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#ifdef ENABLE_ZSTD
+#include <zstd.h>
+#endif
 #ifdef ENABLE_XZ
 #include <lzma.h>
 #endif
@@ -45,6 +48,9 @@ struct file_ops {
 };
 
 struct kmod_file {
+#ifdef ENABLE_ZSTD
+       bool zstd_used;
+#endif
 #ifdef ENABLE_XZ
        bool xz_used;
 #endif
@@ -52,7 +58,7 @@ struct kmod_file {
        gzFile gzf;
 #endif
        int fd;
-       bool direct;
+       enum kmod_file_compression_type compression;
        off_t size;
        void *memory;
        const struct file_ops *ops;
@@ -60,6 +66,141 @@ struct kmod_file {
        struct kmod_elf *elf;
 };
 
+#ifdef ENABLE_ZSTD
+static int zstd_read_block(struct kmod_file *file, size_t block_size,
+                          ZSTD_inBuffer *input, size_t *input_capacity)
+{
+       ssize_t rdret;
+       int ret;
+
+       if (*input_capacity < block_size) {
+               free((void *)input->src);
+               input->src = malloc(block_size);
+               if (input->src == NULL) {
+                       ret = -errno;
+                       ERR(file->ctx, "zstd: %m\n");
+                       return ret;
+               }
+               *input_capacity = block_size;
+       }
+
+       rdret = read(file->fd, (void *)input->src, block_size);
+       if (rdret < 0) {
+               ret = -errno;
+               ERR(file->ctx, "zstd: %m\n");
+               return ret;
+       }
+
+       input->pos = 0;
+       input->size = rdret;
+       return 0;
+}
+
+static int zstd_ensure_outbuffer_space(ZSTD_outBuffer *buffer, size_t min_free)
+{
+       uint8_t *old_buffer = buffer->dst;
+       int ret = 0;
+
+       if (buffer->size - buffer->pos >= min_free)
+               return 0;
+
+       buffer->size += min_free;
+       buffer->dst = realloc(buffer->dst, buffer->size);
+       if (buffer->dst == NULL) {
+               ret = -errno;
+               free(old_buffer);
+       }
+
+       return ret;
+}
+
+static int zstd_decompress_block(struct kmod_file *file, ZSTD_DStream *dstr,
+                                ZSTD_inBuffer *input, ZSTD_outBuffer *output,
+                                size_t *next_block_size)
+{
+       size_t out_buf_min_size = ZSTD_DStreamOutSize();
+       int ret = 0;
+
+       do {
+               ssize_t dsret;
+
+               ret = zstd_ensure_outbuffer_space(output, out_buf_min_size);
+               if (ret) {
+                       ERR(file->ctx, "zstd: %s\n", strerror(-ret));
+                       break;
+               }
+
+               dsret = ZSTD_decompressStream(dstr, output, input);
+               if (ZSTD_isError(dsret)) {
+                       ret = -EINVAL;
+                       ERR(file->ctx, "zstd: %s\n", ZSTD_getErrorName(dsret));
+                       break;
+               }
+               if (dsret > 0)
+                       *next_block_size = (size_t)dsret;
+       } while (input->pos < input->size
+                || output->pos > output->size
+                || output->size - output->pos < out_buf_min_size);
+
+       return ret;
+}
+
+static int load_zstd(struct kmod_file *file)
+{
+       ZSTD_DStream *dstr;
+       size_t next_block_size;
+       size_t zst_inb_capacity = 0;
+       ZSTD_inBuffer zst_inb = { 0 };
+       ZSTD_outBuffer zst_outb = { 0 };
+       int ret;
+
+       dstr = ZSTD_createDStream();
+       if (dstr == NULL) {
+               ret = -EINVAL;
+               ERR(file->ctx, "zstd: Failed to create decompression stream\n");
+               goto out;
+       }
+
+       next_block_size = ZSTD_initDStream(dstr);
+
+       while (true) {
+               ret = zstd_read_block(file, next_block_size, &zst_inb,
+                                     &zst_inb_capacity);
+               if (ret != 0)
+                       goto out;
+               if (zst_inb.size == 0) /* EOF */
+                       break;
+
+               ret = zstd_decompress_block(file, dstr, &zst_inb, &zst_outb,
+                                           &next_block_size);
+               if (ret != 0)
+                       goto out;
+       }
+
+       ZSTD_freeDStream(dstr);
+       free((void *)zst_inb.src);
+       file->zstd_used = true;
+       file->memory = zst_outb.dst;
+       file->size = zst_outb.pos;
+       return 0;
+out:
+       if (dstr != NULL)
+               ZSTD_freeDStream(dstr);
+       free((void *)zst_inb.src);
+       free((void *)zst_outb.dst);
+       return ret;
+}
+
+static void unload_zstd(struct kmod_file *file)
+{
+       if (!file->zstd_used)
+               return;
+       free(file->memory);
+}
+
+static const char magic_zstd[] = {0x28, 0xB5, 0x2F, 0xFD};
+#endif
+
 #ifdef ENABLE_XZ
 static void xz_uncompress_belch(struct kmod_file *file, lzma_ret ret)
 {
@@ -235,16 +376,20 @@ static const char magic_zlib[] = {0x1f, 0x8b};
 
 static const struct comp_type {
        size_t magic_size;
+       enum kmod_file_compression_type compression;
        const char *magic_bytes;
        const struct file_ops ops;
 } comp_types[] = {
+#ifdef ENABLE_ZSTD
+       {sizeof(magic_zstd),    KMOD_FILE_COMPRESSION_ZSTD, magic_zstd, {load_zstd, unload_zstd}},
+#endif
 #ifdef ENABLE_XZ
-       {sizeof(magic_xz), magic_xz, {load_xz, unload_xz}},
+       {sizeof(magic_xz),      KMOD_FILE_COMPRESSION_XZ, magic_xz, {load_xz, unload_xz}},
 #endif
 #ifdef ENABLE_ZLIB
-       {sizeof(magic_zlib), magic_zlib, {load_zlib, unload_zlib}},
+       {sizeof(magic_zlib),    KMOD_FILE_COMPRESSION_ZLIB, magic_zlib, {load_zlib, unload_zlib}},
 #endif
-       {0, NULL, {NULL, NULL}}
+       {0,                     KMOD_FILE_COMPRESSION_NONE, NULL, {NULL, NULL}}
 };
 
 static int load_reg(struct kmod_file *file)
@@ -259,7 +404,7 @@ static int load_reg(struct kmod_file *file)
                            file->fd, 0);
        if (file->memory == MAP_FAILED)
                return -errno;
-       file->direct = true;
+
        return 0;
 }
 
@@ -277,6 +422,7 @@ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file)
        if (file->elf)
                return file->elf;
 
+       kmod_file_load_contents(file);
        file->elf = kmod_elf_new(file->memory, file->size);
        return file->elf;
 }
@@ -287,7 +433,7 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx,
        struct kmod_file *file = calloc(1, sizeof(struct kmod_file));
        const struct comp_type *itr;
        size_t magic_size_max = 0;
-       int err;
+       int err = 0;
 
        if (file == NULL)
                return NULL;
@@ -303,7 +449,6 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx,
                        magic_size_max = itr->magic_size;
        }
 
-       file->direct = false;
        if (magic_size_max > 0) {
                char *buf = alloca(magic_size_max + 1);
                ssize_t sz;
@@ -323,18 +468,21 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx,
                }
 
                for (itr = comp_types; itr->ops.load != NULL; itr++) {
-                       if (memcmp(buf, itr->magic_bytes, itr->magic_size) == 0)
+                       if (memcmp(buf, itr->magic_bytes, itr->magic_size) == 0) {
+                               file->ops = &itr->ops;
+                               file->compression = itr->compression;
                                break;
+                       }
                }
-               if (itr->ops.load != NULL)
-                       file->ops = &itr->ops;
        }
 
-       if (file->ops == NULL)
+       if (file->ops == NULL) {
                file->ops = &reg_ops;
+               file->compression = KMOD_FILE_COMPRESSION_NONE;
+       }
 
-       err = file->ops->load(file);
        file->ctx = ctx;
+
 error:
        if (err < 0) {
                if (file->fd >= 0)
@@ -347,6 +495,18 @@ error:
        return file;
 }
 
+/*
+ *  Callers should just check file->memory got updated
+ */
+void kmod_file_load_contents(struct kmod_file *file)
+{
+       if (file->memory)
+               return;
+
+       /*  The load functions already log possible errors. */
+       file->ops->load(file);
+}
+
 void *kmod_file_get_contents(const struct kmod_file *file)
 {
        return file->memory;
@@ -357,9 +517,9 @@ off_t kmod_file_get_size(const struct kmod_file *file)
        return file->size;
 }
 
-bool kmod_file_get_direct(const struct kmod_file *file)
+enum kmod_file_compression_type kmod_file_get_compression(const struct kmod_file *file)
 {
-       return file->direct;
+       return file->compression;
 }
 
 int kmod_file_get_fd(const struct kmod_file *file)
@@ -372,7 +532,9 @@ void kmod_file_unref(struct kmod_file *file)
        if (file->elf)
                kmod_elf_unref(file->elf);
 
-       file->ops->unload(file);
+       if (file->memory)
+               file->ops->unload(file);
+
        if (file->fd >= 0)
                close(file->fd);
        free(file);
index b22ac2a5f89e1a48a9ee52aee916c7c2c5295ec6..26a7e287f17f82159ba05f943ad4f6c58bc44e0b 100644 (file)
@@ -11,7 +11,7 @@
 #include "libkmod.h"
 
 static _always_inline_ _printf_format_(2, 3) void
-       kmod_log_null(struct kmod_ctx *ctx, const char *format, ...) {}
+       kmod_log_null(const struct kmod_ctx *ctx, const char *format, ...) {}
 
 #define kmod_log_cond(ctx, prio, arg...) \
        do { \
@@ -25,10 +25,12 @@ static _always_inline_ _printf_format_(2, 3) void
 #  else
 #    define DBG(ctx, arg...) kmod_log_null(ctx, ## arg)
 #  endif
+#  define NOTICE(ctx, arg...) kmod_log_cond(ctx, LOG_NOTICE, ## arg)
 #  define INFO(ctx, arg...) kmod_log_cond(ctx, LOG_INFO, ## arg)
 #  define ERR(ctx, arg...) kmod_log_cond(ctx, LOG_ERR, ## arg)
 #else
 #  define DBG(ctx, arg...) kmod_log_null(ctx, ## arg)
+#  define NOTICE(ctx, arg...) kmod_log_null(ctx, ## arg)
 #  define INFO(ctx, arg...) kmod_log_null(ctx, ## arg)
 #  define ERR(ctx, arg...) kmod_log_null(ctx, ## arg)
 #endif
@@ -59,6 +61,13 @@ struct kmod_list {
        void *data;
 };
 
+enum kmod_file_compression_type {
+       KMOD_FILE_COMPRESSION_NONE = 0,
+       KMOD_FILE_COMPRESSION_ZSTD,
+       KMOD_FILE_COMPRESSION_XZ,
+       KMOD_FILE_COMPRESSION_ZLIB,
+};
+
 struct kmod_list *kmod_list_append(struct kmod_list *list, const void *data) _must_check_ __attribute__((nonnull(2)));
 struct kmod_list *kmod_list_prepend(struct kmod_list *list, const void *data) _must_check_ __attribute__((nonnull(2)));
 struct kmod_list *kmod_list_remove(struct kmod_list *list) _must_check_;
@@ -103,6 +112,7 @@ void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod, const c
 void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod, const char *key) __attribute__((nonnull(1, 2, 3)));
 
 const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx) __attribute__((nonnull(1)));
+enum kmod_file_compression_type kmod_get_kernel_compression(const struct kmod_ctx *ctx) __attribute__((nonnull(1)));
 
 /* libkmod-config.c */
 struct kmod_config_path {
@@ -146,14 +156,14 @@ void kmod_module_set_visited(struct kmod_module *mod, bool visited) __attribute_
 void kmod_module_set_builtin(struct kmod_module *mod, bool builtin) __attribute__((nonnull((1))));
 void kmod_module_set_required(struct kmod_module *mod, bool required) __attribute__((nonnull(1)));
 bool kmod_module_is_builtin(struct kmod_module *mod) __attribute__((nonnull(1)));
-int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list) __attribute__((nonnull(1, 2)));
 
 /* libkmod-file.c */
 struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename) _must_check_ __attribute__((nonnull(1,2)));
 struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) __attribute__((nonnull(1)));
+void kmod_file_load_contents(struct kmod_file *file) __attribute__((nonnull(1)));
 void *kmod_file_get_contents(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
 off_t kmod_file_get_size(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
-bool kmod_file_get_direct(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
+enum kmod_file_compression_type kmod_file_get_compression(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
 int kmod_file_get_fd(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
 void kmod_file_unref(struct kmod_file *file) __attribute__((nonnull(1)));
 
@@ -165,7 +175,7 @@ struct kmod_modversion {
        char *symbol;
 };
 
-struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_ __attribute__((nonnull(1)));
+struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_;
 void kmod_elf_unref(struct kmod_elf *elf) __attribute__((nonnull(1)));
 const void *kmod_elf_get_memory(const struct kmod_elf *elf) _must_check_ __attribute__((nonnull(1)));
 int kmod_elf_get_strings(const struct kmod_elf *elf, const char *section, char ***array) _must_check_ __attribute__((nonnull(1,2,3)));
@@ -197,9 +207,4 @@ bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signat
 void kmod_module_signature_info_free(struct kmod_signature_info *sig_info) __attribute__((nonnull));
 
 /* libkmod-builtin.c */
-struct kmod_builtin_iter;
-struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx) __attribute__((nonnull(1)));
-void kmod_builtin_iter_free(struct kmod_builtin_iter *iter) __attribute__((nonnull(1)));
-bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter) __attribute__((nonnull(1)));
-bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter, char modname[static PATH_MAX]) __attribute__((nonnull(1, 2)));
 ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname, char ***modinfo) __attribute__((nonnull(1, 2, 3)));
index 76a6dc30930f7195cd486aef109ca8683112cb2e..585da41a7be7e49e045943c03eae0180e232bb98 100644 (file)
@@ -431,17 +431,18 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
                        return -EEXIST;
                }
 
-               *mod = kmod_module_ref(m);
-               return 0;
-       }
+               kmod_module_ref(m);
+       } else {
+               err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
+               if (err < 0) {
+                       free(abspath);
+                       return err;
+               }
 
-       err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
-       if (err < 0) {
-               free(abspath);
-               return err;
+               m->path = abspath;
        }
 
-       m->path = abspath;
+       m->builtin = KMOD_MODULE_BUILTIN_NO;
        *mod = m;
 
        return 0;
@@ -498,13 +499,26 @@ KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
        return mod;
 }
 
-#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish)    \
-       do {                                                            \
-               if ((_err) < 0)                                         \
-                       goto _label_err;                                \
-               if (*(_list) != NULL)                                   \
-                       goto finish;                                    \
-       } while (0)
+typedef int (*lookup_func)(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
+
+static int __kmod_module_new_from_lookup(struct kmod_ctx *ctx, const lookup_func lookup[],
+                                        size_t lookup_count, const char *s,
+                                        struct kmod_list **list)
+{
+       unsigned int i;
+
+       for (i = 0; i < lookup_count; i++) {
+               int err;
+
+               err = lookup[i](ctx, s, list);
+               if (err < 0 && err != -ENOSYS)
+                       return err;
+               else if (*list != NULL)
+                       return 0;
+       }
+
+       return 0;
+}
 
 /**
  * kmod_module_new_from_lookup:
@@ -520,7 +534,7 @@ KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
  *
  * The search order is: 1. aliases in configuration file; 2. module names in
  * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
- * in modules.alias index.
+ * from install commands; 5. builtin indexes from kernel.
  *
  * The initial refcount is 1, and needs to be decremented to release the
  * resources of the kmod_module. The returned @list must be released by
@@ -537,8 +551,17 @@ KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
                                                const char *given_alias,
                                                struct kmod_list **list)
 {
-       int err;
+       static const lookup_func lookup[] = {
+               kmod_lookup_alias_from_config,
+               kmod_lookup_alias_from_moddep_file,
+               kmod_lookup_alias_from_symbols_file,
+               kmod_lookup_alias_from_commands,
+               kmod_lookup_alias_from_aliases_file,
+               kmod_lookup_alias_from_builtin_file,
+               kmod_lookup_alias_from_kernel_builtin_file,
+       };
        char alias[PATH_MAX];
+       int err;
 
        if (ctx == NULL || given_alias == NULL)
                return -ENOENT;
@@ -555,46 +578,75 @@ KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
 
        DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
 
-       /* Aliases from config file override all the others */
-       err = kmod_lookup_alias_from_config(ctx, alias, list);
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+       err = __kmod_module_new_from_lookup(ctx, lookup, ARRAY_SIZE(lookup),
+                                           alias, list);
 
-       DBG(ctx, "lookup modules.dep %s\n", alias);
-       err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+       DBG(ctx, "lookup=%s found=%d\n", alias, err >= 0 && *list);
 
-       DBG(ctx, "lookup modules.symbols %s\n", alias);
-       err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+       if (err < 0) {
+               kmod_module_unref_list(*list);
+               *list = NULL;
+       }
 
-       DBG(ctx, "lookup install and remove commands %s\n", alias);
-       err = kmod_lookup_alias_from_commands(ctx, alias, list);
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+       return err;
+}
 
-       DBG(ctx, "lookup modules.aliases %s\n", alias);
-       err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+/**
+ * kmod_module_new_from_name_lookup:
+ * @ctx: kmod library context
+ * @modname: module name to look for
+ * @mod: returned module on success
+ *
+ * Lookup by module name, without considering possible aliases. This is similar
+ * to kmod_module_new_from_lookup(), but don't consider as source indexes and
+ * configurations that work with aliases. When succesful, this always resolves
+ * to one and only one module.
+ *
+ * The search order is: 1. module names in modules.dep index;
+ * 2. builtin indexes from kernel.
+ *
+ * The initial refcount is 1, and needs to be decremented to release the
+ * resources of the kmod_module. Since libkmod keeps track of all
+ * kmod_modules created, they are all released upon @ctx destruction too. Do
+ * not unref @ctx before all the desired operations with the returned list are
+ * completed.
+ *
+ * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
+ * methods failed, which is basically due to memory allocation failure. If
+ * module is not found, it still returns 0, but @mod is left untouched.
+ */
+KMOD_EXPORT int kmod_module_new_from_name_lookup(struct kmod_ctx *ctx,
+                                                const char *modname,
+                                                struct kmod_module **mod)
+{
+       static const lookup_func lookup[] = {
+               kmod_lookup_alias_from_moddep_file,
+               kmod_lookup_alias_from_builtin_file,
+               kmod_lookup_alias_from_kernel_builtin_file,
+       };
+       char name_norm[PATH_MAX];
+       struct kmod_list *list = NULL;
+       int err;
 
-       DBG(ctx, "lookup modules.builtin.modinfo %s\n", alias);
-       err = kmod_lookup_alias_from_kernel_builtin_file(ctx, alias, list);
-       if (err == -ENOSYS) {
-               /* Optional index missing, try the old one */
-               DBG(ctx, "lookup modules.builtin %s\n", alias);
-               err = kmod_lookup_alias_from_builtin_file(ctx, alias, list);
-       }
-       CHECK_ERR_AND_FINISH(err, fail, list, finish);
+       if (ctx == NULL || modname == NULL || mod == NULL)
+               return -ENOENT;
 
+       modname_normalize(modname, name_norm, NULL);
+
+       DBG(ctx, "input modname=%s, normalized=%s\n", modname, name_norm);
+
+       err = __kmod_module_new_from_lookup(ctx, lookup, ARRAY_SIZE(lookup),
+                                           name_norm, &list);
+
+       DBG(ctx, "lookup=%s found=%d\n", name_norm, err >= 0 && list);
+
+       if (err >= 0 && list != NULL)
+               *mod = kmod_module_get_module(list);
+
+       kmod_module_unref_list(list);
 
-finish:
-       DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
-       return err;
-fail:
-       DBG(ctx, "Failed to lookup %s\n", alias);
-       kmod_module_unref_list(*list);
-       *list = NULL;
        return err;
 }
-#undef CHECK_ERR_AND_FINISH
 
 /**
  * kmod_module_unref_list:
@@ -771,11 +823,13 @@ extern long delete_module(const char *name, unsigned int flags);
 /**
  * kmod_module_remove_module:
  * @mod: kmod module
- * @flags: flags to pass to Linux kernel when removing the module. The only valid flag is
+ * @flags: flags used when removing the module.
  * KMOD_REMOVE_FORCE: force remove module regardless if it's still in
- * use by a kernel subsystem or other process;
- * KMOD_REMOVE_NOWAIT is always enforced, causing us to pass O_NONBLOCK to
+ * use by a kernel subsystem or other process; passed directly to Linux kernel
+ * KMOD_REMOVE_NOWAIT: is always enforced, causing us to pass O_NONBLOCK to
  * delete_module(2).
+ * KMOD_REMOVE_NOLOG: when module removal fails, do not log anything as the
+ * caller may want to handle retries and log when appropriate.
  *
  * Remove a module from Linux kernel.
  *
@@ -784,6 +838,8 @@ extern long delete_module(const char *name, unsigned int flags);
 KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
                                                        unsigned int flags)
 {
+       unsigned int libkmod_flags = flags & 0xff;
+
        int err;
 
        if (mod == NULL)
@@ -796,7 +852,8 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
        err = delete_module(mod->name, flags);
        if (err != 0) {
                err = -errno;
-               ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
+               if (!(libkmod_flags & KMOD_REMOVE_NOLOG))
+                       ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
        }
 
        return err;
@@ -804,6 +861,82 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
 
 extern long init_module(const void *mem, unsigned long len, const char *args);
 
+static int do_finit_module(struct kmod_module *mod, unsigned int flags,
+                          const char *args)
+{
+       enum kmod_file_compression_type compression, kernel_compression;
+       unsigned int kernel_flags = 0;
+       int err;
+
+       /*
+        * When module is not compressed or its compression type matches the
+        * one in use by the kernel, there is no need to read the file
+        * in userspace. Otherwise, re-use ENOSYS to trigger the same fallback
+        * as when finit_module() is not supported.
+        */
+       compression = kmod_file_get_compression(mod->file);
+       kernel_compression = kmod_get_kernel_compression(mod->ctx);
+       if (!(compression == KMOD_FILE_COMPRESSION_NONE ||
+             compression == kernel_compression))
+               return -ENOSYS;
+
+       if (compression != KMOD_FILE_COMPRESSION_NONE)
+               kernel_flags |= MODULE_INIT_COMPRESSED_FILE;
+
+       if (flags & KMOD_INSERT_FORCE_VERMAGIC)
+               kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
+       if (flags & KMOD_INSERT_FORCE_MODVERSION)
+               kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;
+
+       err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
+       if (err < 0)
+               err = -errno;
+
+       return err;
+}
+
+static int do_init_module(struct kmod_module *mod, unsigned int flags,
+                         const char *args)
+{
+       struct kmod_elf *elf;
+       const void *mem;
+       off_t size;
+       int err;
+
+       kmod_file_load_contents(mod->file);
+
+       if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
+               elf = kmod_file_get_elf(mod->file);
+               if (elf == NULL) {
+                       err = -errno;
+                       return err;
+               }
+
+               if (flags & KMOD_INSERT_FORCE_MODVERSION) {
+                       err = kmod_elf_strip_section(elf, "__versions");
+                       if (err < 0)
+                               INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
+               }
+
+               if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
+                       err = kmod_elf_strip_vermagic(elf);
+                       if (err < 0)
+                               INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
+               }
+
+               mem = kmod_elf_get_memory(elf);
+       } else {
+               mem = kmod_file_get_contents(mod->file);
+       }
+       size = kmod_file_get_size(mod->file);
+
+       err = init_module(mem, size, args);
+       if (err < 0)
+               err = -errno;
+
+       return err;
+}
+
 /**
  * kmod_module_insert_module:
  * @mod: kmod module
@@ -824,9 +957,6 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
                                                        const char *options)
 {
        int err;
-       const void *mem;
-       off_t size;
-       struct kmod_elf *elf;
        const char *path;
        const char *args = options ? options : "";
 
@@ -847,50 +977,14 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
                }
        }
 
-       if (kmod_file_get_direct(mod->file)) {
-               unsigned int kernel_flags = 0;
-
-               if (flags & KMOD_INSERT_FORCE_VERMAGIC)
-                       kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
-               if (flags & KMOD_INSERT_FORCE_MODVERSION)
-                       kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;
-
-               err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
-               if (err == 0 || errno != ENOSYS)
-                       goto init_finished;
-       }
-
-       if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
-               elf = kmod_file_get_elf(mod->file);
-               if (elf == NULL) {
-                       err = -errno;
-                       return err;
-               }
-
-               if (flags & KMOD_INSERT_FORCE_MODVERSION) {
-                       err = kmod_elf_strip_section(elf, "__versions");
-                       if (err < 0)
-                               INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
-               }
-
-               if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
-                       err = kmod_elf_strip_vermagic(elf);
-                       if (err < 0)
-                               INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
-               }
+       err = do_finit_module(mod, flags, args);
+       if (err == -ENOSYS)
+               err = do_init_module(mod, flags, args);
 
-               mem = kmod_elf_get_memory(elf);
-       } else {
-               mem = kmod_file_get_contents(mod->file);
-       }
-       size = kmod_file_get_size(mod->file);
+       if (err < 0)
+               INFO(mod->ctx, "Failed to insert module '%s': %s\n",
+                    path, strerror(-err));
 
-       err = init_module(mem, size, args);
-init_finished:
-       if (err < 0) {
-               err = -errno;
-               INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
-       }
        return err;
 }
 
@@ -1753,6 +1847,10 @@ KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
 
        pathlen = snprintf(path, sizeof(path),
                                "/sys/module/%s/initstate", mod->name);
+       if (pathlen >= (int)sizeof(path)) {
+               /* Too long path was truncated */
+               return -ENAMETOOLONG;
+       }
        fd = open(path, O_RDONLY|O_CLOEXEC);
        if (fd < 0) {
                err = -errno;
@@ -2277,7 +2375,7 @@ list_error:
  *
  * After use, free the @list by calling kmod_module_info_free_list().
  *
- * Returns: 0 on success or < 0 otherwise.
+ * Returns: number of entries in @list on success or < 0 otherwise.
  */
 KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
 {
@@ -2886,43 +2984,3 @@ KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list
                list = kmod_list_remove(list);
        }
 }
-
-/**
- * kmod_module_get_builtin:
- * @ctx: kmod library context
- * @list: where to save the builtin module list
- *
- * Returns: 0 on success or < 0 otherwise.
- */
-int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list)
-{
-       struct kmod_builtin_iter *iter;
-       int err = 0;
-
-       iter = kmod_builtin_iter_new(ctx);
-       if (!iter)
-               return -errno;
-
-       while (kmod_builtin_iter_next(iter)) {
-               struct kmod_module *mod = NULL;
-               char modname[PATH_MAX];
-
-               if (!kmod_builtin_iter_get_modname(iter, modname)) {
-                       err = -errno;
-                       goto fail;
-               }
-
-               kmod_module_new_from_name(ctx, modname, &mod);
-               kmod_module_set_builtin(mod, true);
-
-               *list = kmod_list_append(*list, mod);
-       }
-
-       kmod_builtin_iter_free(iter);
-       return err;
-fail:
-       kmod_builtin_iter_free(iter);
-       kmod_module_unref_list(*list);
-       *list = NULL;
-       return err;
-}
index 4e8748c26c1c8b1b440b9fa48b1420ffa452a5fb..80f6447bcea07eb885ea96f87235269259005e90 100644 (file)
@@ -56,6 +56,7 @@ enum pkey_hash_algo {
        PKEY_HASH_SHA384,
        PKEY_HASH_SHA512,
        PKEY_HASH_SHA224,
+       PKEY_HASH_SM3,
        PKEY_HASH__LAST
 };
 
@@ -68,6 +69,7 @@ const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
        [PKEY_HASH_SHA384]      = "sha384",
        [PKEY_HASH_SHA512]      = "sha512",
        [PKEY_HASH_SHA224]      = "sha224",
+       [PKEY_HASH_SM3]         = "sm3",
 };
 
 enum pkey_id_type {
@@ -125,6 +127,7 @@ struct pkcs7_private {
        PKCS7 *pkcs7;
        unsigned char *key_id;
        BIGNUM *sno;
+       char *hash_algo;
 };
 
 static void pkcs7_free(void *s)
@@ -135,38 +138,11 @@ static void pkcs7_free(void *s)
        PKCS7_free(pvt->pkcs7);
        BN_free(pvt->sno);
        free(pvt->key_id);
+       free(pvt->hash_algo);
        free(pvt);
        si->private = NULL;
 }
 
-static int obj_to_hash_algo(const ASN1_OBJECT *o)
-{
-       int nid;
-
-       nid = OBJ_obj2nid(o);
-       switch (nid) {
-       case NID_md4:
-               return PKEY_HASH_MD4;
-       case NID_md5:
-               return PKEY_HASH_MD5;
-       case NID_sha1:
-               return PKEY_HASH_SHA1;
-       case NID_ripemd160:
-               return PKEY_HASH_RIPE_MD_160;
-       case NID_sha256:
-               return PKEY_HASH_SHA256;
-       case NID_sha384:
-               return PKEY_HASH_SHA384;
-       case NID_sha512:
-               return PKEY_HASH_SHA512;
-       case NID_sha224:
-               return PKEY_HASH_SHA224;
-       default:
-               return -1;
-       }
-       return -1;
-}
-
 static const char *x509_name_to_str(X509_NAME *name)
 {
        int i;
@@ -213,6 +189,8 @@ static bool fill_pkcs7(const char *mem, off_t size,
        unsigned char *key_id_str;
        struct pkcs7_private *pvt;
        const char *issuer_str;
+       char *hash_algo;
+       int hash_algo_len;
 
        size -= sig_len;
        pkcs7_raw = mem + size;
@@ -271,21 +249,37 @@ static bool fill_pkcs7(const char *mem, off_t size,
 
        X509_ALGOR_get0(&o, NULL, NULL, dig_alg);
 
-       sig_info->hash_algo = pkey_hash_algo[obj_to_hash_algo(o)];
+       // Use OBJ_obj2txt to calculate string length
+       hash_algo_len = OBJ_obj2txt(NULL, 0, o, 0);
+       if (hash_algo_len < 0)
+               goto err3;
+       hash_algo = malloc(hash_algo_len + 1);
+       if (hash_algo == NULL)
+               goto err3;
+       hash_algo_len = OBJ_obj2txt(hash_algo, hash_algo_len + 1, o, 0);
+       if (hash_algo_len < 0)
+               goto err4;
+
+       // Assign libcrypto hash algo string or number
+       sig_info->hash_algo = hash_algo;
+
        sig_info->id_type = pkey_id_type[modsig->id_type];
 
        pvt = malloc(sizeof(*pvt));
        if (pvt == NULL)
-               goto err3;
+               goto err4;
 
        pvt->pkcs7 = pkcs7;
        pvt->key_id = key_id_str;
        pvt->sno = sno_bn;
+       pvt->hash_algo = hash_algo;
        sig_info->private = pvt;
 
        sig_info->free = pkcs7_free;
 
        return true;
+err4:
+       free(hash_algo);
 err3:
        free(key_id_str);
 err2:
index 43423d63a889e36ca31c9042589673370e7f500f..213b42482fb6be6984552b76b7cb28f0a12483cc 100644 (file)
@@ -50,7 +50,7 @@
  * and is passed to all library operations.
  */
 
-static struct _index_files {
+static const struct {
        const char *fn;
        const char *prefix;
 } index_files[] = {
@@ -61,9 +61,11 @@ static struct _index_files {
        [KMOD_INDEX_MODULES_BUILTIN] = { .fn = "modules.builtin", .prefix = ""},
 };
 
-static const char *default_config_paths[] = {
+static const char *const default_config_paths[] = {
        SYSCONFDIR "/modprobe.d",
        "/run/modprobe.d",
+       "/usr/local/lib/modprobe.d",
+       DISTCONFDIR "/modprobe.d",
        "/lib/modprobe.d",
        NULL
 };
@@ -82,6 +84,7 @@ struct kmod_ctx {
        void *log_data;
        const void *userdata;
        char *dirname;
+       enum kmod_file_compression_type kernel_compression;
        struct kmod_config *config;
        struct hash *modules_by_name;
        struct index_mm *indexes[_KMOD_INDEX_MODULES_SIZE];
@@ -207,7 +210,7 @@ static int log_priority(const char *priority)
        return 0;
 }
 
-static const char *dirname_default_prefix = "/lib/modules";
+static const char *dirname_default_prefix = MODULE_DIRECTORY;
 
 static char *get_kernel_release(const char *dirname)
 {
@@ -226,16 +229,51 @@ static char *get_kernel_release(const char *dirname)
        return p;
 }
 
+static enum kmod_file_compression_type get_kernel_compression(struct kmod_ctx *ctx)
+{
+       const char *path = "/sys/module/compression";
+       char buf[16];
+       int fd;
+       int err;
+
+       fd = open(path, O_RDONLY|O_CLOEXEC);
+       if (fd < 0) {
+               /* Not having the file is not an error: kernel may be too old */
+               DBG(ctx, "could not open '%s' for reading: %m\n", path);
+               return KMOD_FILE_COMPRESSION_NONE;
+       }
+
+       err = read_str_safe(fd, buf, sizeof(buf));
+       close(fd);
+       if (err < 0) {
+               ERR(ctx, "could not read from '%s': %s\n",
+                   path, strerror(-err));
+               return KMOD_FILE_COMPRESSION_NONE;
+       }
+
+       if (streq(buf, "zstd\n"))
+               return KMOD_FILE_COMPRESSION_ZSTD;
+       else if (streq(buf, "xz\n"))
+               return KMOD_FILE_COMPRESSION_XZ;
+       else if (streq(buf, "gzip\n"))
+               return KMOD_FILE_COMPRESSION_ZLIB;
+
+       ERR(ctx, "unknown kernel compression %s", buf);
+
+       return KMOD_FILE_COMPRESSION_NONE;
+}
+
 /**
  * kmod_new:
  * @dirname: what to consider as linux module's directory, if NULL
- *           defaults to /lib/modules/`uname -r`. If it's relative,
+ *           defaults to $MODULE_DIRECTORY/`uname -r`. If it's relative,
  *           it's treated as relative to the current working directory.
  *           Otherwise, give an absolute dirname.
  * @config_paths: ordered array of paths (directories or files) where
  *                to load from user-defined configuration parameters such as
- *                alias, blacklists, commands (install, remove). If
- *                NULL defaults to /run/modprobe.d, /etc/modprobe.d and
+ *                alias, blacklists, commands (install, remove). If NULL
+ *                defaults to /etc/modprobe.d, /run/modprobe.d,
+ *                /usr/local/lib/modprobe.d, DISTCONFDIR/modprobe.d, and
  *                /lib/modprobe.d. Give an empty vector if configuration should
  *                not be read. This array must be null terminated.
  *
@@ -270,6 +308,8 @@ KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname,
        if (env != NULL)
                kmod_set_log_priority(ctx, log_priority(env));
 
+       ctx->kernel_compression = get_kernel_compression(ctx);
+
        if (config_paths == NULL)
                config_paths = default_config_paths;
        err = kmod_config_new(ctx, &ctx->config, config_paths);
@@ -977,3 +1017,8 @@ const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx)
 {
        return ctx->config;
 }
+
+enum kmod_file_compression_type kmod_get_kernel_compression(const struct kmod_ctx *ctx)
+{
+       return ctx->kernel_compression;
+}
index 3cab2e521656d70aefad4d4933bd2fa2464d4a6c..7251aa7286dd969fe151c7199070bf33a011e45f 100644 (file)
@@ -129,6 +129,9 @@ int kmod_module_new_from_path(struct kmod_ctx *ctx, const char *path,
                                                struct kmod_module **mod);
 int kmod_module_new_from_lookup(struct kmod_ctx *ctx, const char *given_alias,
                                                struct kmod_list **list);
+int kmod_module_new_from_name_lookup(struct kmod_ctx *ctx,
+                                    const char *modname,
+                                    struct kmod_module **mod);
 int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
                                                struct kmod_list **list);
 
@@ -142,6 +145,8 @@ struct kmod_module *kmod_module_get_module(const struct kmod_list *entry);
 enum kmod_remove {
        KMOD_REMOVE_FORCE = O_TRUNC,
        KMOD_REMOVE_NOWAIT = O_NONBLOCK, /* always set */
+       /* libkmod-only defines, not passed to kernel */
+       KMOD_REMOVE_NOLOG = 1,
 };
 
 /* Insertion flags */
index e4fdf21dcd8f1ddbfd2ccc41b74c2656aa0175f8..3acca6a6f135ef1da99b9c2ec2613e5eaacaf7bd 100644 (file)
@@ -7,5 +7,5 @@ Name: libkmod
 Description: Library to deal with kernel modules
 Version: @VERSION@
 Libs: -L${libdir} -lkmod
-Libs.private: @liblzma_LIBS@ @zlib_LIBS@
+Libs.private: @libzstd_LIBS@ @liblzma_LIBS@ @zlib_LIBS@
 Cflags: -I${includedir}
index 5f5e1fbac2507c24e97cc79a3436647e366855d5..0c04fda4b3088a9b1201a07912354e9ca649519e 100644 (file)
@@ -30,6 +30,7 @@ global:
        kmod_module_new_from_name;
        kmod_module_new_from_path;
        kmod_module_new_from_lookup;
+       kmod_module_new_from_name_lookup;
        kmod_module_new_from_loaded;
        kmod_module_ref;
        kmod_module_unref;
diff --git a/libkmod/python/.gitignore b/libkmod/python/.gitignore
deleted file mode 100644 (file)
index 69af451..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-__pycache__
-dist
-*.c
-*.pyc
-*.so
-kmod/version.py
diff --git a/libkmod/python/README b/libkmod/python/README
deleted file mode 100644 (file)
index 75c2636..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-python-kmod
-===========
-
-Python bindings for kmod/libkmod
-
-python-kmod is a Python wrapper module for libkmod, exposing common
-module operations: listing installed modules, modprobe, and rmmod.
-It is at:
-
-Example (python invoked as root)
---------------------------------
-
-::
-
-  >>> import kmod
-  >>> km = kmod.Kmod()
-  >>> [(m.name, m.size) for m in km.loaded()]
-  [(u'nfs', 407706),
-   (u'nfs_acl', 12741)
-   ...
-   (u'virtio_blk', 17549)]
-  >>> km.modprobe("btrfs")
-  >>> km.rmmod("btrfs")
diff --git a/libkmod/python/kmod/__init__.py b/libkmod/python/kmod/__init__.py
deleted file mode 100644 (file)
index 0d79787..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-"Libkmod -- Python interface to kmod API."
-
-from .version import __version__
-try:
-    from .kmod import Kmod
-except ImportError:
-    # this is a non-Linux platform
-    pass
diff --git a/libkmod/python/kmod/_libkmod_h.pxd b/libkmod/python/kmod/_libkmod_h.pxd
deleted file mode 100644 (file)
index 7191953..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport libc.stdint as _stdint
-
-
-cdef extern from *:
-    ctypedef char* const_char_ptr 'const char *'
-    ctypedef char* const_char_const_ptr 'const char const *'
-    ctypedef void* const_void_ptr 'const void *'
-
-
-cdef extern from 'stdbool.h':
-    ctypedef struct bool:
-        pass
-
-
-cdef extern from 'libkmod/libkmod.h':
-    # library user context - reads the config and system
-    # environment, user variables, allows custom logging
-    cdef struct kmod_ctx:
-        pass
-
-    kmod_ctx *kmod_new(
-        const_char_ptr dirname, const_char_const_ptr config_paths)
-    kmod_ctx *kmod_ref(kmod_ctx *ctx)
-    kmod_ctx *kmod_unref(kmod_ctx *ctx)
-
-    # Management of libkmod's resources
-    int kmod_load_resources(kmod_ctx *ctx)
-    void kmod_unload_resources(kmod_ctx *ctx)
-
-    # access to kmod generated lists
-    cdef struct kmod_list:
-        pass
-    ctypedef kmod_list* const_kmod_list_ptr 'const struct kmod_list *'
-    kmod_list *kmod_list_next(
-        const_kmod_list_ptr list, const_kmod_list_ptr curr)
-    kmod_list *kmod_list_prev(
-        const_kmod_list_ptr list, const_kmod_list_ptr curr)
-    kmod_list *kmod_list_last(const_kmod_list_ptr list)
-
-    # Operate on kernel modules
-    cdef struct kmod_module:
-        pass
-    ctypedef kmod_module* const_kmod_module_ptr 'const struct kmod_module *'
-    int kmod_module_new_from_name(
-        kmod_ctx *ctx, const_char_ptr name, kmod_module **mod)
-    int kmod_module_new_from_lookup(
-        kmod_ctx *ctx, const_char_ptr given_alias, kmod_list **list)
-    int kmod_module_new_from_loaded(kmod_ctx *ctx, kmod_list **list)
-
-    kmod_module *kmod_module_ref(kmod_module *mod)
-    kmod_module *kmod_module_unref(kmod_module *mod)
-    int kmod_module_unref_list(kmod_list *list)
-    kmod_module *kmod_module_get_module(kmod_list *entry)
-
-    # Flags to kmod_module_probe_insert_module
-    # codes below can be used in return value, too
-    enum: KMOD_PROBE_APPLY_BLACKLIST
-
-    #ctypedef int (*install_callback_t)(
-    #    kmod_module *m, const_char_ptr cmdline, const_void_ptr data)
-    #ctypedef void (*print_action_callback_t)(
-    #    kmod_module *m, bool install, const_char_ptr options)
-
-    int kmod_module_remove_module(
-        kmod_module *mod, unsigned int flags)
-    int kmod_module_insert_module(
-        kmod_module *mod, unsigned int flags, const_char_ptr options)
-    int kmod_module_probe_insert_module(
-        kmod_module *mod, unsigned int flags, const_char_ptr extra_options,
-        int (*run_install)(
-            kmod_module *m, const_char_ptr cmdline, void *data),
-        const_void_ptr data,
-        void (*print_action)(
-            kmod_module *m, bool install, const_char_ptr options),
-        )
-
-    const_char_ptr kmod_module_get_name(const_kmod_module_ptr mod)
-    const_char_ptr kmod_module_get_path(const_kmod_module_ptr mod)
-    const_char_ptr kmod_module_get_options(const_kmod_module_ptr mod)
-    const_char_ptr kmod_module_get_install_commands(const_kmod_module_ptr mod)
-    const_char_ptr kmod_module_get_remove_commands(const_kmod_module_ptr mod)
-
-    # Information regarding "live information" from module's state, as
-    # returned by kernel
-    int kmod_module_get_refcnt(const_kmod_module_ptr mod)
-    long kmod_module_get_size(const_kmod_module_ptr mod)
-
-    # Information retrieved from ELF headers and section
-    int kmod_module_get_info(const_kmod_module_ptr mod, kmod_list **list)
-    const_char_ptr kmod_module_info_get_key(const_kmod_list_ptr entry)
-    const_char_ptr kmod_module_info_get_value(const_kmod_list_ptr entry)
-    void kmod_module_info_free_list(kmod_list *list)
-
-    int kmod_module_get_versions(const_kmod_module_ptr mod, kmod_list **list)
-    const_char_ptr kmod_module_version_get_symbol(const_kmod_list_ptr entry)
-    _stdint.uint64_t kmod_module_version_get_crc(const_kmod_list_ptr entry)
-    void kmod_module_versions_free_list(kmod_list *list)
diff --git a/libkmod/python/kmod/_util.pxd b/libkmod/python/kmod/_util.pxd
deleted file mode 100644 (file)
index 80cbb28..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport _libkmod_h
-
-
-cdef object char_ptr_to_str(_libkmod_h.const_char_ptr bytes)
diff --git a/libkmod/python/kmod/_util.pyx b/libkmod/python/kmod/_util.pyx
deleted file mode 100644 (file)
index 39eec3a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-import sys as _sys
-
-cimport _libkmod_h
-
-
-cdef object char_ptr_to_str(_libkmod_h.const_char_ptr char_ptr):
-    if char_ptr is NULL:
-        return None
-    if _sys.version_info >= (3,):  # Python 3
-        return str(char_ptr, 'ascii')
-    # Python 2
-    return unicode(char_ptr, 'ascii')
diff --git a/libkmod/python/kmod/error.py b/libkmod/python/kmod/error.py
deleted file mode 100644 (file)
index 123f4ce..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-class KmodError (Exception):
-    pass
diff --git a/libkmod/python/kmod/kmod.pxd b/libkmod/python/kmod/kmod.pxd
deleted file mode 100644 (file)
index 7805d71..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport _libkmod_h
-
-
-cdef class Kmod (object):
-    cdef _libkmod_h.kmod_ctx *_kmod_ctx
-    cdef object mod_dir
diff --git a/libkmod/python/kmod/kmod.pyx b/libkmod/python/kmod/kmod.pyx
deleted file mode 100644 (file)
index 3e73a1c..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2012 Red Hat, Inc.
-#                    W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-"Define the Kmod class"
-
-cimport cython as _cython
-cimport _libkmod_h
-from error import KmodError as _KmodError
-cimport module as _module
-import module as _module
-cimport list as _list
-import list as _list
-
-
-cdef class Kmod (object):
-    "Wrap a struct kmod_ctx* item"
-    def __cinit__(self):
-        self._kmod_ctx = NULL
-        self.mod_dir = None
-
-    def __dealloc__(self):
-        self._cleanup()
-
-    def __init__(self, mod_dir=None):
-        self.set_mod_dir(mod_dir=mod_dir)
-
-    def set_mod_dir(self, mod_dir=None):
-        self.mod_dir = mod_dir
-        self._setup()
-
-    def _setup(self):
-        cdef char *mod_dir = NULL
-        self._cleanup()
-        if self.mod_dir:
-            mod_dir = self.mod_dir
-        self._kmod_ctx = _libkmod_h.kmod_new(mod_dir, NULL);
-        if self._kmod_ctx is NULL:
-            raise _KmodError('Could not initialize')
-        _libkmod_h.kmod_load_resources(self._kmod_ctx)
-
-    def _cleanup(self):
-        if self._kmod_ctx is not NULL:
-            _libkmod_h.kmod_unload_resources(self._kmod_ctx);
-            self._kmod_ctx = NULL
-
-    def loaded(self):
-        "iterate through currently loaded modules"
-        cdef _list.ModList ml = _list.ModList()
-        cdef _list.ModListItem mli
-        err = _libkmod_h.kmod_module_new_from_loaded(self._kmod_ctx, &ml.list)
-        if err < 0:
-            raise _KmodError('Could not get loaded modules')
-        for item in ml:
-            mli = <_list.ModListItem> item
-            mod = _module.Module()
-            mod.from_mod_list_item(item)
-            yield mod
-
-    def lookup(self, alias_name, flags=_libkmod_h.KMOD_PROBE_APPLY_BLACKLIST):
-        "iterate through modules matching `alias_name`"
-        cdef _list.ModList ml = _list.ModList()
-        cdef _list.ModListItem mli
-        if hasattr(alias_name, 'encode'):
-            alias_name = alias_name.encode('ascii')
-        err = _libkmod_h.kmod_module_new_from_lookup(
-            self._kmod_ctx, alias_name, &ml.list)
-        if err < 0:
-            raise _KmodError('Could not modprobe')
-        for item in ml:
-            mli = <_list.ModListItem> item
-            mod = _module.Module()
-            mod.from_mod_list_item(item)
-            yield mod
-
-    @_cython.always_allow_keywords(True)
-    def module_from_name(self, name):
-        cdef _module.Module mod = _module.Module()
-        if hasattr(name, 'encode'):
-            name = name.encode('ascii')
-        err = _libkmod_h.kmod_module_new_from_name(
-            self._kmod_ctx, name, &mod.module)
-        if err < 0:
-            raise _KmodError('Could not get module')
-        return mod
-
-    def list(self):
-        "iterate through currently loaded modules and sizes"
-        for mod in self.loaded():
-            yield (mod.name, mod.size)
-
-    def modprobe(self, name, quiet=False, *args, **kwargs):
-        """
-        Load a module (or alias) and all modules on which it depends.
-        The 'quiet' option defaults to False; set to True to mimic the behavior
-        of the '--quiet' commandline option.
-        """
-        mods = list(self.lookup(alias_name=name))
-
-        if not mods and not quiet:
-            raise _KmodError('Could not modprobe %s' % name)
-
-        for mod in mods:
-            mod.insert(*args, **kwargs)
-
-    def rmmod(self, module_name, *args, **kwargs):
-       """
-       remove module from current tree
-       e.g. km.rmmod("thinkpad_acpi")
-       """
-       mod = self.module_from_name(name=module_name)
-       mod.remove(*args, **kwargs)
diff --git a/libkmod/python/kmod/list.pxd b/libkmod/python/kmod/list.pxd
deleted file mode 100644 (file)
index 8e5b388..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport _libkmod_h
-
-
-cdef class ModListItem (object):
-    cdef _libkmod_h.kmod_list *list
-
-
-cdef class ModList (ModListItem):
-    cdef _libkmod_h.kmod_list *_next
diff --git a/libkmod/python/kmod/list.pyx b/libkmod/python/kmod/list.pyx
deleted file mode 100644 (file)
index ef0e0d4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport _libkmod_h
-
-
-cdef class ModListItem (object):
-    "Wrap a struct kmod_list* list item"
-    def __cinit__(self):
-        self.list = NULL
-
-
-cdef class ModList (ModListItem):
-    "Wrap a struct kmod_list* list with iteration"
-    def __cinit__(self):
-        self._next = NULL
-
-    def __dealloc__(self):
-        if self.list is not NULL:
-            _libkmod_h.kmod_module_unref_list(self.list)
-
-    def __iter__(self):
-        self._next = self.list
-        return self
-
-    def __next__(self):
-        if self._next is NULL:
-            raise StopIteration()
-        mli = ModListItem()
-        mli.list = self._next
-        self._next = _libkmod_h.kmod_list_next(self.list, self._next)
-        return mli
diff --git a/libkmod/python/kmod/module.pxd b/libkmod/python/kmod/module.pxd
deleted file mode 100644 (file)
index c7d7da4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-cimport _libkmod_h
-cimport list as _list
-
-
-cdef class Module (object):
-    cdef _libkmod_h.kmod_module *module
-
-    cpdef from_mod_list_item(self, _list.ModListItem item)
diff --git a/libkmod/python/kmod/module.pyx b/libkmod/python/kmod/module.pyx
deleted file mode 100644 (file)
index 42aa92e..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-import collections as _collections
-
-cimport libc.errno as _errno
-
-cimport _libkmod_h
-from error import KmodError as _KmodError
-cimport list as _list
-import list as _list
-cimport _util
-import _util
-
-
-cdef class Module (object):
-    "Wrap a struct kmod_module* item"
-    def __cinit__(self):
-        self.module = NULL
-
-    def __dealloc__(self):
-        self._cleanup()
-
-    def _cleanup(self):
-        if self.module is not NULL:
-            _libkmod_h.kmod_module_unref(self.module)
-            self.module = NULL
-
-    cpdef from_mod_list_item(self, _list.ModListItem item):
-        self._cleanup()
-        self.module = _libkmod_h.kmod_module_get_module(item.list)
-
-    def _name_get(self):
-        return _util.char_ptr_to_str(
-            _libkmod_h.kmod_module_get_name(self.module))
-    name = property(fget=_name_get)
-
-    def _path_get(self):
-        return _util.char_ptr_to_str(
-            _libkmod_h.kmod_module_get_path(self.module))
-    path = property(fget=_path_get)
-
-    def _options_get(self):
-        return _util.char_ptr_to_str(
-            _libkmod_h.kmod_module_get_options(self.module))
-    options = property(fget=_options_get)
-
-    def _install_commands_get(self):
-        return _util.char_ptr_to_str(
-            _libkmod_h.kmod_module_get_install_commands(self.module))
-    install_commands = property(fget=_install_commands_get)
-
-    def _remove_commands_get(self):
-        return _util.char_ptr_to_str(
-            _libkmod_h.kmod_module_get_remove_commands(self.module))
-    remove_commands = property(fget=_remove_commands_get)
-
-    def _refcnt_get(self):
-        return _libkmod_h.kmod_module_get_refcnt(self.module)
-    refcnt = property(fget=_refcnt_get)
-
-    def _size_get(self):
-        return _libkmod_h.kmod_module_get_size(self.module)
-    size = property(fget=_size_get)
-
-    def _info_get(self):
-        cdef _list.ModList ml = _list.ModList()
-        cdef _list.ModListItem mli
-        err = _libkmod_h.kmod_module_get_info(self.module, &ml.list)
-        if err < 0:
-            raise _KmodError('Could not get info')
-        info = _collections.OrderedDict()
-        try:
-            for item in ml:
-                mli = <_list.ModListItem> item
-                key = _util.char_ptr_to_str(
-                    _libkmod_h.kmod_module_info_get_key(mli.list))
-                value = _util.char_ptr_to_str(
-                    _libkmod_h.kmod_module_info_get_value(mli.list))
-                info[key] = value
-        finally:
-            _libkmod_h.kmod_module_info_free_list(ml.list)
-            ml.list = NULL
-        return info
-    info = property(fget=_info_get)
-
-    def _versions_get(self):
-        cdef _list.ModList ml = _list.ModList()
-        cdef _list.ModListItem mli
-        err = _libkmod_h.kmod_module_get_versions(self.module, &ml.list)
-        if err < 0:
-            raise _KmodError('Could not get versions')
-        try:
-            for item in ml:
-                mli = <_list.ModListItem> item
-                symbol = _util.char_ptr_to_str(
-                    _libkmod_h.kmod_module_version_get_symbol(mli.list))
-                crc = _libkmod_h.kmod_module_version_get_crc(mli.list)
-                yield {'symbol': symbol, 'crc': crc}
-        finally:
-            _libkmod_h.kmod_module_versions_free_list(ml.list)
-            ml.list = NULL
-    versions = property(fget=_versions_get)
-
-    def insert(self, flags=0, extra_options=None, install_callback=None,
-               data=None, print_action_callback=None):
-        """
-        insert module to current tree. 
-        e.g.
-        km = kmod.Kmod()
-        tp = km.module_from_name("thinkpad_acpi")
-        tp.insert(extra_options='fan_control=1')
-        """
-        cdef char *opt = NULL
-        #cdef _libkmod_h.install_callback_t install = NULL
-        cdef int (*install)(
-            _libkmod_h.kmod_module *, _libkmod_h.const_char_ptr, void *)
-        install = NULL
-        cdef void *d = NULL
-        #cdef _libkmod_h.print_action_callback_t print_action = NULL
-        cdef void (*print_action)(
-            _libkmod_h.kmod_module *, _libkmod_h.bool,
-            _libkmod_h.const_char_ptr)
-        print_action = NULL
-        if extra_options:
-            opt = extra_options
-        # TODO: convert callbacks and data from Python object to C types
-        err = _libkmod_h.kmod_module_probe_insert_module(
-            self.module, flags, opt, install, d, print_action)
-        if err == -_errno.EEXIST:
-            raise _KmodError('Module already loaded')
-        elif err < 0:
-            raise _KmodError('Could not load module')
-
-    def remove(self, flags=0):
-        """
-        remove module from current tree
-        e.g.
-        km = kmod.Kmod()
-        tp = km.module_from_name("thinkpad_acpi")
-        tp.remove()
-        """
-        err = _libkmod_h.kmod_module_remove_module(self.module, flags)
-        if err < 0:
-            raise _KmodError('Could not remove module')
diff --git a/libkmod/python/kmod/version.py.in b/libkmod/python/kmod/version.py.in
deleted file mode 100644 (file)
index 4daa94d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
-#
-# This file is part of python-kmod.
-#
-# python-kmod is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License version 2.1 as published
-# by the Free Software Foundation.
-#
-# python-kmod 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with python-kmod.  If not, see <http://www.gnu.org/licenses/>.
-
-__version__ = '@VERSION@'
index 11514d52a1904a13303b299c1a8b5b64c1f05388..d62ff21c799ff734d2392ae76d147080f807b17b 100644 (file)
@@ -13,13 +13,26 @@ dist_man_MANS = $(MAN5) $(MAN8) $(MAN_STUB)
 modules.dep.bin.5: modules.dep.5
 endif
 
-EXTRA_DIST = $(MAN5:%.5=%.xml) $(MAN8:%.8=%.xml)
+EXTRA_DIST = $(MAN5:%.5=%.5.xml) $(MAN8:%.8=%.8.xml)
 CLEANFILES = $(dist_man_MANS)
 
-%.5 %.8: %.xml
-       $(AM_V_XSLT)$(XSLT) \
+define generate_manpage
+       $(AM_V_XSLT)if [ '$(distconfdir)' != '/lib' ] ; then \
+               sed -e 's|@DISTCONFDIR@|$(distconfdir)|g' $< ; \
+       else \
+               sed -e '/@DISTCONFDIR@/d' $< ; \
+       fi | \
+       sed -e 's|@MODULE_DIRECTORY@|$(module_directory)|g' | \
+       $(XSLT) \
                -o $@ \
                --nonet \
                --stringparam man.output.quietly 1 \
                --param funcsynopsis.style "'ansi'" \
-               http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+               http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl -
+endef
+
+%.5: %.5.xml
+       $(generate_manpage)
+
+%.8: %.8.xml
+       $(generate_manpage)
similarity index 91%
rename from man/depmod.xml
rename to man/depmod.8.xml
index ea0be27280b2c9eba315368f669d1b6b5a3d8299..fce2a4a67a89d8d1c31ec4b19f034b3502c5beb4 100644 (file)
@@ -45,6 +45,7 @@
     <cmdsynopsis>
       <command>depmod</command>
       <arg><option>-b <replaceable>basedir</replaceable></option></arg>
+      <arg><option>-o <replaceable>outdir</replaceable></option></arg>
       <arg><option>-e</option></arg>
       <arg><option>-E <replaceable>Module.symvers</replaceable></option></arg>
       <arg><option>-F <replaceable>System.map</replaceable></option></arg>
@@ -79,7 +80,7 @@
     </para>
     <para> <command>depmod</command> creates a list of module dependencies by
       reading each module under
-      <filename>/lib/modules/</filename><replaceable>version</replaceable> and
+      <filename>@MODULE_DIRECTORY@/</filename><replaceable>version</replaceable> and
       determining what symbols it exports and what symbols it needs.  By
       default, this list is written to <filename>modules.dep</filename>, and a
       binary hashed version named <filename>modules.dep.bin</filename>, in the
         <listitem>
           <para>
             If your modules are not currently in the (normal) directory
-            <filename>/lib/modules/</filename><replaceable>version</replaceable>,
+            <filename>@MODULE_DIRECTORY@/</filename><replaceable>version</replaceable>,
             but in a staging area, you can specify a
             <replaceable>basedir</replaceable> which is prepended to the
             directory name.  This <replaceable>basedir</replaceable> is
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>-o <replaceable>outdir</replaceable></option>
+        </term>
+        <term>
+          <option>--outdir <replaceable>outdir</replaceable></option>
+        </term>
+        <listitem>
+          <para>
+            Set the output directory where depmod will store any generated file.
+            <replaceable>outdir</replaceable> serves as a root to that location,
+            similar to how <replaceable>basedir</replaceable> is used. Also this
+            setting takes precedence and if used together with
+            <replaceable>basedir</replaceable> it will result in the input being
+            that directory, but the output being the one set by
+            <replaceable>outdir</replaceable>.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>
           <option>-C</option>
similarity index 86%
rename from man/depmod.d.xml
rename to man/depmod.d.5.xml
index 4341a568e8a0070df998eeafada35d05fcc8d868..b07e6a2bd4fe41bee53974a0b09b7be4181853ab 100644 (file)
   </refnamediv>
 
   <refsynopsisdiv>
-    <para><filename>/usr/lib/depmod.d/*.conf</filename></para>
-    <para><filename>/etc/depmod.d/*.conf</filename></para>
+    <para><filename>/lib/depmod.d/*.conf</filename></para>
+    <para><filename>@DISTCONFDIR@/depmod.d/*.conf</filename></para>
+    <para><filename>/usr/local/lib/depmod.d/*.conf</filename></para>
     <para><filename>/run/depmod.d/*.conf</filename></para>
+    <para><filename>/etc/depmod.d/*.conf</filename></para>
   </refsynopsisdiv>
 
   <refsect1><title>DESCRIPTION</title>
@@ -68,7 +70,7 @@
         </term>
         <listitem>
           <para>
-            This allows you to specify the order in which /lib/modules
+            This allows you to specify the order in which @MODULE_DIRECTORY@
             (or other configured module location) subdirectories will
             be processed by <command>depmod</command>. Directories are
             listed in order, with the highest priority given to the
             <command>depmod</command> command. It is possible to
             specify one kernel or all kernels using the * wildcard.
             <replaceable>modulesubdirectory</replaceable> is the
-            name of the subdirectory under /lib/modules (or other
+            name of the subdirectory under @MODULE_DIRECTORY@ (or other
             module location) where the target module is installed.
           </para>
           <para>
             specifying the following command: "override kmod * extra".
             This will ensure that any matching module name installed
             under the <command>extra</command> subdirectory within
-            /lib/modules (or other module location) will take priority
+            @MODULE_DIRECTORY@ (or other module location) will take priority
             over any likenamed module already provided by the kernel.
           </para>
         </listitem>
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>exclude <replaceable>excludedir</replaceable>
+        </term>
+        <listitem>
+          <para>
+            This specifies the trailing directories that will be excluded
+            during the search for kernel modules.
+          </para>
+          <para>
+           The <replaceable>excludedir</replaceable> is the trailing directory
+           to exclude
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
similarity index 100%
rename from man/insmod.xml
rename to man/insmod.8.xml
similarity index 100%
rename from man/kmod.xml
rename to man/kmod.8.xml
similarity index 100%
rename from man/lsmod.xml
rename to man/lsmod.8.xml
similarity index 98%
rename from man/modinfo.xml
rename to man/modinfo.8.xml
index 9fe0324a25276235f9bd700088f6c51bec0b2e55..b6c4d6045829234f35afbd8a8c223feb5f4f7acc 100644 (file)
@@ -54,7 +54,7 @@
       <command>modinfo</command> extracts information from the Linux Kernel
       modules given on the command line.  If the module name is not a filename,
       then the
-      <filename>/lib/modules/</filename><replaceable>version</replaceable>
+      <filename>@MODULE_DIRECTORY@/</filename><replaceable>version</replaceable>
       directory is searched, as is also done by
       <citerefentry><refentrytitle>modprobe</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       when loading kernel modules.
similarity index 94%
rename from man/modprobe.xml
rename to man/modprobe.8.xml
index 0372b6b23b87d9a5bbd4cfc2a5b4dc1fbc07e1a9..4d1fd59c000ba2d1c8de12703581ed29e8f4d5c7 100644 (file)
@@ -78,7 +78,7 @@
       is no difference between _ and - in module names (automatic
       underscore conversion is performed).
       <command>modprobe</command> looks in the module directory
-      <filename>/lib/modules/`uname -r`</filename> for all
+      <filename>@MODULE_DIRECTORY@/`uname -r`</filename> for all
       the modules and other files, except for the optional
       configuration files in the
       <filename>/etc/modprobe.d</filename> directory
       kernel (in addition to any options listed in the configuration
       file).
     </para>
+    <para>
+      When loading modules, <replaceable>modulename</replaceable> can also
+      be a path to the module. If the path is relative, it must
+      explicitly start with "./". Note that this may fail when using a
+      path to a module with dependencies not matching the installed depmod
+      database.
+    </para>
   </refsect1>
 
   <refsect1><title>OPTIONS</title>
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>-w</option>
+        </term>
+        <term>
+        <option>--wait=</option>TIMEOUT_MSEC
+        </term>
+        <listitem>
+          <para>
+            This option causes <command>modprobe -r</command> to continue trying to
+            remove a module if it fails due to the module being busy, i.e. its refcount
+            is not 0 at the time the call is made. Modprobe tries to remove the module
+            with an incremental sleep time between each tentative up until the maximum
+            wait time in milliseconds passed in this option.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>
           <option>-S</option>
similarity index 98%
rename from man/modprobe.d.xml
rename to man/modprobe.d.5.xml
index 211af8488abbb3f20d3cdfb4e617111a54da7f2f..2bf6537f07e66d9ff5a4d1817b25e54d7f402613 100644 (file)
 
   <refsynopsisdiv>
     <para><filename>/lib/modprobe.d/*.conf</filename></para>
-    <para><filename>/etc/modprobe.d/*.conf</filename></para>
+    <para><filename>@DISTCONFDIR@/modprobe.d/*.conf</filename></para>
+    <para><filename>/usr/local/lib/modprobe.d/*.conf</filename></para>
     <para><filename>/run/modprobe.d/*.conf</filename></para>
+    <para><filename>/etc/modprobe.d/*.conf</filename></para>
   </refsynopsisdiv>
 
   <refsect1><title>DESCRIPTION</title>
similarity index 89%
rename from man/modules.dep.xml
rename to man/modules.dep.5.xml
index e53293a1db675a7394be90d974c3d7ab44d0c63e..8ef6d8b3536e95b7fe7c324677df655d5ed5634e 100644 (file)
@@ -34,8 +34,8 @@
   </refnamediv>
 
   <refsynopsisdiv>
-    <para><filename>/lib/modules/modules.dep</filename></para>
-    <para><filename>/lib/modules/modules.dep.bin</filename></para>
+    <para><filename>@MODULE_DIRECTORY@/modules.dep</filename></para>
+    <para><filename>@MODULE_DIRECTORY@/modules.dep.bin</filename></para>
   </refsynopsisdiv>
 
   <refsect1><title>DESCRIPTION</title>
       <filename>modules.dep.bin</filename> is a binary file generated by
       <command>depmod</command> listing the dependencies for
       every module in the directories under
-      <filename>/lib/modules/</filename><replaceable>version</replaceable>.
+      <filename>@MODULE_DIRECTORY@/</filename><replaceable>version</replaceable>.
       It is used by kmod tools such as <command>modprobe</command> and
       libkmod.
     </para>
     <para>
-      Its text counterpar is located in the same directory with the name
+      Its text counterpart is located in the same directory with the name
       <filename>modules.dep</filename>. The text version is maintained only
       for easy of reading by humans and is in no way used by any kmod tool.
     </para>
similarity index 98%
rename from man/rmmod.xml
rename to man/rmmod.8.xml
index e7c7e5f9e7dc44bc6c4444a886348039c5ab42f2..67bcbedd972b40ac3f82051bbffecde3f1fca31a 100644 (file)
@@ -52,7 +52,8 @@
       want to use
       <citerefentry>
         <refentrytitle>modprobe</refentrytitle><manvolnum>8</manvolnum>
-      </citerefentry> with the <option>-r</option> option instead.
+      </citerefentry> with the <option>-r</option> option instead
+      since it removes unused dependent modules as well.
     </para>
   </refsect1>
 
index 7fe3f807711add1fe39c6c4c2a07c07c5eb53c5a..a87bc5074ee611e790ca493eb7c1b599536ec672 100644 (file)
@@ -241,12 +241,15 @@ void *hash_find(const struct hash *hash, const char *key)
                .key = key,
                .value = NULL
        };
-       const struct hash_entry *entry = bsearch(
-               &se, bucket->entries, bucket->used,
-               sizeof(struct hash_entry), hash_entry_cmp);
-       if (entry == NULL)
+       const struct hash_entry *entry;
+
+       if (!bucket->entries)
                return NULL;
-       return (void *)entry->value;
+
+       entry = bsearch(&se, bucket->entries, bucket->used,
+                       sizeof(struct hash_entry), hash_entry_cmp);
+
+       return entry ? (void *)entry->value : NULL;
 }
 
 int hash_del(struct hash *hash, const char *key)
index 4fc54059519f535a209199af7e6b6f34797e38d6..b59f7dc778841547e10654af2f0b801d423e3b8f 100644 (file)
        })
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr))
+
 #define XSTRINGIFY(x) #x
 #define STRINGIFY(x) XSTRINGIFY(x)
 
+#define XCONCATENATE(x, y) x ## y
+#define CONCATENATE(x, y) XCONCATENATE(x, y)
+#define UNIQ(x) CONCATENATE(x, __COUNTER__)
+
 /* Temporaries for importing index handling */
 #define NOFAIL(x) (x)
 #define fatal(x...) do { } while (0)
@@ -69,5 +74,3 @@
 #define noreturn __attribute__((noreturn))
 #endif
 #endif
-
-#define UNIQ __COUNTER__
index 4c0d136e4ca5cdf73f5b1541dcf40b71ada896c2..262944419efb79579e8cbf9ff045686114d6529c 100644 (file)
 # define MODULE_INIT_IGNORE_VERMAGIC 2
 #endif
 
+#ifndef MODULE_INIT_COMPRESSED_FILE
+# define MODULE_INIT_COMPRESSED_FILE 4
+#endif
+
 #ifndef __NR_finit_module
 # define __NR_finit_module -1
 #endif
index fd2028df5a603007ee4233f2bdf850c6e4224e6d..e2bab83a23105693a1b12d9fb59a00de65d90e1c 100644 (file)
@@ -45,6 +45,9 @@ static const struct kmod_ext {
 #endif
 #ifdef ENABLE_XZ
        {".ko.xz", sizeof(".ko.xz") - 1},
+#endif
+#ifdef ENABLE_ZSTD
+       {".ko.zst", sizeof(".ko.zst") - 1},
 #endif
        { }
 };
@@ -351,7 +354,7 @@ char *freadline_wrapped(FILE *fp, unsigned int *linenum)
 /* path handling functions                                                  */
 /* ************************************************************************ */
 
-bool path_is_absolute(const char *p)
+static bool path_is_absolute(const char *p)
 {
        assert(p != NULL);
 
@@ -457,12 +460,84 @@ int mkdir_parents(const char *path, mode_t mode)
        return mkdir_p(path, end - path, mode);
 }
 
-unsigned long long ts_usec(const struct timespec *ts)
+static unsigned long long ts_usec(const struct timespec *ts)
 {
        return (unsigned long long) ts->tv_sec * USEC_PER_SEC +
               (unsigned long long) ts->tv_nsec / NSEC_PER_USEC;
 }
 
+static unsigned long long ts_msec(const struct timespec *ts)
+{
+       return (unsigned long long) ts->tv_sec * MSEC_PER_SEC +
+              (unsigned long long) ts->tv_nsec / NSEC_PER_MSEC;
+}
+
+static struct timespec msec_ts(unsigned long long msec)
+{
+       struct timespec ts = {
+               .tv_sec = msec / MSEC_PER_SEC,
+               .tv_nsec = (msec % MSEC_PER_SEC) * NSEC_PER_MSEC,
+       };
+
+       return ts;
+}
+
+int sleep_until_msec(unsigned long long msec)
+{
+       struct timespec ts = msec_ts(msec);
+
+       if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL) < 0 &&
+           errno != EINTR)
+               return -errno;
+
+       return 0;
+}
+
+/*
+ * Exponential retry backoff with tail
+ */
+unsigned long long get_backoff_delta_msec(unsigned long long t0,
+                                         unsigned long long tend,
+                                         unsigned long long *delta)
+{
+       unsigned long long t;
+
+       t = now_msec();
+
+       if (!*delta)
+               *delta = 1;
+       else
+               *delta <<= 1;
+
+       while (t + *delta > tend)
+               *delta >>= 1;
+
+       if (!*delta && tend > t)
+               *delta = tend - t;
+
+       return t + *delta;
+}
+
+unsigned long long now_usec(void)
+{
+       struct timespec ts;
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+               return 0;
+
+       return ts_usec(&ts);
+}
+
+unsigned long long now_msec(void)
+{
+       struct timespec ts;
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+               return 0;
+
+       return ts_msec(&ts);
+}
+
 unsigned long long stat_mstamp(const struct stat *st)
 {
 #ifdef HAVE_STRUCT_STAT_ST_MTIM
index c6a31dfb205ab162730db8ba2fd051b09aa4faf7..c4a3916bd85e8cfe2f86709b030a677de81eca77 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <time.h>
 
 #include <shared/macro.h>
 
@@ -37,12 +38,25 @@ char *freadline_wrapped(FILE *fp, unsigned int *linenum) __attribute__((nonnull(
 
 /* path handling functions                                                  */
 /* ************************************************************************ */
-bool path_is_absolute(const char *p) _must_check_ __attribute__((nonnull(1)));
 char *path_make_absolute_cwd(const char *p) _must_check_ __attribute__((nonnull(1)));
 int mkdir_p(const char *path, int len, mode_t mode);
 int mkdir_parents(const char *path, mode_t mode);
 unsigned long long stat_mstamp(const struct stat *st);
-unsigned long long ts_usec(const struct timespec *ts);
+
+/* time-related functions
+ * ************************************************************************ */
+#define USEC_PER_SEC   1000000ULL
+#define USEC_PER_MSEC  1000ULL
+#define MSEC_PER_SEC   1000ULL
+#define NSEC_PER_MSEC  1000000ULL
+
+unsigned long long now_usec(void);
+unsigned long long now_msec(void);
+int sleep_until_msec(unsigned long long msec);
+unsigned long long get_backoff_delta_msec(unsigned long long t0,
+                                         unsigned long long tend,
+                                         unsigned long long *delta);
+
 
 /* endianess and alignments                                                 */
 /* ************************************************************************ */
index 9d26b884053602226bbc9c911c96ffd10ff7f908..5465b1a0cf4126b088b522b6165a8b15fef22998 100644 (file)
@@ -18,7 +18,6 @@
 /test-modprobe
 /test-hash
 /test-list
-/test-tools
 /rootfs
 /stamp-rootfs
 /test-scratchbuf.log
@@ -53,5 +52,3 @@
 /test-testsuite.trs
 /test-list.log
 /test-list.trs
-/test-tools.log
-/test-tools.trs
diff --git a/testsuite/mkosi/.gitignore b/testsuite/mkosi/.gitignore
deleted file mode 100644 (file)
index 0e0981a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/*-image.raw*
-/.mkosi-*
-/mkosi.cache
diff --git a/testsuite/mkosi/mkosi.arch b/testsuite/mkosi/mkosi.arch
deleted file mode 100644 (file)
index ace5d95..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-[Distribution]
-Distribution=arch
-Release=(rolling)
-
-[Output]
-Output = arch-image.raw
-
-[Packages]
-Packages = valgrind
-BuildPackages =
-       automake
-       gcc
-       git
-       make
-       pkg-config
-       python2
-       python2-future
-       autoconf
-       gtk-doc
-       docbook-xml
-       docbook-xsl
-       linux-headers
-       openssl
-
-[Partitions]
-RootSize = 3G
diff --git a/testsuite/mkosi/mkosi.build b/testsuite/mkosi/mkosi.build
deleted file mode 100755 (executable)
index c0ba549..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash -ex
-
-function find_kdir() {
-    local kdirs=(/usr/lib/modules/*/build/Makefile /usr/src/kernels/*/Makefile)
-    local kdir=""
-
-    for f in "${kdirs[@]}"; do
-        if [ -f "$f" ]; then
-            kdir=$f
-            break
-        fi
-    done
-
-    if [ -z "$kdir" ]; then
-        printf '==> Unable to find kernel headers to build modules for tests\n' >&2
-        exit 1
-    fi
-
-    kdir=${kdir%/Makefile}
-
-    echo $kdir
-}
-
-if [ -f configure ]; then
-    make distclean
-fi
-
-rm -rf build
-mkdir build
-cd build
-
-kdir=$(find_kdir)
-IFS=/ read _ _ _ kver _ <<<"$kdir"
-
-../autogen.sh c --disable-python
-make -j
-make check KDIR="$kdir" KVER="$kver"
-make install
diff --git a/testsuite/mkosi/mkosi.clear b/testsuite/mkosi/mkosi.clear
deleted file mode 100644 (file)
index 03ba2f0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-[Distribution]
-Distribution=clear
-Release=latest
-
-[Output]
-Output = clear-image.raw
-
-[Packages]
-Packages=
-       os-core-update
-BuildPackages=
-       os-core-dev
-       linux-dev
-
-[Partitions]
-RootSize = 5G
-
-[Host]
-# This is where swupd-extract is usually installed.
-ExtraSearchPaths=$SUDO_HOME/go/bin
\ No newline at end of file
diff --git a/testsuite/mkosi/mkosi.fedora b/testsuite/mkosi/mkosi.fedora
deleted file mode 100644 (file)
index 5252f87..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-[Distribution]
-Distribution=fedora
-Release=29
-
-[Output]
-Output = fedora-image.raw
-
-[Packages]
-Packages = valgrind
-BuildPackages =
-       autoconf
-       automake
-       gcc
-       git
-       gtk-doc
-       kernel-devel
-       libtool
-       libxslt
-       make
-       pkgconf-pkg-config
-       xml-common
-       xz-devel
-       zlib-devel
-       openssl-devel
-
-[Partitions]
-RootSize = 2G
index fca12f3456a77f6dbd75af84a67b8a667ab78cfd..6d9c7b13d1f318da1ff1c232b7ba707a9f953776 100644 (file)
@@ -1,4 +1,3 @@
-*o.cmd
 *.ko
 !mod-simple-*.ko
 !cache/*.ko
@@ -8,6 +7,7 @@
 *.mod
 *.a
 *.cmd
+*.o.d
 
 modules.order
 Module.symvers
index e6045b0dd9326b131cc54ab478c48ab0f6abae71..a7ab09bea2bfa5ccaca5e2c0642301c115c82d24 100644 (file)
@@ -47,7 +47,7 @@ endif
 
 else
 # normal makefile
-KDIR ?= /lib/modules/`uname -r`/build
+KDIR ?= $(module_prefix)/lib/modules/`uname -r`/build
 KVER ?= `uname -r`
 ifeq ($(FAKE_BUILD),)
     FAKE_BUILD=0
index cb385807da90e454b6ceb0c1d0a5d5f422302437..503e4d895117e41e0e30973bbe8241c16a260d33 100644 (file)
@@ -1,16 +1,32 @@
+#include <linux/debugfs.h>
 #include <linux/init.h>
 #include <linux/module.h>
 
+static struct dentry *debugfs_dir;
+
+static int test_show(struct seq_file *s, void *data)
+{
+       seq_puts(s, "test");
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(test);
+
 static int __init test_module_init(void)
 {
+       debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       debugfs_create_file("test", 0444, debugfs_dir, NULL, &test_fops);
+
        return 0;
 }
 
 static void test_module_exit(void)
 {
+       debugfs_remove_recursive(debugfs_dir);
 }
+
 module_init(test_module_init);
 module_exit(test_module_exit);
 
 MODULE_AUTHOR("Lucas De Marchi <lucas.demarchi@intel.com>");
-MODULE_LICENSE("LGPL");
+MODULE_LICENSE("GPL");
index fa5fcebd18a15f79592ab02647c2164764f326b0..5a291b1be1b01decef5dd8675c3062b106a7f80c 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+/* We unset _FILE_OFFSET_BITS here so we can override both stat and stat64 on
+ * 32-bit architectures and forward each to the right libc function */
+#undef _FILE_OFFSET_BITS
+
 #include <assert.h>
 #include <dirent.h>
 #include <dlfcn.h>
@@ -159,8 +163,15 @@ TS_EXPORT int open ## suffix (const char *path, int flags, ...)    \
        return _fn(p, flags);                                   \
 }
 
-/* wrapper template for __xstat family */
+/*
+ * wrapper template for __xstat family
+ * This family got deprecated/dropped in glibc 2.32.9000, but we still need
+ * to keep it for a while for programs that were built against previous versions
+ */
 #define WRAP_VERSTAT(prefix, suffix)                       \
+TS_EXPORT int prefix ## stat ## suffix (int ver,           \
+                             const char *path,             \
+                             struct stat ## suffix *st);   \
 TS_EXPORT int prefix ## stat ## suffix (int ver,           \
                              const char *path,             \
                              struct stat ## suffix *st)    \
@@ -181,25 +192,23 @@ TS_EXPORT int prefix ## stat ## suffix (int ver,      \
 }
 
 WRAP_1ARG(DIR*, NULL, opendir);
+WRAP_1ARG(int, -1, chdir);
 
 WRAP_2ARGS(FILE*, NULL, fopen, const char*);
+WRAP_2ARGS(FILE*, NULL, fopen64, const char*);
 WRAP_2ARGS(int, -1, mkdir, mode_t);
 WRAP_2ARGS(int, -1, access, int);
 WRAP_2ARGS(int, -1, stat, struct stat*);
 WRAP_2ARGS(int, -1, lstat, struct stat*);
-#ifndef _FILE_OFFSET_BITS
 WRAP_2ARGS(int, -1, stat64, struct stat64*);
 WRAP_2ARGS(int, -1, lstat64, struct stat64*);
 WRAP_OPEN(64);
-#endif
 
 WRAP_OPEN();
 
 #ifdef HAVE___XSTAT
 WRAP_VERSTAT(__x,);
 WRAP_VERSTAT(__lx,);
-#ifndef _FILE_OFFSET_BITS
 WRAP_VERSTAT(__x,64);
 WRAP_VERSTAT(__lx,64);
 #endif
-#endif
diff --git a/testsuite/populate-modules.sh b/testsuite/populate-modules.sh
deleted file mode 100755 (executable)
index 5140f7a..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/bash
-
-set -e
-
-MODULE_PLAYGROUND=$1
-ROOTFS=$2
-
-declare -A map
-map=(
-    ["test-depmod/search-order-simple/lib/modules/4.4.4/kernel/crypto/"]="mod-simple.ko"
-    ["test-depmod/search-order-simple/lib/modules/4.4.4/updates/"]="mod-simple.ko"
-    ["test-depmod/search-order-same-prefix/lib/modules/4.4.4/foo/"]="mod-simple.ko"
-    ["test-depmod/search-order-same-prefix/lib/modules/4.4.4/foobar/"]="mod-simple.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-c.ko"]="mod-loop-c.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-d.ko"]="mod-loop-d.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-e.ko"]="mod-loop-e.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-f.ko"]="mod-loop-f.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-g.ko"]="mod-loop-g.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-h.ko"]="mod-loop-h.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-i.ko"]="mod-loop-i.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-j.ko"]="mod-loop-j.ko"
-    ["test-depmod/detect-loop/lib/modules/4.4.4/kernel/mod-loop-k.ko"]="mod-loop-k.ko"
-    ["test-depmod/search-order-external-first/lib/modules/4.4.4/foo/"]="mod-simple.ko"
-    ["test-depmod/search-order-external-first/lib/modules/4.4.4/foobar/"]="mod-simple.ko"
-    ["test-depmod/search-order-external-first/lib/modules/external/"]="mod-simple.ko"
-    ["test-depmod/search-order-external-last/lib/modules/4.4.4/foo/"]="mod-simple.ko"
-    ["test-depmod/search-order-external-last/lib/modules/4.4.4/foobar/"]="mod-simple.ko"
-    ["test-depmod/search-order-external-last/lib/modules/external/"]="mod-simple.ko"
-    ["test-depmod/search-order-override/lib/modules/4.4.4/foo/"]="mod-simple.ko"
-    ["test-depmod/search-order-override/lib/modules/4.4.4/override/"]="mod-simple.ko"
-    ["test-dependencies/lib/modules/4.0.20-kmod/kernel/fs/foo/"]="mod-foo-b.ko"
-    ["test-dependencies/lib/modules/4.0.20-kmod/kernel/"]="mod-foo-c.ko"
-    ["test-dependencies/lib/modules/4.0.20-kmod/kernel/lib/"]="mod-foo-a.ko"
-    ["test-dependencies/lib/modules/4.0.20-kmod/kernel/fs/"]="mod-foo.ko"
-    ["test-init/"]="mod-simple.ko"
-    ["test-remove/"]="mod-simple.ko"
-    ["test-modprobe/show-depends/lib/modules/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
-    ["test-modprobe/show-depends/lib/modules/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
-    ["test-modprobe/show-depends/lib/modules/4.4.4/kernel/mod-simple.ko"]="mod-simple.ko"
-    ["test-modprobe/show-exports/mod-loop-a.ko"]="mod-loop-a.ko"
-    ["test-modprobe/softdep-loop/lib/modules/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
-    ["test-modprobe/softdep-loop/lib/modules/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
-    ["test-modprobe/install-cmd-loop/lib/modules/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
-    ["test-modprobe/install-cmd-loop/lib/modules/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
-    ["test-modprobe/force/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
-    ["test-modprobe/oldkernel/lib/modules/3.3.3/kernel/"]="mod-simple.ko"
-    ["test-modprobe/oldkernel-force/lib/modules/3.3.3/kernel/"]="mod-simple.ko"
-    ["test-modprobe/alias-to-none/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
-    ["test-modprobe/module-param-kcmdline/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
-    ["test-modprobe/external/lib/modules/external/"]="mod-simple.ko"
-    ["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/block/cciss.ko"]="mod-fake-cciss.ko"
-    ["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/hpsa.ko"]="mod-fake-hpsa.ko"
-    ["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/scsi_mod.ko"]="mod-fake-scsi-mod.ko"
-    ["test-modinfo/mod-simple-i386.ko"]="mod-simple-i386.ko"
-    ["test-modinfo/mod-simple-x86_64.ko"]="mod-simple-x86_64.ko"
-    ["test-modinfo/mod-simple-sparc64.ko"]="mod-simple-sparc64.ko"
-    ["test-modinfo/mod-simple-sha1.ko"]="mod-simple.ko"
-    ["test-modinfo/mod-simple-sha256.ko"]="mod-simple.ko"
-    ["test-modinfo/mod-simple-pkcs7.ko"]="mod-simple.ko"
-    ["test-modinfo/external/lib/modules/external/mod-simple.ko"]="mod-simple.ko"
-    ["test-tools/insert/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
-    ["test-tools/remove/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
-)
-
-gzip_array=(
-    "test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/block/cciss.ko"
-    "test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/hpsa.ko"
-    "test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/scsi_mod.ko"
-    )
-
-attach_sha256_array=(
-    "test-modinfo/mod-simple-sha256.ko"
-    )
-
-attach_sha1_array=(
-    "test-modinfo/mod-simple-sha1.ko"
-    )
-
-attach_pkcs7_array=(
-    "test-modinfo/mod-simple-pkcs7.ko"
-    )
-
-for k in ${!map[@]}; do
-    dst=${ROOTFS}/$k
-    src=${MODULE_PLAYGROUND}/${map[$k]}
-
-    if test "${dst: -1}" = "/"; then
-        install -d $dst
-        install -t $dst $src
-    else
-        install -D $src $dst
-    fi
-done
-
-# start poking the final rootfs...
-
-# gzip these modules
-for m in "${gzip_array[@]}"; do
-    gzip $ROOTFS/$m
-done
-
-for m in "${attach_sha1_array[@]}"; do
-    cat ${MODULE_PLAYGROUND}/dummy.sha1 >> ${ROOTFS}/$m
-done
-
-for m in "${attach_sha256_array[@]}"; do
-    cat ${MODULE_PLAYGROUND}/dummy.sha256 >> ${ROOTFS}/$m
-done
-
-for m in "${attach_pkcs7_array[@]}"; do
-    cat ${MODULE_PLAYGROUND}/dummy.pkcs7 >> ${ROOTFS}/$m
-done
diff --git a/testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.alias b/testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.alias
new file mode 100644 (file)
index 0000000..5675329
--- /dev/null
@@ -0,0 +1,37 @@
+# Aliases extracted from modules themselves.
+alias pci:v0000103Cd00003230sv0000103Csd0000323Dbc*sc*i* cciss
+alias pci:v0000103Cd00003230sv0000103Csd00003237bc*sc*i* cciss
+alias pci:v0000103Cd00003238sv0000103Csd00003215bc*sc*i* cciss
+alias pci:v0000103Cd00003238sv0000103Csd00003214bc*sc*i* cciss
+alias pci:v0000103Cd00003238sv0000103Csd00003213bc*sc*i* cciss
+alias pci:v0000103Cd00003238sv0000103Csd00003212bc*sc*i* cciss
+alias pci:v0000103Cd00003238sv0000103Csd00003211bc*sc*i* cciss
+alias pci:v0000103Cd00003230sv0000103Csd00003235bc*sc*i* cciss
+alias pci:v0000103Cd00003230sv0000103Csd00003234bc*sc*i* cciss
+alias pci:v0000103Cd00003230sv0000103Csd00003223bc*sc*i* cciss
+alias pci:v0000103Cd00003220sv0000103Csd00003225bc*sc*i* cciss
+alias pci:v00000E11d00000046sv00000E11sd0000409Dbc*sc*i* cciss
+alias pci:v00000E11d00000046sv00000E11sd0000409Cbc*sc*i* cciss
+alias pci:v00000E11d00000046sv00000E11sd0000409Bbc*sc*i* cciss
+alias pci:v00000E11d00000046sv00000E11sd0000409Abc*sc*i* cciss
+alias pci:v00000E11d00000046sv00000E11sd00004091bc*sc*i* cciss
+alias pci:v00000E11d0000B178sv00000E11sd00004083bc*sc*i* cciss
+alias pci:v00000E11d0000B178sv00000E11sd00004082bc*sc*i* cciss
+alias pci:v00000E11d0000B178sv00000E11sd00004080bc*sc*i* cciss
+alias pci:v00000E11d0000B060sv00000E11sd00004070bc*sc*i* cciss
+alias pci:v0000103Cd*sv*sd*bc01sc04i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003356bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003355bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003354bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003353bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003352bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003351bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Bsv0000103Csd00003350bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003233bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd0000324Bbc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd0000324Abc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003249bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003247bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003245bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003243bc*sc*i* hpsa
+alias pci:v0000103Cd0000323Asv0000103Csd00003241bc*sc*i* hpsa
diff --git a/testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.dep b/testsuite/rootfs-pristine/test-depmod/modules-outdir/correct-modules.dep
new file mode 100644 (file)
index 0000000..ec50ac3
--- /dev/null
@@ -0,0 +1,3 @@
+kernel/drivers/block/cciss.ko:
+kernel/drivers/scsi/scsi_mod.ko:
+kernel/drivers/scsi/hpsa.ko: kernel/drivers/scsi/scsi_mod.ko
diff --git a/testsuite/rootfs-pristine/test-depmod/modules-outdir/lib/modules/4.4.4/modules.order b/testsuite/rootfs-pristine/test-depmod/modules-outdir/lib/modules/4.4.4/modules.order
new file mode 100644 (file)
index 0000000..4b64309
--- /dev/null
@@ -0,0 +1,7 @@
+#336
+kernel/drivers/block/cciss.ko
+#2094
+kernel/drivers/scsi/scsi_mod.ko
+#2137
+kernel/drivers/scsi/hpsa.ko
+
diff --git a/testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin b/testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin
new file mode 100644 (file)
index 0000000..1cbec61
--- /dev/null
@@ -0,0 +1 @@
+kernel/fake_builtin.ko
diff --git a/testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin.bin b/testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin.bin
new file mode 100644 (file)
index 0000000..0423f03
Binary files /dev/null and b/testsuite/rootfs-pristine/test-init-load-resources-empty-builtin-aliases-bin/lib/modules/5.6.0/modules.builtin.bin differ
diff --git a/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin b/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin
new file mode 100644 (file)
index 0000000..1cbec61
--- /dev/null
@@ -0,0 +1 @@
+kernel/fake_builtin.ko
diff --git a/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin.bin b/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin.bin
new file mode 100644 (file)
index 0000000..0423f03
Binary files /dev/null and b/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.builtin.bin differ
diff --git a/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.symbols.bin b/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.symbols.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-init-load-resources/lib/modules/5.6.0/modules.symbols.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias
new file mode 100644 (file)
index 0000000..ba76e18
--- /dev/null
@@ -0,0 +1 @@
+# Aliases extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.alias.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep
new file mode 100644 (file)
index 0000000..e612900
--- /dev/null
@@ -0,0 +1 @@
+/lib/modules/external/mod-simple.ko:
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep.bin
new file mode 100644 (file)
index 0000000..556e3c8
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.dep.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.softdep b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.softdep
new file mode 100644 (file)
index 0000000..5554ccc
--- /dev/null
@@ -0,0 +1 @@
+# Soft dependencies extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols
new file mode 100644 (file)
index 0000000..618c345
--- /dev/null
@@ -0,0 +1 @@
+# Aliases for symbols, used by symbol_request().
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/lib/modules/4.4.4/modules.symbols.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/proc/modules b/testsuite/rootfs-pristine/test-modprobe/module-from-abspath/proc/modules
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias
new file mode 100644 (file)
index 0000000..ba76e18
--- /dev/null
@@ -0,0 +1 @@
+# Aliases extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.alias.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.builtin.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.builtin.bin
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep
new file mode 100644 (file)
index 0000000..e612900
--- /dev/null
@@ -0,0 +1 @@
+/lib/modules/external/mod-simple.ko:
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep.bin
new file mode 100644 (file)
index 0000000..556e3c8
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.dep.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.devname b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.devname
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.softdep b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.softdep
new file mode 100644 (file)
index 0000000..5554ccc
--- /dev/null
@@ -0,0 +1 @@
+# Soft dependencies extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols
new file mode 100644 (file)
index 0000000..618c345
--- /dev/null
@@ -0,0 +1 @@
+# Aliases for symbols, used by symbol_request().
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols.bin b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/lib/modules/4.4.4/modules.symbols.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/proc/modules b/testsuite/rootfs-pristine/test-modprobe/module-from-relpath/proc/modules
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/correct.txt b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/correct.txt
new file mode 100644 (file)
index 0000000..d80da6d
--- /dev/null
@@ -0,0 +1,5 @@
+options psmouse foo
+options parport dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
+
+# End of configuration files. Dumping indexes now:
+
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/correct.txt b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/correct.txt
new file mode 100644 (file)
index 0000000..d80da6d
--- /dev/null
@@ -0,0 +1,5 @@
+options psmouse foo
+options parport dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
+
+# End of configuration files. Dumping indexes now:
+
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/proc/cmdline b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/module-param-kcmdline7/proc/cmdline
new file mode 100644 (file)
index 0000000..86f9052
--- /dev/null
@@ -0,0 +1 @@
+psmouse.foo parport.dyndbg="file drivers/parport/ieee1284_ops.c +mpf" quiet rw
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/proc/cmdline b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline7/proc/cmdline
new file mode 100644 (file)
index 0000000..86f9052
--- /dev/null
@@ -0,0 +1 @@
+psmouse.foo parport.dyndbg="file drivers/parport/ieee1284_ops.c +mpf" quiet rw
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/correct.txt b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/correct.txt
new file mode 100644 (file)
index 0000000..d80da6d
--- /dev/null
@@ -0,0 +1,5 @@
+options psmouse foo
+options parport dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
+
+# End of configuration files. Dumping indexes now:
+
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/correct.txt b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/correct.txt
new file mode 100644 (file)
index 0000000..d80da6d
--- /dev/null
@@ -0,0 +1,5 @@
+options psmouse foo
+options parport dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
+
+# End of configuration files. Dumping indexes now:
+
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/proc/cmdline b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/module-param-kcmdline7/proc/cmdline
new file mode 100644 (file)
index 0000000..86f9052
--- /dev/null
@@ -0,0 +1 @@
+psmouse.foo parport.dyndbg="file drivers/parport/ieee1284_ops.c +mpf" quiet rw
diff --git a/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/proc/cmdline b/testsuite/rootfs-pristine/test-modprobe/module-param-kcmdline8/proc/cmdline
new file mode 100644 (file)
index 0000000..eab04ad
--- /dev/null
@@ -0,0 +1 @@
+psmouse.foo "parport.dyndbg=file drivers/parport/ieee1284_ops.c +mpf" quiet rw
diff --git a/testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep
deleted file mode 100644 (file)
index 5476653..0000000
+++ /dev/null
@@ -1 +0,0 @@
-kernel/mod-simple.ko:
diff --git a/testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep.bin
deleted file mode 100644 (file)
index b09a854..0000000
Binary files a/testsuite/rootfs-pristine/test-tools/insert/lib/modules/4.4.4/modules.dep.bin and /dev/null differ
diff --git a/testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep
deleted file mode 100644 (file)
index 5476653..0000000
+++ /dev/null
@@ -1 +0,0 @@
-kernel/mod-simple.ko:
diff --git a/testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep.bin
deleted file mode 100644 (file)
index b09a854..0000000
Binary files a/testsuite/rootfs-pristine/test-tools/remove/lib/modules/4.4.4/modules.dep.bin and /dev/null differ
diff --git a/testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/initstate b/testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/initstate
deleted file mode 100644 (file)
index e23fe64..0000000
+++ /dev/null
@@ -1 +0,0 @@
-live
diff --git a/testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/refcnt b/testsuite/rootfs-pristine/test-tools/remove/sys/module/mod_simple/refcnt
deleted file mode 100644 (file)
index 573541a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/testsuite/setup-rootfs.sh b/testsuite/setup-rootfs.sh
new file mode 100755 (executable)
index 0000000..5477c69
--- /dev/null
@@ -0,0 +1,179 @@
+#!/bin/bash
+
+set -e
+
+ROOTFS_PRISTINE=$1
+ROOTFS=$2
+MODULE_PLAYGROUND=$3
+CONFIG_H=$4
+SYSCONFDIR=$5
+
+# create rootfs from rootfs-pristine
+
+create_rootfs() {
+       rm -rf "$ROOTFS"
+       mkdir -p $(dirname "$ROOTFS")
+       cp -r "$ROOTFS_PRISTINE" "$ROOTFS"
+       find "$ROOTFS" -type d -exec chmod +w {} \;
+       find "$ROOTFS" -type f -name .gitignore -exec rm -f {} \;
+       if [ "$MODULE_DIRECTORY" != "/lib/modules" ] ; then
+               sed -i -e "s|/lib/modules|$MODULE_DIRECTORY|g" $(find "$ROOTFS" -name \*.txt -o -name \*.conf -o -name \*.dep)
+               sed -i -e "s|$MODULE_DIRECTORY/external|/lib/modules/external|g" $(find "$ROOTFS" -name \*.txt -o -name \*.conf -o -name \*.dep)
+               for i in "$ROOTFS"/*/lib/modules/* "$ROOTFS"/*/*/lib/modules/* ; do
+                       version="$(basename $i)"
+                       [ $version != 'external' ] || continue
+                       mod="$(dirname $i)"
+                       lib="$(dirname $mod)"
+                       up="$(dirname $lib)$MODULE_DIRECTORY"
+                       mkdir -p "$up"
+                       mv "$i" "$up"
+               done
+       fi
+
+       if [ "$SYSCONFDIR" != "/etc" ]; then
+               find "$ROOTFS" -type d -name etc -printf "%h\n" | while read -r e; do
+                       mkdir -p "$(dirname $e/$SYSCONFDIR)"
+                       mv $e/{etc,$SYSCONFDIR}
+               done
+       fi
+}
+
+feature_enabled() {
+       local feature=$1
+       grep KMOD_FEATURES  $CONFIG_H | head -n 1 | grep -q \+$feature
+}
+
+declare -A map
+map=(
+    ["test-depmod/search-order-simple$MODULE_DIRECTORY/4.4.4/kernel/crypto/"]="mod-simple.ko"
+    ["test-depmod/search-order-simple$MODULE_DIRECTORY/4.4.4/updates/"]="mod-simple.ko"
+    ["test-depmod/search-order-same-prefix$MODULE_DIRECTORY/4.4.4/foo/"]="mod-simple.ko"
+    ["test-depmod/search-order-same-prefix$MODULE_DIRECTORY/4.4.4/foobar/"]="mod-simple.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-c.ko"]="mod-loop-c.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-d.ko"]="mod-loop-d.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-e.ko"]="mod-loop-e.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-f.ko"]="mod-loop-f.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-g.ko"]="mod-loop-g.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-h.ko"]="mod-loop-h.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-i.ko"]="mod-loop-i.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-j.ko"]="mod-loop-j.ko"
+    ["test-depmod/detect-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-k.ko"]="mod-loop-k.ko"
+    ["test-depmod/search-order-external-first$MODULE_DIRECTORY/4.4.4/foo/"]="mod-simple.ko"
+    ["test-depmod/search-order-external-first$MODULE_DIRECTORY/4.4.4/foobar/"]="mod-simple.ko"
+    ["test-depmod/search-order-external-first/lib/modules/external/"]="mod-simple.ko"
+    ["test-depmod/search-order-external-last$MODULE_DIRECTORY/4.4.4/foo/"]="mod-simple.ko"
+    ["test-depmod/search-order-external-last$MODULE_DIRECTORY/4.4.4/foobar/"]="mod-simple.ko"
+    ["test-depmod/search-order-external-last/lib/modules/external/"]="mod-simple.ko"
+    ["test-depmod/search-order-override$MODULE_DIRECTORY/4.4.4/foo/"]="mod-simple.ko"
+    ["test-depmod/search-order-override$MODULE_DIRECTORY/4.4.4/override/"]="mod-simple.ko"
+    ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/fs/foo/"]="mod-foo-b.ko"
+    ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/"]="mod-foo-c.ko"
+    ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/lib/"]="mod-foo-a.ko"
+    ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/fs/"]="mod-foo.ko"
+    ["test-init/"]="mod-simple.ko"
+    ["test-remove/"]="mod-simple.ko"
+    ["test-modprobe/show-depends$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-modprobe/show-depends$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-modprobe/show-depends$MODULE_DIRECTORY/4.4.4/kernel/mod-simple.ko"]="mod-simple.ko"
+    ["test-modprobe/show-exports/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-modprobe/softdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-modprobe/softdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-modprobe/install-cmd-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-modprobe/install-cmd-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-modprobe/force$MODULE_DIRECTORY/4.4.4/kernel/"]="mod-simple.ko"
+    ["test-modprobe/oldkernel$MODULE_DIRECTORY/3.3.3/kernel/"]="mod-simple.ko"
+    ["test-modprobe/oldkernel-force$MODULE_DIRECTORY/3.3.3/kernel/"]="mod-simple.ko"
+    ["test-modprobe/alias-to-none$MODULE_DIRECTORY/4.4.4/kernel/"]="mod-simple.ko"
+    ["test-modprobe/module-param-kcmdline$MODULE_DIRECTORY/4.4.4/kernel/"]="mod-simple.ko"
+    ["test-modprobe/external/lib/modules/external/"]="mod-simple.ko"
+    ["test-modprobe/module-from-abspath/home/foo/"]="mod-simple.ko"
+    ["test-modprobe/module-from-relpath/home/foo/"]="mod-simple.ko"
+    ["test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/block/cciss.ko"]="mod-fake-cciss.ko"
+    ["test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/hpsa.ko"]="mod-fake-hpsa.ko"
+    ["test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/scsi_mod.ko"]="mod-fake-scsi-mod.ko"
+    ["test-depmod/modules-outdir$MODULE_DIRECTORY/4.4.4/kernel/drivers/block/cciss.ko"]="mod-fake-cciss.ko"
+    ["test-depmod/modules-outdir$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/hpsa.ko"]="mod-fake-hpsa.ko"
+    ["test-depmod/modules-outdir$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/scsi_mod.ko"]="mod-fake-scsi-mod.ko"
+    ["test-modinfo/mod-simple-i386.ko"]="mod-simple-i386.ko"
+    ["test-modinfo/mod-simple-x86_64.ko"]="mod-simple-x86_64.ko"
+    ["test-modinfo/mod-simple-sparc64.ko"]="mod-simple-sparc64.ko"
+    ["test-modinfo/mod-simple-sha1.ko"]="mod-simple.ko"
+    ["test-modinfo/mod-simple-sha256.ko"]="mod-simple.ko"
+    ["test-modinfo/mod-simple-pkcs7.ko"]="mod-simple.ko"
+    ["test-modinfo/external/lib/modules/external/mod-simple.ko"]="mod-simple.ko"
+)
+
+gzip_array=(
+    "test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/block/cciss.ko"
+    )
+
+xz_array=(
+    "test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/scsi_mod.ko"
+    )
+
+zstd_array=(
+    "test-depmod/modules-order-compressed$MODULE_DIRECTORY/4.4.4/kernel/drivers/scsi/hpsa.ko"
+    )
+
+attach_sha256_array=(
+    "test-modinfo/mod-simple-sha256.ko"
+    )
+
+attach_sha1_array=(
+    "test-modinfo/mod-simple-sha1.ko"
+    )
+
+attach_pkcs7_array=(
+    "test-modinfo/mod-simple-pkcs7.ko"
+    )
+
+create_rootfs
+
+for k in "${!map[@]}"; do
+    dst=${ROOTFS}/$k
+    src=${MODULE_PLAYGROUND}/${map[$k]}
+
+    if [[ $dst = */ ]]; then
+        install -d "$dst"
+        install -t "$dst" "$src"
+    else
+        install -D "$src" "$dst"
+    fi
+done
+
+# start poking the final rootfs...
+
+# compress modules with each format if feature is enabled
+if feature_enabled ZLIB; then
+       for m in "${gzip_array[@]}"; do
+           gzip "$ROOTFS/$m"
+       done
+fi
+
+if feature_enabled XZ; then
+       for m in "${xz_array[@]}"; do
+           xz "$ROOTFS/$m"
+       done
+fi
+
+if feature_enabled ZSTD; then
+       for m in "${zstd_array[@]}"; do
+           zstd --rm $ROOTFS/$m
+       done
+fi
+
+for m in "${attach_sha1_array[@]}"; do
+    cat "${MODULE_PLAYGROUND}/dummy.sha1" >>"${ROOTFS}/$m"
+done
+
+for m in "${attach_sha256_array[@]}"; do
+    cat "${MODULE_PLAYGROUND}/dummy.sha256" >>"${ROOTFS}/$m"
+done
+
+for m in "${attach_pkcs7_array[@]}"; do
+    cat "${MODULE_PLAYGROUND}/dummy.pkcs7" >>"${ROOTFS}/$m"
+done
+
+touch testsuite/stamp-rootfs
index 47dafb4dd618304904dfce28e1f4fbbdb81cbb76..c96dbf0a62bef7251605c6fb4d4a8a59e988f1ee 100644 (file)
 
 #include "testsuite.h"
 
-#ifdef ENABLE_ZLIB
-#define MODULES_ORDER_UNAME "4.4.4"
+#define MODULES_UNAME "4.4.4"
 #define MODULES_ORDER_ROOTFS TESTSUITE_ROOTFS "test-depmod/modules-order-compressed"
-#define MODULES_ORDER_LIB_MODULES MODULES_ORDER_ROOTFS "/lib/modules/" MODULES_ORDER_UNAME
+#define MODULES_ORDER_LIB_MODULES MODULES_ORDER_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_modules_order_for_compressed(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -44,7 +43,7 @@ static noreturn int depmod_modules_order_for_compressed(const struct test *t)
 DEFINE_TEST(depmod_modules_order_for_compressed,
        .description = "check if depmod let aliases in right order when using compressed modules",
        .config = {
-               [TC_UNAME_R] = MODULES_ORDER_UNAME,
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = MODULES_ORDER_ROOTFS,
        },
        .output = {
@@ -54,9 +53,41 @@ DEFINE_TEST(depmod_modules_order_for_compressed,
                        { }
                },
        });
-#endif
+
+#define MODULES_OUTDIR_ROOTFS TESTSUITE_ROOTFS "test-depmod/modules-outdir"
+#define MODULES_OUTDIR_LIB_MODULES_OUTPUT MODULES_OUTDIR_ROOTFS "/outdir" MODULE_DIRECTORY "/" MODULES_UNAME
+#define MODULES_OUTDIR_LIB_MODULES_INPUT MODULES_OUTDIR_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
+static noreturn int depmod_modules_outdir(const struct test *t)
+{
+       const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
+       const char *const args[] = {
+               progname,
+               "--outdir", MODULES_OUTDIR_ROOTFS "/outdir/",
+               NULL,
+       };
+
+       test_spawn_prog(progname, args);
+       exit(EXIT_FAILURE);
+}
+
+DEFINE_TEST(depmod_modules_outdir,
+       .description = "check if depmod honours the outdir option",
+       .config = {
+               [TC_UNAME_R] = MODULES_UNAME,
+               [TC_ROOTFS] = MODULES_OUTDIR_ROOTFS,
+       },
+       .output = {
+               .files = (const struct keyval[]) {
+                       { MODULES_OUTDIR_LIB_MODULES_OUTPUT "/modules.dep",
+                         MODULES_OUTDIR_ROOTFS "/correct-modules.dep" },
+                       { MODULES_OUTDIR_LIB_MODULES_OUTPUT "/modules.alias",
+                         MODULES_OUTDIR_ROOTFS "/correct-modules.alias" },
+                       { }
+               },
+       });
 
 #define SEARCH_ORDER_SIMPLE_ROOTFS TESTSUITE_ROOTFS "test-depmod/search-order-simple"
+#define SEARCH_ORDER_SIMPLE_LIB_MODULES SEARCH_ORDER_SIMPLE_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_search_order_simple(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -71,18 +102,19 @@ static noreturn int depmod_search_order_simple(const struct test *t)
 DEFINE_TEST(depmod_search_order_simple,
        .description = "check if depmod honor search order in config",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = SEARCH_ORDER_SIMPLE_ROOTFS,
        },
        .output = {
                .files = (const struct keyval[]) {
-                       { SEARCH_ORDER_SIMPLE_ROOTFS "/lib/modules/4.4.4/correct-modules.dep",
-                         SEARCH_ORDER_SIMPLE_ROOTFS "/lib/modules/4.4.4/modules.dep" },
+                       { SEARCH_ORDER_SIMPLE_LIB_MODULES "/correct-modules.dep",
+                         SEARCH_ORDER_SIMPLE_LIB_MODULES "/modules.dep" },
                        { }
                },
        });
 
 #define SEARCH_ORDER_SAME_PREFIX_ROOTFS TESTSUITE_ROOTFS "test-depmod/search-order-same-prefix"
+#define SEARCH_ORDER_SAME_PREFIX_LIB_MODULES SEARCH_ORDER_SAME_PREFIX_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_search_order_same_prefix(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -97,13 +129,13 @@ static noreturn int depmod_search_order_same_prefix(const struct test *t)
 DEFINE_TEST(depmod_search_order_same_prefix,
        .description = "check if depmod honor search order in config with same prefix",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = SEARCH_ORDER_SAME_PREFIX_ROOTFS,
        },
        .output = {
                .files = (const struct keyval[]) {
-                       { SEARCH_ORDER_SAME_PREFIX_ROOTFS "/lib/modules/4.4.4/correct-modules.dep",
-                         SEARCH_ORDER_SAME_PREFIX_ROOTFS "/lib/modules/4.4.4/modules.dep" },
+                       { SEARCH_ORDER_SAME_PREFIX_LIB_MODULES "/correct-modules.dep",
+                         SEARCH_ORDER_SAME_PREFIX_LIB_MODULES "/modules.dep" },
                        { }
                },
        });
@@ -123,7 +155,7 @@ static noreturn int depmod_detect_loop(const struct test *t)
 DEFINE_TEST(depmod_detect_loop,
        .description = "check if depmod detects module loops correctly",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = DETECT_LOOP_ROOTFS,
        },
        .expected_fail = true,
@@ -132,6 +164,7 @@ DEFINE_TEST(depmod_detect_loop,
        });
 
 #define SEARCH_ORDER_EXTERNAL_FIRST_ROOTFS TESTSUITE_ROOTFS "test-depmod/search-order-external-first"
+#define SEARCH_ORDER_EXTERNAL_FIRST_LIB_MODULES SEARCH_ORDER_EXTERNAL_FIRST_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_search_order_external_first(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -146,18 +179,19 @@ static noreturn int depmod_search_order_external_first(const struct test *t)
 DEFINE_TEST(depmod_search_order_external_first,
        .description = "check if depmod honor external keyword with higher priority",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = SEARCH_ORDER_EXTERNAL_FIRST_ROOTFS,
        },
        .output = {
                .files = (const struct keyval[]) {
-                       { SEARCH_ORDER_EXTERNAL_FIRST_ROOTFS "/lib/modules/4.4.4/correct-modules.dep",
-                         SEARCH_ORDER_EXTERNAL_FIRST_ROOTFS "/lib/modules/4.4.4/modules.dep" },
+                       { SEARCH_ORDER_EXTERNAL_FIRST_LIB_MODULES "/correct-modules.dep",
+                         SEARCH_ORDER_EXTERNAL_FIRST_LIB_MODULES "/modules.dep" },
                        { }
                },
        });
 
 #define SEARCH_ORDER_EXTERNAL_LAST_ROOTFS TESTSUITE_ROOTFS "test-depmod/search-order-external-last"
+#define SEARCH_ORDER_EXTERNAL_LAST_LIB_MODULES SEARCH_ORDER_EXTERNAL_LAST_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_search_order_external_last(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -172,18 +206,19 @@ static noreturn int depmod_search_order_external_last(const struct test *t)
 DEFINE_TEST(depmod_search_order_external_last,
        .description = "check if depmod honor external keyword with lower priority",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = SEARCH_ORDER_EXTERNAL_LAST_ROOTFS,
        },
        .output = {
                .files = (const struct keyval[]) {
-                       { SEARCH_ORDER_EXTERNAL_LAST_ROOTFS "/lib/modules/4.4.4/correct-modules.dep",
-                         SEARCH_ORDER_EXTERNAL_LAST_ROOTFS "/lib/modules/4.4.4/modules.dep" },
+                       { SEARCH_ORDER_EXTERNAL_LAST_LIB_MODULES "/correct-modules.dep",
+                         SEARCH_ORDER_EXTERNAL_LAST_LIB_MODULES "/modules.dep" },
                        { }
                },
        });
 
 #define SEARCH_ORDER_OVERRIDE_ROOTFS TESTSUITE_ROOTFS "test-depmod/search-order-override"
+#define SEARCH_ORDER_OVERRIDE_LIB_MODULES SEARCH_ORDER_OVERRIDE_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
 static noreturn int depmod_search_order_override(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
@@ -198,13 +233,13 @@ static noreturn int depmod_search_order_override(const struct test *t)
 DEFINE_TEST(depmod_search_order_override,
        .description = "check if depmod honor override keyword",
        .config = {
-               [TC_UNAME_R] = "4.4.4",
+               [TC_UNAME_R] = MODULES_UNAME,
                [TC_ROOTFS] = SEARCH_ORDER_OVERRIDE_ROOTFS,
        },
        .output = {
                .files = (const struct keyval[]) {
-                       { SEARCH_ORDER_OVERRIDE_ROOTFS "/lib/modules/4.4.4/correct-modules.dep",
-                         SEARCH_ORDER_OVERRIDE_ROOTFS "/lib/modules/4.4.4/modules.dep" },
+                       { SEARCH_ORDER_OVERRIDE_LIB_MODULES "/correct-modules.dep",
+                         SEARCH_ORDER_OVERRIDE_LIB_MODULES "/modules.dep" },
                        { }
                },
        });
index 96512808b82951fc5b013f3cd6e217e6fb0c172c..edbfc233160165e567b203a8e4360cfbdb0fa729 100644 (file)
 
 #include "testsuite.h"
 
+static noreturn int test_load_resources(const struct test *t)
+{
+       struct kmod_ctx *ctx;
+       const char *null_config = NULL;
+       int err;
+
+       ctx = kmod_new(NULL, &null_config);
+       if (ctx == NULL)
+               exit(EXIT_FAILURE);
+
+       kmod_set_log_priority(ctx, 7);
+
+       err = kmod_load_resources(ctx);
+       if (err != 0) {
+               ERR("could not load libkmod resources: %s\n", strerror(-err));
+               exit(EXIT_FAILURE);
+       }
+
+       kmod_unref(ctx);
+
+       exit(EXIT_SUCCESS);
+}
+DEFINE_TEST(test_load_resources,
+           .description = "test if kmod_load_resources works (recent modprobe on kernel without modules.builtin.modinfo)",
+           .config = {
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-init-load-resources/",
+               [TC_UNAME_R] = "5.6.0",
+           },
+           .need_spawn = true);
+
+DEFINE_TEST(test_load_resources,
+           .description = "test if kmod_load_resources works with empty modules.builtin.aliases.bin (recent depmod on kernel without modules.builtin.modinfo)",
+           .config = {
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-init-load-resources-empty-builtin-aliases-bin/",
+               [TC_UNAME_R] = "5.6.0",
+           },
+           .need_spawn = true);
+
 static noreturn int test_initlib(const struct test *t)
 {
        struct kmod_ctx *ctx;
index da2303a1a6bca65e4260c5dce67a74ec24ad6347..9332e8f21eeb80aa5821a03d5c624c280d67896f 100644 (file)
@@ -45,7 +45,7 @@ static noreturn int test_initstate_from_lookup(const struct test *t)
                exit(EXIT_FAILURE);
 
        err = kmod_module_new_from_lookup(ctx, "fake-builtin", &list);
-       if (err != 0) {
+       if (err < 0) {
                ERR("could not create module from lookup: %s\n", strerror(-err));
                exit(EXIT_FAILURE);
        }
index f908d56fd309b73710078440f24e9c1f8af35adb..309f3e34c5fc84f3c874d68280916c66b8721ceb 100644 (file)
@@ -207,7 +207,7 @@ DEFINE_TEST(modprobe_install_cmd_loop,
        .modules_loaded = "mod-loop-b,mod-loop-a",
        );
 
-static noreturn int modprobe_param_kcmdline(const struct test *t)
+static noreturn int modprobe_param_kcmdline_show_deps(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
        const char *const args[] = {
@@ -219,7 +219,7 @@ static noreturn int modprobe_param_kcmdline(const struct test *t)
        test_spawn_prog(progname, args);
        exit(EXIT_FAILURE);
 }
-DEFINE_TEST(modprobe_param_kcmdline,
+DEFINE_TEST(modprobe_param_kcmdline_show_deps,
        .description = "check if params from kcmdline are passed to (f)init_module call",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -231,7 +231,7 @@ DEFINE_TEST(modprobe_param_kcmdline,
        .modules_loaded = "",
        );
 
-static noreturn int modprobe_param_kcmdline2(const struct test *t)
+static noreturn int modprobe_param_kcmdline(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
        const char *const args[] = {
@@ -243,7 +243,7 @@ static noreturn int modprobe_param_kcmdline2(const struct test *t)
        test_spawn_prog(progname, args);
        exit(EXIT_FAILURE);
 }
-DEFINE_TEST(modprobe_param_kcmdline2,
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline2, modprobe_param_kcmdline,
        .description = "check if params with no value are parsed correctly from kcmdline",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -255,19 +255,7 @@ DEFINE_TEST(modprobe_param_kcmdline2,
        .modules_loaded = "",
        );
 
-static noreturn int modprobe_param_kcmdline3(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
-       const char *const args[] = {
-               progname,
-               "-c",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(modprobe_param_kcmdline3,
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline3, modprobe_param_kcmdline,
        .description = "check if unrelated strings in kcmdline are correctly ignored",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -279,19 +267,7 @@ DEFINE_TEST(modprobe_param_kcmdline3,
        .modules_loaded = "",
        );
 
-static noreturn int modprobe_param_kcmdline4(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
-       const char *const args[] = {
-               progname,
-               "-c",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(modprobe_param_kcmdline4,
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline4, modprobe_param_kcmdline,
        .description = "check if unrelated strings in kcmdline are correctly ignored",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -303,19 +279,7 @@ DEFINE_TEST(modprobe_param_kcmdline4,
        .modules_loaded = "",
        );
 
-static noreturn int modprobe_param_kcmdline5(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
-       const char *const args[] = {
-               progname,
-               "-c",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(modprobe_param_kcmdline5,
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline5, modprobe_param_kcmdline,
        .description = "check if params with spaces are parsed correctly from kcmdline",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -327,20 +291,7 @@ DEFINE_TEST(modprobe_param_kcmdline5,
        .modules_loaded = "",
        );
 
-
-static noreturn int modprobe_param_kcmdline6(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
-       const char *const args[] = {
-               progname,
-               "-c",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(modprobe_param_kcmdline6,
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline6, modprobe_param_kcmdline,
        .description = "check if dots on other parts of kcmdline don't confuse our parser",
        .config = {
                [TC_UNAME_R] = "4.4.4",
@@ -352,6 +303,30 @@ DEFINE_TEST(modprobe_param_kcmdline6,
        .modules_loaded = "",
        );
 
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline7, modprobe_param_kcmdline,
+       .description = "check if dots on other parts of kcmdline don't confuse our parser",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-param-kcmdline7",
+       },
+       .output = {
+               .out = TESTSUITE_ROOTFS "test-modprobe/module-param-kcmdline7/correct.txt",
+       },
+       .modules_loaded = "",
+       );
+
+DEFINE_TEST_WITH_FUNC(modprobe_param_kcmdline8, modprobe_param_kcmdline,
+       .description = "check if dots on other parts of kcmdline don't confuse our parser",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-param-kcmdline8",
+       },
+       .output = {
+               .out = TESTSUITE_ROOTFS "test-modprobe/module-param-kcmdline8/correct.txt",
+       },
+       .modules_loaded = "",
+       );
+
 
 static noreturn int modprobe_force(const struct test *t)
 {
@@ -441,4 +416,54 @@ DEFINE_TEST(modprobe_external,
        .modules_loaded = "mod-simple",
        );
 
+static noreturn int modprobe_module_from_abspath(const struct test *t)
+{
+       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
+       const char *const args[] = {
+               progname,
+               "/home/foo/mod-simple.ko",
+               NULL,
+       };
+
+       test_spawn_prog(progname, args);
+       exit(EXIT_FAILURE);
+}
+DEFINE_TEST(modprobe_module_from_abspath,
+       .description = "check modprobe able to load module given as an absolute path",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-from-abspath",
+               [TC_INIT_MODULE_RETCODES] = "",
+       },
+       .modules_loaded = "mod-simple",
+       );
+
+static noreturn int modprobe_module_from_relpath(const struct test *t)
+{
+       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
+       const char *const args[] = {
+               progname,
+               "./mod-simple.ko",
+               NULL,
+       };
+
+       if (chdir("/home/foo") != 0) {
+               perror("failed to change into /home/foo");
+               exit(EXIT_FAILURE);
+       }
+
+       test_spawn_prog(progname, args);
+       exit(EXIT_FAILURE);
+}
+DEFINE_TEST(modprobe_module_from_relpath,
+       .description = "check modprobe able to load module given as a relative path",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-from-relpath",
+               [TC_INIT_MODULE_RETCODES] = "",
+       },
+       .need_spawn = true,
+       .modules_loaded = "mod-simple",
+       );
+
 TESTSUITE_MAIN();
index 360065cbef72a0971f2b40ab8aae8f9679e7a809..9872b783f3dc62e2b82535d5c40b30e609f7af23 100644 (file)
@@ -29,7 +29,7 @@
 
 static int from_name(const struct test *t)
 {
-       static const char *modnames[] = {
+       static const char *const modnames[] = {
                "ext4",
                "balbalbalbbalbalbalbalbalbalbal",
                "snd-hda-intel",
@@ -37,7 +37,7 @@ static int from_name(const struct test *t)
                "iTCO_wdt",
                NULL,
        };
-       const char **p;
+       const char *const *p;
        struct kmod_ctx *ctx;
        struct kmod_module *mod;
        const char *null_config = NULL;
@@ -72,11 +72,11 @@ DEFINE_TEST(from_name,
 
 static int from_alias(const struct test *t)
 {
-       static const char *modnames[] = {
+       static const char *const modnames[] = {
                "ext4.*",
                NULL,
        };
-       const char **p;
+       const char *const *p;
        struct kmod_ctx *ctx;
        int err;
 
index 56e73609f2048e158d9ba84ba8b1aa748d4c2483..c77c4bbc04eb1b0edd41972b49e884c2f0d05c46 100644 (file)
@@ -64,7 +64,7 @@ static int testsuite_rootfs_fopen(const struct test *t)
        char s[100];
        int n;
 
-       fp = fopen("/lib/modules/a", "r");
+       fp = fopen(MODULE_DIRECTORY "/a", "r");
        if (fp == NULL)
                return EXIT_FAILURE;;
 
@@ -89,7 +89,7 @@ static int testsuite_rootfs_open(const struct test *t)
        char buf[100];
        int fd, done;
 
-       fd = open("/lib/modules/a", O_RDONLY);
+       fd = open(MODULE_DIRECTORY "/a", O_RDONLY);
        if (fd < 0)
                return EXIT_FAILURE;
 
@@ -121,12 +121,12 @@ static int testsuite_rootfs_stat_access(const struct test *t)
 {
        struct stat st;
 
-       if (access("/lib/modules/a", F_OK) < 0) {
+       if (access(MODULE_DIRECTORY "/a", F_OK) < 0) {
                ERR("access failed: %m\n");
                return EXIT_FAILURE;
        }
 
-       if (stat("/lib/modules/a", &st) < 0) {
+       if (stat(MODULE_DIRECTORY "/a", &st) < 0) {
                ERR("stat failed: %m\n");
                return EXIT_FAILURE;
        }
diff --git a/testsuite/test-tools.c b/testsuite/test-tools.c
deleted file mode 100644 (file)
index 4a9ee9b..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "testsuite.h"
-
-static noreturn int kmod_tool_insert(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/kmod";
-       const char *const args[] = {
-               progname,
-               "insert", "mod-simple",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(kmod_tool_insert,
-       .description = "check kmod insert",
-       .config = {
-               [TC_UNAME_R] = "4.4.4",
-               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-tools/insert",
-               [TC_INIT_MODULE_RETCODES] = "",
-       },
-       .modules_loaded = "mod-simple",
-       );
-
-static noreturn int kmod_tool_remove(const struct test *t)
-{
-       const char *progname = ABS_TOP_BUILDDIR "/tools/kmod";
-       const char *const args[] = {
-               progname,
-               "remove", "mod-simple",
-               NULL,
-       };
-
-       test_spawn_prog(progname, args);
-       exit(EXIT_FAILURE);
-}
-DEFINE_TEST(kmod_tool_remove,
-       .description = "check kmod remove",
-       .config = {
-               [TC_UNAME_R] = "4.4.4",
-               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-tools/remove",
-               [TC_DELETE_MODULE_RETCODES] = "",
-       },
-       );
-
-TESTSUITE_MAIN();
index 5e25e587d69bdc4e0dd8f00f37bfb3405f770e3f..e3243e8bc6a2c6935310d2ba5e475149edda36dd 100644 (file)
@@ -31,7 +31,7 @@
 
 static int alias_1(const struct test *t)
 {
-       static const char *input[] = {
+       static const char *const input[] = {
                "test1234",
                "test[abcfoobar]2211",
                "bar[aaa][bbbb]sss",
@@ -42,7 +42,7 @@ static int alias_1(const struct test *t)
 
        char buf[PATH_MAX];
        size_t len;
-       const char **alias;
+       const char *const *alias;
 
        for (alias = input; *alias != NULL; alias++) {
                int ret;
@@ -156,6 +156,9 @@ static int test_path_ends_with_kmod_ext(const struct test *t)
 #endif
 #ifdef ENABLE_XZ
                { "/bla.ko.xz", true },
+#endif
+#ifdef ENABLE_ZSTD
+               { "/bla.ko.zst", true },
 #endif
                { "/bla.ko.x", false },
                { "/bla.ko.", false },
@@ -226,4 +229,45 @@ DEFINE_TEST(test_addu64_overflow,
        );
 
 
+static int test_backoff_time(const struct test *t)
+{
+       unsigned long long delta = 0;
+
+       /* Check exponential increments */
+       get_backoff_delta_msec(now_msec(), now_msec() + 10, &delta);
+       assert_return(delta == 1, EXIT_FAILURE);
+       get_backoff_delta_msec(now_msec(), now_msec() + 10, &delta);
+       assert_return(delta == 2, EXIT_FAILURE);
+       get_backoff_delta_msec(now_msec(), now_msec() + 10, &delta);
+       assert_return(delta == 4, EXIT_FAILURE);
+       get_backoff_delta_msec(now_msec(), now_msec() + 10, &delta);
+       assert_return(delta == 8, EXIT_FAILURE);
+
+       {
+               unsigned long long t0, tend;
+
+               /* Check tail */
+               delta = 4;
+               tend = now_msec() + 3;
+               t0 = tend - 10;
+               get_backoff_delta_msec(t0, tend, &delta);
+               assert_return(delta == 2, EXIT_FAILURE);
+               tend = now_msec() + 1;
+               t0 = tend - 9;
+               get_backoff_delta_msec(t0, tend, &delta);
+               assert_return(delta == 1, EXIT_FAILURE);
+               tend = now_msec();
+               t0 = tend - 10;
+               get_backoff_delta_msec(t0, tend, &delta);
+               assert_return(delta == 0, EXIT_FAILURE);
+       }
+
+       return EXIT_SUCCESS;
+}
+DEFINE_TEST(test_backoff_time,
+       .description = "check implementation of get_backoff_delta_msec()",
+       .need_spawn = false,
+       );
+
+
 TESTSUITE_MAIN();
index e46f3d8b215ac5d1718088e48024e8cfd3ad4002..318343ac8cdff33ae76dbfcbbd7bb1990b608d11 100644 (file)
@@ -37,6 +37,7 @@
 #include "testsuite.h"
 
 static const char *ANSI_HIGHLIGHT_GREEN_ON = "\x1B[1;32m";
+static const char *ANSI_HIGHLIGHT_YELLOW_ON = "\x1B[1;33m";
 static const char *ANSI_HIGHLIGHT_RED_ON =  "\x1B[1;31m";
 static const char *ANSI_HIGHLIGHT_OFF = "\x1B[0m";
 
@@ -50,8 +51,9 @@ static const struct option options[] = {
 };
 
 #define OVERRIDE_LIBDIR ABS_TOP_BUILDDIR "/testsuite/.libs/"
+#define TEST_TIMEOUT_USEC 2 * USEC_PER_SEC
 
-struct _env_config {
+static const struct {
        const char *key;
        const char *ldpreload;
 } env_config[_TC_LAST] = {
@@ -61,19 +63,6 @@ struct _env_config {
        [TC_DELETE_MODULE_RETCODES] = { S_TC_DELETE_MODULE_RETCODES, OVERRIDE_LIBDIR "delete_module.so" },
 };
 
-#define USEC_PER_SEC  1000000ULL
-#define USEC_PER_MSEC  1000ULL
-#define TEST_TIMEOUT_USEC 2 * USEC_PER_SEC
-static unsigned long long now_usec(void)
-{
-       struct timespec ts;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
-               return 0;
-
-       return ts_usec(&ts);
-}
-
 static void help(void)
 {
        const struct option *itr;
@@ -948,6 +937,14 @@ static inline int test_run_parent(const struct test *t, int fdout[2],
        int err;
        bool matchout, match_modules;
 
+       if (t->skip) {
+               LOG("%sSKIPPED%s: %s\n",
+                       ANSI_HIGHLIGHT_YELLOW_ON, ANSI_HIGHLIGHT_OFF,
+                       t->name);
+               err = EXIT_SUCCESS;
+               goto exit;
+       }
+
        /* Close write-fds */
        if (t->output.out != NULL)
                close(fdout[1]);
index 7ed96bf48d2953434951e3cb9e74920e05a3af97..44d17300d371c56199b6a871eb0bd891e55474f3 100644 (file)
@@ -109,6 +109,8 @@ struct test {
        const struct keyval *env_vars;
        bool need_spawn;
        bool expected_fail;
+       /* allow to skip tests that don't meet compile-time dependencies */
+       bool skip;
        bool print_outputs;
 } __attribute__((aligned(8)));
 
@@ -138,14 +140,16 @@ int test_run(const struct test *t);
 
 
 /* Test definitions */
-#define DEFINE_TEST(_name, ...) \
-       static const struct test s##_name##UNIQ \
+#define DEFINE_TEST_WITH_FUNC(_name, _func, ...) \
+       static const struct test UNIQ(s##_name) \
        __attribute__((used, section("kmod_tests"), aligned(8))) = { \
                .name = #_name, \
-               .func = _name, \
+               .func = _func, \
                ## __VA_ARGS__ \
        };
 
+#define DEFINE_TEST(_name, ...) DEFINE_TEST_WITH_FUNC(_name, _name, __VA_ARGS__)
+
 #define TESTSUITE_MAIN() \
        extern struct test __start_kmod_tests[] __attribute__((weak, visibility("hidden")));    \
        extern struct test __stop_kmod_tests[] __attribute__((weak, visibility("hidden")));     \
index 875e31480818c4a2a32709dbc3911fbbf8942774..43fc354afb09f95d6389b2a7644907eb6a604ade 100644 (file)
@@ -50,18 +50,21 @@ static int verbose = DEFAULT_VERBOSE;
 
 static const char CFG_BUILTIN_KEY[] = "built-in";
 static const char CFG_EXTERNAL_KEY[] = "external";
-static const char *default_cfg_paths[] = {
-       "/run/depmod.d",
+static const char *const default_cfg_paths[] = {
        SYSCONFDIR "/depmod.d",
+       "/run/depmod.d",
+       "/usr/local/lib/depmod.d",
+       DISTCONFDIR "/depmod.d",
        "/lib/depmod.d",
        NULL
 };
 
-static const char cmdopts_s[] = "aAb:C:E:F:euqrvnP:wmVh";
+static const char cmdopts_s[] = "aAb:o:C:E:F:euqrvnP:wmVh";
 static const struct option cmdopts[] = {
        { "all", no_argument, 0, 'a' },
        { "quick", no_argument, 0, 'A' },
        { "basedir", required_argument, 0, 'b' },
+       { "outdir", required_argument, 0, 'o' },
        { "config", required_argument, 0, 'C' },
        { "symvers", required_argument, 0, 'E' },
        { "filesyms", required_argument, 0, 'F' },
@@ -103,6 +106,7 @@ static void help(void)
                "\n"
                "The following options are useful for people managing distributions:\n"
                "\t-b, --basedir=DIR    Use an image of a module tree.\n"
+               "\t-o, --outdir=DIR     Output directory for generated files.\n"
                "\t-F, --filesyms=FILE  Use the file instead of the\n"
                "\t                     current kernel symbols.\n"
                "\t-E, --symvers=FILE   Use Module.symvers file to check\n"
@@ -186,7 +190,7 @@ static struct index_node *index_create(void)
 {
        struct index_node *node;
 
-       node = NOFAIL(calloc(sizeof(struct index_node), 1));
+       node = NOFAIL(calloc(1, sizeof(struct index_node)));
        node->prefix = NOFAIL(strdup(""));
        node->first = INDEX_CHILDMAX;
 
@@ -249,7 +253,7 @@ static int index_add_value(struct index_value **values,
                values = &(*values)->next;
 
        len = strlen(value);
-       v = NOFAIL(calloc(sizeof(struct index_value) + len + 1, 1));
+       v = NOFAIL(calloc(1, sizeof(struct index_value) + len + 1));
        v->next = *values;
        v->priority = priority;
        memcpy(v->value, value, len + 1);
@@ -280,7 +284,7 @@ static int index_insert(struct index_node *node, const char *key,
                                struct index_node *n;
 
                                /* New child is copy of node with prefix[j+1..N] */
-                               n = NOFAIL(calloc(sizeof(struct index_node), 1));
+                               n = NOFAIL(calloc(1, sizeof(struct index_node)));
                                memcpy(n, node, sizeof(struct index_node));
                                n->prefix = NOFAIL(strdup(&prefix[j+1]));
 
@@ -309,7 +313,7 @@ static int index_insert(struct index_node *node, const char *key,
                                node->first = ch;
                        if (ch > node->last)
                                node->last = ch;
-                       node->children[ch] = NOFAIL(calloc(sizeof(struct index_node), 1));
+                       node->children[ch] = NOFAIL(calloc(1, sizeof(struct index_node)));
 
                        child = node->children[ch];
                        child->prefix = NOFAIL(strdup(&key[i+1]));
@@ -457,10 +461,17 @@ struct cfg_external {
        char path[];
 };
 
+struct cfg_exclude {
+       struct cfg_exclude *next;
+       char exclude_dir[];
+};
+
 struct cfg {
        const char *kversion;
        char dirname[PATH_MAX];
        size_t dirnamelen;
+       char outdirname[PATH_MAX];
+       size_t outdirnamelen;
        char sym_prefix;
        uint8_t check_symvers;
        uint8_t print_unknown;
@@ -468,6 +479,7 @@ struct cfg {
        struct cfg_override *overrides;
        struct cfg_search *searches;
        struct cfg_external *externals;
+       struct cfg_exclude *excludes;
 };
 
 static enum search_type cfg_define_search_type(const char *path)
@@ -579,6 +591,30 @@ static void cfg_external_free(struct cfg_external *ext)
        free(ext);
 }
 
+static int cfg_exclude_add(struct cfg *cfg, const char *path)
+{
+       struct cfg_exclude *exc;
+       size_t len = strlen(path);
+
+       exc = malloc(sizeof(struct cfg_exclude) + len + 1);
+       if (exc == NULL) {
+               ERR("exclude add: out of memory\n");
+               return -ENOMEM;
+       }
+       memcpy(exc->exclude_dir, path, len + 1);
+
+       DBG("exclude add: %s\n", path);
+
+       exc->next = cfg->excludes;
+       cfg->excludes = exc;
+       return 0;
+}
+
+static void cfg_exclude_free(struct cfg_exclude *exc)
+{
+       free(exc);
+}
+
 static int cfg_kernel_matches(const struct cfg *cfg, const char *pattern)
 {
        regex_t re;
@@ -656,6 +692,11 @@ static int cfg_file_parse(struct cfg *cfg, const char *filename)
                        }
 
                        cfg_external_add(cfg, dir);
+               } else if (streq(cmd, "exclude")) {
+                       const char *sp;
+                       while ((sp = strtok_r(NULL, "\t ", &saveptr)) != NULL) {
+                               cfg_exclude_add(cfg, sp);
+                       }
                } else if (streq(cmd, "include")
                                || streq(cmd, "make_map_files")) {
                        INF("%s:%u: command %s not implemented yet\n",
@@ -856,6 +897,12 @@ static void cfg_free(struct cfg *cfg)
                cfg->externals = cfg->externals->next;
                cfg_external_free(tmp);
        }
+
+       while (cfg->excludes) {
+               struct cfg_exclude *tmp = cfg->excludes;
+               cfg->excludes = cfg->excludes->next;
+               cfg_exclude_free(tmp);
+       }
 }
 
 
@@ -864,7 +911,7 @@ struct vertex;
 struct mod {
        struct kmod_module *kmod;
        char *path;
-       const char *relpath; /* path relative to '$ROOT/lib/modules/$VER/' */
+       const char *relpath; /* path relative to '$ROOT$MODULE_DIRECTORY/$VER/' */
        char *uncrelpath; /* same as relpath but ending in .ko */
        struct kmod_list *info_list;
        struct kmod_list *dep_sym_list;
@@ -1228,6 +1275,25 @@ add:
        return 0;
 }
 
+static bool should_exclude_dir(const struct cfg *cfg, const char *name)
+{
+       struct cfg_exclude *exc;
+
+       if (name[0] == '.' && (name[1] == '\0' ||
+                       (name[1] == '.' && name[2] == '\0')))
+               return true;
+
+       if (streq(name, "build") || streq(name, "source"))
+               return true;
+
+       for (exc = cfg->excludes; exc != NULL; exc = exc->next) {
+               if (streq(name, exc->exclude_dir))
+                       return true;
+       }
+
+       return false;
+}
+
 static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, struct scratchbuf *s_path)
 {
        struct dirent *de;
@@ -1239,11 +1305,9 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
                size_t namelen;
                uint8_t is_dir;
 
-               if (name[0] == '.' && (name[1] == '\0' ||
-                                      (name[1] == '.' && name[2] == '\0')))
-                       continue;
-               if (streq(name, "build") || streq(name, "source"))
+               if (should_exclude_dir(depmod->cfg, name))
                        continue;
+
                namelen = strlen(name);
                if (scratchbuf_alloc(s_path, baselen + namelen + 2) < 0) {
                        err = -ENOMEM;
@@ -1523,7 +1587,7 @@ static int depmod_load_modules(struct depmod *depmod)
                struct kmod_list *l, *list = NULL;
                int err = kmod_module_get_symbols(mod->kmod, &list);
                if (err < 0) {
-                       if (err == -ENOENT)
+                       if (err == -ENODATA)
                                DBG("ignoring %s: no symbols\n", mod->path);
                        else
                                ERR("failed to load symbols from %s: %s\n",
@@ -2345,6 +2409,103 @@ static int output_builtin_bin(struct depmod *depmod, FILE *out)
        return 0;
 }
 
+static int flush_stream(FILE *in, int endchar)
+{
+       size_t i = 0;
+       int c;
+
+       for (c = fgetc(in);
+            c != EOF && c != endchar && c != '\0';
+            c = fgetc(in))
+               ;
+
+       return c == endchar ? i : 0;
+}
+
+static int flush_stream_to(FILE *in, int endchar, char *dst, size_t dst_sz)
+{
+       size_t i = 0;
+       int c;
+
+       for (c = fgetc(in);
+            c != EOF && c != endchar && c != '\0' && i < dst_sz;
+            c = fgetc(in))
+               dst[i++] = c;
+
+       if (i == dst_sz) {
+               WRN("Could not flush stream: %d. Partial content: %.*s\n",
+                   ENOSPC, (int) dst_sz, dst);
+               i--;
+       }
+
+       return c == endchar ? i : 0;
+}
+
+static int output_builtin_alias_bin(struct depmod *depmod, FILE *out)
+{
+       FILE *in;
+       struct index_node *idx;
+       int ret;
+
+       if (out == stdout)
+               return 0;
+
+       in = dfdopen(depmod->cfg->dirname, "modules.builtin.modinfo", O_RDONLY, "r");
+       if (in == NULL)
+               return 0;
+
+       idx = index_create();
+       if (idx == NULL) {
+               fclose(in);
+               return -ENOMEM;
+       }
+
+       /* format: modname.key=value\0 */
+       while (!feof(in) && !ferror(in)) {
+               char alias[PATH_MAX];
+               char modname[PATH_MAX];
+               char value[PATH_MAX];
+               size_t len;
+
+               len = flush_stream_to(in, '.', modname, sizeof(modname));
+               modname[len] = '\0';
+               if (!len)
+                       continue;
+
+               len = flush_stream_to(in, '=', value, sizeof(value));
+               value[len] = '\0';
+               if (!streq(value, "alias")) {
+                       flush_stream(in, '\0');
+                       continue;
+               }
+
+               len = flush_stream_to(in, '\0', value, sizeof(value));
+               value[len] = '\0';
+               if (!len)
+                       continue;
+
+               alias[0] = '\0';
+               if (alias_normalize(value, alias, NULL) < 0) {
+                       WRN("Unmatched bracket in %s\n", value);
+                       continue;
+               }
+
+               index_insert(idx, alias, modname, 0);
+       }
+
+       if (ferror(in)) {
+               ret = -EINVAL;
+       } else {
+               index_write(idx, out);
+               ret = 0;
+       }
+
+       index_destroy(idx);
+       fclose(in);
+
+       return ret;
+}
+
 static int output_devname(struct depmod *depmod, FILE *out)
 {
        size_t i;
@@ -2402,72 +2563,6 @@ static int output_devname(struct depmod *depmod, FILE *out)
        return 0;
 }
 
-static int output_builtin_alias_bin(struct depmod *depmod, FILE *out)
-{
-       int ret = 0, count = 0;
-       struct index_node *idx;
-       struct kmod_list *l, *builtin = NULL;
-
-       if (out == stdout)
-               return 0;
-
-       idx = index_create();
-       if (idx == NULL) {
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       ret = kmod_module_get_builtin(depmod->ctx, &builtin);
-       if (ret < 0) {
-               if (ret == -ENOENT)
-                       ret = 0;
-               goto fail;
-       }
-
-       kmod_list_foreach(l, builtin) {
-               struct kmod_list *ll, *info_list = NULL;
-               struct kmod_module *mod = l->data;
-               const char *modname = kmod_module_get_name(mod);
-
-               ret = kmod_module_get_info(mod, &info_list);
-               if (ret < 0)
-                       goto fail;
-
-               kmod_list_foreach(ll, info_list) {
-                       char alias[PATH_MAX];
-                       const char *key = kmod_module_info_get_key(ll);
-                       const char *value = kmod_module_info_get_value(ll);
-
-                       if (!streq(key, "alias"))
-                               continue;
-
-                       alias[0] = '\0';
-                       if (alias_normalize(value, alias, NULL) < 0) {
-                               WRN("Unmatched bracket in %s\n", value);
-                               continue;
-                       }
-
-                       index_insert(idx, alias, modname, 0);
-               }
-
-               kmod_module_info_free_list(info_list);
-
-               index_insert(idx, modname, modname, 0);
-               count++;
-       }
-
-       if (count)
-               index_write(idx, out);
-
-       index_destroy(idx);
-
-fail:
-       if (builtin)
-               kmod_module_unref_list(builtin);
-
-       return ret;
-}
-
 static int depmod_output(struct depmod *depmod, FILE *out)
 {
        static const struct depfile {
@@ -2486,7 +2581,7 @@ static int depmod_output(struct depmod *depmod, FILE *out)
                { "modules.devname", output_devname },
                { }
        };
-       const char *dname = depmod->cfg->dirname;
+       const char *dname = depmod->cfg->outdirname;
        int dfd, err = 0;
        struct timeval tv;
 
@@ -2495,6 +2590,11 @@ static int depmod_output(struct depmod *depmod, FILE *out)
        if (out != NULL)
                dfd = -1;
        else {
+               err = mkdir_p(dname, strlen(dname), 0755);
+               if (err < 0) {
+                       CRIT("could not create directory %s: %m\n", dname);
+                       return err;
+               }
                dfd = open(dname, O_RDONLY);
                if (dfd < 0) {
                        err = -errno;
@@ -2808,6 +2908,7 @@ static int do_depmod(int argc, char *argv[])
        FILE *out = NULL;
        int err = 0, all = 0, maybe_all = 0, n_config_paths = 0;
        _cleanup_free_ char *root = NULL;
+       _cleanup_free_ char *out_root = NULL;
        _cleanup_free_ const char **config_paths = NULL;
        const char *system_map = NULL;
        const char *module_symvers = NULL;
@@ -2837,6 +2938,11 @@ static int do_depmod(int argc, char *argv[])
                                free(root);
                        root = path_make_absolute_cwd(optarg);
                        break;
+               case 'o':
+                       if (out_root)
+                               free(out_root);
+                       out_root = path_make_absolute_cwd(optarg);
+                       break;
                case 'C': {
                        size_t bytes = sizeof(char *) * (n_config_paths + 2);
                        void *tmp = realloc(config_paths, bytes);
@@ -2918,8 +3024,12 @@ static int do_depmod(int argc, char *argv[])
        }
 
        cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX,
-                                 "%s/lib/modules/%s",
-                                 root == NULL ? "" : root, cfg.kversion);
+                                 "%s" MODULE_DIRECTORY "/%s",
+                                 root ?: "", cfg.kversion);
+
+       cfg.outdirnamelen = snprintf(cfg.outdirname, PATH_MAX,
+                                    "%s" MODULE_DIRECTORY "/%s",
+                                    out_root ?: (root ?: ""), cfg.kversion);
 
        if (optind == argc)
                all = 1;
diff --git a/tools/insert.c b/tools/insert.c
deleted file mode 100644 (file)
index 0ebcef9..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * kmod-insert - insert a module into the kernel.
- *
- * Copyright (C) 2015 Intel Corporation. All rights reserved.
- * Copyright (C) 2011-2013  ProFUSION embedded systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libkmod/libkmod.h>
-
-#include "kmod.h"
-
-static const char cmdopts_s[] = "h";
-static const struct option cmdopts[] = {
-       {"help", no_argument, 0, 'h'},
-       { }
-};
-
-static void help(void)
-{
-       printf("Usage:\n"
-              "\t%s insert [options] module\n"
-              "Options:\n"
-              "\t-h, --help        show this help\n",
-              program_invocation_short_name);
-}
-
-static const char *mod_strerror(int err)
-{
-       switch (err) {
-       case KMOD_PROBE_APPLY_BLACKLIST:
-               return "Module is blacklisted";
-       case -EEXIST:
-               return "Module already in kernel";
-       case -ENOENT:
-               return "Unknown symbol in module or unknown parameter (see dmesg)";
-       default:
-               return strerror(-err);
-       }
-}
-
-static int do_insert(int argc, char *argv[])
-{
-       struct kmod_ctx *ctx;
-       struct kmod_list *list = NULL, *l;
-       const char *name;
-       int err, r = EXIT_SUCCESS;
-
-       for (;;) {
-               int c, idx = 0;
-               c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
-               if (c == -1)
-                       break;
-               switch (c) {
-               case 'h':
-                       help();
-                       return EXIT_SUCCESS;
-               default:
-                       ERR("Unexpected getopt_long() value '%c'.\n", c);
-                       return EXIT_FAILURE;
-               }
-       }
-
-       if (optind >= argc) {
-               ERR("Missing module name\n");
-               return EXIT_FAILURE;
-       }
-
-       ctx = kmod_new(NULL, NULL);
-       if (!ctx) {
-               ERR("kmod_new() failed!\n");
-               return EXIT_FAILURE;
-       }
-
-       name = argv[optind];
-       err = kmod_module_new_from_lookup(ctx, name, &list);
-       if (err < 0) {
-               ERR("Could not lookup module matching '%s': %s\n", name, strerror(-err));
-               r = EXIT_FAILURE;
-               goto end;
-       }
-
-       if (list == NULL) {
-               ERR("No module matches '%s'\n", name);
-               r = EXIT_FAILURE;
-               goto end;
-       }
-
-       kmod_list_foreach(l, list) {
-               struct kmod_module *mod = kmod_module_get_module(l);
-
-               err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
-               if (err != 0) {
-                       r = EXIT_FAILURE;
-                       ERR("Could not insert '%s': %s\n", kmod_module_get_name(mod), mod_strerror(err));
-               }
-
-               kmod_module_unref(mod);
-       }
-
-       kmod_module_unref_list(list);
-end:
-       kmod_unref(ctx);
-       return r;
-}
-
-const struct kmod_cmd kmod_cmd_insert = {
-       .name = "insert",
-       .cmd = do_insert,
-       .help = "insert a module into the kernel",
-};
index 55689c075ab13ea60490a3e5b23ad309a429e39c..1015575f7d127bf794f6a09f35a633c44856c6b5 100644 (file)
@@ -42,11 +42,6 @@ static const struct kmod_cmd *kmod_cmds[] = {
        &kmod_cmd_help,
        &kmod_cmd_list,
        &kmod_cmd_static_nodes,
-
-#ifdef ENABLE_EXPERIMENTAL
-       &kmod_cmd_insert,
-       &kmod_cmd_remove,
-#endif
 };
 
 static const struct kmod_cmd *kmod_compat_cmds[] = {
diff --git a/tools/kmod.pc.in b/tools/kmod.pc.in
new file mode 100644 (file)
index 0000000..97215c8
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@prefix@
+sysconfdir=@sysconfdir@
+distconfdir=@distconfdir@
+module_directory=@module_directory@
+module_compressions=@module_compressions@
+module_signatures=@module_signatures@
+
+Name: kmod
+Description: Tools to deal with kernel modules
+Version: @VERSION@
index 0231bb03e3dba5607af040a205af9e82929e2271..cacc32dc4c40b41048a39347ad8f72192d1d23f5 100644 (file)
@@ -178,7 +178,11 @@ static int modinfo_do(struct kmod_module *mod)
        is_builtin = (filename == NULL);
 
        if (is_builtin) {
-               printf("%-16s%s%c", "name:", kmod_module_get_name(mod), separator);
+               if (field == NULL)
+                       printf("%-16s%s%c", "name:",
+                              kmod_module_get_name(mod), separator);
+               else if (field != NULL && streq(field, "name"))
+                       printf("%s%c", kmod_module_get_name(mod), separator);
                filename = "(builtin)";
        }
 
@@ -289,6 +293,24 @@ static int modinfo_path_do(struct kmod_ctx *ctx, const char *path)
        return err;
 }
 
+static int modinfo_name_do(struct kmod_ctx *ctx, const char *name)
+{
+       struct kmod_module *mod = NULL;
+       int err;
+
+       err = kmod_module_new_from_name_lookup(ctx, name, &mod);
+       if (err < 0 || mod == NULL) {
+               ERR("Module name %s not found.\n", name);
+               return err < 0 ? err : -ENOENT;
+       }
+
+       err = modinfo_do(mod);
+       kmod_module_unref(mod);
+
+       return err;
+}
+
+
 static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
 {
        struct kmod_list *l, *list = NULL;
@@ -314,7 +336,7 @@ static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
        return err;
 }
 
-static const char cmdopts_s[] = "adlpn0F:k:b:Vh";
+static const char cmdopts_s[] = "adlpn0mF:k:b:Vh";
 static const struct option cmdopts[] = {
        {"author", no_argument, 0, 'a'},
        {"description", no_argument, 0, 'd'},
@@ -322,6 +344,7 @@ static const struct option cmdopts[] = {
        {"parameters", no_argument, 0, 'p'},
        {"filename", no_argument, 0, 'n'},
        {"null", no_argument, 0, '0'},
+       {"modname", no_argument, 0, 'm'},
        {"field", required_argument, 0, 'F'},
        {"set-version", required_argument, 0, 'k'},
        {"basedir", required_argument, 0, 'b'},
@@ -333,7 +356,7 @@ static const struct option cmdopts[] = {
 static void help(void)
 {
        printf("Usage:\n"
-               "\t%s [options] filename [args]\n"
+               "\t%s [options] <modulename|filename> [args]\n"
                "Options:\n"
                "\t-a, --author                Print only 'author'\n"
                "\t-d, --description           Print only 'description'\n"
@@ -341,9 +364,10 @@ static void help(void)
                "\t-p, --parameters            Print only 'parm'\n"
                "\t-n, --filename              Print only 'filename'\n"
                "\t-0, --null                  Use \\0 instead of \\n\n"
+               "\t-m, --modname               Handle argument as module name instead of alias or filename\n"
                "\t-F, --field=FIELD           Print only provided FIELD\n"
                "\t-k, --set-version=VERSION   Use VERSION instead of `uname -r`\n"
-               "\t-b, --basedir=DIR           Use DIR as filesystem root for /lib/modules\n"
+               "\t-b, --basedir=DIR           Use DIR as filesystem root for " MODULE_DIRECTORY "\n"
                "\t-V, --version               Show version\n"
                "\t-h, --help                  Show this help\n",
                program_invocation_short_name);
@@ -368,6 +392,7 @@ static int do_modinfo(int argc, char *argv[])
        const char *kversion = NULL;
        const char *root = NULL;
        const char *null_config = NULL;
+       bool arg_is_modname = false;
        int i, err;
 
        for (;;) {
@@ -394,6 +419,9 @@ static int do_modinfo(int argc, char *argv[])
                case '0':
                        separator = '\0';
                        break;
+               case 'm':
+                       arg_is_modname = true;
+                       break;
                case 'F':
                        field = optarg;
                        break;
@@ -434,7 +462,7 @@ static int do_modinfo(int argc, char *argv[])
                        }
                        kversion = u.release;
                }
-               snprintf(dirname_buf, sizeof(dirname_buf), "%s/lib/modules/%s",
+               snprintf(dirname_buf, sizeof(dirname_buf), "%s" MODULE_DIRECTORY "/%s",
                         root, kversion);
                dirname = dirname_buf;
        }
@@ -450,7 +478,9 @@ static int do_modinfo(int argc, char *argv[])
                const char *name = argv[i];
                int r;
 
-               if (is_module_filename(name))
+               if (arg_is_modname)
+                       r = modinfo_name_do(ctx, name);
+               else if (is_module_filename(name))
                        r = modinfo_path_do(ctx, name);
                else
                        r = modinfo_alias_do(ctx, name);
index 9387537f7bc2446ac6015136cea4fea57237fd31..5306bef250da2afc9bebb8e9312c87518367c9c8 100644 (file)
@@ -32,6 +32,7 @@
 #include <sys/wait.h>
 
 #include <shared/array.h>
+#include <shared/util.h>
 #include <shared/macro.h>
 
 #include <libkmod/libkmod.h>
@@ -54,14 +55,19 @@ static int use_blacklist = 0;
 static int force = 0;
 static int strip_modversion = 0;
 static int strip_vermagic = 0;
-static int remove_dependencies = 0;
+static int remove_holders = 0;
+static unsigned long long wait_msec = 0;
 static int quiet_inuse = 0;
 
-static const char cmdopts_s[] = "arRibfDcnC:d:S:sqvVh";
+static const char cmdopts_s[] = "arw:RibfDcnC:d:S:sqvVh";
 static const struct option cmdopts[] = {
        {"all", no_argument, 0, 'a'},
+
        {"remove", no_argument, 0, 'r'},
        {"remove-dependencies", no_argument, 0, 5},
+       {"remove-holders", no_argument, 0, 5},
+       {"wait", required_argument, 0, 'w'},
+
        {"resolve-alias", no_argument, 0, 'R'},
        {"first-time", no_argument, 0, 3},
        {"ignore-install", no_argument, 0, 'i'},
@@ -107,8 +113,11 @@ static void help(void)
                "\t                            be a module name to be inserted\n"
                "\t                            or removed (-r)\n"
                "\t-r, --remove                Remove modules instead of inserting\n"
-               "\t    --remove-dependencies   Also remove modules depending on it\n"
-               "\t-R, --resolve-alias         Only lookup and print alias and exit\n"
+               "\t    --remove-dependencies   Deprecated: use --remove-holders\n"
+               "\t    --remove-holders        Also remove module holders (use together with -r)\n"
+               "\t-w, --wait <MSEC>           When removing a module, wait up to MSEC for\n"
+               "\t                            module's refcount to become 0 so it can be\n"
+               "\t                            removed (use together with -r)\n"
                "\t    --first-time            Fail if module already inserted or removed\n"
                "\t-i, --ignore-install        Ignore install commands\n"
                "\t-i, --ignore-remove         Ignore remove commands\n"
@@ -120,6 +129,7 @@ static void help(void)
                "\t    --force-vermagic        Ignore module's version magic\n"
                "\n"
                "Query Options:\n"
+               "\t-R, --resolve-alias         Only lookup and print alias and exit\n"
                "\t-D, --show-depends          Only print module dependencies and exit\n"
                "\t-c, --showconfig            Print out known configuration and exit\n"
                "\t-c, --show-config           Same as --showconfig\n"
@@ -132,7 +142,7 @@ static void help(void)
                "\t-n, --show                  Same as --dry-run\n"
 
                "\t-C, --config=FILE           Use FILE instead of default search paths\n"
-               "\t-d, --dirname=DIR           Use DIR as filesystem root for /lib/modules\n"
+               "\t-d, --dirname=DIR           Use DIR as filesystem root for " MODULE_DIRECTORY "\n"
                "\t-S, --set-version=VERSION   Use VERSION instead of `uname -r`\n"
 
                "\t-s, --syslog                print to syslog, not stderr\n"
@@ -320,10 +330,11 @@ end:
 static int rmmod_do_remove_module(struct kmod_module *mod)
 {
        const char *modname = kmod_module_get_name(mod);
-       struct kmod_list *deps, *itr;
+       unsigned long long interval_msec = 0, t0_msec = 0,
+                     tend_msec = 0;
        int flags = 0, err;
 
-       SHOW("rmmod %s\n", kmod_module_get_name(mod));
+       SHOW("rmmod %s\n", modname);
 
        if (dry_run)
                return 0;
@@ -331,33 +342,55 @@ static int rmmod_do_remove_module(struct kmod_module *mod)
        if (force)
                flags |= KMOD_REMOVE_FORCE;
 
-       err = kmod_module_remove_module(mod, flags);
-       if (err == -EEXIST) {
-               if (!first_time)
-                       err = 0;
-               else
-                       LOG("Module %s is not in kernel.\n", modname);
-       }
+       if (wait_msec)
+               flags |= KMOD_REMOVE_NOLOG;
 
-       deps = kmod_module_get_dependencies(mod);
-       if (deps != NULL) {
-               kmod_list_foreach(itr, deps) {
-                       struct kmod_module *dep = kmod_module_get_module(itr);
-                       if (kmod_module_get_refcnt(dep) == 0)
-                               rmmod_do_remove_module(dep);
-                       kmod_module_unref(dep);
+       do {
+               err = kmod_module_remove_module(mod, flags);
+               if (err == -EEXIST) {
+                       if (!first_time)
+                               err = 0;
+                       else
+                               LOG("Module %s is not in kernel.\n", modname);
+                       break;
+               } else if (err == -EAGAIN && wait_msec) {
+                       unsigned long long until_msec;
+
+                       if (!t0_msec) {
+                               t0_msec = now_msec();
+                               tend_msec = t0_msec + wait_msec;
+                               interval_msec = 1;
+                       }
+
+                       until_msec = get_backoff_delta_msec(t0_msec, tend_msec,
+                                                         &interval_msec);
+                       err = sleep_until_msec(until_msec);
+
+                       if (!t0_msec)
+                               err = -ENOTSUP;
+
+                       if (err < 0) {
+                               ERR("Failed to sleep: %s\n", strerror(-err));
+                               err = -EAGAIN;
+                               break;
+                       }
+               } else {
+                       break;
                }
-               kmod_module_unref_list(deps);
-       }
+       } while (interval_msec);
+
+       if (err < 0 && wait_msec)
+               ERR("could not remove '%s': %s\n", modname, strerror(-err));
 
        return err;
 }
 
-#define RMMOD_FLAG_DO_DEPENDENCIES     0x1
+#define RMMOD_FLAG_REMOVE_HOLDERS      0x1
 #define RMMOD_FLAG_IGNORE_BUILTIN      0x2
 static int rmmod_do_module(struct kmod_module *mod, int flags);
 
-static int rmmod_do_deps_list(struct kmod_list *list, bool stop_on_errors)
+/* Remove modules in reverse order */
+static int rmmod_do_modlist(struct kmod_list *list, bool stop_on_errors)
 {
        struct kmod_list *l;
 
@@ -391,7 +424,8 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                cmd = kmod_module_get_remove_commands(mod);
        }
 
-       if (cmd == NULL && !ignore_loaded) {
+       /* Quick check if module is loaded, otherwise there's nothing to do */
+       if (!cmd && !ignore_loaded) {
                int state = kmod_module_get_initstate(mod);
 
                if (state < 0) {
@@ -413,17 +447,21 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                }
        }
 
-       rmmod_do_deps_list(post, false);
+       /* 1. @mod's post-softdeps in reverse order */
+       rmmod_do_modlist(post, false);
 
-       if ((flags & RMMOD_FLAG_DO_DEPENDENCIES) && remove_dependencies) {
-               struct kmod_list *deps = kmod_module_get_dependencies(mod);
+       /* 2. Other modules holding @mod */
+       if (flags & RMMOD_FLAG_REMOVE_HOLDERS) {
+               struct kmod_list *holders = kmod_module_get_holders(mod);
 
-               err = rmmod_do_deps_list(deps, true);
+               err = rmmod_do_modlist(holders, true);
+               kmod_module_unref_list(holders);
                if (err < 0)
                        goto error;
        }
 
-       if (!ignore_loaded && !cmd) {
+       /* 3. @mod itself, but check for refcnt first */
+       if (!cmd && !ignore_loaded && !wait_msec) {
                int usage = kmod_module_get_refcnt(mod);
 
                if (usage > 0) {
@@ -435,7 +473,7 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                }
        }
 
-       if (cmd == NULL)
+       if (!cmd)
                err = rmmod_do_remove_module(mod);
        else
                err = command_do(mod, "remove", cmd, NULL);
@@ -443,7 +481,22 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
        if (err < 0)
                goto error;
 
-       rmmod_do_deps_list(pre, false);
+       /* 4. Other modules that became unused: errors are non-fatal */
+       if (!cmd) {
+               struct kmod_list *deps, *itr;
+
+               deps = kmod_module_get_dependencies(mod);
+               kmod_list_foreach(itr, deps) {
+                       struct kmod_module *dep = kmod_module_get_module(itr);
+                       if (kmod_module_get_refcnt(dep) == 0)
+                               rmmod_do_remove_module(dep);
+                       kmod_module_unref(dep);
+               }
+               kmod_module_unref_list(deps);
+       }
+
+       /* 5. @mod's pre-softdeps in reverse order: errors are non-fatal */
+       rmmod_do_modlist(pre, false);
 
 error:
        kmod_module_unref_list(pre);
@@ -468,7 +521,9 @@ static int rmmod(struct kmod_ctx *ctx, const char *alias)
 
        kmod_list_foreach(l, list) {
                struct kmod_module *mod = kmod_module_get_module(l);
-               err = rmmod_do_module(mod, RMMOD_FLAG_DO_DEPENDENCIES);
+               int flags = remove_holders ? RMMOD_FLAG_REMOVE_HOLDERS : 0;
+
+               err = rmmod_do_module(mod, flags);
                kmod_module_unref(mod);
                if (err < 0)
                        break;
@@ -515,21 +570,68 @@ static void print_action(struct kmod_module *m, bool install,
                printf("insmod %s %s\n", kmod_module_get_path(m), options);
 }
 
+static int insmod_insert(struct kmod_module *mod, int flags,
+                               const char *extra_options)
+{
+       int err = 0;
+       void (*show)(struct kmod_module *m, bool install,
+                                               const char *options) = NULL;
+
+       if (do_show || verbose > DEFAULT_VERBOSE)
+               show = &print_action;
+
+       if (lookup_only)
+               printf("%s\n", kmod_module_get_name(mod));
+       else
+               err = kmod_module_probe_insert_module(mod, flags,
+                               extra_options, NULL, NULL, show);
+
+       if (err >= 0)
+               /* ignore flag return values such as a mod being blacklisted */
+               err = 0;
+       else {
+               switch (err) {
+               case -EEXIST:
+                       ERR("could not insert '%s': Module already in kernel\n",
+                                               kmod_module_get_name(mod));
+                       break;
+               case -ENOENT:
+                       ERR("could not insert '%s': Unknown symbol in module, "
+                                       "or unknown parameter (see dmesg)\n",
+                                       kmod_module_get_name(mod));
+                       break;
+               default:
+                       ERR("could not insert '%s': %s\n",
+                                       kmod_module_get_name(mod),
+                                       strerror(-err));
+                       break;
+               }
+       }
+
+       return err;
+}
+
 static int insmod(struct kmod_ctx *ctx, const char *alias,
                                                const char *extra_options)
 {
        struct kmod_list *l, *list = NULL;
+       struct kmod_module *mod = NULL;
        int err, flags = 0;
 
-       void (*show)(struct kmod_module *m, bool install,
-                                               const char *options) = NULL;
-
-       err = kmod_module_new_from_lookup(ctx, alias, &list);
-
-       if (list == NULL || err < 0) {
-               LOG("Module %s not found in directory %s\n", alias,
-                       ctx ? kmod_get_dirname(ctx) : "(missing)");
-               return -ENOENT;
+       if (strncmp(alias, "/", 1) == 0 || strncmp(alias, "./", 2) == 0) {
+               err = kmod_module_new_from_path(ctx, alias, &mod);
+               if (err < 0) {
+                       LOG("Failed to get module from path %s: %s\n", alias,
+                               strerror(-err));
+                       return -ENOENT;
+               }
+       } else {
+               err = kmod_module_new_from_lookup(ctx, alias, &list);
+               if (list == NULL || err < 0) {
+                       LOG("Module %s not found in directory %s\n", alias,
+                               ctx ? kmod_get_dirname(ctx) : "(missing)");
+                       return -ENOENT;
+               }
        }
 
        if (strip_modversion || force)
@@ -542,8 +644,6 @@ static int insmod(struct kmod_ctx *ctx, const char *alias,
                flags |= KMOD_PROBE_IGNORE_LOADED;
        if (dry_run)
                flags |= KMOD_PROBE_DRY_RUN;
-       if (do_show || verbose > DEFAULT_VERBOSE)
-               show = &print_action;
 
        flags |= KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY;
 
@@ -552,42 +652,18 @@ static int insmod(struct kmod_ctx *ctx, const char *alias,
        if (first_time)
                flags |= KMOD_PROBE_FAIL_ON_LOADED;
 
-       kmod_list_foreach(l, list) {
-               struct kmod_module *mod = kmod_module_get_module(l);
-
-               if (lookup_only)
-                       printf("%s\n", kmod_module_get_name(mod));
-               else {
-                       err = kmod_module_probe_insert_module(mod, flags,
-                                       extra_options, NULL, NULL, show);
-               }
-
-               if (err >= 0)
-                       /* ignore flag return values such as a mod being blacklisted */
-                       err = 0;
-               else {
-                       switch (err) {
-                       case -EEXIST:
-                               ERR("could not insert '%s': Module already in kernel\n",
-                                                       kmod_module_get_name(mod));
-                               break;
-                       case -ENOENT:
-                               ERR("could not insert '%s': Unknown symbol in module, "
-                                               "or unknown parameter (see dmesg)\n",
-                                               kmod_module_get_name(mod));
-                               break;
-                       default:
-                               ERR("could not insert '%s': %s\n",
-                                               kmod_module_get_name(mod),
-                                               strerror(-err));
-                               break;
-                       }
-               }
-
+       /* If module is loaded from path */
+       if (mod != NULL) {
+               err = insmod_insert(mod, flags, extra_options);
                kmod_module_unref(mod);
+       } else {
+               kmod_list_foreach(l, list) {
+                       mod = kmod_module_get_module(l);
+                       err = insmod_insert(mod, flags, extra_options);
+                       kmod_module_unref(mod);
+               }
+               kmod_module_unref_list(list);
        }
-
-       kmod_module_unref_list(list);
        return err;
 }
 
@@ -683,7 +759,7 @@ static int options_from_array(char **args, int nargs, char **output)
 static char **prepend_options_from_env(int *p_argc, char **orig_argv)
 {
        const char *p, *env = getenv("MODPROBE_OPTIONS");
-       char **new_argv, *str_start, *str_end, *str, *s, *quote;
+       char **new_argv, *str_end, *str, *s, *quote;
        int i, argc = *p_argc;
        size_t envlen, space_count = 0;
 
@@ -701,10 +777,10 @@ static char **prepend_options_from_env(int *p_argc, char **orig_argv)
                return NULL;
 
        new_argv[0] = orig_argv[0];
-       str_start = str = (char *) (new_argv + argc + space_count + 3);
+       str = (char *) (new_argv + argc + space_count + 3);
        memcpy(str, env, envlen + 1);
 
-       str_end = str_start + envlen;
+       str_end = str + envlen;
 
        quote = NULL;
        for (i = 1, s = str; *s != '\0'; s++) {
@@ -743,7 +819,7 @@ static char **prepend_options_from_env(int *p_argc, char **orig_argv)
        }
 
        memcpy(new_argv + i, orig_argv + 1, sizeof(char *) * (argc - 1));
-       new_argv[i + argc] = NULL;
+       new_argv[i + argc - 1] = NULL;
        *p_argc = i + argc - 1;
 
        return new_argv;
@@ -765,6 +841,7 @@ static int do_modprobe(int argc, char **orig_argv)
        int do_show_modversions = 0;
        int do_show_exports = 0;
        int err;
+       struct stat stat_buf;
 
        argv = prepend_options_from_env(&argc, orig_argv);
        if (argv == NULL) {
@@ -786,11 +863,18 @@ static int do_modprobe(int argc, char **orig_argv)
                        do_remove = 1;
                        break;
                case 5:
-                       remove_dependencies = 1;
+                       remove_holders = 1;
                        break;
-               case 'R':
-                       lookup_only = 1;
+               case 'w': {
+                       char *endptr = NULL;
+                       wait_msec = strtoul(optarg, &endptr, 0);
+                       if (!*optarg || *endptr) {
+                               ERR("unexpected wait value '%s'.\n", optarg);
+                               err = -1;
+                               goto done;
+                       }
                        break;
+               }
                case 3:
                        first_time = 1;
                        break;
@@ -814,6 +898,9 @@ static int do_modprobe(int argc, char **orig_argv)
                        dry_run = 1;
                        do_show = 1;
                        break;
+               case 'R':
+                       lookup_only = 1;
+                       break;
                case 'c':
                        do_show_config = 1;
                        break;
@@ -883,6 +970,12 @@ static int do_modprobe(int argc, char **orig_argv)
        args = argv + optind;
        nargs = argc - optind;
 
+       if (!use_syslog &&
+           (!stderr ||
+            fileno(stderr) == -1 ||
+            fstat(fileno(stderr), &stat_buf)))
+               use_syslog = 1;
+
        log_open(use_syslog);
 
        if (!do_show_config) {
@@ -906,7 +999,7 @@ static int do_modprobe(int argc, char **orig_argv)
                        kversion = u.release;
                }
                snprintf(dirname_buf, sizeof(dirname_buf),
-                               "%s/lib/modules/%s", root,
+                               "%s" MODULE_DIRECTORY "/%s", root,
                                kversion);
                dirname = dirname_buf;
        }
diff --git a/tools/remove.c b/tools/remove.c
deleted file mode 100644 (file)
index 387ef0e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * kmod-remove - remove modules from the kernel.
- *
- * Copyright (C) 2015 Intel Corporation. All rights reserved.
- * Copyright (C) 2011-2013  ProFUSION embedded systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libkmod/libkmod.h>
-
-#include "kmod.h"
-
-static const char cmdopts_s[] = "h";
-static const struct option cmdopts[] = {
-       {"help", no_argument, 0, 'h'},
-       { }
-};
-
-static void help(void)
-{
-       printf("Usage:\n"
-              "\t%s remove [options] module\n"
-              "Options:\n"
-              "\t-h, --help        show this help\n",
-              program_invocation_short_name);
-}
-
-static int check_module_inuse(struct kmod_module *mod) {
-       struct kmod_list *holders;
-       int state, ret;
-
-       state = kmod_module_get_initstate(mod);
-
-       if (state == KMOD_MODULE_BUILTIN) {
-               ERR("Module %s is builtin.\n", kmod_module_get_name(mod));
-               return -ENOENT;
-       } else if (state < 0) {
-               ERR("Module %s is not currently loaded\n",
-                               kmod_module_get_name(mod));
-               return -ENOENT;
-       }
-
-       holders = kmod_module_get_holders(mod);
-       if (holders != NULL) {
-               struct kmod_list *itr;
-
-               ERR("Module %s is in use by:", kmod_module_get_name(mod));
-
-               kmod_list_foreach(itr, holders) {
-                       struct kmod_module *hm = kmod_module_get_module(itr);
-                       fprintf(stderr, " %s", kmod_module_get_name(hm));
-                       kmod_module_unref(hm);
-               }
-               fputc('\n', stderr);
-
-               kmod_module_unref_list(holders);
-               return -EBUSY;
-       }
-
-       ret = kmod_module_get_refcnt(mod);
-       if (ret > 0) {
-               ERR("Module %s is in use\n", kmod_module_get_name(mod));
-               return -EBUSY;
-       } else if (ret == -ENOENT) {
-               ERR("Module unloading is not supported\n");
-       }
-
-       return ret;
-}
-
-static int do_remove(int argc, char *argv[])
-{
-       struct kmod_ctx *ctx;
-       struct kmod_module *mod;
-       const char *name;
-       int err, r = EXIT_SUCCESS;
-
-       for (;;) {
-               int c, idx =0;
-               c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
-               if (c == -1)
-                       break;
-               switch (c) {
-               case 'h':
-                       help();
-                       return EXIT_SUCCESS;
-
-               default:
-                       ERR("Unexpected getopt_long() value '%c'.\n", c);
-                       return EXIT_FAILURE;
-               }
-       }
-
-       if (optind >= argc) {
-               ERR("Missing module name\n");
-               return EXIT_FAILURE;
-       }
-
-       ctx = kmod_new(NULL, NULL);
-       if (!ctx) {
-               ERR("kmod_new() failed!\n");
-               return EXIT_FAILURE;
-       }
-
-       name = argv[optind];
-       err = kmod_module_new_from_name(ctx, name, &mod);
-       if (err < 0) {
-               ERR("Could not remove module %s: %s\n", name, strerror(-err));
-               goto end;
-       }
-
-       err = check_module_inuse(mod);
-       if (err < 0)
-               goto unref;
-
-       err = kmod_module_remove_module(mod, 0);
-       if (err < 0)
-               goto unref;
-
-unref:
-       kmod_module_unref(mod);
-
-end:
-       kmod_unref(ctx);
-       if (err < 0) {
-               r = EXIT_FAILURE;
-               ERR("Could not remove module %s: %s\n", name, strerror(-err));
-       }
-       return r;
-}
-
-const struct kmod_cmd kmod_cmd_remove = {
-       .name = "remove",
-       .cmd = do_remove,
-       .help = "remove module from kernel",
-};
index 8d2356da73f3613540bb2e4d2f4f82b17cbe5f2a..5ef3743e967bf2f7d00ad122a9166f363ab66d35 100644 (file)
@@ -212,15 +212,15 @@ static int do_static_nodes(int argc, char *argv[])
                goto finish;
        }
 
-       snprintf(modules, sizeof(modules), "/lib/modules/%s/modules.devname", kernel.release);
+       snprintf(modules, sizeof(modules), MODULE_DIRECTORY "/%s/modules.devname", kernel.release);
        in = fopen(modules, "re");
        if (in == NULL) {
                if (errno == ENOENT) {
-                       fprintf(stderr, "Warning: /lib/modules/%s/modules.devname not found - ignoring\n",
+                       fprintf(stderr, "Warning: " MODULE_DIRECTORY "/%s/modules.devname not found - ignoring\n",
                                kernel.release);
                        ret = EXIT_SUCCESS;
                } else {
-                       fprintf(stderr, "Error: could not open /lib/modules/%s/modules.devname - %m\n",
+                       fprintf(stderr, "Error: could not open " MODULE_DIRECTORY "/%s/modules.devname - %m\n",
                                kernel.release);
                        ret = EXIT_FAILURE;
                }