]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
fix(kernel-modules): detect block device's hardware driver
authorPingfan Liu <piliu@redhat.com>
Wed, 28 Jul 2021 10:13:43 +0000 (18:13 +0800)
committerJóhann B. Guðmundsson <johannbg@gmail.com>
Fri, 13 Aug 2021 11:36:25 +0000 (11:36 +0000)
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 <piliu@redhat.com>
---
v2 -> v3:
  address shellcheck in dracut-functions.sh
v1 -> v2:
  remove local variable _extra_mod
  shorten subject

dracut-functions.sh
modules.d/90kernel-modules/module-setup.sh

index 5206bd218b6e722fe19095446b0ba3c6154e26f7..32177994822e8e13fa421adbd4683d1c8ae81185 100755 (executable)
@@ -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.
index 69dc18b59586c18b3d38ea7217388977fdc374cf..613c20e78cd330e188a1ab2192ebc7dd1b6777d3 100755 (executable)
@@ -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
     }