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

Bug#699434: grub-installer: support for Intel Matrix Raid



Package: grub-installer
Version: 183
Tags: patch

See metabug 699430, http://bugs.debian.org/699430 :
        (debian-installer: support for Intel Matrix Raid (RST, imsm)

  * Support for mdadm fakeraid (currently only IMSM formatted disks):
    - also detect mdadm fakeraid underneath lvm, if it's just one array
    - install grub on each disk of the underlying array
    - add md/0 entry to device.map so grub-probe works (for upgrades etc)

This is by far the most intrusive patch - all the others are trivial.
Description:

- move make_device_map() upwards so that we can call it earlier
  in the script. Also, if $md_bootdev is set, add a (otherwise
  unused) "(md/0)" entry to device.map - otherwise grub-probe
  freaks out on upgrades.
- add is_mdraid_bootable(). It checks if the device is a Intel
  Matrix Raid device, in RAID1 mode. If not it returns false.
  Otherwise it sets $md_dev, $md_devs, $md_super and $md_level,
   and returns true.
- if installing on an lvm device, it finds the underlying device,
  and checks if it's a single mdraid array. If so $disc_under_lvm
  is set.
- if we're installing on a mdraid device and is_mdraid_bootable()
  is true, we set $disc_offered to the mdraid device, and set
  the $default_bootdev variable to all the underlying real disks.
- when installing on an mdraid device, always create the grub device.map
- do not try to guess the bootdevice if we already set $default_bootdev

Note that effectively this patch does NOT change any existing
behaviour if you are not trying to install on an Intel Matrix Raid
RAID1 array. As that wasn't supported before anyway, there is
no chance on regression.

Thanks

diff -ruN 00-ORIG/grub-installer-1.83/debian/changelog grub-installer-1.83/debian/changelog
--- 00-ORIG/grub-installer-1.83/debian/changelog	2012-10-27 06:07:35.000000000 +0000
+++ grub-installer-1.83/debian/changelog	2013-01-29 15:03:58.462971942 +0000
@@ -1,3 +1,12 @@
+grub-installer (1.83+1) unstable; urgency=low
+
+  * Support for mdadm fakeraid (currently only IMSM formatted disks):
+    - also detect mdadm fakeraid underneath lvm, if it's just one array
+    - install grub on each disk of the underlying array
+    - add md/0 entry to device.map so grub-probe works (for upgrades etc)
+
+ -- Miquel van Smoorenburg <miquels@debian.org>  Tue, 29 Jan 2013 15:50:37 +0100
+
 grub-installer (1.83) unstable; urgency=low
 
   [ Milan Kupcevic ]
diff -ruN 00-ORIG/grub-installer-1.83/grub-installer grub-installer-1.83/grub-installer
--- 00-ORIG/grub-installer-1.83/grub-installer	2012-10-25 01:01:57.000000000 +0000
+++ grub-installer-1.83/grub-installer	2013-01-29 14:56:40.103337917 +0000
@@ -217,6 +217,69 @@
 	echo "$ids"
 }
 
