commit:     153a877d333d3b85920267535aef950056c92192
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Thu Sep  9 00:16:42 2021 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Thu Sep  9 00:59:03 2021 +0000
URL:        https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=153a877d

Refactor (compressed) kernel module handling

To support a specific module compression algorithm, two things are needed:

Used depmod utility on host system building the kernel must support chosen
module compression algorithm to generate proper modules.dep file or
genkernel would be unable to read module dependencies when copying modules
to initramfs.

At runtime, used modprobe utility must be able to handle chosen module
compression algorithm or modules would be unloadable.

To address the first requirement, genkernel will now check if used kmod
utility on host system supports chosen module compression algorithm.

To address the runtime requirement, this commit will switch from BusyBox's
modutils implementation to kmod because BusyBox does not support ZSTD
compression (yet).

Bug: https://bugs.gentoo.org/809344
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 gen_configkernel.sh                  |  7 ++++
 gen_determineargs.sh                 |  6 +++
 gen_funcs.sh                         | 72 ++++++++++++++++++++++++++++++++++++
 gen_initramfs.sh                     | 22 ++++++++++-
 gkbuilds/kmod.gkbuild                | 26 ++++++++++++-
 patches/kmod/29/kmod-29-static.patch | 12 ++++++
 6 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/gen_configkernel.sh b/gen_configkernel.sh
