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

[PATCH initramfs-tools] dep_add_modules: Add modules needed for /usr device



In case the root and /usr filesystems are of different types, or are
on different types of device, we must add the modules needed for both.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
I don't think we have an open bug report for this, but it's obvious we
need to deal with it.  It looks like a big patch but mostly it's
renaming to generalise from root.

Tested using a VM with MODULES=dep, root on virtio disk and /usr on an
emulated PIIX PATA disk.

Ben.

 hook-functions | 152 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 83 insertions(+), 69 deletions(-)

diff --git a/hook-functions b/hook-functions
index e71f0f8..4edbfde 100644
--- a/hook-functions
+++ b/hook-functions
@@ -256,53 +256,61 @@ add_loaded_modules()
 	fi
 }
 
-# find and only copy root relevant modules
-dep_add_modules()
+# find and only copy modules relevant to a mountpoint
+dep_add_modules_mount()
 {
-	local block minor root FSTYPE root_dev_path
+	local dir block minor dev_node FSTYPE dev_sys_path
 	local modules=
 
+	dir="$1"
+
 	# require mounted sysfs
 	if [ ! -d /sys/devices/ ]; then
 		echo "mkinitramfs: MODULES dep requires mounted sysfs on /sys" >&2
 		exit 1
 	fi
 
-	# findout root block device + fstype
+	# find out block device + fstype
 	eval "$( mount | while read -r dev foo mp foo fs opts rest ; do \
-        	[ "$mp" = "/" ] && [ "$fs" != "rootfs" ] \
-		&& printf "root='%s'\nFSTYPE='%s'" "$dev" "$fs" \
+		[ "$mp" = "$dir" ] && [ "$fs" != "rootfs" ] \
+		&& printf "dev_node='%s'\nFSTYPE='%s'" "$dev" "$fs" \
 		&& break; done)"
 
 	# On failure fallback to /proc/mounts if readable
-	if [ -z "$root" ] && [ -r /proc/mounts ]; then
+	if [ -z "$dev_node" ] && [ -r /proc/mounts ]; then
 		eval "$(while read dev mp fs opts rest ; do \
-			[ "$mp" = "/" ] && [ "$fs" != "rootfs" ] \
-			&& printf "root=$dev\nFSTYPE=$fs"\
+			[ "$mp" = "$dir" ] && [ "$fs" != "rootfs" ] \
+			&& printf "dev_node=$dev\nFSTYPE=$fs"\
 			&& break; done < /proc/mounts)"
 	fi
 
-	# handle ubifs and return since ubifs root is a char device but
-	# most of the commands below only work with block devices.
+	# Only the root mountpoint has to exist; do nothing if any other
+	# directory is not a mountpoint.
+	if [ "$dir" != / ] && [ -z "$dev_node" ]; then
+		return
+	fi
+
+	# handle ubifs and return since ubifs is mounted on char devices
+	# but most of the commands below only work with block devices.
 	if [ "${FSTYPE}" = "ubifs" ]; then
 		manual_add_modules "${FSTYPE}"
 		return
 	fi
 
-	if [ "${root}" = "/dev/root" ] ; then
-		if [ -b "${root}" ]; then
+	if [ "$dir" = / ] && [ "${dev_node}" = "/dev/root" ] ; then
+		if [ -b "${dev_node}" ]; then
 			# Match it to the canonical device name by UUID
-			root="/dev/disk/by-uuid/"$(blkid -o value -s UUID ${root}) 2>/dev/null
+			dev_node="/dev/disk/by-uuid/"$(blkid -o value -s UUID ${dev_node}) 2>/dev/null
 		else
 			# Does not exist in our namespace, so look at the
 			# kernel command line
-			root=
+			dev_node=
 			for arg in $(cat /proc/cmdline); do
 				case "$arg" in
 				root=*)
-					root="${arg#root=}"
-					if [ "${root#/dev/}" = "$root" ]; then
-						root="/dev/$root"
+					dev_node="${arg#root=}"
+					if [ "${dev_node#/dev/}" = "$dev_node" ]; then
+						dev_node="/dev/$dev_node"
 					fi
 					;;
 				--)
@@ -315,9 +323,10 @@ dep_add_modules()
 		fi
 	fi
 
-	# recheck root device
-	if [ -z "$root" ] || ! root="$(readlink -f ${root})" || ! [ -b "$root" ]; then
-		echo "mkinitramfs: failed to determine root device" >&2
+	# recheck device
+	if [ -z "$dev_node" ] || ! dev_node="$(readlink -f ${dev_node})" \
+		|| ! [ -b "$dev_node" ]; then
+		echo "mkinitramfs: failed to determine device for $dir" >&2
 		echo "mkinitramfs: workaround is MODULES=most, check:" >&2
 		echo "grep -r MODULES /etc/initramfs-tools/" >&2
 		echo "" >&2
@@ -327,26 +336,26 @@ dep_add_modules()
 	fi
 
 	# do not trust mount, check superblock
-	eval "$(/usr/lib/klibc/bin/fstype ${root})"
+	eval "$(/usr/lib/klibc/bin/fstype ${dev_node})"
 
-	# check that fstype rootfs recognition
+	# check that fstype fs recognition
 	if [ "${FSTYPE}" = "unknown" ]; then
-		FSTYPE=$(blkid -o value -s TYPE "${root}")
+		FSTYPE=$(blkid -o value -s TYPE "${dev_node}")
 		if [  -z "${FSTYPE}" ]; then
-			echo "mkinitramfs: unknown fstype on root ${root}" >&2
+			echo "mkinitramfs: unknown fstype on device ${dev_node}" >&2
 			echo "mkinitramfs: workaround is MODULES=most" >&2
 			echo "Error please report bug on initramfs-tools" >&2
 			exit 1
 		fi
 	fi
 
-	# Add rootfs
+	# Add filesystem
 	modules="$modules ${FSTYPE}"
 
-	# lvm or luks root
-	if [ "${root#/dev/mapper/}" != "${root}" ] \
-		|| [ "${root#/dev/dm-}" != "${root}" ]; then
-		minor=$((0x$(stat --format "%T" ${root}) % 256))
+	# lvm or luks device
+	if [ "${dev_node#/dev/mapper/}" != "${dev_node}" ] \
+		|| [ "${dev_node#/dev/dm-}" != "${dev_node}" ]; then
+		minor=$((0x$(stat --format "%T" ${dev_node}) % 256))
 		block=$(ls -1 /sys/block/dm-${minor}/slaves | head -n 1)
 		# lvm on luks or luks on lvm, possibly lvm snapshots
 		while [ "${block#dm-}" != "${block}" ]; do
@@ -363,85 +372,85 @@ dep_add_modules()
 		else
 			block=${block%%[0-9]*}
 		fi
