From 817f53312678153037928344823e2a1f11fd3a69 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 5 Dec 2019 13:44:41 +0100 Subject: [PATCH] kmod.prov: fix and speed it up For kernel builds, /usr/lib/rpm/kmod.prov is fork+execed by rpmbuild in "Processing files:" step about 8000 times, single-threaded, with cumulative run time of ~2 minutes. Speed up this script, by avoiding additional fork+execing. Tested to work, observed speedup: almost exactly 2 times faster. While verifying correctness, noticed that old script was buggy - it was generating a bogus "Provides:" item - kmod(modules.builtin.modinfo), because the logic in script was filtering for */*.ko files and for */modules.builtin* files, and wasn't prepared for the existence of */modules.builtin.modinfo file. Signed-off-by: Denys Vlasenko --- kmod.prov | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/kmod.prov b/kmod.prov index f02d8a0..bbe5aa0 100644 --- a/kmod.prov +++ b/kmod.prov @@ -1,17 +1,28 @@ #!/bin/sh +x +# Kernel build can have many thousands of modules. +# kmod.prov is run for every one of them. +# Try to make this script run as fast as we can. +# For example, use shell string ops instead of external programs +# where possible. IFS=$'\n' -for i in $(grep -E '(/lib/modules/.*\.ko|/lib/modules/.*/modules.builtin)'); -do - kmod=$(basename $i | sed -e 's/.[xg]z//'); +read -r fname || exit - if [ $kmod == "modules.builtin" ]; then - for j in $(cat $i); do - j=$(basename $j); - echo "kmod($j)" - done - else - echo "kmod($kmod)" - fi -done +# Only process files from .../lib/modules/... subtree +[ "${fname#*/lib/modules/*}" != "$fname" ] || exit 0 + +kmod=${fname##*/} # like basename, but faster + +if [ "$kmod" = "modules.builtin" ]; then + for j in $(cat -- "$fname"); do + echo "kmod(${j##*/})" + done + exit 0 +fi + +kmod=${kmod%.gz} +kmod=${kmod%.xz} +if [ "${kmod%.ko}" != "$kmod" ]; then + echo "kmod($kmod)" +fi