+make_device_map () {
+	# If you're preseeding (hd0) et al, stop - preseed OS device names
+	# instead.  However, for backward compatibility we ensure that a
+	# device.map exists if you do this.
+	[ "$grub_version" = grub2 ] || return 0
+	[ ! -e "$device_map" ] || return 0
+	local no_floppy
+	case $1 in
+		\(fd*|fd*)
+			no_floppy=
+			;;
+		*)
+			no_floppy=--no-floppy
+			;;
+	esac
+	$chroot $ROOT grub-mkdevicemap $no_floppy
+	if [ -n "$md_bootdev" ]
+	then
+		# This is lame- shouldn't need this, but otherwise
+		# grub-probe freaks out.
+		echo "(md/0)	$md_bootdev" >> $ROOT/boot/grub/device.map
+	fi
+}
+
+is_mdraid_bootable () {
+	local device="$1"
+	local mddisk=${device#/dev/}
+	local super
+	local level="`cat /sys/block/$mddisk/md/level 2>/dev/null ||:`"
+	local array_metadata="`cat /sys/block/$mddisk/md/metadata_version 2>/dev/null ||:`"
+	case "$array_metadata" in
+		external:/md*)
+			local ctdisk=${array_metadata#external:/}
+			ctdisk=${ctdisk%/*}
+			super="`cat /sys/block/$ctdisk/md/metadata_version 2>/dev/null ||:`"
+			super=${super#external:}
+			;;
+	esac
+	# Right now mdadm only supports imsm fakeraid, and grub doesn't know
+	# about it at all but raid1 works regardless. So restrict to imsm + raid1.
+	if [ "$level" = raid1 ] && [ "$super" = "imsm" ]
+	then
+		# Find the disks that make up the array to that grub can
+		# be installed onto all of them. As soon as grub supports
+		# imsm raid we should be able to install directly to the
+		# md device instead.
+		local mddisks="`echo /sys/block/$mddisk/md/dev-* |
+				sed -ne 's!/sys/block/md[0-9]\+/md/dev-\([^ \*]\+\)!/dev/\1!pg'`"
+		if [ -n "$mddisks" ]; then
+			md_devs="$mddisks"
+			md_super=$super
+			md_level=$level
+			for i in /dev/disk/by-id/md-*; do
+				if [ "`mapdevfs $i ||:`" = $device ]; then
+					md_dev=$i
+				fi
+			done
+			return 0
+		fi
+	fi
+	return 1
+}
+
 rootfs=$(findfs /)
 bootfs=$(findfs /boot)
 [ -n "$bootfs" ] || bootfs="$rootfs"
@@ -240,7 +303,7 @@
 
 case $prefix in
     /dev/md)
-	disc_offered_devfs="$bootfs"
+	disc_offered_devfs="${bootfs%p[0-9]}"
 	;;
     /dev/mapper)
 	disc_offered_devfs="$bootfs"
@@ -294,6 +357,29 @@
 	# Don't set frdev/frdisk here, otherwise you'll end up in different
 	# code paths below ...
 	frtype=lvm
+	# See if underlying device is a single MD disk
+	d_under=
+	devno=`ls -lL ${disc_offered} | sed -ne 's/^.* \([0-9]\+\), *\([0-9]\+\) .*$/\1:\2/p'`
+	for d_under_iter in /sys/dev/block/$devno/slaves/*; do
+		if [ -n "$d_under" ]; then
+			d_under=
+			break
+		fi
+		d_under=${d_under_iter#/sys/*/slaves/}
+	done
+	case "$d_under" in
+		md[0-9]*p[0-9])
+			prefix="/dev/md"
+			disc_under_lvm=/dev/${d_under%p[0-9]}
+			;;
+	esac
+fi
+
+if [ "$prefix" = /dev/md ] && is_mdraid_bootable ${disc_under_lvm:-$disc_offered}
+then
+	disc_offered="$md_dev"
+	md_bootdev="$md_dev"
+	default_bootdev="$md_devs"
 fi
 
 info "Identified partition label for $bootfs: $bootfslabel"
@@ -455,6 +541,10 @@
 
 grub_debian_version="$($chroot $ROOT dpkg-query -W -f '${Version}' $inst_package)"
 
+if [ -n "$md_bootdev" ]; then
+	make_device_map
+fi
+
 db_progress STEP 1
 db_progress INFO grub-installer/progress/step_os-probe
 os-prober > /tmp/os-probed || true
@@ -537,11 +627,14 @@
 
 # Try to avoid using (hd0) as a boot device name.  Something which can be
 # turned into a stable by-id name is better.
-default_bootdev_os="$($chroot $ROOT grub-mkdevicemap --no-floppy -m - | head -n1 | cut -f2)"
-if [ "$default_bootdev_os" ]; then
-	default_bootdev="$($chroot $ROOT readlink -f "$default_bootdev_os")"
-else
-	default_bootdev="(hd0)"
+if [ -z "$default_bootdev" ]; then
+	default_bootdev_os="$($chroot $ROOT grub-mkdevicemap --no-floppy -m - | head -n1 | cut -f2)"
+	if [ "$default_bootdev_os" ]; then
+		default_bootdev="$($chroot $ROOT readlink -f "$default_bootdev_os")"
+	else
+		default_bootdev="(hd0)"
+	fi
+	default_bootdev_guessed=1
 fi
 
 # Set a sensible default boot device, so that we aren't installing GRUB to
@@ -566,6 +659,7 @@
 	    (([ -n "$cdfs" ] && [ "$cdfs" != "iso9660" ]) || \
 	     [ "$hybrid" = true ])) || \
 	   ([ "$default_bootdev" != '(hd0)' ] && \
+	    [ -n "$default_bootdev_guessed" ] && \
 	    ! partmap "$default_bootdev" >/dev/null && \
 	    ! grub_probe -t fs -d "$default_bootdev" >/dev/null); then
 		db_fget grub-installer/bootdev seen
@@ -758,24 +852,6 @@
 	echo "$disk $part"
 }
 
-make_device_map () {
-	# If you're preseeding (hd0) et al, stop - preseed OS device names
-	# instead.  However, for backward compatibility we ensure that a
-	# device.map exists if you do this.
-	[ "$grub_version" = grub2 ] || return 0
-	[ ! -e "$device_map" ] || return 0
-	local no_floppy
-	case $1 in
-		\(fd*|fd*)
-			no_floppy=
-			;;
-		*)
-			no_floppy=--no-floppy
-			;;
-	esac
-	$chroot $ROOT grub-mkdevicemap $no_floppy
-}
-
 make_active_partition () {
 	bootdisk=
 	bootpart=


Reply to: