Skip to content

Commit dc3b976

Browse files
aafeijoo-suseharaldh
authored andcommitted
fix(dracut-functions.sh): get block device driver if in a virtual subsystem
dracut does not install the kernel module of the block device that contains the root filesystem if the following preconditions are met: - Running in host-only mode. - Symlinks of all block devices needed to boot the system pointing to virtual subsystems. The get_dev_module function uses "udevadm info -a" to get the corresponding kernel modules of a /sys/class/*/* or /dev/* device. This function is called in modules.d/90kernel-modules/module-setup.sh to detect if dracut must install block device drivers in host-only mode. The symlinks in /sys/dev/block/ usually point to "real" devices in /sys/devices/pci*. But, we have come across some NVMe systems where the kernel creates the symlinks in /sys/dev/block/ pointing to "virtual" devices instead. In this case, udevadm never finds any "driver" attributes following up the chain of parent devices.
1 parent d364ce8 commit dc3b976

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

dracut-functions.sh

+25-1
Original file line numberDiff line numberDiff line change
@@ -945,5 +945,29 @@ block_is_netdevice() {
945945
946946
# get the corresponding kernel modules of a /sys/class/*/* or/dev/* device
947947
get_dev_module() {
948-
udevadm info -a "$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p'
948+
local dev_attr_walk
949+
local dev_drivers
950+
dev_attr_walk=$(udevadm info -a "$1")
951+
dev_drivers=$(echo "$dev_attr_walk" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p')
952+
# if no kernel modules found and device is in a virtual subsystem, follow symlinks
953+
if [[ -z $dev_drivers && $(udevadm info -q path "$1") == "/devices/virtual"* ]]; then
954+
local dev_vkernel
955+
local dev_vsubsystem
956+
local dev_vpath
957+
dev_vkernel=$(echo "$dev_attr_walk" | sed -n 's/\s*KERNELS=="\(\S\+\)"/\1/p' | tail -1)
958+
dev_vsubsystem=$(echo "$dev_attr_walk" | sed -n 's/\s*SUBSYSTEMS=="\(\S\+\)"/\1/p' | tail -1)
959+
dev_vpath="/sys/devices/virtual/$dev_vsubsystem/$dev_vkernel"
960+
if [[ -n $dev_vkernel && -n $dev_vsubsystem && -d $dev_vpath ]]; then
961+
local dev_links
962+
local dev_link
963+
dev_links=$(find "$dev_vpath" -maxdepth 1 -type l ! -name "subsystem" -exec readlink {} \;)
964+
for dev_link in $dev_links; do
965+
[[ -n $dev_drivers && ${dev_drivers: -1} != $'\n' ]] && dev_drivers+=$'\n'
966+
dev_drivers+=$(udevadm info -a "$dev_vpath/$dev_link" \
967+
| sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p' \
968+
| grep -v -e pcieport)
969+
done
970+
fi
971+
fi
972+
echo "$dev_drivers"
949973
}

0 commit comments

Comments
 (0)