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

Re: Bug#251905: Problems/workarounds for install to root on LVM on RAID



Martin Michlmayr wrote:

* tbm <tbm@cyrius.com> [2004-05-31 13:37]:
1) partman won't let you build an LVM on top of a RAID device

Still there.  This needs changed to libparted - maybe you can look at
this.

I haven't looked at this. If it doesn't involve lots of coding, I may be able to take a stab at it.

3) Grub install fails when /boot is on a RAID1 device

Still there.

Attached are two patches to address this (one for grub-install, and one for update-grub). Patches are against the version I have installed, which according to the changelog is 0.94+cvs20040511-1

update-grub:
------------

This one is pretty easy. The convert routine (which fails when passed an md device) is only called to get a default grub root device to use if one is not provided in the menu.lst file. It's not really necessary to have anything provided by this routine (in fact, if device.map doesn't exist, the default behavior is simply set the default to (hd0,0)).

I just created a convert_default 'wrapper', which calls convert() and returns the result or (hd0,0) if anything goes wrong (ie: convert exits with non-zero status).

grub-install:
-------------

This is a bit more complicated, as we actually have to figure out what device(s) to install grub on. My solution was to add a test for an md device prior to any of the other processing in the convert() procedure. If we're trying to convert /dev/md*, the new procedure getraid_mdadm() is called to identify a BIOS device we can then pass to the rest of the convert() code.

The getraid_mdadm procedure is pretty much lifted from the Debian mkinitrd scripts (at least the part that converts an md device into a list of physical drives). I modified the routine to return a single device, and to return the highest priority BIOS device that's also part of the RAID array. If no RAID members are BIOS devices (according to the device.map file), the first device listed by mdadm is returned.

NOTES:
------

- I have not implemented support for raidtools extraction of the RAID device info (ie: mdadm is required), although the code is in the mkinitrd script. If needed, this is left as an exercise for the reader :)

- I did not modify grub-install to install itself on the MBR of *ALL* devices in the array (which I usually do manually, in case the 'primary' HDD is the one that dies). This may or may not be desired behavior, but it seems somewhat unsafe to simply assume this behavior is wanted. You can do this manually by:
  grub-install '(hd0)'
  grub-install '(hd1)'
  ...

- I have not yet tested these mods on a 'bare-metal' install, but my system still boots after running 'grub-install' and 'update-grub' with the included mods. I need to do another re-install, so hopefully I'll be able to report on the success (or failure) of these patches on a ground-up install.

--
Charles Steinkuehler
charles@steinkuehler.net
--- grub-install.was	2004-06-21 14:36:27.000000000 -0500
+++ grub-install	2004-06-21 14:34:05.000000000 -0500
@@ -80,6 +80,50 @@
 EOF
 }
 
+# Usage: getraid_mdadm mddevice
+# Routine to find a physical device from an md device
+# If found, the first grub BIOS device (from device.map) is returned 
+# If no BIOS drives match the RAID devices, the first device returned
+# from mdadm -D is returned
+getraid_mdadm() {
+	device=$1
+	mdadm=$(mdadm -D "$device") || {
+		echo "$PROG: mdadm -D $device failed" >&2
+		exit 1
+	}
+	eval "$(
+		echo "$mdadm" | awk '
+			$1 == "Number" && $2 == "Major" { start = 1; next }
+			$1 == "UUID" { print "uuid=" $3; start = 0; next }
+			!start { next }
+			$2 == 0 && $3 == 0 { next }
+			{ devices = devices "\n" $NF }
+			END { print "devices='\''" devices "'\''" }
+		'
+	)"
+
+	# Convert RAID devices list into a list of disks
+	tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
+					 -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+					 -e 's%\(fd[0-9]*\)$%\1%' \
+					 -e 's%/part[0-9]*$%/disc%' \
+					 -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
+					 -e '/^$/d' |
+				     sed -n '1h;2,$H;${g;s/\n/|/g;p}'`
+
+	# Find first BIOS disk that's a member of the RAID array
+	# Default to first RAID member if no tmp_disks are BIOS devices
+	set -- `egrep $tmp_disks $device_map | \
+		sort | \
+		sed -n 1p `
+	device=${2:-${tmp_disks%%|*}}
+
+	# Return first partition on BIOS disk that's part of the RAID
+	echo "$devices" | \
+		sed -n "\:${device}:p" | \
+		sed -n 1p
+}
+
 # Usage: convert os_device
 # Convert an OS device to the corresponding GRUB drive.
 # This part is OS-specific.
@@ -95,6 +139,10 @@
     # Break the device name into the disk part and the partition part.
     case "$host_os" in
     linux*)
+	# Find an actual physical device if we're passed a RAID device
+	case $1 in
+		/dev/md*)  set -- `getraid_mdadm $1`
+	esac
 	tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
 				  -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
 				  -e 's%\(fd[0-9]*\)$%\1%' \
--- update-grub.was	2004-06-21 14:37:35.000000000 -0500
+++ update-grub	2004-06-21 14:46:58.000000000 -0500
@@ -196,6 +196,18 @@
     fi
 }
 
+# Usage: convert_default os_device
+# Convert an OS device to the corresponding GRUB drive.
+# Calls OS-specific convert, and returns a default of
+# (hd0,0) if anything goes wrong
+convert_default () {
+	local tmp
+	if tmp=$(convert $1 2>/dev/null) ; then
+		echo $tmp
+	else
+		echo "(hd0,0)"
+	fi
+}
 
 ## Configuration Options
 # directory's to look for the grub installation and the menu file
@@ -224,9 +236,9 @@
 # if we don't have a device.map then we can't use the convert function.
 if test -f "$device_map" ; then
 	if test -z "$boot_device" ; then
-		grub_root_device=$(convert "$root_device")
+		grub_root_device=$(convert_default "$root_device")
 	else
-		grub_root_device=$(convert "$boot_device")
+		grub_root_device=$(convert_default "$boot_device")
 	fi
 else
 	grub_root_device="(hd0,0)"

Reply to: