From 7973b9d099599bdde375065d25514d4f21295bba Mon Sep 17 00:00:00 2001 From: Sevinj Aghayeva Date: Thu, 14 Apr 2022 19:09:23 -0400 Subject: mbuto: support building a minimal image for kernel selftests Add suboption -C for the case of -p kselftests for choosing a test collection to run. For example, specifying "-p kselftests -C net" creates an image that contains only the tests from the net collection and only the kernel modules needed to run those tests. If there are missing modules for running the tests, a warning will be emitted showing missing modules names. The -C option is similar to the -c option of run_kselftests.sh, but unlike run_kselftest.sh's option it currently doesn't support specifying multiple collections. This will be fixed later. Also add suboption -T for the case of -p kselftests for choosing a specific test. For example, specifying: -p kselftests -T net:ip_defrag.sh" create an image that runs only the single test when booted. This option is also similar to run_kselftest.sh's -t option, but it lacks some functionality, which will be added later. Signed-off-by: Sevinj Aghayeva v1 -> v2: Update TOOLS, Use variable names for commands, and use capitalized versions of run_kselftests.sh options (-C and -T). --- mbuto | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 154 insertions(+), 27 deletions(-) diff --git a/mbuto b/mbuto index c643c9b..2c39942 100755 --- a/mbuto +++ b/mbuto @@ -205,7 +205,12 @@ profile_kselftests() { KERNEL="$(cat include/config/kernel.release)" - ${MAKE} -C tools/testing/selftests/ install >/dev/null 2>&1 + __skip_targets=$(${AWK} '/^TARGETS/ { print $3}' \ + tools/testing/selftests/Makefile | \ + ${GREP} -v "^${SUBOPT_collection}$" | ${TR} '\n' ' ') + + ${MAKE} SKIP_TARGETS="${__skip_targets}" -C \ + tools/testing/selftests/ install >/dev/null 2>&1 MODDIR="$(${REALPATH} .mbuto_mods)" ${RM} -rf "${MODDIR}" @@ -213,19 +218,46 @@ profile_kselftests() { INSTALL_MOD_PATH="${MODDIR}" ${MAKE} modules_install -j ${THREADS} \ >/dev/null - __skip_dirs="drivers/gpu drivers/iio drivers/infiniband drivers/media - drivers/net/ethernet drivers/net/wireless - drivers/scsi drivers/usb" - __skip_args= - for __d in ${__skip_dirs}; do - __skip_args="${__skip_args}-path ${__d} -prune " - done - KMODS="$(${FIND} "${MODDIR}" ${__skip_args} \ - -o -name '*.ko' -printf "%p ")" + __cfg="./tools/testing/selftests/${SUBOPT_collection}/config" + KMODS= + if [ -f ${__cfg} ]; then + __mods=$(${AWK} -F'=' '/=m/ {print $1}' ${__cfg} | ${SORT} -u) + + __egrep_pattern="" + for __c in ${__mods}; do + __egrep_pattern='^obj-\$\('"${__c}"'\).*.o$|'"${__egrep_pattern}" + done + __egrep_pattern=${__egrep_pattern%|} + + __kmods_needed= + __find_pattern= + for __mo in $(${EGREP} -rn --include "*Makefile" ${__egrep_pattern} | \ + ${AWK} -F'+=' '/+=/ {print $2}'); do + __m=$(${BASENAME} -s .o ${__mo}) + __find_pattern="-name ${__m}.ko -o ${__find_pattern}" + __kmods_needed="${__m} ${__kmods_needed}" + done + __find_pattern=${__find_pattern%-o } - workers kmod_strip_worker + KMODS=$(${FIND} "${MODDIR}" ${__find_pattern} | ${TR} '\n' ' ') - KMODS="$(basename -a -s .ko ${KMODS})" + workers kmod_strip_worker + + KMODS="$(${BASENAME} -a -s .ko ${KMODS})" + + __kmods_missing= + for __n in ${__kmods_needed}; do + __found=0 + for __f in ${KMODS}; do + [ ${__n} = ${__f} ] && __found=1 + done + [ ${__found} -eq 0 ] && \ + __kmods_missing="${__n} ${__kmods_missing}" + done + if [ ! -z "${__kmods_missing}" ]; then + notice "WARNING: missing modules: ${__kmods_missing}" + fi + fi LINKS="${LINKS:- bash /init @@ -240,6 +272,10 @@ profile_kselftests() { COPIES="${COPIES} tools/testing/selftests/kselftest_install/*," + __run_args= + [ ! -z ${SUBOPT_collection} ] && __run_args="-c ${SUBOPT_collection}" + [ ! -z ${SUBOPT_test} ] && __run_args="${__run_args} -t ${SUBOPT_test}" + FIXUP='#!/bin/sh export PATH=/bin:/usr/bin:/sbin:/usr/sbin @@ -266,7 +302,7 @@ profile_kselftests() { echo 3 > /proc/sys/kernel/printk echo "Press s for shell, any other key to run selftests" read a - [ "${a}" != "s" ] && ./run_kselftest.sh + [ "${a}" != "s" ] && ./run_kselftest.sh '"${__run_args}"' ' for __f in $(${FIND} tools/testing/selftests/kselftest_install/ \ @@ -286,9 +322,10 @@ profile_kselftests() { ### Helpers #################################################################### # List of tools used here, assigned to uppercase variable names -TOOLS="basename bc cat cd chmod cp cpio depmod diff dirname du file find grep - gzip ldconfig ldd ln ls make mkdir mknod mktemp modprobe mv printf - readlink realpath rm rmdir seq sleep strip sync umount uname wget which" +TOOLS="awk basename bc cat cd chmod cp cpio depmod diff dirname du file find + grep egrep gzip ldconfig ldd ln ls make mkdir mknod mktemp modprobe mv + printf readlink realpath rm rmdir seq sleep sort strip sync tr umount + uname wget which" # err() - Print error and exit # $@: Error message, optionally with printf format and arguments @@ -392,6 +429,81 @@ workers() { ################################################################################ +### Suboption Parsing ######################################################### + +SUBOPTS=' + kselftests C collection Select a collection of kernel tests + kselftests T test Select a test from a collection +' + +subopts_profile= +# subopts_usage() - Print suboption usage for a single, passed SUBOPTS line +# $1: Profile name from SUBOPTS line +# $2: Short option name from SUBOPTS line +# $3: Unused +# $4: Option description from SUBOPTS line +subopts_usage_one() { + __profile="${1}" + __short="${2}" + __help="${4}" + + if [ "${usage_subopts_profile}" != ${__profile} ]; then + usage_subopts_profile="${__profile}" + printf "\tSub-options for profile ${__profile}:\n" + fi + + printf "\t\t-%s: %s\n" ${__short} "${__help}" +} + +# subopts_usage() - Print suboption usage for all SUBOPTS +subopts_usage() { + IFS=' +' + for __line in ${SUBOPTS}; do + IFS=' ' + subopts_usage_one ${__line} + IFS=' +' + done + unset IFS +} + +# subopts_get_one() - Sub-option value from arguments, check one SUBOPTS line +# $1: Short option name as passed on command line +# $2: Value passed on command line +# $3: Profile name from SUBOPTS +# $4: Short option name from SUBOPTS +# $5: Long option name from SUBOPTS, used in SUBOPT_name assignment +subopts_get_one() { + __passed="${1}" + __value="${2}" + __profile="${3}" + __short="${4}" + __name="${5}" + + [ "${__profile}" != "${PROFILE}" ] && return 1 + [ "${__passed}" != "${__short}" ] && return 1 + + eval $(echo SUBOPT_${__name}="${__value}") +} + +# subopts_get() - Set sub-option values, validating against SUBOPTS +# $1: Short option name as passed on command line +# $2: Value passed on command line +# Return: 0 on success, 1 if option doesn't match known ones +subopts_get() { + IFS=' +' + for __line in ${SUBOPTS}; do + IFS=' ' + subopts_get_one "${1}" "${2}" ${__line} && unset IFS && return 0 + IFS=' +' + done + unset IFS + return 1 +} + ### CPIO ####################################################################### # cpio_init() - Source existing CPIO archive, or create if needed @@ -972,8 +1084,19 @@ usage() { echo " relative root for /lib/modules. Default: /" echo " -p PROFILE" echo " select profile for add-ons, one of:" - echo " base bash kata kata_debug passt" + echo " base bash kata kata_debug passt kselftests" echo " Default: base" + echo + echo " kselftests sub-options (same as run_kselftests.sh):" + echo " -C collection" + echo " select a collection of tests to run" + echo " -T collection:test" + echo " select a specific test to run" + echo " Examples:" + echo " -p kselftests -c net" + echo " run all the tests in net collection" + echo " -p kselftests -t net:ip_defrag.sh" + echo " run ip_defrag.sh from net collection" echo " -s SCRIPT|-" echo " fix-up script to run before init, '-' for none" echo " -v: verbose" @@ -1026,17 +1149,21 @@ usage() { ARGS=${@} # Parse options -while getopts c:df:k:m:p:s:vh __opt; do +while getopts :c:df:k:m:p:s:vh __opt; do case ${__opt} in - c) COMPRESS="${OPTARG}" ;; - d) STRIP="n" ;; - f) OUT="${OPTARG}" ;; - k) KERNEL="${OPTARG}" ;; - m) MODDIR="${OPTARG}" ;; - p) PROFILE="${OPTARG}" ;; - s) SCRIPT="${OPTARG}" ;; - v) VERBOSE="y" ;; - h|*) usage ;; + c) COMPRESS="${OPTARG}" ;; + d) STRIP="n" ;; + f) OUT="${OPTARG}" ;; + k) KERNEL="${OPTARG}" ;; + m) MODDIR="${OPTARG}" ;; + p) PROFILE="${OPTARG}" ;; + s) SCRIPT="${OPTARG}" ;; + v) VERBOSE="y" ;; + ?) + eval arg=\${$((OPTIND))} + OPTIND=$((OPTIND + 1)) + subopts_get "${OPTARG}" "${arg}" || usage ;; + h|*) usage ;; esac done shift $((OPTIND - 1)) -- cgit v1.2.3