d1a34d
From 697811ff58c3dfa62fad86e9fe8c9dd7268cadfa Mon Sep 17 00:00:00 2001
d1a34d
From: Pingfan Liu <piliu@redhat.com>
d1a34d
Date: Wed, 28 Jul 2021 18:13:43 +0800
d1a34d
Subject: [PATCH] fix(kernel-modules): detect block device's hardware driver
d1a34d
d1a34d
On hostonly mode, the platform driver is not copied blindless. There
d1a34d
should be a way to detect the real hardware driver, which probes a block
d1a34d
device.
d1a34d
d1a34d
/sys/dev/block/major:minor is a symbol link, which points to the real
d1a34d
device, recording the hardware stack. And those info can help to
d1a34d
identify the associated drivers for the hardware stack.
d1a34d
d1a34d
Signed-off-by: Pingfan Liu <piliu@redhat.com>
d1a34d
---
d1a34d
v2 -> v3:
d1a34d
  address shellcheck in dracut-functions.sh
d1a34d
v1 -> v2:
d1a34d
  remove local variable _extra_mod
d1a34d
  shorten subject
d1a34d
d1a34d
(cherry picked from commit c86f4d286000d1e76fd405560b4114537e2cbbff)
d1a34d
d1a34d
Resolves: #1981251
d1a34d
---
d1a34d
 dracut-functions.sh                        | 21 +++++++++++++++++++++
d1a34d
 modules.d/90kernel-modules/module-setup.sh |  6 ++++++
d1a34d
 2 files changed, 27 insertions(+)
d1a34d
d1a34d
diff --git a/dracut-functions.sh b/dracut-functions.sh
d1a34d
index 5206bd21..32177994 100755
d1a34d
--- a/dracut-functions.sh
d1a34d
+++ b/dracut-functions.sh
d1a34d
@@ -617,6 +617,27 @@ for_each_host_dev_and_slaves() {
d1a34d
     return 1
d1a34d
 }
d1a34d
 
d1a34d
+# /sys/dev/block/major:minor is symbol link to real hardware device
d1a34d
+# go downstream $(realpath /sys/dev/block/major:minor) to detect driver
d1a34d
+get_blockdev_drv_through_sys() {
d1a34d
+    local _block_mods=""
d1a34d
+    local _path
d1a34d
+
d1a34d
+    _path=$(realpath "$1")
d1a34d
+    while true; do
d1a34d
+        if [[ -L "$_path"/driver/module ]]; then
d1a34d
+            _mod=$(realpath "$_path"/driver/module)
d1a34d
+            _mod=$(basename "$_mod")
d1a34d
+            _block_mods="$_block_mods $_mod"
d1a34d
+        fi
d1a34d
+        _path=$(dirname "$_path")
d1a34d
+        if [[ $_path == '/sys/devices' ]] || [[ $_path == '/' ]]; then
d1a34d
+            break
d1a34d
+        fi
d1a34d
+    done
d1a34d
+    echo "$_block_mods"
d1a34d
+}
d1a34d
+
d1a34d
 # ugly workaround for the lvm design
d1a34d
 # There is no volume group device,
d1a34d
 # so, there are no slave devices for volume groups.
d1a34d
diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh
d1a34d
index 36f8ca3c..86e281ae 100755
d1a34d
--- a/modules.d/90kernel-modules/module-setup.sh
d1a34d
+++ b/modules.d/90kernel-modules/module-setup.sh
d1a34d
@@ -16,9 +16,15 @@ installkernel() {
d1a34d
     }
d1a34d
 
d1a34d
     record_block_dev_drv() {
d1a34d
+
d1a34d
         for _mod in $(get_dev_module /dev/block/"$1"); do
d1a34d
             _hostonly_drvs["$_mod"]="$_mod"
d1a34d
         done
d1a34d
+
d1a34d
+        for _mod in $(get_blockdev_drv_through_sys "/sys/dev/block/$1"); do
d1a34d
+            _hostonly_drvs["$_mod"]="$_mod"
d1a34d
+        done
d1a34d
+
d1a34d
         ((${#_hostonly_drvs[@]} > 0)) && return 0
d1a34d
         return 1
d1a34d
     }
d1a34d