index bff3fdc..62113dc 100755
--- a/gen_configkernel.sh
+++ b/gen_configkernel.sh
@@ -347,6 +347,13 @@ config_kernel() {
                unset kconfig_md5sum_old kconfig_md5sum_new
        fi
 
+       # Check for suitable kmod
+       determine_KEXT
+       if ! isTrue "$(is_kext_supported_by_kmod "${KEXT}")"
+       then
+               gen_die "${KMOD_CMD} does not support chosen module compression 
algorithm. Please re-emerge sys-apps/kmod with USE=$(get_kext_kmod_use_flag 
"${KEXT}") enabled or adjust CONFIG_MODULE_COMPRESS_* kernel option!"
+       fi
+
        local -a required_kernel_options
        [ -f "${KCONFIG_MODIFIED_MARKER}" ] && rm "${KCONFIG_MODIFIED_MARKER}"
 

diff --git a/gen_determineargs.sh b/gen_determineargs.sh
index 21d3b22..027c696 100755
--- a/gen_determineargs.sh
+++ b/gen_determineargs.sh
@@ -314,6 +314,12 @@ determine_real_args() {
                gen_die "'realpath -m /' failed. We need a realpath version 
which supports '-m' mode!"
        fi
 
+       KMOD_CMD=$(which kmod 2>/dev/null)
+       if [ -z "${KMOD_CMD}" ]
+       then
+               gen_die "kmod not found. Is sys-apps/kmod installed?"
+       fi
+
        if hash grep &>/dev/null
        then
                GREP_CMD=grep

diff --git a/gen_funcs.sh b/gen_funcs.sh
index d40607c..6bc59e6 100755
--- a/gen_funcs.sh
+++ b/gen_funcs.sh
@@ -287,6 +287,48 @@ is_psf_file() {
        echo "${file_is_psf}"
 }
 
+is_kext_supported_by_kmod() {
+       [[ ${#} -ne 1 ]] \
+               && gen_die "$(get_useful_function_stack "${FUNCNAME}")Invalid 
usage of ${FUNCNAME}(): Function takes exactly one argument (${#} given)!"
+
+       local requested_feature=${1}
+       requested_feature=${requested_feature##*.}
+       requested_feature=${requested_feature^^}
+
+       local is_supported=no
+
+       if [[ "${requested_feature}" == GZ ]]
+       then
+               requested_feature=ZLIB
+       elif [[ "${requested_feature}" == ZST ]]
+       then
+               requested_feature=ZSTD
+       fi
+
+       case "${requested_feature}" in
+               KO)
+                       is_supported=yes
+                       ;;
+               *)
+                       local line
+                       while read line; do
+                               if [[ ! ${line} =~ ^[\+\-] ]]
+                               then
+                                       continue
+                               fi
+
+                               if [[ ${line} =~ \+${requested_feature} ]]
+                               then
+                                       is_supported=yes
+                                       break
+                               fi
+                       done < <("${KMOD_CMD}" -V)
+                       ;;
+       esac
+
+       echo "${is_supported}"
+}
+
 is_valid_ssh_host_keys_parameter_value() {
        local parameter_value=${1}
 
@@ -2123,6 +2165,36 @@ make_bootdir_writable() {
        fi
 }
 
+get_kext_kmod_use_flag() {
+       [[ ${#} -ne 1 ]] \
+               && gen_die "$(get_useful_function_stack "${FUNCNAME}")Invalid 
usage of ${FUNCNAME}(): Function takes exactly one argument (${#} given)!"
+
+       local kext=${1}
+       kext=${kext##*.}
+       kext=${kext^^}
+
+       local use_flag=
+
+       case "${kext}" in
+               GZ)
+                       use_flag="zlib"
+                       ;;
+               KO)
+                       ;;
+               XZ)
+                       use_flag="lzma"
+                       ;;
+               ZST)
+                       use_flag="zstd"
+                       ;;
+               *)
+                       gen_die "$(get_useful_function_stack)Internal error: 
KEXT '${kext}' is unknown!"
+                       ;;
+       esac
+
+       echo "${use_flag}"
+}
+
 # @FUNCTION: get_nproc
 # @USAGE: [${fallback:-1}]
 # @DESCRIPTION:

diff --git a/gen_initramfs.sh b/gen_initramfs.sh
index b9aeb0b..8f11127 100755
--- a/gen_initramfs.sh
+++ b/gen_initramfs.sh
@@ -1727,9 +1727,19 @@ append_modules() {
                rm -r "${TDIR}" || gen_die "Failed to clean out existing 
'${TDIR}'!"
        fi
 
+       populate_binpkg kmod
+
        mkdir "${TDIR}" || gen_die "Failed to create '${TDIR}'!"
+
+       unpack "$(get_gkpkg_binpkg kmod)" "${TDIR}"
+
        cd "${TDIR}" || gen_die "Failed to chdir to '${TDIR}'!"
 
+       # Delete unneeded files
+       rm -rf \
+               usr/include \
+               usr/lib
+
        local mydir=
        for mydir in \
                etc/modules \
@@ -1788,7 +1798,7 @@ append_modules() {
                || gen_die "Failed to copy '${modules_srcdir}/modules*' to 
'${modules_dstdir}'!"
 
        print_info 2 "$(get_indent 2)modules: Updating modules.dep ..."
-       local a depmod_cmd=( depmod -a -b "${TDIR}" ${KV} )
+       local depmod_cmd=( depmod -a -b "${TDIR}" ${KV} )
        print_info 3 "COMMAND: ${depmod_cmd[*]}" 1 0 1
        eval "${depmod_cmd[@]}" || gen_die "Failed to run '${depmod_cmd[*]}'!"
 
@@ -1986,6 +1996,16 @@ append_data() {
 create_initramfs() {
        print_info 1 "initramfs: >> Initializing ..."
 
+       if ! isTrue "${BUILD_KERNEL}"
+       then
+               # Check early for suitable kmod
+               determine_KEXT
+               if ! isTrue "$(is_kext_supported_by_kmod "${KEXT}")"
+               then
+                       gen_die "${KMOD_CMD} does not support chosen module 
compression algorithm. Please re-emerge sys-apps/kmod with 
USE=$(get_kext_kmod_use_flag "${KEXT}") enabled or adjust 
CONFIG_MODULE_COMPRESS_* kernel option!"
+               fi
+       fi
+
        # Create empty cpio
        CPIO_ARCHIVE="${TMPDIR}/${GK_FILENAME_TEMP_INITRAMFS}"
        append_data 'devices' # WARNING, must be first!

diff --git a/gkbuilds/kmod.gkbuild b/gkbuilds/kmod.gkbuild
index 8572b77..ac6b3e2 100644
--- a/gkbuilds/kmod.gkbuild
+++ b/gkbuilds/kmod.gkbuild
@@ -20,8 +20,9 @@ src_prepare() {
 src_configure() {
        local myconf=(
                --enable-static
+               --disable-manpages
                --disable-python
-               --disable-tools
+               --enable-tools
                --with-xz
                --with-zlib
                --with-zstd
@@ -48,4 +49,27 @@ src_install() {
 
        rm -rf \
                "${D}"/usr/share/
+
+       "${STRIP}" --strip-all "${D}"/usr/bin/kmod \
+               || die "Failed to strip '${D}/usr/bin/kmod'!"
+
+       mkdir "${D}"/bin || die "Failed to create '${D}/bin'!"
+
+       mkdir "${D}"/sbin || die "Failed to create '${D}/sbin'!"
+
+       # We need to install these links where busybox would create them
+       local symlink_targets=()
+       symlink_targets+=( /sbin/depmod )
+       symlink_targets+=( /sbin/insmod )
+       symlink_targets+=( /sbin/lsmod )
+       symlink_targets+=( /sbin/modinfo )
+       symlink_targets+=( /sbin/modprobe )
+       symlink_targets+=( /sbin/rmmod )
+
+       local symlink_target=
+       for symlink_target in "${symlink_targets[@]}"
+       do
+               ln -s ../usr/bin/kmod "${D}${symlink_target}" \
+                       || die "Failed to create symlink 
'${D}${symlink_target}' to '${D}/usr/bin/kmod'!"
+       done
 }

diff --git a/patches/kmod/29/kmod-29-static.patch 
b/patches/kmod/29/kmod-29-static.patch
new file mode 100644
index 0000000..c29ab7f
--- /dev/null
+++ b/patches/kmod/29/kmod-29-static.patch
@@ -0,0 +1,12 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -155,6 +155,8 @@ tools_kmod_SOURCES += \
+       tools/remove.c
+ endif
+ 
++tools_kmod_LDFLAGS = -all-static
++
+ tools_kmod_LDADD = \
+       shared/libshared.la \
+       libkmod/libkmod-internal.la
+ 

Reply via email to