-	# md root new naming scheme /dev/md/X
-	elif [ "${root#/dev/md/}" != "${root}" ]; then
-		root=${root#/dev/md/}
+	# md device new naming scheme /dev/md/X
+	elif [ "${dev_node#/dev/md/}" != "${dev_node}" ]; then
+		dev_node=${dev_node#/dev/md/}
 		# strip partion number
-		root=${root%%p[0-9]*}
+		dev_node=${dev_node%%p[0-9]*}
 		# drop the partition number only for sdX and hdX devices
 		# and keep it for other devices like loop#, dm-# devices
-		block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$root' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
-	# md root /dev/mdX
-	elif [ "${root#/dev/md}" != "${root}" ]; then
-		root=${root#/dev/md}
+		block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$dev_node' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
+	# md device /dev/mdX
+	elif [ "${dev_node#/dev/md}" != "${dev_node}" ]; then
+		dev_node=${dev_node#/dev/md}
 		# strip partion number
-		root=${root%%p[0-9]*}
+		dev_node=${dev_node%%p[0-9]*}
 		# drop the partition number only for sdX and hdX devices
 		# and keep it for other devices like loop#, dm-# devices
-		block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$root' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
+		block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$dev_node' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
 	# cciss device
-	elif [ "${root#/dev/cciss/}" != "${root}" ]; then
-		block=${root#/dev/cciss/*}
+	elif [ "${dev_node#/dev/cciss/}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/cciss/*}
 		block="cciss!${block%p*}"
 	# ida device
-	elif [ "${root#/dev/ida/}" != "${root}" ]; then
-		block=${root#/dev/ida/*}
+	elif [ "${dev_node#/dev/ida/}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/ida/*}
 		block="ida!${block%p*}"
-	# loop root /dev/loopX
-	elif [ "${root#/dev/loop}" != "${root}" ]; then
-		root=${root#/dev/}
+	# loop device /dev/loopX
+	elif [ "${dev_node#/dev/loop}" != "${dev_node}" ]; then
+		dev_node=${dev_node#/dev/}
 		block=$(losetup -a \
-			| awk "/${root}/{print substr(\$3, 7, 3); exit}")
+			| awk "/${dev_node}/{print substr(\$3, 7, 3); exit}")
 	# Xen virtual device /dev/xvdX
-	elif [ "${root#/dev/xvd}" != "${root}" ]; then
-		block=${root#/dev/}
+	elif [ "${dev_node#/dev/xvd}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/}
 		# Xen has a mode where only the individual partitions are
 		# registered with the kernel as well as the usual full disk
 		# with partition table scheme.
 		if [ ! -e /sys/block/${block} ] ; then
 			block=${block%%[0-9]*}
 		fi
-	# mmc root /dev/mmcblkXpX
-	elif [ "${root#/dev/mmcblk}" != "${root}" ]; then
-		block=${root#/dev/}
+	# mmc device /dev/mmcblkXpX
+	elif [ "${dev_node#/dev/mmcblk}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/}
 		block=${block%%p[0-9]*}
 
-	# nbd root /dev/nbdXpX
-	elif [ "${root#/dev/nbd}" != "${root}" ]; then
-		block=${root#/dev/}
+	# nbd device /dev/nbdXpX
+	elif [ "${dev_node#/dev/nbd}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/}
 		block=${block%%p[0-9]*}
 
-	# DAC960 - good old mylex raid - root dev format /dev/rd/cXdXpX
-	elif [ "${root#/dev/rd/c}" != "${root}" ]; then
-		block="rd!c${root#/dev/rd/c}"
+	# DAC960 - good old mylex raid - device format /dev/rd/cXdXpX
+	elif [ "${dev_node#/dev/rd/c}" != "${dev_node}" ]; then
+		block="rd!c${dev_node#/dev/rd/c}"
 		block=${block%%p[0-9]*}
 
 	# etherd device
-	elif [ "${root#/dev/etherd/}" != "${root}" ]; then
-		block=${root#/dev/etherd/*}
+	elif [ "${dev_node#/dev/etherd/}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/etherd/*}
 		block="etherd!${block%p*}"
 	# i2o raid device
-	elif [ "${root#/dev/i2o/}" != "${root}" ]; then
-		block=${root#/dev/i2o/}
+	elif [ "${dev_node#/dev/i2o/}" != "${dev_node}" ]; then
+		block=${dev_node#/dev/i2o/}
 		block=${block%%[0-9]*}
 		block='i2o!'$block
-	# classical root device
+	# classical block device
 	else
-		block=${root#/dev/}
+		block=${dev_node#/dev/}
 		block=${block%%[0-9]*}
 	fi
 
 	# Error out if /sys lack block dev
 	if [ -z "${block}" ] || [ ! -e /sys/block/${block} ]; then
-		echo "mkinitramfs: for root ${root} missing ${block} /sys/block/ entry" >&2
+		echo "mkinitramfs: for device ${dev_node} missing ${block} /sys/block/ entry" >&2
 		echo "mkinitramfs: workaround is MODULES=most" >&2
 		echo "mkinitramfs: Error please report the bug" >&2
 		exit 1
 	fi
 
 	# sys walk ATA
-	root_dev_path=$(readlink -f /sys/block/${block}/device)
-	sys_walk_mod_add ${root_dev_path}
+	dev_sys_path=$(readlink -f /sys/block/${block}/device)
+	sys_walk_mod_add ${dev_sys_path}
 
 	# sys walk some important device classes
 	for class in gpio phy regulator; do
@@ -459,7 +468,7 @@ dep_add_modules()
 
 	# catch old-style IDE
 	if [ -e /sys/bus/ide/devices/ ]; then
-		sys_walk_modalias ${root_dev_path}
+		sys_walk_modalias ${dev_sys_path}
 		modules="$modules ide-gd_mod ide-cd"
 	fi
 
@@ -491,6 +500,11 @@ dep_add_modules()
 	manual_add_modules $modules
 }
 
+dep_add_modules()
+{
+	dep_add_modules_mount /
+	dep_add_modules_mount /usr
+}
 
 # The modules "most" classes added per default to the initramfs
 auto_add_modules()

-- 
Ben Hutchings
The generation of random numbers is too important to be left to chance.
                                                            - Robert Coveyou

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: