[Bug 872220] Re: Fails to boot when there's problems with softraid

Simon Bazley 872220 at bugs.launchpad.net
Wed Oct 3 15:37:30 UTC 2012


diff -u -r initramfs-tools/hooks/mdadm initramfs-tools-mdadm-changes/hooks/mdadm
--- initramfs-tools/hooks/mdadm 2012-08-04 07:54:25.000000000 +0100
+++ initramfs-tools-mdadm-changes/hooks/mdadm   2012-10-03 16:24:49.000000000 +0100
@@ -61,12 +61,112 @@
 done
 
 # copy the mdadm configuration
+FSTAB=/etc/fstab
 CONFIG=/etc/mdadm/mdadm.conf
 ALTCONFIG=/etc/mdadm.conf
 DESTMDADMCONF=$DESTDIR/etc/mdadm/mdadm.conf
+BOOTREQDDRIVES=$DESTDIR/etc/mdadm/boot_required
 [ ! -f $CONFIG ] && [ -f $ALTCONFIG ] && CONFIG=$ALTCONFIG || :
 mkdir -p ${DESTDIR}/etc/mdadm
 
+is_md_device()
+{
+       # --misc --detail will only return OK for active arrays
+       mdadm --misc --detail $1 >/dev/null 2>&1
+       ACTIVE=$?
+       # --misc --examine will only return OK for inactive arrays
+       mdadm --misc --examine $1 >/dev/null 2>&1
+       INACTIVE=$?
+       return $((${ACTIVE} & ${INACTIVE}))
+}
+
+find_inactive_md_device_uuid_from_scan()
+{
+       # mdadm --misc --scan --examine returns a list including inactives, but uses the form /dev/md/0 instead of /dev/md0
+       scanname=`echo $1 |sed "s/\(\/dev\/md\)\([0-9]*\)/\1\/\2/"`
+       mdadm --misc --scan --examine 2>/dev/null|grep ${scanname} | while read array device params; do
+               uuid=${params#*UUID=}; uuid=${uuid%% *}
+               echo ${uuid}
+               return 0
+       done
+       return 1
+}
+
+log_details_about_required_md_device()
+{
+       #echo "Seems $1 is an md device"
+       mduuid=`mdadm --misc --detail $1 2>/dev/null|grep UUID|sed "s/^.*UUID : \([:a-z0-9]*\).*$/\1/"`
+       if [ "${mduuid}" = "" ] ; then
+               mduuid=`find_inactive_md_device_uuid_from_scan $1`
+       fi
+       if [ "${mduuid}" != "" ] ; then
+               echo "Identified, md device $1, identified by UUID ${mduuid}, as required in fstab. "
+               echo $1 >> ${BOOTREQDDRIVES}
+               echo ${mduuid} >> ${BOOTREQDDRIVES}
+               return 0
+       else 
+               #echo "Couldn't work out the uuid for md device $1"
+               return 1
+       fi
+}
+
+
+identify_required_md_device()
+{
+       #echo "Identifying $1"
+       #Device identified as a valid device, so lets see if it is an md device
+       if is_md_device $1; then
+               #echo "$1 is an md_device"
+               # It is an md device, so try to log important details, for next boot
+               if ! log_details_about_required_md_device $1; then
+                       # Something went wrong identifying device details, so just log what we can
+                       echo "Had issues identifying details for md_device $1"
+                       if ! grep -q $1 ${BOOTREQDDRIVES}; then
+                               echo $1 ${BOOTREQDDRIVES}
+                       fi
+               fi
+#      else
+#              echo "$1 is not an md_device"
+       fi
+}
+
+# PARSE FSTAB to get a list of md file_systems essential for boot
+rm -f ${BOOTREQDDRIVES}
+touch ${BOOTREQDDRIVES}
+cat ${FSTAB} | grep -v ^\# | while read file_system mount_point type options dump pass; do
+       if [ "${pass}" = "" ] ; then
+               pass=0
+       fi
+       if [ ${pass} != 0 ] ; then
+               # Looks like ${file_system} is one who's failure would halt the boot, so consider it as a required device
+               #echo "Considering ${file_system}"
+               if echo "${file_system}" | grep -q "UUID"; then
+                       # Device identified by UUID, so look up the actual device name
+                       uuid=${file_system#*UUID=}; uuid=${uuid%% *}
+                       mount_source=`readlink -f /dev/disk/by-uuid/${uuid}`
+                       # ${mount_source} is the path I'd expect to be the actual device, let's see if that is a valid device
+                       if [ -e "/dev/disk/by-uuid/${uuid}"  -a "${mount_source}" != "" ] ; then
+                               identify_required_md_device ${mount_source}
+                       else
+                               # Generated device name didn't lookup to something valid, that could be a device mapper issue
+                               # This might be a problem with which kernel modules are loaded right now, rather than a problem
+                               # So register an error, and log the UUID that we have so far as required, it might be enough
+                               echo "Seems readlink couldn't identify /dev/disk/by-uuid/${uuid}.  Assuming it's required for boot"
+                               if ! grep -q ${uuid} ${BOOTREQDDRIVES}; then
+                                       echo ${uuid} >> ${BOOTREQDDRIVES}
+                               fi
+                       fi
+               else
+                       # Not a UUID device, so let's look up the device name to double check it isn't an md device anyway
+                       identify_required_md_device ${file_system}
+               fi
+       fi
+done
+if [ ! -s ${BOOTREQDDRIVES} ] ; then
+       rm -f ${BOOTREQDDRIVES}
+       echo "Checking /etc/fstab found no md devices are require to boot"
+fi
+
 if [ ! -f $CONFIG ]; then
         # there is no configuration file, so let's create one
         if /usr/share/mdadm/mkconf generate $CONFIG; then
diff -u -r initramfs-tools/scripts/local-premount/mdadm initramfs-tools-mdadm-changes/scripts/local-premount/mdadm
--- initramfs-tools/scripts/local-premount/mdadm        2012-08-04 07:54:25.000000000 +0100
+++ initramfs-tools-mdadm-changes/scripts/local-premount/mdadm  2012-10-03 16:09:27.000000000 +0100
@@ -8,5 +8,7 @@
 . /scripts/functions
 
 wait_for_udev
-degraded_arrays || exit 0
-mountroot_fail || panic "Dropping to a shell."
+(degraded_arrays && degraded_arrays_needed_for_boot) || exit 0
+sleep 10
+#degraded_arrays || exit 0
+mountroot_fail || panic "Dropping to a shell (type exit to attempt to continue with a normal boot)."
diff -u -r initramfs-tools/scripts/mdadm-functions initramfs-tools-mdadm-changes/scripts/mdadm-functions
--- initramfs-tools/scripts/mdadm-functions     2012-08-04 07:54:25.000000000 +0100
+++ initramfs-tools-mdadm-changes/scripts/mdadm-functions       2012-10-03 16:09:01.000000000 +0100
@@ -1,15 +1,61 @@
 #!/bin/sh
 
+find_inactive_md_device_uuid_from_scan()
+{
+       # mdadm --misc --scan --examine returns a list including inactives, but uses the form /dev/md/0 instead of /dev/md0
+       scanname=`echo $1 |sed "s/\(\/dev\/md\)\([0-9]*\)/\1\/\2/"`
+       mdadm --misc --scan --examine 2>/dev/null|grep ${scanname} | while read array device params; do
+               uuid=${params#*UUID=}; uuid=${uuid%% *}
+               echo ${uuid}
+               return 0
+       done
+       return 1
+}
+
+degraded_arrays_needed_for_boot()
+{
+       BOOTREQDDRIVES=/etc/mdadm/boot_required
+       if [ ! -s ${BOOTREQDDRIVES} ] ; then
+               echo "There are no md devices required to boot"
+               return 1
+       fi
+       if ! degraded_arrays; then
+               echo "There are no degraded arrays, so no need to check for required devices"
+               return 1
+       fi
+       #cat ${BOOTREQDDRIVES}
+       # --scan --detail will return active arrays on stdout and inactive messages identifying arrays on stderr
+       /sbin/mdadm --misc --scan --detail 2>&1 |grep "does not appear to be active"| while read mdadm md dev device extras; do
+               uuid=`find_inactive_md_device_uuid_from_scan ${device}`
+               echo "Found ${device} aka ${uuid} to be degraded"
+               if grep -q "${device}" ${BOOTREQDDRIVES}; then
+                       echo "Found ${device} in list of md devices that are required to boot"
+                       return 1
+               fi
+               if grep -q "${uuid}" ${BOOTREQDDRIVES}; then
+                       echo "Found ${uuid} in list of md devices that are required to boot"
+                       return 1
+               fi
+       done 
+       if [ $? = 1 ]; then
+               return 0
+       fi
+       echo "None of the degraded devices were found in list of md devices that are required to boot"
+       return 1
+} 
 
 degraded_arrays()
 {
        mdadm --misc --scan --detail --test >/dev/null 2>&1
        return $((! $?))
+       #RETVAL=$?
+       #echo "Returning $((! ${RETVAL}))"
+       #return $((! ${RETVAL}))
 }
 
 mountroot_fail()
 {
-       if degraded_arrays; then
+       if degraded_arrays && degraded_arrays_needed_for_boot; then
                cat <<EOF
 ** WARNING: There appears to be one or more degraded RAID devices **

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to mdadm in Ubuntu.
https://bugs.launchpad.net/bugs/872220

Title:
  Fails to boot when there's problems with softraid

Status in “mdadm” package in Ubuntu:
  Triaged

Bug description:
  Ubuntu 11.10 has a new feature that it warns you while booting if
  there's a program with the softraid.

  It tells you that a hard disk in the softraid is missing, then asks,
  on the console:

  Continue to boot? y/N

  But it ignores all keypresses. After 5 seconds or so it then times
  out, falls to the default "N" option, and dumps you to a emergency
  bash prompt, with no indication on how to proceed.

  The feature is a good idea, but not in the current broken state.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/mdadm/+bug/872220/+subscriptions




More information about the foundations-bugs mailing list