From: Pingfan Liu Date: Wed, 28 Jul 2021 10:13:43 +0000 (+0800) Subject: fix(kernel-modules): detect block device's hardware driver X-Git-Tag: 056~111 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c86f4d286000d1e76fd405560b4114537e2cbbff;p=thirdparty%2Fdracut.git fix(kernel-modules): detect block device's hardware driver On hostonly mode, the platform driver is not copied blindless. There should be a way to detect the real hardware driver, which probes a block device. /sys/dev/block/major:minor is a symbol link, which points to the real device, recording the hardware stack. And those info can help to identify the associated drivers for the hardware stack. Signed-off-by: Pingfan Liu --- v2 -> v3: address shellcheck in dracut-functions.sh v1 -> v2: remove local variable _extra_mod shorten subject --- diff --git a/dracut-functions.sh b/dracut-functions.sh index 5206bd218..321779948 100755 --- a/dracut-functions.sh +++ b/dracut-functions.sh @@ -617,6 +617,27 @@ for_each_host_dev_and_slaves() { return 1 } +# /sys/dev/block/major:minor is symbol link to real hardware device +# go downstream $(realpath /sys/dev/block/major:minor) to detect driver +get_blockdev_drv_through_sys() { + local _block_mods="" + local _path + + _path=$(realpath "$1") + while true; do + if [[ -L "$_path"/driver/module ]]; then + _mod=$(realpath "$_path"/driver/module) + _mod=$(basename "$_mod") + _block_mods="$_block_mods $_mod" + fi + _path=$(dirname "$_path") + if [[ $_path == '/sys/devices' ]] || [[ $_path == '/' ]]; then + break + fi + done + echo "$_block_mods" +} + # ugly workaround for the lvm design # There is no volume group device, # so, there are no slave devices for volume groups. diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh index 69dc18b59..613c20e78 100755 --- a/modules.d/90kernel-modules/module-setup.sh +++ b/modules.d/90kernel-modules/module-setup.sh @@ -16,9 +16,15 @@ installkernel() { } record_block_dev_drv() { + for _mod in $(get_dev_module /dev/block/"$1"); do _hostonly_drvs["$_mod"]="$_mod" done + + for _mod in $(get_blockdev_drv_through_sys "/sys/dev/block/$1"); do + _hostonly_drvs["$_mod"]="$_mod" + done + ((${#_hostonly_drvs[@]} > 0)) && return 0 return 1 }