From 881eda695ed552474b9d1e5befe084d7bfab3d50 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 29 Aug 2011 13:40:21 -0700 Subject: [PATCH] instmods: get filenames from stdin if no args; use it Use bash "[[ string =~ pattern ]]" instead of "egrep -q". Replace control-dominated serial fondling for var in $(proc1); do proc2 var; done with data-dominated parallel pipeline proc1 | while read var; do proc2 var; done Together this is a large savings. [harald@redhat.com: fixed network kernel module filter] --- dracut-functions | 57 ++++++++++++++++++++-------- modules.d/40network/module-setup.sh | 19 +++++++-- modules.d/90kernel-modules/module-setup.sh | 11 +++++- modules.d/90multipath/module-setup.sh | 15 +++++-- modules.d/95iscsi/module-setup.sh | 12 ++++- 5 files changed, 84 insertions(+), 30 deletions(-) diff --git a/dracut-functions b/dracut-functions index 4d3317c..556d309 100755 --- a/dracut-functions +++ b/dracut-functions @@ -863,49 +863,63 @@ filter_kernel_modules_by_path () ( esac done ) +find_kernel_modules_by_path () ( + if ! [[ $hostonly ]]; then + find "$srcmods/kernel/$1" "$srcmods/extra" "$srcmods/weak-updates" \ + -name "*.ko" -o -name "*.ko.gz" 2>/dev/null + else + cut -d " " -f 1 /dev/null + fi +) filter_kernel_modules () { filter_kernel_modules_by_path drivers "$1" } +find_kernel_modules () { + find_kernel_modules_by_path drivers +} + # install kernel modules along with all their dependencies. instmods() { [[ $no_kernel = yes ]] && return - local _mod _mpargs _moddirname - local _ret=0 - while (($# > 0)); do - _mod=${1%.ko*} + + function inst1mod() { + local _mod="$1" case $_mod in =*) # This introduces 2 incompatible meanings for =* arguments # to instmods. We need to decide which one to keep. if [[ $_mod = =ata && -f $srcmods/modules.block ]]; then - instmods $_mpargs \ - $(egrep 'ata|ahci' "${srcmods}/modules.block") + ( echo -n "$_mpargs"; egrep 'ata|ahci' "${srcmods}/modules.block" ) \ + | instmods elif [ -f $srcmods/modules.${_mod#=} ]; then - instmods $_mpargs $(cat ${srcmods}/modules.${_mod#=} ) + ( echo -n "$_mpargs"; cat "${srcmods}/modules.${_mod#=}" ) \ + | instmods else - instmods $_mpargs $(find "$srcmods" -path "*/${_mod#=}/*") + ( echo -n "$_mpargs"; find "$srcmods" -path "*/${_mod#=}/*" ) \ + | instmods fi ;; - --*) - _mpargs+=" $_mod";; - i2o_scsi) shift; continue;; # Do not load this diagnostic-only module + --*) _mpargs+="${_mod##*/}"$'\n' ;; # one _mod per line; lops '--' + i2o_scsi) return ;; # Do not load this diagnostic-only module *) _mod=${_mod##*/} + # if we are already installed, skip this module and go on # to the next one. - [[ -f $initdir/$1 ]] && { shift; continue; } + [[ -f $initdir/$1 ]] && return + # If we are building a host-specific initramfs and this # module is not already loaded, move on to the next one. [[ $hostonly ]] && ! grep -qe "\<${_mod//-/_}\>" /proc/modules \ - && ! echo $add_drivers | grep -qe "\<${_mod}\>" && { - shift; continue - } + && ! echo $add_drivers | grep -qe "\<${_mod}\>" \ + && return # We use '-d' option in modprobe only if modules prefix path # differs from default '/'. This allows us to use Dracut with # old version of modprobe which doesn't have '-d' option. - _moddirname=${srcmods%%/lib/modules/*} + local _moddirname=${srcmods%%/lib/modules/*} [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/" # ok, load the module, all its dependencies, and any firmware @@ -915,6 +929,17 @@ instmods() { ((_ret+=$?)) ;; esac + } + + local _mpargs _ret=0 + if (($# == 0)); then # filenames from stdin + local _mod + while read _mod; do + inst1mod "${_mod%.ko*}" + done + fi + while (($# > 0)); do # filenames as args + inst1mod ${1%.ko*} shift done return $_ret diff --git a/modules.d/40network/module-setup.sh b/modules.d/40network/module-setup.sh index 39366b6..cb81269 100755 --- a/modules.d/40network/module-setup.sh +++ b/modules.d/40network/module-setup.sh @@ -24,15 +24,24 @@ depends() { installkernel() { # Include wired net drivers, excluding wireless - net_module_test() { + net_module_filter() { local _net_drivers='eth_type_trans|register_virtio_device' local _unwanted_drivers='/(wireless|isdn|uwb)/' - egrep -q $_net_drivers "$1" && \ - egrep -qv 'iw_handler_get_spy' "$1" && \ - [[ ! $1 =~ $_unwanted_drivers ]] + local _fname + while read _fname; do + local _fcont + case "$_fname" in + *.ko) _fcont="$(< $_fname)" ;; + *.ko.gz) _fcont="$(gzip -dc $_fname)" ;; + esac + [[ $_fcont =~ $_net_drivers + && ! $_fcont =~ iw_handler_get_spy \ + && ! $_fname =~ $_unwanted_drivers ]] \ + && echo "$_fname" + done } - instmods $(filter_kernel_modules_by_path drivers/net net_module_test) + find_kernel_modules_by_path drivers/net | net_module_filter | instmods instmods ecb arc4 # bridge modules diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh index 245ec0b..9fc4248 100755 --- a/modules.d/90kernel-modules/module-setup.sh +++ b/modules.d/90kernel-modules/module-setup.sh @@ -9,6 +9,15 @@ installkernel() { egrep -q "$blockfuncs" "$1" } + block_module_filter() { + local _blockfuncs='ahci_init_controller|ata_scsi_ioctl|scsi_add_host|blk_init_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device' + local _f + while read _f; do case "$_f" in + *.ko) [[ $(< $_f) =~ $_blockfuncs ]] && echo "$_f" ;; + *.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;; + esac + done + } hostonly='' instmods sr_mod sd_mod scsi_dh scsi_dh_rdac scsi_dh_emc hostonly='' instmods pcmcia firewire-ohci hostonly='' instmods usb_storage sdhci sdhci-pci @@ -18,7 +27,7 @@ installkernel() { # install unix socket support hostonly='' instmods unix instmods "=drivers/pcmcia" =ide "=drivers/usb/storage" - instmods $(filter_kernel_modules block_module_test) + find_kernel_modules | block_module_filter | instmods # if not on hostonly mode, install all known filesystems, # if the required list is not set via the filesystems variable if ! [[ $hostonly ]]; then diff --git a/modules.d/90multipath/module-setup.sh b/modules.d/90multipath/module-setup.sh index e9a47fc..f68b58d 100755 --- a/modules.d/90multipath/module-setup.sh +++ b/modules.d/90multipath/module-setup.sh @@ -33,13 +33,18 @@ depends() { } installkernel() { - mp_mod_test() { - local mpfuncs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target' - egrep -q "$mpfuncs" "$1" + mp_mod_filter() { + local _mpfuncs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target' + local _f + while read _f; do case "$_f" in + *.ko) [[ $(< $_f) =~ $_mpfuncs ]] && echo "$_f" ;; + *.ko.gz) [[ $(gzip -dc <$_f) =~ $_mpfuncs ]] && echo "$_f" ;; + esac + done } - instmods $(filter_kernel_modules_by_path drivers/scsi mp_mod_test) - instmods $(filter_kernel_modules_by_path drivers/md mp_mod_test) + ( find_kernel_modules_by_path drivers/scsi; + find_kernel_modules_by_path drivers/md ) | mp_mod_filter | instmods } install() { diff --git a/modules.d/95iscsi/module-setup.sh b/modules.d/95iscsi/module-setup.sh index 3db40ea..b7771ab 100755 --- a/modules.d/95iscsi/module-setup.sh +++ b/modules.d/95iscsi/module-setup.sh @@ -42,11 +42,17 @@ depends() { installkernel() { instmods iscsi_tcp iscsi_ibft crc32c - iscsi_module_test() { + iscsi_module_filter() { local _iscsifuncs='iscsi_register_transport' - fgrep -q "$_iscsifuncs" "$1" + local _f + while read _f; do case "$_f" in + *.ko) [[ $(< $_f) =~ $_iscsifuncs ]] && echo "$_f" ;; + *.ko.gz) [[ $(gzip -dc <$_f) =~ $_iscsifuncs ]] && echo "$_f" ;; + esac + done } - instmods $(filter_kernel_modules_by_path drivers/scsi iscsi_module_test) + find_kernel_modules_by_path drivers/scsi \ + | iscsi_module_filter | instmods } install() {