[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#620814: initramfs-tools: fails to include essential module for other leg of md0



Thusly spoke maximilian attems (maks@debian.org on 2011-04-05 06:44
+0000):
> On Mon, Apr 04, 2011 at 10:15:21PM +0000, Arno Schuring wrote:
> > 
> > 
> > > no, check your box with:
> > > egrep MODULES -r /etc/initramfs-tools/
> > 
> > Great.
> > 
> > /etc/initramfs-tools/initramfs.conf:# MODULES: [ most | netboot |
> > dep | list ] /etc/initramfs-tools/initramfs.conf:MODULES=most
> 
> > /etc/initramfs-tools/conf.d/driver-policy:MODULES=dep
> 
> you choose so on your Debian installation. on the why only you can
> respond (:
Habit. But my surprise was that MODULES was defined twice. Having never
dealt with conf.d before, I didn't think to look there.

> The expert install has a seemingly bad phrase so that many
> users seem to prefer MODULES=dep, when that question is shown.
I did use expert install, but I would have chosen dep anyway; it's
never bitten me in the past, and I used to use very small (32MB)
IDE-flash drives for /boot.

> As you noticed the file is unowned and can be removed and the
> initramfs regenerated.
> 
> Nevertheless your fail in MODULES=dep is interesting and didn't have
> time yet to properly read this corresponding bug.
Since I had already spent so much time reading into the source, I spent
another hour yesterday to rewrite hook-functions to my liking. Patch
attached. It basically replaces the entire sysfs-from-dev divination
with a walker that uses sysfs' slave links to reach the underlying
device, collecting modules along the way.

Please treat this as an FYI, not a push. The exercise is academic
anyway, since this is not in any way a resource-constrained device. I'm
not comfortable signing off on this code, because
a) I simply can't test and have no experience with block devices other
than lvm, md and plain partitions.
b) the code assumes a lot about sysfs that I have not been able to
support with documentation:
- there appears to be no guarantee about the existence of a block
  device at all (maybe it's driver-dependent?)
- no guarantee about whether following slaves/ in /block/ will always
  reach an endpoint under /devices/
- "Never depend on the "device"-link" is mentioned explicitly in the
  document, but there appears to be no other way to reach driver/ from
  /block/ (?). It also explicitly says "Accessing
  /sys/class/net/eth0/device is a bug in the application"
c) initramfs is not exactly the place where you can afford to be naive
without consequence


That said, this code WorksForMe(tm), I've tried very hard not to
break any old code paths. It can't replace the existing code anyway
because it relies on udev, which is non-essential. I think
sys_walk_device might be useful though.

Oh, and there's several indentation violations to avoid huge
whitespace-only changes. Like I said, it's not a submission.
--- hook-functions.orig	2011-01-28 15:11:01.000000000 +0100
+++ hook-functions	2011-04-06 00:54:41.307212833 +0200
@@ -213,10 +213,37 @@
 	fi
 }
 
+sys_walk_device()
+{
+	local dev_path
+
+	dev_path="${1}"
+	# regular device or partition
+	if [ "${dev_path#/sys/devices/}" != "${dev_path}" ]; then
+		sys_walk_mod_add "${dev_path}"
+	elif [ -e "${dev_path}/dev" ]; then
+		sys_walk_mod_add "$(readlink -f "${dev_path}/device")"
+	fi
+	# possible dm/md device node
+	if [ -e "${dev_path}/dm" ]; then
+		manual_add_modules lvm
+	elif [ -e "${dev_path}/md" ]; then
+		#this works even for level=raid5 (module raid456.ko)
+		manual_add_modules "$(cat "${dev_path}/md/level")"
+	fi
+
+	if [ -e "${dev_path}/slaves" ]; then
+		#FIXME this breaks on spaces in the devpath
+		for slave in "${dev_path}"/slaves/* ; do
+			sys_walk_device "$(readlink -f "${slave}")"
+		done
+	fi
+}
+
 # find and only copy root relevant modules
 dep_add_modules()
 {
-	local block minor root FSTYPE root_dev_path x
+	local block minor root FSTYPE root_dev_path sys_path x
 
 	# require mounted sysfs
 	if [ ! -d /sys/devices/ ]; then
@@ -274,6 +301,11 @@
 	# Add rootfs
 	manual_add_modules "${FSTYPE}"
 
+	# query udev for the sysfs device path
+	sys_path="$(udevadm info --query=path --name="${root}")"
+
+# use old code path only if we failed to find the correct device
+if [ -z "${sys_path}" ]; then
 	# lvm or luks root
 	if [ "${root#/dev/mapper/}" != "${root}" ] \
 		|| [ "${root#/dev/dm-}" != "${root}" ]; then
@@ -359,10 +391,15 @@
 		echo "mkinitramfs: Error please report the bug" >&2
 		exit 1
 	fi
+fi
 
+	if [ -n "${sys_path}" ]; then
+		sys_walk_device "/sys${sys_path}"
+	else
 	# sys walk ATA
 	root_dev_path=$(readlink -f /sys/block/${block}/device)
 	sys_walk_mod_add ${root_dev_path}
+	fi
 
 	# catch old-style IDE
 	if [ -d "${DESTDIR}/lib/modules/${version}/kernel/drivers/ide" ]; then

Reply to: